Version Description
- new: HTML sub-option: "minify inline CSS/ JS" (off by default).
- new: Misc option: permanently allow the "do not run compatibility logic" flag to be removed (which was set for users upgrading from AO 2.9.* to AO 3.0.* as the assumption was things were working anyway).
- security: improvements to the critical CSS settings page to fix authenticated cross site scripting issues as reported by WPScan Security.
- bugfix: "defer inline JS" of very large chunks of inline JS could cause server errors (PCRE crash actually) so not deferring if string is more then 200000 characters (filter available).
- some other minor changes/ improvements/ hooks, see the GitHub commit log
Download this release
Release Info
Developer | futtta |
Plugin | Autoptimize |
Version | 3.1.0 |
Comparing to | |
See all releases |
Code changes from version 3.0.4 to 3.1.0
- autoptimize.php +2 -2
- classes/autoptimizeBase.php +3 -3
- classes/autoptimizeCache.php +2 -2
- classes/autoptimizeCompatibility.php +20 -15
- classes/autoptimizeConfig.php +54 -38
- classes/autoptimizeCriticalCSSBase.php +3 -3
- classes/autoptimizeCriticalCSSCore.php +15 -16
- classes/autoptimizeCriticalCSSCron.php +2 -0
- classes/autoptimizeCriticalCSSSettings.php +11 -15
- classes/autoptimizeCriticalCSSSettingsAjax.php +10 -1
- classes/autoptimizeExitSurvey.php +4 -3
- classes/autoptimizeExtra.php +5 -5
- classes/autoptimizeHTML.php +11 -1
- classes/autoptimizeImages.php +7 -7
- classes/autoptimizeMain.php +9 -1
- classes/autoptimizeMetabox.php +2 -0
- classes/autoptimizePartners.php +1 -1
- classes/autoptimizeScripts.php +7 -8
- classes/autoptimizeStyles.php +1 -1
- classes/autoptimizeUtils.php +3 -3
- classes/autoptimizeVersionUpdatesHandler.php +3 -3
- classes/critcss-inc/admin_settings_rules.js.php +7 -3
- classes/static/exit-survey/exit-survey.js +4 -0
- readme.txt +20 -160
autoptimize.php
CHANGED
@@ -3,7 +3,7 @@
|
|
3 |
* Plugin Name: Autoptimize
|
4 |
* Plugin URI: https://autoptimize.com/
|
5 |
* Description: Makes your site faster by optimizing CSS, JS, Images, Google fonts and more.
|
6 |
-
* Version: 3.0
|
7 |
* Author: Frank Goossens (futtta)
|
8 |
* Author URI: https://autoptimize.com/
|
9 |
* Text Domain: autoptimize
|
@@ -21,7 +21,7 @@ if ( ! defined( 'ABSPATH' ) ) {
|
|
21 |
exit;
|
22 |
}
|
23 |
|
24 |
-
define( 'AUTOPTIMIZE_PLUGIN_VERSION', '3.0
|
25 |
|
26 |
// plugin_dir_path() returns the trailing slash!
|
27 |
define( 'AUTOPTIMIZE_PLUGIN_DIR', plugin_dir_path( __FILE__ ) );
|
3 |
* Plugin Name: Autoptimize
|
4 |
* Plugin URI: https://autoptimize.com/
|
5 |
* Description: Makes your site faster by optimizing CSS, JS, Images, Google fonts and more.
|
6 |
+
* Version: 3.1.0
|
7 |
* Author: Frank Goossens (futtta)
|
8 |
* Author URI: https://autoptimize.com/
|
9 |
* Text Domain: autoptimize
|
21 |
exit;
|
22 |
}
|
23 |
|
24 |
+
define( 'AUTOPTIMIZE_PLUGIN_VERSION', '3.1.0' );
|
25 |
|
26 |
// plugin_dir_path() returns the trailing slash!
|
27 |
define( 'AUTOPTIMIZE_PLUGIN_DIR', plugin_dir_path( __FILE__ ) );
|
classes/autoptimizeBase.php
CHANGED
@@ -150,7 +150,7 @@ abstract class autoptimizeBase
|
|
150 |
// As we replaced the content-domain with the site-domain, we should match against that.
|
151 |
$tmp_ao_root = preg_replace( '/https?:/', '', AUTOPTIMIZE_WP_SITE_URL );
|
152 |
}
|
153 |
-
|
154 |
if ( is_multisite() && ! is_main_site() && ! empty( $this->cdn_url ) && apply_filters( 'autoptimize_filter_base_getpage_multisite_cdn_juggling', true ) ) {
|
155 |
// multisite child sites with CDN need the network_site_url as tmp_ao_root but only if directory-based multisite.
|
156 |
$_network_site_url = network_site_url();
|
@@ -171,8 +171,8 @@ abstract class autoptimizeBase
|
|
171 |
|
172 |
// Prepend with WP_ROOT_DIR to have full path to file.
|
173 |
$path = str_replace( '//', '/', trailingslashit( WP_ROOT_DIR ) . $path );
|
174 |
-
|
175 |
-
// Allow path to be altered, e.g. in the case of bedrock-like setups where
|
176 |
// core, theme & plugins might be in different locations on the filesystem.
|
177 |
$path = apply_filters( 'autoptimize_filter_base_getpath_path', $path, $url );
|
178 |
|
150 |
// As we replaced the content-domain with the site-domain, we should match against that.
|
151 |
$tmp_ao_root = preg_replace( '/https?:/', '', AUTOPTIMIZE_WP_SITE_URL );
|
152 |
}
|
153 |
+
|
154 |
if ( is_multisite() && ! is_main_site() && ! empty( $this->cdn_url ) && apply_filters( 'autoptimize_filter_base_getpage_multisite_cdn_juggling', true ) ) {
|
155 |
// multisite child sites with CDN need the network_site_url as tmp_ao_root but only if directory-based multisite.
|
156 |
$_network_site_url = network_site_url();
|
171 |
|
172 |
// Prepend with WP_ROOT_DIR to have full path to file.
|
173 |
$path = str_replace( '//', '/', trailingslashit( WP_ROOT_DIR ) . $path );
|
174 |
+
|
175 |
+
// Allow path to be altered, e.g. in the case of bedrock-like setups where
|
176 |
// core, theme & plugins might be in different locations on the filesystem.
|
177 |
$path = apply_filters( 'autoptimize_filter_base_getpath_path', $path, $url );
|
178 |
|
classes/autoptimizeCache.php
CHANGED
@@ -391,7 +391,7 @@ class autoptimizeCache
|
|
391 |
return false;
|
392 |
}
|
393 |
}
|
394 |
-
|
395 |
if ( ! self::cacheavail() ) {
|
396 |
return false;
|
397 |
}
|
@@ -823,7 +823,7 @@ class autoptimizeCache
|
|
823 |
$_kinsta_clear_cache_url = 'https://localhost/kinsta-clear-cache-all';
|
824 |
$_kinsta_response = wp_remote_get(
|
825 |
$_kinsta_clear_cache_url,
|
826 |
-
array(
|
827 |
'sslverify' => false,
|
828 |
'timeout' => 5,
|
829 |
)
|
391 |
return false;
|
392 |
}
|
393 |
}
|
394 |
+
|
395 |
if ( ! self::cacheavail() ) {
|
396 |
return false;
|
397 |
}
|
823 |
$_kinsta_clear_cache_url = 'https://localhost/kinsta-clear-cache-all';
|
824 |
$_kinsta_response = wp_remote_get(
|
825 |
$_kinsta_clear_cache_url,
|
826 |
+
array(
|
827 |
'sslverify' => false,
|
828 |
'timeout' => 5,
|
829 |
)
|
classes/autoptimizeCompatibility.php
CHANGED
@@ -1,7 +1,7 @@
|
|
1 |
<?php
|
2 |
/**
|
3 |
* Multiple compatibility snippets to ensure important/ stubborn plugins work out of the box.
|
4 |
-
*
|
5 |
*/
|
6 |
|
7 |
if ( ! defined( 'ABSPATH' ) ) {
|
@@ -24,7 +24,7 @@ class autoptimizeCompatibility
|
|
24 |
|
25 |
/**
|
26 |
* Runs multiple compatibility snippets to ensure important plugins work out of the box.
|
27 |
-
*
|
28 |
*/
|
29 |
public function run()
|
30 |
{
|
@@ -32,7 +32,7 @@ class autoptimizeCompatibility
|
|
32 |
if ( defined( 'ELEMENTOR_VERSION' ) && is_user_logged_in() && current_user_can( 'edit_posts' ) && apply_filters( 'autoptimize_filter_compatibility_editelementor_active', true ) ) {
|
33 |
add_filter( 'autoptimize_filter_js_noptimize', '__return_true' );
|
34 |
}
|
35 |
-
|
36 |
// Revslider; jQuery should not be deferred + exclude all revslider JS.
|
37 |
if ( defined( 'RS_REVISION' ) && $this->conf->get( 'autoptimize_js' ) && true == $this->inline_js_config_checker() && apply_filters( 'autoptimize_filter_compatibility_revslider_active', true ) ) {
|
38 |
add_filter( 'autoptimize_filter_js_exclude', function( $js_excl = '', $html = '' ) {
|
@@ -41,24 +41,24 @@ class autoptimizeCompatibility
|
|
41 |
if ( is_array( $js_excl ) ) {
|
42 |
$js_excl = implode( ',', $js_excl );
|
43 |
}
|
44 |
-
|
45 |
$js_excl .= ',' . $revslider_excl;
|
46 |
}
|
47 |
return $js_excl;
|
48 |
}, 11, 2 );
|
49 |
}
|
50 |
-
|
51 |
// Revslider; remove revslider JS if no slides in HTML for non-logged in users.
|
52 |
if ( defined( 'RS_REVISION' ) && $this->conf->get( 'autoptimize_js' ) && false === is_user_logged_in() && apply_filters( 'autoptimize_filter_compatibility_revslider_remover_active', true ) ) {
|
53 |
add_filter( 'autoptimize_filter_js_removables', function( $to_remove = '', $html = '' ) {
|
54 |
if ( ! empty( $html ) && false === strpos( $html, '<rs-slides>') ) {
|
55 |
$to_remove .= 'plugins/revslider, setREVStartSize, window.RSIW, window.RS_MODULES';
|
56 |
}
|
57 |
-
|
58 |
return $to_remove;
|
59 |
-
}, 11, 2 );
|
60 |
}
|
61 |
-
|
62 |
// Exclude jQuery if inline JS is found that requires jQuery.
|
63 |
if ( $this->inline_js_config_checker() && false === strpos( $this->conf->get( 'autoptimize_js_exclude' ), 'jquery.min.js' ) && apply_filters( 'autoptimize_filter_compatibility_inline_jquery', true ) ) {
|
64 |
add_filter( 'autoptimize_filter_js_exclude', function( $js_excl = '', $html = '' ) {
|
@@ -66,15 +66,20 @@ class autoptimizeCompatibility
|
|
66 |
if ( is_array( $js_excl ) ) {
|
67 |
$js_excl = implode( ',', $js_excl );
|
68 |
}
|
69 |
-
|
70 |
if ( false === strpos( $js_excl, 'jquery.min.js' ) ) {
|
71 |
$js_excl .= ', jquery.min.js';
|
72 |
}
|
|
|
|
|
|
|
|
|
|
|
73 |
}
|
74 |
return $js_excl;
|
75 |
}, 12, 2 );
|
76 |
}
|
77 |
-
|
78 |
// Make JS-based Gutenberg blocks work OOTB.
|
79 |
if ( $this->inline_js_config_checker() && apply_filters( 'autoptimize_filter_compatibility_gutenberg_js', true ) ) {
|
80 |
add_filter( 'autoptimize_filter_js_exclude', function( $js_excl = '', $html = '' ) {
|
@@ -82,11 +87,11 @@ class autoptimizeCompatibility
|
|
82 |
if ( is_array( $js_excl ) ) {
|
83 |
$js_excl = implode( ',', $js_excl );
|
84 |
}
|
85 |
-
|
86 |
if ( false === strpos( $js_excl, 'jquery.min.js' ) ) {
|
87 |
$js_excl .= ', jquery.min.js';
|
88 |
}
|
89 |
-
|
90 |
if ( false === strpos( $js_excl, 'wp-includes/js/dist' ) ) {
|
91 |
$js_excl .= ', wp-includes/js/dist';
|
92 |
}
|
@@ -95,10 +100,10 @@ class autoptimizeCompatibility
|
|
95 |
}, 13, 2 );
|
96 |
}
|
97 |
}
|
98 |
-
|
99 |
public function inline_js_config_checker() {
|
100 |
static $inline_js_flagged = null;
|
101 |
-
|
102 |
if ( null === $inline_js_flagged ) {
|
103 |
if ( ( $this->conf->get( 'autoptimize_js_aggregate' ) || apply_filters( 'autoptimize_filter_js_dontaggregate', false ) ) && apply_filters( 'autoptimize_js_include_inline', $this->conf->get( 'autoptimize_js_include_inline' ) ) ) {
|
104 |
// if all files and also inline JS are aggregated we don't have to worry about inline JS.
|
@@ -111,7 +116,7 @@ class autoptimizeCompatibility
|
|
111 |
// in all other cases we need to pay attention to inline JS requiring src'ed JS to be available.
|
112 |
$inline_js_flagged = true;
|
113 |
}
|
114 |
-
|
115 |
return $inline_js_flagged;
|
116 |
}
|
117 |
}
|
1 |
<?php
|
2 |
/**
|
3 |
* Multiple compatibility snippets to ensure important/ stubborn plugins work out of the box.
|
4 |
+
*
|
5 |
*/
|
6 |
|
7 |
if ( ! defined( 'ABSPATH' ) ) {
|
24 |
|
25 |
/**
|
26 |
* Runs multiple compatibility snippets to ensure important plugins work out of the box.
|
27 |
+
*
|
28 |
*/
|
29 |
public function run()
|
30 |
{
|
32 |
if ( defined( 'ELEMENTOR_VERSION' ) && is_user_logged_in() && current_user_can( 'edit_posts' ) && apply_filters( 'autoptimize_filter_compatibility_editelementor_active', true ) ) {
|
33 |
add_filter( 'autoptimize_filter_js_noptimize', '__return_true' );
|
34 |
}
|
35 |
+
|
36 |
// Revslider; jQuery should not be deferred + exclude all revslider JS.
|
37 |
if ( defined( 'RS_REVISION' ) && $this->conf->get( 'autoptimize_js' ) && true == $this->inline_js_config_checker() && apply_filters( 'autoptimize_filter_compatibility_revslider_active', true ) ) {
|
38 |
add_filter( 'autoptimize_filter_js_exclude', function( $js_excl = '', $html = '' ) {
|
41 |
if ( is_array( $js_excl ) ) {
|
42 |
$js_excl = implode( ',', $js_excl );
|
43 |
}
|
44 |
+
|
45 |
$js_excl .= ',' . $revslider_excl;
|
46 |
}
|
47 |
return $js_excl;
|
48 |
}, 11, 2 );
|
49 |
}
|
50 |
+
|
51 |
// Revslider; remove revslider JS if no slides in HTML for non-logged in users.
|
52 |
if ( defined( 'RS_REVISION' ) && $this->conf->get( 'autoptimize_js' ) && false === is_user_logged_in() && apply_filters( 'autoptimize_filter_compatibility_revslider_remover_active', true ) ) {
|
53 |
add_filter( 'autoptimize_filter_js_removables', function( $to_remove = '', $html = '' ) {
|
54 |
if ( ! empty( $html ) && false === strpos( $html, '<rs-slides>') ) {
|
55 |
$to_remove .= 'plugins/revslider, setREVStartSize, window.RSIW, window.RS_MODULES';
|
56 |
}
|
57 |
+
|
58 |
return $to_remove;
|
59 |
+
}, 11, 2 );
|
60 |
}
|
61 |
+
|
62 |
// Exclude jQuery if inline JS is found that requires jQuery.
|
63 |
if ( $this->inline_js_config_checker() && false === strpos( $this->conf->get( 'autoptimize_js_exclude' ), 'jquery.min.js' ) && apply_filters( 'autoptimize_filter_compatibility_inline_jquery', true ) ) {
|
64 |
add_filter( 'autoptimize_filter_js_exclude', function( $js_excl = '', $html = '' ) {
|
66 |
if ( is_array( $js_excl ) ) {
|
67 |
$js_excl = implode( ',', $js_excl );
|
68 |
}
|
69 |
+
|
70 |
if ( false === strpos( $js_excl, 'jquery.min.js' ) ) {
|
71 |
$js_excl .= ', jquery.min.js';
|
72 |
}
|
73 |
+
|
74 |
+
// also exclude jquery.js if for whatever reason that is still used.
|
75 |
+
if ( false === strpos( $js_excl, 'jquery.js' ) ) {
|
76 |
+
$js_excl .= ', jquery.js';
|
77 |
+
}
|
78 |
}
|
79 |
return $js_excl;
|
80 |
}, 12, 2 );
|
81 |
}
|
82 |
+
|
83 |
// Make JS-based Gutenberg blocks work OOTB.
|
84 |
if ( $this->inline_js_config_checker() && apply_filters( 'autoptimize_filter_compatibility_gutenberg_js', true ) ) {
|
85 |
add_filter( 'autoptimize_filter_js_exclude', function( $js_excl = '', $html = '' ) {
|
87 |
if ( is_array( $js_excl ) ) {
|
88 |
$js_excl = implode( ',', $js_excl );
|
89 |
}
|
90 |
+
|
91 |
if ( false === strpos( $js_excl, 'jquery.min.js' ) ) {
|
92 |
$js_excl .= ', jquery.min.js';
|
93 |
}
|
94 |
+
|
95 |
if ( false === strpos( $js_excl, 'wp-includes/js/dist' ) ) {
|
96 |
$js_excl .= ', wp-includes/js/dist';
|
97 |
}
|
100 |
}, 13, 2 );
|
101 |
}
|
102 |
}
|
103 |
+
|
104 |
public function inline_js_config_checker() {
|
105 |
static $inline_js_flagged = null;
|
106 |
+
|
107 |
if ( null === $inline_js_flagged ) {
|
108 |
if ( ( $this->conf->get( 'autoptimize_js_aggregate' ) || apply_filters( 'autoptimize_filter_js_dontaggregate', false ) ) && apply_filters( 'autoptimize_js_include_inline', $this->conf->get( 'autoptimize_js_include_inline' ) ) ) {
|
109 |
// if all files and also inline JS are aggregated we don't have to worry about inline JS.
|
116 |
// in all other cases we need to pay attention to inline JS requiring src'ed JS to be available.
|
117 |
$inline_js_flagged = true;
|
118 |
}
|
119 |
+
|
120 |
return $inline_js_flagged;
|
121 |
}
|
122 |
}
|
classes/autoptimizeConfig.php
CHANGED
@@ -62,7 +62,7 @@ class autoptimizeConfig
|
|
62 |
}
|
63 |
|
64 |
$this->settings_screen_do_remote_http = apply_filters( 'autoptimize_settingsscreen_remotehttp', $this->settings_screen_do_remote_http );
|
65 |
-
|
66 |
if ( $this->is_ao_meta_settings_active() ) {
|
67 |
$metaBox = new autoptimizeMetabox();
|
68 |
}
|
@@ -219,7 +219,7 @@ if ( is_network_admin() && autoptimizeOptionWrapper::is_ao_active_for_network()
|
|
219 |
</li>
|
220 |
<?php } else { ?>
|
221 |
<input type="hidden" id="autoptimize_enable_site_config" name="autoptimize_enable_site_config" value="on" />
|
222 |
-
<?php } ?>
|
223 |
|
224 |
<li class="itemDetail">
|
225 |
<h2 class="itemTitle"><?php _e( 'JavaScript Options', 'autoptimize' ); ?></h2>
|
@@ -351,7 +351,7 @@ echo __( 'A comma-separated list of CSS you want to exclude from being optimized
|
|
351 |
<?php if ( false === autoptimizeUtils::is_plugin_active( 'unusedcss/unusedcss.php' ) ) { ?>
|
352 |
<tr valign="top">
|
353 |
<th scope="row"><?php _e( 'Remove Unused CSS?', 'autoptimize' ); ?></th>
|
354 |
-
<?php
|
355 |
$_rapidload_link = 'https://misc.optimizingmatters.com/partners/?from=csssettings&partner=rapidload';
|
356 |
?>
|
357 |
<td><?php echo sprintf( __( 'If Google Pagespeed Insights detects unused CSS, consider using %s to <strong>reduce your site\'s CSS size to up to 90%</strong>, resulting in a slimmer, faster site!', 'autoptimize' ), '<a href="' . $_rapidload_link . '" target="_blank">the premium Rapidload service</a>' ); ?></td>
|
@@ -368,6 +368,11 @@ $_rapidload_link = 'https://misc.optimizingmatters.com/partners/?from=csssetting
|
|
368 |
<td><input type="checkbox" id="autoptimize_html" name="autoptimize_html" <?php echo $conf->get( 'autoptimize_html' ) ? 'checked="checked" ' : ''; ?>/></td>
|
369 |
</tr>
|
370 |
<tr class="html_sub" valign="top">
|
|
|
|
|
|
|
|
|
|
|
371 |
<th scope="row"><?php _e( 'Keep HTML comments?', 'autoptimize' ); ?></th>
|
372 |
<td><label class="cb_label"><input type="checkbox" name="autoptimize_html_keepcomments" <?php echo $conf->get( 'autoptimize_html_keepcomments' ) ? 'checked="checked" ' : ''; ?>/>
|
373 |
<?php _e( 'Enable this if you want HTML comments to remain in the page.', 'autoptimize' ); ?></label></td>
|
@@ -389,7 +394,7 @@ if ( true === autoptimizeImages::imgopt_active() && true === apply_filters( 'aut
|
|
389 |
} else {
|
390 |
$cdn_editable = '';
|
391 |
$cdn_placeholder = 'placeholder="' . __( 'example: //cdn.yoursite.com/', 'autoptimize' ) . ' "';
|
392 |
-
$cdn_description = __( 'Enter your CDN root URL to enable CDN for Autoptimized files. The URL can be http, https or protocol-relative. This is not needed for Cloudflare.', 'autoptimize' );
|
393 |
}
|
394 |
?>
|
395 |
<td><label><input id="cdn_url" type="text" name="autoptimize_cdn_url" pattern="^(https?:)?\/\/([\da-z\.-]+)\.([\da-z\.]{2,6})([\/\w \.-]*)*(:\d{2,5})?\/?$" style="width:100%" <?php echo $cdn_placeholder . $cdn_editable; ?> value="<?php echo esc_url( autoptimizeOptionWrapper::get_option( 'autoptimize_cdn_url', '' ), array( 'http', 'https' ) ); ?>" /><br />
|
@@ -433,7 +438,7 @@ if ( true === autoptimizeImages::imgopt_active() && true === apply_filters( 'aut
|
|
433 |
<li class="itemDetail">
|
434 |
<h2 class="itemTitle"><?php _e( 'Misc Options', 'autoptimize' ); ?></h2>
|
435 |
<table class="form-table">
|
436 |
-
<tr valign="top"
|
437 |
<th scope="row"><?php _e( 'Save aggregated script/css as static files?', 'autoptimize' ); ?></th>
|
438 |
<td><label class="cb_label"><input type="checkbox" name="autoptimize_cache_nogzip" <?php echo $conf->get( 'autoptimize_cache_nogzip') ? 'checked="checked" ' : ''; ?>/>
|
439 |
<?php _e( 'By default files saved are static css/js, uncheck this option if your webserver doesn\'t properly handle the compression and expiry.', 'autoptimize' ); ?></label></td>
|
@@ -478,6 +483,13 @@ if ( true === autoptimizeImages::imgopt_active() && true === apply_filters( 'aut
|
|
478 |
<?php _e( 'Add a "metabox" to the post/ page edit screen allowing different optimizations to be turned off on a per post/ page level?', 'autoptimize' ); ?></label></td>
|
479 |
</tr>
|
480 |
<?php } ?>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
481 |
</table>
|
482 |
</li>
|
483 |
|
@@ -568,7 +580,7 @@ if ( true === autoptimizeImages::imgopt_active() && true === apply_filters( 'aut
|
|
568 |
check_exclusions( "js", "off" );
|
569 |
}
|
570 |
});
|
571 |
-
|
572 |
jQuery( "#autoptimize_js_defer_not_aggregate" ).change(function() {
|
573 |
if (this.checked && jQuery("#autoptimize_js").prop('checked')) {
|
574 |
jQuery( "#autoptimize_js_aggregate" ).prop( 'checked', false ); // uncheck "aggregate JS"
|
@@ -670,7 +682,7 @@ if ( true === autoptimizeImages::imgopt_active() && true === apply_filters( 'aut
|
|
670 |
jQuery(".js_sub:visible").fadeTo('fast',.33);
|
671 |
}
|
672 |
}
|
673 |
-
|
674 |
function check_exclusions( what, state ) {
|
675 |
exclusion_node = 'input[name="autoptimize_' + what + '_exclude"]';
|
676 |
current_exclusion = jQuery( exclusion_node ).val();
|
@@ -680,9 +692,9 @@ if ( true === autoptimizeImages::imgopt_active() && true === apply_filters( 'aut
|
|
680 |
} else if ( what == "css") {
|
681 |
default_exclusion = ", admin-bar.min.css, dashicons.min.css, wp-content/cache/, wp-content/uploads/";
|
682 |
}
|
683 |
-
|
684 |
default_in_current = current_exclusion.indexOf(default_exclusion);
|
685 |
-
|
686 |
if ( state == "on" && default_in_current == -1 ) {
|
687 |
jQuery( exclusion_node ).val( current_exclusion + default_exclusion );
|
688 |
} else if ( state = "off" && current_exclusion == default_exclusion ) {
|
@@ -730,6 +742,7 @@ if ( true === autoptimizeImages::imgopt_active() && true === apply_filters( 'aut
|
|
730 |
public function registersettings() {
|
731 |
register_setting( 'autoptimize', 'autoptimize_html' );
|
732 |
register_setting( 'autoptimize', 'autoptimize_html_keepcomments' );
|
|
|
733 |
register_setting( 'autoptimize', 'autoptimize_enable_site_config' );
|
734 |
register_setting( 'autoptimize', 'autoptimize_js' );
|
735 |
register_setting( 'autoptimize', 'autoptimize_js_aggregate' );
|
@@ -757,6 +770,7 @@ if ( true === autoptimizeImages::imgopt_active() && true === apply_filters( 'aut
|
|
757 |
register_setting( 'autoptimize', 'autoptimize_minify_excluded' );
|
758 |
register_setting( 'autoptimize', 'autoptimize_cache_fallback' );
|
759 |
register_setting( 'autoptimize', 'autoptimize_enable_meta_ao_settings' );
|
|
|
760 |
}
|
761 |
|
762 |
public function setmeta( $links, $file = null )
|
@@ -792,34 +806,36 @@ if ( true === autoptimizeImages::imgopt_active() && true === apply_filters( 'aut
|
|
792 |
public static function get_defaults()
|
793 |
{
|
794 |
static $config = array(
|
795 |
-
'autoptimize_html'
|
796 |
-
'autoptimize_html_keepcomments'
|
797 |
-
'
|
798 |
-
'
|
799 |
-
'
|
800 |
-
'
|
801 |
-
'
|
802 |
-
'
|
803 |
-
'
|
804 |
-
'
|
805 |
-
'
|
806 |
-
'
|
807 |
-
'
|
808 |
-
'
|
809 |
-
'
|
810 |
-
'
|
811 |
-
'
|
812 |
-
'
|
813 |
-
'
|
814 |
-
'
|
815 |
-
'
|
816 |
-
'
|
817 |
-
'
|
818 |
-
'
|
819 |
-
'
|
820 |
-
'
|
821 |
-
'
|
822 |
-
'
|
|
|
|
|
823 |
);
|
824 |
|
825 |
return $config;
|
@@ -1033,7 +1049,7 @@ if ( true === autoptimizeImages::imgopt_active() && true === apply_filters( 'aut
|
|
1033 |
return true;
|
1034 |
} else if ( array_key_exists( 'ao_post_optimize', $_meta_value ) && 'on' !== $_meta_value['ao_post_optimize'] ) {
|
1035 |
// ao entirely off for this page.
|
1036 |
-
return false;
|
1037 |
} else if ( array_key_exists( $optim, $_meta_value ) && empty( $_meta_value[$optim] ) ) {
|
1038 |
// sub-optimization off for this page.
|
1039 |
return false;
|
62 |
}
|
63 |
|
64 |
$this->settings_screen_do_remote_http = apply_filters( 'autoptimize_settingsscreen_remotehttp', $this->settings_screen_do_remote_http );
|
65 |
+
|
66 |
if ( $this->is_ao_meta_settings_active() ) {
|
67 |
$metaBox = new autoptimizeMetabox();
|
68 |
}
|
219 |
</li>
|
220 |
<?php } else { ?>
|
221 |
<input type="hidden" id="autoptimize_enable_site_config" name="autoptimize_enable_site_config" value="on" />
|
222 |
+
<?php } ?>
|
223 |
|
224 |
<li class="itemDetail">
|
225 |
<h2 class="itemTitle"><?php _e( 'JavaScript Options', 'autoptimize' ); ?></h2>
|
351 |
<?php if ( false === autoptimizeUtils::is_plugin_active( 'unusedcss/unusedcss.php' ) ) { ?>
|
352 |
<tr valign="top">
|
353 |
<th scope="row"><?php _e( 'Remove Unused CSS?', 'autoptimize' ); ?></th>
|
354 |
+
<?php
|
355 |
$_rapidload_link = 'https://misc.optimizingmatters.com/partners/?from=csssettings&partner=rapidload';
|
356 |
?>
|
357 |
<td><?php echo sprintf( __( 'If Google Pagespeed Insights detects unused CSS, consider using %s to <strong>reduce your site\'s CSS size to up to 90%</strong>, resulting in a slimmer, faster site!', 'autoptimize' ), '<a href="' . $_rapidload_link . '" target="_blank">the premium Rapidload service</a>' ); ?></td>
|
368 |
<td><input type="checkbox" id="autoptimize_html" name="autoptimize_html" <?php echo $conf->get( 'autoptimize_html' ) ? 'checked="checked" ' : ''; ?>/></td>
|
369 |
</tr>
|
370 |
<tr class="html_sub" valign="top">
|
371 |
+
<th scope="row"><?php _e( 'Also minify inline JS/ CSS?', 'autoptimize' ); ?></th>
|
372 |
+
<td><label class="cb_label"><input type="checkbox" name="autoptimize_html_minify_inline" <?php echo $conf->get( 'autoptimize_html_minify_inline' ) ? 'checked="checked" ' : ''; ?>/>
|
373 |
+
<?php _e( 'Enable this if you want inline JS or CSS to be minified as well.', 'autoptimize' ); ?></label></td>
|
374 |
+
</tr>
|
375 |
+
<tr class="html_sub" valign="top">
|
376 |
<th scope="row"><?php _e( 'Keep HTML comments?', 'autoptimize' ); ?></th>
|
377 |
<td><label class="cb_label"><input type="checkbox" name="autoptimize_html_keepcomments" <?php echo $conf->get( 'autoptimize_html_keepcomments' ) ? 'checked="checked" ' : ''; ?>/>
|
378 |
<?php _e( 'Enable this if you want HTML comments to remain in the page.', 'autoptimize' ); ?></label></td>
|
394 |
} else {
|
395 |
$cdn_editable = '';
|
396 |
$cdn_placeholder = 'placeholder="' . __( 'example: //cdn.yoursite.com/', 'autoptimize' ) . ' "';
|
397 |
+
$cdn_description = __( 'Enter your CDN root URL to enable CDN for Autoptimized files. The URL can be http, https or protocol-relative. This is not needed for Cloudflare.', 'autoptimize' );
|
398 |
}
|
399 |
?>
|
400 |
<td><label><input id="cdn_url" type="text" name="autoptimize_cdn_url" pattern="^(https?:)?\/\/([\da-z\.-]+)\.([\da-z\.]{2,6})([\/\w \.-]*)*(:\d{2,5})?\/?$" style="width:100%" <?php echo $cdn_placeholder . $cdn_editable; ?> value="<?php echo esc_url( autoptimizeOptionWrapper::get_option( 'autoptimize_cdn_url', '' ), array( 'http', 'https' ) ); ?>" /><br />
|
438 |
<li class="itemDetail">
|
439 |
<h2 class="itemTitle"><?php _e( 'Misc Options', 'autoptimize' ); ?></h2>
|
440 |
<table class="form-table">
|
441 |
+
<tr valign="top">
|
442 |
<th scope="row"><?php _e( 'Save aggregated script/css as static files?', 'autoptimize' ); ?></th>
|
443 |
<td><label class="cb_label"><input type="checkbox" name="autoptimize_cache_nogzip" <?php echo $conf->get( 'autoptimize_cache_nogzip') ? 'checked="checked" ' : ''; ?>/>
|
444 |
<?php _e( 'By default files saved are static css/js, uncheck this option if your webserver doesn\'t properly handle the compression and expiry.', 'autoptimize' ); ?></label></td>
|
483 |
<?php _e( 'Add a "metabox" to the post/ page edit screen allowing different optimizations to be turned off on a per post/ page level?', 'autoptimize' ); ?></label></td>
|
484 |
</tr>
|
485 |
<?php } ?>
|
486 |
+
<?php if ( false !== (bool) autoptimizeOptionWrapper::get_option( 'autoptimize_installed_before_compatibility', false ) ) { ?>
|
487 |
+
<tr valign="top">
|
488 |
+
<th scope="row"><?php _e( 'Disable extra compatibilty logic?', 'autoptimize' ); ?></th>
|
489 |
+
<td><label class="cb_label"><input type="checkbox" name="autoptimize_installed_before_compatibility" checked="checked" />
|
490 |
+
<?php _e( 'In Autoptimize 3.0 extra compatibiity logic was added (e.g. for Gutenberg blocks, Revolution Slider, jQuery-heavy plugins, ...), but if you had Autoptimize installed already before the update to 3.0, this compatibility code was disabled. <strong>Untick this option to permanently enable the compatibility logic</strong>.', 'autoptimize' ); ?></label></td>
|
491 |
+
</tr>
|
492 |
+
<?php } ?>
|
493 |
</table>
|
494 |
</li>
|
495 |
|
580 |
check_exclusions( "js", "off" );
|
581 |
}
|
582 |
});
|
583 |
+
|
584 |
jQuery( "#autoptimize_js_defer_not_aggregate" ).change(function() {
|
585 |
if (this.checked && jQuery("#autoptimize_js").prop('checked')) {
|
586 |
jQuery( "#autoptimize_js_aggregate" ).prop( 'checked', false ); // uncheck "aggregate JS"
|
682 |
jQuery(".js_sub:visible").fadeTo('fast',.33);
|
683 |
}
|
684 |
}
|
685 |
+
|
686 |
function check_exclusions( what, state ) {
|
687 |
exclusion_node = 'input[name="autoptimize_' + what + '_exclude"]';
|
688 |
current_exclusion = jQuery( exclusion_node ).val();
|
692 |
} else if ( what == "css") {
|
693 |
default_exclusion = ", admin-bar.min.css, dashicons.min.css, wp-content/cache/, wp-content/uploads/";
|
694 |
}
|
695 |
+
|
696 |
default_in_current = current_exclusion.indexOf(default_exclusion);
|
697 |
+
|
698 |
if ( state == "on" && default_in_current == -1 ) {
|
699 |
jQuery( exclusion_node ).val( current_exclusion + default_exclusion );
|
700 |
} else if ( state = "off" && current_exclusion == default_exclusion ) {
|
742 |
public function registersettings() {
|
743 |
register_setting( 'autoptimize', 'autoptimize_html' );
|
744 |
register_setting( 'autoptimize', 'autoptimize_html_keepcomments' );
|
745 |
+
register_setting( 'autoptimize', 'autoptimize_html_minify_inline' );
|
746 |
register_setting( 'autoptimize', 'autoptimize_enable_site_config' );
|
747 |
register_setting( 'autoptimize', 'autoptimize_js' );
|
748 |
register_setting( 'autoptimize', 'autoptimize_js_aggregate' );
|
770 |
register_setting( 'autoptimize', 'autoptimize_minify_excluded' );
|
771 |
register_setting( 'autoptimize', 'autoptimize_cache_fallback' );
|
772 |
register_setting( 'autoptimize', 'autoptimize_enable_meta_ao_settings' );
|
773 |
+
register_setting( 'autoptimize', 'autoptimize_installed_before_compatibility' );
|
774 |
}
|
775 |
|
776 |
public function setmeta( $links, $file = null )
|
806 |
public static function get_defaults()
|
807 |
{
|
808 |
static $config = array(
|
809 |
+
'autoptimize_html' => 0,
|
810 |
+
'autoptimize_html_keepcomments' => 0,
|
811 |
+
'autoptimize_html_minify_inline' => 0,
|
812 |
+
'autoptimize_enable_site_config' => 1,
|
813 |
+
'autoptimize_js' => 0,
|
814 |
+
'autoptimize_js_aggregate' => 0,
|
815 |
+
'autoptimize_js_defer_not_aggregate' => 1,
|
816 |
+
'autoptimize_js_defer_inline' => 1,
|
817 |
+
'autoptimize_js_exclude' => '', // 'wp-includes/js/dist/, wp-includes/js/tinymce/, js/jquery/jquery.min.js',
|
818 |
+
'autoptimize_js_trycatch' => 0,
|
819 |
+
'autoptimize_js_justhead' => 0,
|
820 |
+
'autoptimize_js_include_inline' => 0,
|
821 |
+
'autoptimize_js_forcehead' => 0,
|
822 |
+
'autoptimize_css' => 0,
|
823 |
+
'autoptimize_css_aggregate' => 0,
|
824 |
+
'autoptimize_css_exclude' => '', // admin-bar.min.css, dashicons.min.css, wp-content/cache/, wp-content/uploads/',
|
825 |
+
'autoptimize_css_justhead' => 0,
|
826 |
+
'autoptimize_css_include_inline' => 0,
|
827 |
+
'autoptimize_css_defer' => 0,
|
828 |
+
'autoptimize_css_defer_inline' => '',
|
829 |
+
'autoptimize_css_inline' => 0,
|
830 |
+
'autoptimize_css_datauris' => 0,
|
831 |
+
'autoptimize_cdn_url' => '',
|
832 |
+
'autoptimize_cache_nogzip' => 1,
|
833 |
+
'autoptimize_optimize_logged' => 1,
|
834 |
+
'autoptimize_optimize_checkout' => 0,
|
835 |
+
'autoptimize_minify_excluded' => 1,
|
836 |
+
'autoptimize_cache_fallback' => 1,
|
837 |
+
'autoptimize_enable_meta_ao_settings' => 1,
|
838 |
+
'autoptimize_installed_before_compatibility' => 0,
|
839 |
);
|
840 |
|
841 |
return $config;
|
1049 |
return true;
|
1050 |
} else if ( array_key_exists( 'ao_post_optimize', $_meta_value ) && 'on' !== $_meta_value['ao_post_optimize'] ) {
|
1051 |
// ao entirely off for this page.
|
1052 |
+
return false;
|
1053 |
} else if ( array_key_exists( $optim, $_meta_value ) && empty( $_meta_value[$optim] ) ) {
|
1054 |
// sub-optimization off for this page.
|
1055 |
return false;
|
classes/autoptimizeCriticalCSSBase.php
CHANGED
@@ -86,7 +86,7 @@ class autoptimizeCriticalCSSBase {
|
|
86 |
}
|
87 |
|
88 |
$this->filepath = __FILE__;
|
89 |
-
|
90 |
// Add keychecker action for scheduled use.
|
91 |
add_action( 'ao_ccss_keychecker', array( $this, 'ao_ccss_check_key' ) );
|
92 |
}
|
@@ -109,7 +109,7 @@ class autoptimizeCriticalCSSBase {
|
|
109 |
// and schedule maintenance job.
|
110 |
wp_schedule_event( time(), 'twicedaily', 'ao_ccss_maintenance' );
|
111 |
}
|
112 |
-
|
113 |
if ( wp_next_scheduled( 'ao_ccss_keychecker' ) ) {
|
114 |
// api is active now, no need to check key as it is checked by using the API.
|
115 |
wp_clear_scheduled_hook( 'ao_ccss_keychecker' );
|
@@ -419,7 +419,7 @@ class autoptimizeCriticalCSSBase {
|
|
419 |
* Scheduled action to check an inactive key. Not part of autoptimizeCriticalCSSCron.php
|
420 |
* to allow us to only load the main cron logic if we have an active key to begin with.
|
421 |
*
|
422 |
-
*/
|
423 |
public function ao_ccss_check_key() {
|
424 |
$ao_ccss_key = $this->get_option( 'key' );
|
425 |
$_result = $this->_core->ao_ccss_key_validation( $ao_ccss_key );
|
86 |
}
|
87 |
|
88 |
$this->filepath = __FILE__;
|
89 |
+
|
90 |
// Add keychecker action for scheduled use.
|
91 |
add_action( 'ao_ccss_keychecker', array( $this, 'ao_ccss_check_key' ) );
|
92 |
}
|
109 |
// and schedule maintenance job.
|
110 |
wp_schedule_event( time(), 'twicedaily', 'ao_ccss_maintenance' );
|
111 |
}
|
112 |
+
|
113 |
if ( wp_next_scheduled( 'ao_ccss_keychecker' ) ) {
|
114 |
// api is active now, no need to check key as it is checked by using the API.
|
115 |
wp_clear_scheduled_hook( 'ao_ccss_keychecker' );
|
419 |
* Scheduled action to check an inactive key. Not part of autoptimizeCriticalCSSCron.php
|
420 |
* to allow us to only load the main cron logic if we have an active key to begin with.
|
421 |
*
|
422 |
+
*/
|
423 |
public function ao_ccss_check_key() {
|
424 |
$ao_ccss_key = $this->get_option( 'key' );
|
425 |
$_result = $this->_core->ao_ccss_key_validation( $ao_ccss_key );
|
classes/autoptimizeCriticalCSSCore.php
CHANGED
@@ -547,9 +547,9 @@ class autoptimizeCriticalCSSCore {
|
|
547 |
// Perform basic exploit avoidance and CSS validation.
|
548 |
if ( ! empty( $ccss ) ) {
|
549 |
// Try to avoid code injection.
|
550 |
-
$blocklist = array( '#!/', 'function(', '<script', '<?php' );
|
551 |
foreach ( $blocklist as $blocklisted ) {
|
552 |
-
if (
|
553 |
$this->ao_ccss_log( 'Critical CSS received contained blocklisted content.', 2 );
|
554 |
return false;
|
555 |
}
|
@@ -580,21 +580,20 @@ class autoptimizeCriticalCSSCore {
|
|
580 |
// 3: DD (for debug)
|
581 |
// Default: UU (for unkown).
|
582 |
$level = false;
|
583 |
-
|
584 |
-
|
585 |
-
|
586 |
-
|
587 |
-
|
588 |
-
|
589 |
-
|
590 |
-
|
591 |
-
|
592 |
-
if ( $debug ) {
|
593 |
$level = 'DD';
|
594 |
-
|
595 |
-
|
596 |
-
|
597 |
-
|
598 |
}
|
599 |
|
600 |
// Prepare and write a log message if there's a valid level.
|
547 |
// Perform basic exploit avoidance and CSS validation.
|
548 |
if ( ! empty( $ccss ) ) {
|
549 |
// Try to avoid code injection.
|
550 |
+
$blocklist = array( '#!/', 'function(', '<script', '<?php', '</style', ' onload=', ' onerror=', ' onmouse', ' onscroll=', ' onclick=' );
|
551 |
foreach ( $blocklist as $blocklisted ) {
|
552 |
+
if ( stripos( $ccss, $blocklisted ) !== false ) {
|
553 |
$this->ao_ccss_log( 'Critical CSS received contained blocklisted content.', 2 );
|
554 |
return false;
|
555 |
}
|
580 |
// 3: DD (for debug)
|
581 |
// Default: UU (for unkown).
|
582 |
$level = false;
|
583 |
+
if ( $debug ) {
|
584 |
+
switch ( $lvl ) {
|
585 |
+
case 1:
|
586 |
+
$level = 'II';
|
587 |
+
break;
|
588 |
+
case 2:
|
589 |
+
$level = 'EE';
|
590 |
+
break;
|
591 |
+
case 3:
|
|
|
592 |
$level = 'DD';
|
593 |
+
break;
|
594 |
+
default:
|
595 |
+
$level = 'UU';
|
596 |
+
}
|
597 |
}
|
598 |
|
599 |
// Prepare and write a log message if there's a valid level.
|
classes/autoptimizeCriticalCSSCron.php
CHANGED
@@ -231,6 +231,7 @@ class autoptimizeCriticalCSSCron {
|
|
231 |
$jprops['jvstat'] = $apireq['validationStatus'];
|
232 |
$jprops['jftime'] = microtime( true );
|
233 |
$rule_update = true;
|
|
|
234 |
$this->criticalcss->log( 'Job id <' . $jprops['ljid'] . '> result request successful, remote id <' . $jprops['jid'] . '>, status <' . $jprops['jqstat'] . '>, file saved <' . $jprops['file'] . '>', 3 );
|
235 |
} elseif ( 'GOOD' == $apireq['resultStatus'] && ( 'BAD' == $apireq['validationStatus'] || 'SCREENSHOT_WARN_BLANK' == $apireq['validationStatus'] ) ) {
|
236 |
// SUCCESS: GOOD job with BAD or SCREENSHOT_WARN_BLANK validation
|
@@ -242,6 +243,7 @@ class autoptimizeCriticalCSSCron {
|
|
242 |
if ( apply_filters( 'autoptimize_filter_ccss_save_review_rules', true ) ) {
|
243 |
$jprops['file'] = $this->ao_ccss_save_file( $apireq['css'], $trule, true );
|
244 |
$rule_update = true;
|
|
|
245 |
$this->criticalcss->log( 'Job id <' . $jprops['ljid'] . '> result request successful, remote id <' . $jprops['jid'] . '>, status <' . $jprops['jqstat'] . ', file saved <' . $jprops['file'] . '> but requires REVIEW', 3 );
|
246 |
} else {
|
247 |
$this->criticalcss->log( 'Job id <' . $jprops['ljid'] . '> result request successful, remote id <' . $jprops['jid'] . '>, status <' . $jprops['jqstat'] . ', file not saved because it required REVIEW.', 3 );
|
231 |
$jprops['jvstat'] = $apireq['validationStatus'];
|
232 |
$jprops['jftime'] = microtime( true );
|
233 |
$rule_update = true;
|
234 |
+
do_action( 'autoptimize_action_ccss_cron_rule_saved', $jprops['rtarget'], $jprops['file'] );
|
235 |
$this->criticalcss->log( 'Job id <' . $jprops['ljid'] . '> result request successful, remote id <' . $jprops['jid'] . '>, status <' . $jprops['jqstat'] . '>, file saved <' . $jprops['file'] . '>', 3 );
|
236 |
} elseif ( 'GOOD' == $apireq['resultStatus'] && ( 'BAD' == $apireq['validationStatus'] || 'SCREENSHOT_WARN_BLANK' == $apireq['validationStatus'] ) ) {
|
237 |
// SUCCESS: GOOD job with BAD or SCREENSHOT_WARN_BLANK validation
|
243 |
if ( apply_filters( 'autoptimize_filter_ccss_save_review_rules', true ) ) {
|
244 |
$jprops['file'] = $this->ao_ccss_save_file( $apireq['css'], $trule, true );
|
245 |
$rule_update = true;
|
246 |
+
do_action( 'autoptimize_action_ccss_cron_rule_saved', $jprops['rtarget'], $jprops['file'] );
|
247 |
$this->criticalcss->log( 'Job id <' . $jprops['ljid'] . '> result request successful, remote id <' . $jprops['jid'] . '>, status <' . $jprops['jqstat'] . ', file saved <' . $jprops['file'] . '> but requires REVIEW', 3 );
|
248 |
} else {
|
249 |
$this->criticalcss->log( 'Job id <' . $jprops['ljid'] . '> result request successful, remote id <' . $jprops['jid'] . '>, status <' . $jprops['jqstat'] . ', file not saved because it required REVIEW.', 3 );
|
classes/autoptimizeCriticalCSSSettings.php
CHANGED
@@ -39,6 +39,11 @@ class autoptimizeCriticalCSSSettings {
|
|
39 |
}
|
40 |
|
41 |
$criticalcss_ajax = new autoptimizeCriticalCSSSettingsAjax();
|
|
|
|
|
|
|
|
|
|
|
42 |
}
|
43 |
}
|
44 |
|
@@ -70,7 +75,7 @@ class autoptimizeCriticalCSSSettings {
|
|
70 |
register_setting( 'ao_ccss_options_group', 'autoptimize_ccss_unloadccss' );
|
71 |
|
72 |
// And add submenu-page.
|
73 |
-
add_submenu_page(
|
74 |
}
|
75 |
|
76 |
public function admin_assets( $hook ) {
|
@@ -114,6 +119,7 @@ class autoptimizeCriticalCSSSettings {
|
|
114 |
$ao_css_defer_inline = $this->criticalcss->get_option( 'css_defer_inline' );
|
115 |
$ao_ccss_loggedin = $this->criticalcss->get_option( 'loggedin' );
|
116 |
$ao_ccss_forcepath = $this->criticalcss->get_option( 'forcepath' );
|
|
|
117 |
?>
|
118 |
<script>document.title = "Autoptimize: <?php _e( 'Critical CSS', 'autoptimize' ); ?> " + document.title;</script>
|
119 |
<div class="wrap">
|
@@ -151,8 +157,7 @@ class autoptimizeCriticalCSSSettings {
|
|
151 |
}
|
152 |
|
153 |
// Check for "inline & defer CSS" being active in Autoptimize.
|
154 |
-
if ( ! empty( $ao_ccss_key ) && ! $ao_css_defer ) {
|
155 |
-
if ( empty( $ao_ccss_keyst ) ) {
|
156 |
// no keystate so likely in activation-process of CCSS, let's enable "inline & defer CSS" immediately to make things easier!
|
157 |
autoptimizeOptionWrapper::update_option( 'autoptimize_css_defer', 'on' );
|
158 |
?>
|
@@ -162,16 +167,6 @@ class autoptimizeCriticalCSSSettings {
|
|
162 |
?>
|
163 |
</p></div>
|
164 |
<?php
|
165 |
-
} else {
|
166 |
-
// we have keystate, so "inline & defer CSS" was probably disabled for troubleshooting, warn but let users continue.
|
167 |
-
?>
|
168 |
-
<div class="notice-warning notice"><p>
|
169 |
-
<?php
|
170 |
-
_e( "Please <strong>activate the \"Eliminate render-blocking CSS\" option</strong> on Autoptimize's main settings page to ensure critical CSS is used on the front-end.", 'autoptimize' );
|
171 |
-
?>
|
172 |
-
</p></div>
|
173 |
-
<?php
|
174 |
-
}
|
175 |
}
|
176 |
|
177 |
// check if WordPress cron is disabled and warn if so.
|
@@ -317,7 +312,7 @@ class autoptimizeCriticalCSSSettings {
|
|
317 |
// Render rules section for manual rules.
|
318 |
ao_ccss_render_rules();
|
319 |
} else {
|
320 |
-
echo "<input class='hidden' name='
|
321 |
}
|
322 |
|
323 |
// But if key is other than valid, add hidden fields to persist settings when submitting form
|
@@ -338,6 +333,7 @@ class autoptimizeCriticalCSSSettings {
|
|
338 |
echo '<input class="hidden" name="autoptimize_css_defer_inline" value="' . esc_attr( $ao_css_defer_inline ) . '">';
|
339 |
echo '<input class="hidden" name="autoptimize_ccss_loggedin" value="' . esc_attr( $ao_ccss_loggedin ). '">';
|
340 |
echo '<input class="hidden" name="autoptimize_ccss_forcepath" value="' . esc_attr( $ao_ccss_forcepath ) . '">';
|
|
|
341 |
}
|
342 |
// Render key panel unconditionally.
|
343 |
ao_ccss_render_key( $ao_ccss_key, $key['status'], $key['stmsg'], $key['msg'], $key['color'] );
|
@@ -415,7 +411,7 @@ class autoptimizeCriticalCSSSettings {
|
|
415 |
return $_has_auto_rules;
|
416 |
}
|
417 |
|
418 |
-
public function is_multisite_network_admin() {
|
419 |
static $_multisite_network_admin = null;
|
420 |
|
421 |
if ( null === $_multisite_network_admin ) {
|
39 |
}
|
40 |
|
41 |
$criticalcss_ajax = new autoptimizeCriticalCSSSettingsAjax();
|
42 |
+
|
43 |
+
// if debug logging is off but the file is present, then remove the debug log file.
|
44 |
+
if ( empty( $this->criticalcss->get_option( 'debug' ) ) && file_exists( AO_CCSS_LOG ) ) {
|
45 |
+
unlink( AO_CCSS_LOG );
|
46 |
+
}
|
47 |
}
|
48 |
}
|
49 |
|
75 |
register_setting( 'ao_ccss_options_group', 'autoptimize_ccss_unloadccss' );
|
76 |
|
77 |
// And add submenu-page.
|
78 |
+
add_submenu_page( '', 'Critical CSS', 'Critical CSS', 'manage_options', 'ao_critcss', array( $this, 'ao_criticalcsssettings_page' ) );
|
79 |
}
|
80 |
|
81 |
public function admin_assets( $hook ) {
|
119 |
$ao_css_defer_inline = $this->criticalcss->get_option( 'css_defer_inline' );
|
120 |
$ao_ccss_loggedin = $this->criticalcss->get_option( 'loggedin' );
|
121 |
$ao_ccss_forcepath = $this->criticalcss->get_option( 'forcepath' );
|
122 |
+
$ao_ccss_domain = $this->criticalcss->get_option( 'domain' );
|
123 |
?>
|
124 |
<script>document.title = "Autoptimize: <?php _e( 'Critical CSS', 'autoptimize' ); ?> " + document.title;</script>
|
125 |
<div class="wrap">
|
157 |
}
|
158 |
|
159 |
// Check for "inline & defer CSS" being active in Autoptimize.
|
160 |
+
if ( ! empty( $ao_ccss_key ) && ! $ao_css_defer && empty( $ao_ccss_keyst ) ) {
|
|
|
161 |
// no keystate so likely in activation-process of CCSS, let's enable "inline & defer CSS" immediately to make things easier!
|
162 |
autoptimizeOptionWrapper::update_option( 'autoptimize_css_defer', 'on' );
|
163 |
?>
|
167 |
?>
|
168 |
</p></div>
|
169 |
<?php
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
170 |
}
|
171 |
|
172 |
// check if WordPress cron is disabled and warn if so.
|
312 |
// Render rules section for manual rules.
|
313 |
ao_ccss_render_rules();
|
314 |
} else {
|
315 |
+
echo "<input class='hidden' name='autoptimize_ccss_rules' value='" . json_encode( $ao_ccss_rules, JSON_FORCE_OBJECT ) . "'>";
|
316 |
}
|
317 |
|
318 |
// But if key is other than valid, add hidden fields to persist settings when submitting form
|
333 |
echo '<input class="hidden" name="autoptimize_css_defer_inline" value="' . esc_attr( $ao_css_defer_inline ) . '">';
|
334 |
echo '<input class="hidden" name="autoptimize_ccss_loggedin" value="' . esc_attr( $ao_ccss_loggedin ). '">';
|
335 |
echo '<input class="hidden" name="autoptimize_ccss_forcepath" value="' . esc_attr( $ao_ccss_forcepath ) . '">';
|
336 |
+
echo '<input class="hidden" name="autoptimize_ccss_domain" id="autoptimize_ccss_domain" value="' . esc_attr( $ao_ccss_domain ) . '">';
|
337 |
}
|
338 |
// Render key panel unconditionally.
|
339 |
ao_ccss_render_key( $ao_ccss_key, $key['status'], $key['stmsg'], $key['msg'], $key['color'] );
|
411 |
return $_has_auto_rules;
|
412 |
}
|
413 |
|
414 |
+
public static function is_multisite_network_admin() {
|
415 |
static $_multisite_network_admin = null;
|
416 |
|
417 |
if ( null === $_multisite_network_admin ) {
|
classes/autoptimizeCriticalCSSSettingsAjax.php
CHANGED
@@ -115,7 +115,6 @@ class autoptimizeCriticalCSSSettingsAjax {
|
|
115 |
wp_die();
|
116 |
}
|
117 |
|
118 |
-
|
119 |
public function critcss_rm_callback() {
|
120 |
// Ajax handler to delete a critical CSS from the filesystem
|
121 |
// Check referer.
|
@@ -299,6 +298,11 @@ class autoptimizeCriticalCSSSettingsAjax {
|
|
299 |
$zip->addGlob( AO_CCSS_DIR . '*.css', 0, $options );
|
300 |
$zip->close();
|
301 |
}
|
|
|
|
|
|
|
|
|
|
|
302 |
|
303 |
// Prepare response.
|
304 |
if ( ! $status || $error ) {
|
@@ -409,6 +413,11 @@ class autoptimizeCriticalCSSSettingsAjax {
|
|
409 |
update_option( 'autoptimize_pro_boosters', $settings['pro']['boosters'] );
|
410 |
update_option( 'autoptimize_pro_pagecache', $settings['pro']['pagecache'] );
|
411 |
}
|
|
|
|
|
|
|
|
|
|
|
412 |
} else {
|
413 |
// Settings file doesn't exist, update error flag.
|
414 |
$error = 'settings file does not exist';
|
115 |
wp_die();
|
116 |
}
|
117 |
|
|
|
118 |
public function critcss_rm_callback() {
|
119 |
// Ajax handler to delete a critical CSS from the filesystem
|
120 |
// Check referer.
|
298 |
$zip->addGlob( AO_CCSS_DIR . '*.css', 0, $options );
|
299 |
$zip->close();
|
300 |
}
|
301 |
+
|
302 |
+
// settings.json has been added to zipfile, so can be removed now.
|
303 |
+
if ( file_exists( $exportfile ) ) {
|
304 |
+
unlink( $exportfile );
|
305 |
+
}
|
306 |
|
307 |
// Prepare response.
|
308 |
if ( ! $status || $error ) {
|
413 |
update_option( 'autoptimize_pro_boosters', $settings['pro']['boosters'] );
|
414 |
update_option( 'autoptimize_pro_pagecache', $settings['pro']['pagecache'] );
|
415 |
}
|
416 |
+
|
417 |
+
// settings.json has been imported, so can be removed now.
|
418 |
+
if ( file_exists( $importfile ) ) {
|
419 |
+
unlink( $importfile );
|
420 |
+
}
|
421 |
} else {
|
422 |
// Settings file doesn't exist, update error flag.
|
423 |
$error = 'settings file does not exist';
|
classes/autoptimizeExitSurvey.php
CHANGED
@@ -30,7 +30,7 @@ class autoptimizeExitSurvey
|
|
30 |
|
31 |
function render_survey_model() {
|
32 |
global $wp_version;
|
33 |
-
|
34 |
$data = array(
|
35 |
"home" => home_url(),
|
36 |
"dest" => 'aHR0cHM6Ly9taXNjLm9wdGltaXppbmdtYXR0ZXJzLmNvbS9hb19leGl0X3N1cnZleS9pbmRleC5waHA='
|
@@ -70,12 +70,13 @@ class autoptimizeExitSurvey
|
|
70 |
<li ao-option-id="999">
|
71 |
<input type="radio" name="ao-deactivate-option" id="ao_feedback999">
|
72 |
<label for="ao_feedback999" data-reason="other">
|
73 |
-
<?php _e( 'Other (please specify below)', 'autoptimize' ); ?>
|
|
|
74 |
<textarea width="100%" rows="2" name="comments" placeholder="What can we do better?"></textarea></li>
|
75 |
<hr />
|
76 |
<li ao-option-id="998">
|
77 |
<label for="ao_feedback_email_toggle" data-reason="other detail">
|
78 |
-
<input type="checkbox" id="ao_feedback_email_toggle" name="ao_feedback_email_toggle"
|
79 |
<?php _e( 'I would like be contacted about my experience with Autoptimize.', 'autoptimize' ); ?>
|
80 |
</label>
|
81 |
<input type="email" name="ao-deactivate-option" id="ao_feedback998" placeholder="mymail@domain.xyz" class="hidden">
|
30 |
|
31 |
function render_survey_model() {
|
32 |
global $wp_version;
|
33 |
+
|
34 |
$data = array(
|
35 |
"home" => home_url(),
|
36 |
"dest" => 'aHR0cHM6Ly9taXNjLm9wdGltaXppbmdtYXR0ZXJzLmNvbS9hb19leGl0X3N1cnZleS9pbmRleC5waHA='
|
70 |
<li ao-option-id="999">
|
71 |
<input type="radio" name="ao-deactivate-option" id="ao_feedback999">
|
72 |
<label for="ao_feedback999" data-reason="other">
|
73 |
+
<?php _e( 'Other (please specify below)', 'autoptimize' ); ?>
|
74 |
+
</label>
|
75 |
<textarea width="100%" rows="2" name="comments" placeholder="What can we do better?"></textarea></li>
|
76 |
<hr />
|
77 |
<li ao-option-id="998">
|
78 |
<label for="ao_feedback_email_toggle" data-reason="other detail">
|
79 |
+
<input type="checkbox" id="ao_feedback_email_toggle" name="ao_feedback_email_toggle" />
|
80 |
<?php _e( 'I would like be contacted about my experience with Autoptimize.', 'autoptimize' ); ?>
|
81 |
</label>
|
82 |
<input type="email" name="ao-deactivate-option" id="ao_feedback998" placeholder="mymail@domain.xyz" class="hidden">
|
classes/autoptimizeExtra.php
CHANGED
@@ -189,7 +189,7 @@ class autoptimizeExtra
|
|
189 |
if ( ! empty( $options['autoptimize_extra_text_field_7'] ) || has_filter( 'autoptimize_filter_extra_tobepreloaded' ) || ! empty( autoptimizeConfig::get_post_meta_ao_settings( 'ao_post_preload' ) ) ) {
|
190 |
add_filter( 'autoptimize_html_after_minify', array( $this, 'filter_preload' ), 10, 2 );
|
191 |
}
|
192 |
-
|
193 |
// Remove global styles.
|
194 |
if ( ! empty( $options['autoptimize_extra_checkbox_field_8'] ) ) {
|
195 |
$this->disable_global_styles();
|
@@ -409,7 +409,7 @@ class autoptimizeExtra
|
|
409 |
if ( array_key_exists( 'autoptimize_extra_text_field_7', $options ) ) {
|
410 |
$preloads = array_filter( array_map( 'trim', explode( ',', wp_strip_all_tags( $options['autoptimize_extra_text_field_7'] ) ) ) );
|
411 |
}
|
412 |
-
|
413 |
if ( false === autoptimizeImages::imgopt_active() && false === autoptimizeImages::should_lazyload_wrapper() ) {
|
414 |
// only do this here if imgopt/ lazyload are not active?
|
415 |
$metabox_preloads = array_filter( array_map( 'trim', explode( ',', wp_strip_all_tags( autoptimizeConfig::get_post_meta_ao_settings( 'ao_post_preload' ) ) ) ) );
|
@@ -460,7 +460,7 @@ class autoptimizeExtra
|
|
460 |
|
461 |
return $this->inject_preloads( $preload_output, $in );
|
462 |
}
|
463 |
-
|
464 |
public static function inject_preloads( $preloads, $html ) {
|
465 |
// add string to head (before first link node by default).
|
466 |
$preload_inject = apply_filters( 'autoptimize_filter_extra_preload_inject', '<link' );
|
@@ -468,7 +468,7 @@ class autoptimizeExtra
|
|
468 |
|
469 |
return autoptimizeUtils::substr_replace( $html, $preloads . $preload_inject, $position, strlen( $preload_inject ) );
|
470 |
}
|
471 |
-
|
472 |
public function disable_global_styles()
|
473 |
{
|
474 |
remove_action( 'wp_enqueue_scripts', 'wp_enqueue_global_styles' );
|
@@ -488,7 +488,7 @@ class autoptimizeExtra
|
|
488 |
// no acces if multisite and not network admin and no site config allowed.
|
489 |
if ( autoptimizeConfig::should_show_menu_tabs() ) {
|
490 |
add_submenu_page(
|
491 |
-
|
492 |
'autoptimize_extra',
|
493 |
'autoptimize_extra',
|
494 |
'manage_options',
|
189 |
if ( ! empty( $options['autoptimize_extra_text_field_7'] ) || has_filter( 'autoptimize_filter_extra_tobepreloaded' ) || ! empty( autoptimizeConfig::get_post_meta_ao_settings( 'ao_post_preload' ) ) ) {
|
190 |
add_filter( 'autoptimize_html_after_minify', array( $this, 'filter_preload' ), 10, 2 );
|
191 |
}
|
192 |
+
|
193 |
// Remove global styles.
|
194 |
if ( ! empty( $options['autoptimize_extra_checkbox_field_8'] ) ) {
|
195 |
$this->disable_global_styles();
|
409 |
if ( array_key_exists( 'autoptimize_extra_text_field_7', $options ) ) {
|
410 |
$preloads = array_filter( array_map( 'trim', explode( ',', wp_strip_all_tags( $options['autoptimize_extra_text_field_7'] ) ) ) );
|
411 |
}
|
412 |
+
|
413 |
if ( false === autoptimizeImages::imgopt_active() && false === autoptimizeImages::should_lazyload_wrapper() ) {
|
414 |
// only do this here if imgopt/ lazyload are not active?
|
415 |
$metabox_preloads = array_filter( array_map( 'trim', explode( ',', wp_strip_all_tags( autoptimizeConfig::get_post_meta_ao_settings( 'ao_post_preload' ) ) ) ) );
|
460 |
|
461 |
return $this->inject_preloads( $preload_output, $in );
|
462 |
}
|
463 |
+
|
464 |
public static function inject_preloads( $preloads, $html ) {
|
465 |
// add string to head (before first link node by default).
|
466 |
$preload_inject = apply_filters( 'autoptimize_filter_extra_preload_inject', '<link' );
|
468 |
|
469 |
return autoptimizeUtils::substr_replace( $html, $preloads . $preload_inject, $position, strlen( $preload_inject ) );
|
470 |
}
|
471 |
+
|
472 |
public function disable_global_styles()
|
473 |
{
|
474 |
remove_action( 'wp_enqueue_scripts', 'wp_enqueue_global_styles' );
|
488 |
// no acces if multisite and not network admin and no site config allowed.
|
489 |
if ( autoptimizeConfig::should_show_menu_tabs() ) {
|
490 |
add_submenu_page(
|
491 |
+
'',
|
492 |
'autoptimize_extra',
|
493 |
'autoptimize_extra',
|
494 |
'manage_options',
|
classes/autoptimizeHTML.php
CHANGED
@@ -16,6 +16,13 @@ class autoptimizeHTML extends autoptimizeBase
|
|
16 |
*/
|
17 |
private $keepcomments = false;
|
18 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
19 |
/**
|
20 |
* Whether to force xhtml compatibility.
|
21 |
*
|
@@ -42,6 +49,9 @@ class autoptimizeHTML extends autoptimizeBase
|
|
42 |
// Filter to force xhtml.
|
43 |
$this->forcexhtml = (bool) apply_filters( 'autoptimize_filter_html_forcexhtml', false );
|
44 |
|
|
|
|
|
|
|
45 |
// Filterable strings to be excluded from HTML minification.
|
46 |
$exclude = apply_filters( 'autoptimize_filter_html_exclude', '' );
|
47 |
if ( '' !== $exclude ) {
|
@@ -83,7 +93,7 @@ class autoptimizeHTML extends autoptimizeBase
|
|
83 |
}
|
84 |
|
85 |
// Optionally minify inline JS & CSS.
|
86 |
-
if (
|
87 |
if ( false != autoptimizeOptionWrapper::get_option( 'autoptimize_js' ) && false != autoptimizeConfig::get_post_meta_ao_settings( 'ao_post_js_optimize' ) && true !== apply_filters( 'autoptimize_filter_js_noptimize', false, $this->content ) && false === strpos( $this->content, 'text/template' ) ) {
|
88 |
$options['jsMinifier'] = 'JSMin::minify';
|
89 |
}
|
16 |
*/
|
17 |
private $keepcomments = false;
|
18 |
|
19 |
+
/**
|
20 |
+
* Whether inline CSS/ JS is minified.
|
21 |
+
*
|
22 |
+
* @var bool
|
23 |
+
*/
|
24 |
+
private $minify_inline = false;
|
25 |
+
|
26 |
/**
|
27 |
* Whether to force xhtml compatibility.
|
28 |
*
|
49 |
// Filter to force xhtml.
|
50 |
$this->forcexhtml = (bool) apply_filters( 'autoptimize_filter_html_forcexhtml', false );
|
51 |
|
52 |
+
// minify inline JS/ CSS.
|
53 |
+
$this->minify_inline = (bool) apply_filters( 'autoptimize_html_minify_inline_js_css', $options['minify_inline'] );
|
54 |
+
|
55 |
// Filterable strings to be excluded from HTML minification.
|
56 |
$exclude = apply_filters( 'autoptimize_filter_html_exclude', '' );
|
57 |
if ( '' !== $exclude ) {
|
93 |
}
|
94 |
|
95 |
// Optionally minify inline JS & CSS.
|
96 |
+
if ( $this->minify_inline ) {
|
97 |
if ( false != autoptimizeOptionWrapper::get_option( 'autoptimize_js' ) && false != autoptimizeConfig::get_post_meta_ao_settings( 'ao_post_js_optimize' ) && true !== apply_filters( 'autoptimize_filter_js_noptimize', false, $this->content ) && false === strpos( $this->content, 'text/template' ) ) {
|
98 |
$options['jsMinifier'] = 'JSMin::minify';
|
99 |
}
|
classes/autoptimizeImages.php
CHANGED
@@ -653,7 +653,7 @@ class autoptimizeImages
|
|
653 |
// then call add_lazyload-function with lpiq placeholder if set.
|
654 |
$tag = $this->add_lazyload( $tag, $placeholder );
|
655 |
}
|
656 |
-
|
657 |
// add decoding="async" behind filter, not sure if I'll make it default true yet.
|
658 |
if ( true === apply_filters( 'autoptimize_filter_imgopt_add_decoding', true ) && false === strpos( $tag, ' decoding=' ) ) {
|
659 |
$tag = str_replace( '<img ', '<img decoding="async" ', $tag );
|
@@ -665,7 +665,7 @@ class autoptimizeImages
|
|
665 |
if ( $tag !== $orig_tag ) {
|
666 |
$to_replace[ $orig_tag ] = $tag;
|
667 |
}
|
668 |
-
|
669 |
// and check if image needs to be prelaoded.
|
670 |
if ( ! empty( $metabox_preloads ) && is_array( $metabox_preloads ) && str_replace( $metabox_preloads, '', $tag ) !== $tag ) {
|
671 |
$to_preload .= $this->create_img_preload_tag( $tag );
|
@@ -831,7 +831,7 @@ class autoptimizeImages
|
|
831 |
if ( $this->should_lazyload( $out ) ) {
|
832 |
$to_replace[ $tag ] = $this->add_lazyload( $tag );
|
833 |
}
|
834 |
-
|
835 |
// and check if image needs to be prelaoded.
|
836 |
if ( ! empty( $metabox_preloads ) && is_array( $metabox_preloads ) && str_replace( $metabox_preloads, '', $tag ) !== $tag ) {
|
837 |
$to_preload .= $this->create_img_preload_tag( $tag );
|
@@ -955,7 +955,7 @@ class autoptimizeImages
|
|
955 |
echo apply_filters( 'autoptimize_filter_imgopt_lazyload_jsconfig', '<script' . $type_js . $noptimize_flag . '>window.lazySizesConfig=window.lazySizesConfig||{};window.lazySizesConfig.loadMode=1;</script>' );
|
956 |
echo apply_filters( 'autoptimize_filter_imgopt_lazyload_js', '<script async' . $type_js . $noptimize_flag . ' src=\'' . $lazysizes_js . '\'></script>' );
|
957 |
}
|
958 |
-
|
959 |
public static function create_img_preload_tag( $tag ) {
|
960 |
if ( false === apply_filters( 'autoptimize_filter_imgopt_dopreloads', true ) ) {
|
961 |
return '';
|
@@ -968,7 +968,7 @@ class autoptimizeImages
|
|
968 |
$_from = array( '<img ', ' src=', ' sizes=', ' srcset=' );
|
969 |
$_to = array( '<link rel="preload" as="image" ', ' href=', ' imagesizes=', ' imagesrcset=' );
|
970 |
$tag = str_replace( $_from, $_to, $tag );
|
971 |
-
|
972 |
// and remove title, alt, class and id.
|
973 |
$tag = preg_replace( '/ ((?:title|alt|class|id|loading)=".*")/Um', '', $tag );
|
974 |
if ( $tag !== str_replace( array(' title=', ' class=', ' alt=', ' id=' ), '', $tag ) ) {
|
@@ -1113,7 +1113,7 @@ class autoptimizeImages
|
|
1113 |
}
|
1114 |
return $matches[0];
|
1115 |
}
|
1116 |
-
|
1117 |
public function fix_silly_bgimg_quotes( $tag_in ) {
|
1118 |
// some themes/ pagebuilders wrap backgroundimages in HTML-encoded quotes (or linebreaks) which breaks imgopt/ lazyloading, this removes them.
|
1119 |
return trim( str_replace( array( "\r\n", '"', '"', ''', ''' ), '', $tag_in ) );
|
@@ -1138,7 +1138,7 @@ class autoptimizeImages
|
|
1138 |
// no acces if multisite and not network admin and no site config allowed.
|
1139 |
if ( autoptimizeConfig::should_show_menu_tabs() ) {
|
1140 |
add_submenu_page(
|
1141 |
-
|
1142 |
'autoptimize_imgopt',
|
1143 |
'autoptimize_imgopt',
|
1144 |
'manage_options',
|
653 |
// then call add_lazyload-function with lpiq placeholder if set.
|
654 |
$tag = $this->add_lazyload( $tag, $placeholder );
|
655 |
}
|
656 |
+
|
657 |
// add decoding="async" behind filter, not sure if I'll make it default true yet.
|
658 |
if ( true === apply_filters( 'autoptimize_filter_imgopt_add_decoding', true ) && false === strpos( $tag, ' decoding=' ) ) {
|
659 |
$tag = str_replace( '<img ', '<img decoding="async" ', $tag );
|
665 |
if ( $tag !== $orig_tag ) {
|
666 |
$to_replace[ $orig_tag ] = $tag;
|
667 |
}
|
668 |
+
|
669 |
// and check if image needs to be prelaoded.
|
670 |
if ( ! empty( $metabox_preloads ) && is_array( $metabox_preloads ) && str_replace( $metabox_preloads, '', $tag ) !== $tag ) {
|
671 |
$to_preload .= $this->create_img_preload_tag( $tag );
|
831 |
if ( $this->should_lazyload( $out ) ) {
|
832 |
$to_replace[ $tag ] = $this->add_lazyload( $tag );
|
833 |
}
|
834 |
+
|
835 |
// and check if image needs to be prelaoded.
|
836 |
if ( ! empty( $metabox_preloads ) && is_array( $metabox_preloads ) && str_replace( $metabox_preloads, '', $tag ) !== $tag ) {
|
837 |
$to_preload .= $this->create_img_preload_tag( $tag );
|
955 |
echo apply_filters( 'autoptimize_filter_imgopt_lazyload_jsconfig', '<script' . $type_js . $noptimize_flag . '>window.lazySizesConfig=window.lazySizesConfig||{};window.lazySizesConfig.loadMode=1;</script>' );
|
956 |
echo apply_filters( 'autoptimize_filter_imgopt_lazyload_js', '<script async' . $type_js . $noptimize_flag . ' src=\'' . $lazysizes_js . '\'></script>' );
|
957 |
}
|
958 |
+
|
959 |
public static function create_img_preload_tag( $tag ) {
|
960 |
if ( false === apply_filters( 'autoptimize_filter_imgopt_dopreloads', true ) ) {
|
961 |
return '';
|
968 |
$_from = array( '<img ', ' src=', ' sizes=', ' srcset=' );
|
969 |
$_to = array( '<link rel="preload" as="image" ', ' href=', ' imagesizes=', ' imagesrcset=' );
|
970 |
$tag = str_replace( $_from, $_to, $tag );
|
971 |
+
|
972 |
// and remove title, alt, class and id.
|
973 |
$tag = preg_replace( '/ ((?:title|alt|class|id|loading)=".*")/Um', '', $tag );
|
974 |
if ( $tag !== str_replace( array(' title=', ' class=', ' alt=', ' id=' ), '', $tag ) ) {
|
1113 |
}
|
1114 |
return $matches[0];
|
1115 |
}
|
1116 |
+
|
1117 |
public function fix_silly_bgimg_quotes( $tag_in ) {
|
1118 |
// some themes/ pagebuilders wrap backgroundimages in HTML-encoded quotes (or linebreaks) which breaks imgopt/ lazyloading, this removes them.
|
1119 |
return trim( str_replace( array( "\r\n", '"', '"', ''', ''' ), '', $tag_in ) );
|
1138 |
// no acces if multisite and not network admin and no site config allowed.
|
1139 |
if ( autoptimizeConfig::should_show_menu_tabs() ) {
|
1140 |
add_submenu_page(
|
1141 |
+
'',
|
1142 |
'autoptimize_imgopt',
|
1143 |
'autoptimize_imgopt',
|
1144 |
'manage_options',
|
classes/autoptimizeMain.php
CHANGED
@@ -394,6 +394,12 @@ class autoptimizeMain
|
|
394 |
// 2 generic parameters that could/ should become standard between optimization plugins?)
|
395 |
if ( false === $ao_noptimize ) {
|
396 |
$_qs_showstoppers = array( 'no_cache', 'no_optimize', 'tve', 'elementor-preview', 'fl_builder', 'vc_action', 'et_fb', 'bt-beaverbuildertheme', 'ct_builder', 'fb-edit', 'siteorigin_panels_live_editor', 'preview' );
|
|
|
|
|
|
|
|
|
|
|
|
|
397 |
foreach ( $_qs_showstoppers as $_showstopper ) {
|
398 |
if ( array_key_exists( $_showstopper, $_GET ) ) {
|
399 |
$ao_noptimize = true;
|
@@ -558,7 +564,8 @@ class autoptimizeMain
|
|
558 |
'minify_excluded' => $conf->get( 'autoptimize_minify_excluded' ),
|
559 |
),
|
560 |
'autoptimizeHTML' => array(
|
561 |
-
'keepcomments'
|
|
|
562 |
),
|
563 |
);
|
564 |
|
@@ -618,6 +625,7 @@ class autoptimizeMain
|
|
618 |
'autoptimize_css_exclude',
|
619 |
'autoptimize_html',
|
620 |
'autoptimize_html_keepcomments',
|
|
|
621 |
'autoptimize_enable_site_config',
|
622 |
'autoptimize_enable_meta_ao_settings',
|
623 |
'autoptimize_js',
|
394 |
// 2 generic parameters that could/ should become standard between optimization plugins?)
|
395 |
if ( false === $ao_noptimize ) {
|
396 |
$_qs_showstoppers = array( 'no_cache', 'no_optimize', 'tve', 'elementor-preview', 'fl_builder', 'vc_action', 'et_fb', 'bt-beaverbuildertheme', 'ct_builder', 'fb-edit', 'siteorigin_panels_live_editor', 'preview' );
|
397 |
+
|
398 |
+
// doing Jonathan a quick favor to allow correct unused CSS generation ;-)
|
399 |
+
if ( apply_filters( 'autoptimize_filter_main_showstoppers_do_wp_rocket_a_favor', true ) ) {
|
400 |
+
$_qs_showstoppers[] = 'nowprocket';
|
401 |
+
}
|
402 |
+
|
403 |
foreach ( $_qs_showstoppers as $_showstopper ) {
|
404 |
if ( array_key_exists( $_showstopper, $_GET ) ) {
|
405 |
$ao_noptimize = true;
|
564 |
'minify_excluded' => $conf->get( 'autoptimize_minify_excluded' ),
|
565 |
),
|
566 |
'autoptimizeHTML' => array(
|
567 |
+
'keepcomments' => $conf->get( 'autoptimize_html_keepcomments' ),
|
568 |
+
'minify_inline' => $conf->get( 'autoptimize_html_minify_inline' ),
|
569 |
),
|
570 |
);
|
571 |
|
625 |
'autoptimize_css_exclude',
|
626 |
'autoptimize_html',
|
627 |
'autoptimize_html_keepcomments',
|
628 |
+
'autoptimize_html_minify_inline',
|
629 |
'autoptimize_enable_site_config',
|
630 |
'autoptimize_enable_meta_ao_settings',
|
631 |
'autoptimize_js',
|
classes/autoptimizeMetabox.php
CHANGED
@@ -29,6 +29,8 @@ class autoptimizeMetabox
|
|
29 |
// add extra types e.g. product or ... ?
|
30 |
);
|
31 |
|
|
|
|
|
32 |
foreach ( $screens as $screen ) {
|
33 |
add_meta_box(
|
34 |
'ao_metabox',
|
29 |
// add extra types e.g. product or ... ?
|
30 |
);
|
31 |
|
32 |
+
$screens = apply_filters( 'autoptimize_filter_metabox_screens', $screens );
|
33 |
+
|
34 |
foreach ( $screens as $screen ) {
|
35 |
add_meta_box(
|
36 |
'ao_metabox',
|
classes/autoptimizePartners.php
CHANGED
@@ -44,7 +44,7 @@ class autoptimizePartners
|
|
44 |
public function add_admin_menu()
|
45 |
{
|
46 |
if ( $this->enabled() ) {
|
47 |
-
add_submenu_page(
|
48 |
}
|
49 |
}
|
50 |
|
44 |
public function add_admin_menu()
|
45 |
{
|
46 |
if ( $this->enabled() ) {
|
47 |
+
add_submenu_page( '', 'AO partner', 'AO partner', 'manage_options', 'ao_partners', array( $this, 'ao_partners_page' ) );
|
48 |
}
|
49 |
}
|
50 |
|
classes/autoptimizeScripts.php
CHANGED
@@ -119,7 +119,7 @@ class autoptimizeScripts extends autoptimizeBase
|
|
119 |
* @var bool
|
120 |
*/
|
121 |
private $defer_not_aggregate = false;
|
122 |
-
|
123 |
/**
|
124 |
* Setting; defer inline JS?
|
125 |
*
|
@@ -220,7 +220,7 @@ class autoptimizeScripts extends autoptimizeBase
|
|
220 |
public function read( $options )
|
221 |
{
|
222 |
$noptimize_js = false;
|
223 |
-
|
224 |
// If page/ post check post_meta to see if optimize is off.
|
225 |
if ( false === autoptimizeConfig::get_post_meta_ao_settings( 'ao_post_js_optimize' ) ) {
|
226 |
$noptimize_js = true;
|
@@ -228,7 +228,7 @@ class autoptimizeScripts extends autoptimizeBase
|
|
228 |
|
229 |
// And a filter to enforce JS noptimize.
|
230 |
$noptimize_js = apply_filters( 'autoptimize_filter_js_noptimize', $noptimize_js, $this->content );
|
231 |
-
|
232 |
// And finally bail if noptimize_js is true.
|
233 |
if ( $noptimize_js ) {
|
234 |
return false;
|
@@ -263,12 +263,12 @@ class autoptimizeScripts extends autoptimizeBase
|
|
263 |
}
|
264 |
// and the filter that should have been there to begin with.
|
265 |
$this->aggregate = apply_filters( 'autoptimize_filter_js_aggregate', $this->aggregate );
|
266 |
-
|
267 |
// Defer when not aggregating.
|
268 |
if ( false === $this->aggregate && apply_filters( 'autoptimize_filter_js_defer_not_aggregate', $options['defer_not_aggregate'] ) ) {
|
269 |
$this->defer_not_aggregate = true;
|
270 |
}
|
271 |
-
|
272 |
// Defer inline JS?
|
273 |
if ( ( true === $this->defer_not_aggregate && apply_filters( 'autoptimize_js_filter_defer_inline', $options['defer_inline'] ) ) || apply_filters( 'autoptimize_js_filter_force_defer_inline', false ) ) {
|
274 |
$this->defer_inline = true;
|
@@ -450,9 +450,8 @@ class autoptimizeScripts extends autoptimizeBase
|
|
450 |
} else {
|
451 |
$tag = '';
|
452 |
}
|
453 |
-
} else if ( str_replace( $_inline_dontmove, '', $tag ) === $tag ) {
|
454 |
-
// defer inline JS by base64 encoding it.
|
455 |
-
// preg_match( '#<script.*>(.*)</script>#Usmi', $tag, $match );
|
456 |
preg_match( '#<script(?:[^>](?!id=))*\s*(?:id=(["\'])([^"\']+)\1)*+[^>]*+>(.*?)<\/script>#is', $tag, $match );
|
457 |
if ( $match[2] ) {
|
458 |
$_id = 'id="' . $match[2] . '" ';
|
119 |
* @var bool
|
120 |
*/
|
121 |
private $defer_not_aggregate = false;
|
122 |
+
|
123 |
/**
|
124 |
* Setting; defer inline JS?
|
125 |
*
|
220 |
public function read( $options )
|
221 |
{
|
222 |
$noptimize_js = false;
|
223 |
+
|
224 |
// If page/ post check post_meta to see if optimize is off.
|
225 |
if ( false === autoptimizeConfig::get_post_meta_ao_settings( 'ao_post_js_optimize' ) ) {
|
226 |
$noptimize_js = true;
|
228 |
|
229 |
// And a filter to enforce JS noptimize.
|
230 |
$noptimize_js = apply_filters( 'autoptimize_filter_js_noptimize', $noptimize_js, $this->content );
|
231 |
+
|
232 |
// And finally bail if noptimize_js is true.
|
233 |
if ( $noptimize_js ) {
|
234 |
return false;
|
263 |
}
|
264 |
// and the filter that should have been there to begin with.
|
265 |
$this->aggregate = apply_filters( 'autoptimize_filter_js_aggregate', $this->aggregate );
|
266 |
+
|
267 |
// Defer when not aggregating.
|
268 |
if ( false === $this->aggregate && apply_filters( 'autoptimize_filter_js_defer_not_aggregate', $options['defer_not_aggregate'] ) ) {
|
269 |
$this->defer_not_aggregate = true;
|
270 |
}
|
271 |
+
|
272 |
// Defer inline JS?
|
273 |
if ( ( true === $this->defer_not_aggregate && apply_filters( 'autoptimize_js_filter_defer_inline', $options['defer_inline'] ) ) || apply_filters( 'autoptimize_js_filter_force_defer_inline', false ) ) {
|
274 |
$this->defer_inline = true;
|
450 |
} else {
|
451 |
$tag = '';
|
452 |
}
|
453 |
+
} else if ( str_replace( $_inline_dontmove, '', $tag ) === $tag && strlen( $tag ) < apply_filters( 'autoptimize_filter_script_defer_inline_maxsize', 200000 ) ) {
|
454 |
+
// defer inline JS by base64 encoding it but only if string is not ridiculously huge (to avoid issues with below regex mainly).
|
|
|
455 |
preg_match( '#<script(?:[^>](?!id=))*\s*(?:id=(["\'])([^"\']+)\1)*+[^>]*+>(.*?)<\/script>#is', $tag, $match );
|
456 |
if ( $match[2] ) {
|
457 |
$_id = 'id="' . $match[2] . '" ';
|
classes/autoptimizeStyles.php
CHANGED
@@ -368,7 +368,7 @@ class autoptimizeStyles extends autoptimizeBase
|
|
368 |
if ( '' !== $new_tag ) {
|
369 |
// Optionally defer (preload) non-aggregated CSS.
|
370 |
$new_tag = $this->optionally_defer_excluded( $new_tag, $url );
|
371 |
-
|
372 |
// Check if we still need to CDN (esp. for already minified resources).
|
373 |
if ( ! empty( $this->cdn_url ) || has_filter( 'autoptimize_filter_base_replace_cdn' ) ) {
|
374 |
$new_tag = str_replace( $url, $this->url_replace_cdn( $url ), $new_tag );
|
368 |
if ( '' !== $new_tag ) {
|
369 |
// Optionally defer (preload) non-aggregated CSS.
|
370 |
$new_tag = $this->optionally_defer_excluded( $new_tag, $url );
|
371 |
+
|
372 |
// Check if we still need to CDN (esp. for already minified resources).
|
373 |
if ( ! empty( $this->cdn_url ) || has_filter( 'autoptimize_filter_base_replace_cdn' ) ) {
|
374 |
$new_tag = str_replace( $url, $this->url_replace_cdn( $url ), $new_tag );
|
classes/autoptimizeUtils.php
CHANGED
@@ -400,7 +400,7 @@ class autoptimizeUtils
|
|
400 |
* Now used to show notice, might be used later on to (un)hide page caching in AO if no page cache found.
|
401 |
*
|
402 |
* @return bool
|
403 |
-
*/
|
404 |
public static function find_pagecache( $disregard_transient = false ) {
|
405 |
static $_found_pagecache = null;
|
406 |
|
@@ -441,7 +441,7 @@ class autoptimizeUtils
|
|
441 |
}
|
442 |
}
|
443 |
}
|
444 |
-
|
445 |
// store in transient for 1 week if pagecache found.
|
446 |
if ( true === $_found_pagecache && true !== $disregard_transient ) {
|
447 |
set_transient( $_ao_pagecache_transient, true, WEEK_IN_SECONDS );
|
@@ -457,7 +457,7 @@ class autoptimizeUtils
|
|
457 |
* Used to limit notifications to AO settings pages.
|
458 |
*
|
459 |
* @return bool
|
460 |
-
*/
|
461 |
public static function is_ao_settings() {
|
462 |
$_is_ao_settings = ( str_replace( array( 'autoptimize', 'autoptimize_imgopt', 'ao_critcss', 'autoptimize_extra', 'ao_partners' ), '', $_SERVER['REQUEST_URI'] ) !== $_SERVER['REQUEST_URI'] ? true : false );
|
463 |
return $_is_ao_settings;
|
400 |
* Now used to show notice, might be used later on to (un)hide page caching in AO if no page cache found.
|
401 |
*
|
402 |
* @return bool
|
403 |
+
*/
|
404 |
public static function find_pagecache( $disregard_transient = false ) {
|
405 |
static $_found_pagecache = null;
|
406 |
|
441 |
}
|
442 |
}
|
443 |
}
|
444 |
+
|
445 |
// store in transient for 1 week if pagecache found.
|
446 |
if ( true === $_found_pagecache && true !== $disregard_transient ) {
|
447 |
set_transient( $_ao_pagecache_transient, true, WEEK_IN_SECONDS );
|
457 |
* Used to limit notifications to AO settings pages.
|
458 |
*
|
459 |
* @return bool
|
460 |
+
*/
|
461 |
public static function is_ao_settings() {
|
462 |
$_is_ao_settings = ( str_replace( array( 'autoptimize', 'autoptimize_imgopt', 'ao_critcss', 'autoptimize_extra', 'ao_partners' ), '', $_SERVER['REQUEST_URI'] ) !== $_SERVER['REQUEST_URI'] ? true : false );
|
463 |
return $_is_ao_settings;
|
classes/autoptimizeVersionUpdatesHandler.php
CHANGED
@@ -263,7 +263,7 @@ class autoptimizeVersionUpdatesHandler
|
|
263 |
|
264 |
/**
|
265 |
* remove CCSS request limit option + update jquery exclusion to include WordPress 5.6 jquery.min.js.
|
266 |
-
*/
|
267 |
private function upgrade_from_2_7() {
|
268 |
delete_option( 'autoptimize_ccss_rlimit' );
|
269 |
$js_exclusions = get_option( 'autoptimize_js_exclude', '' );
|
@@ -272,9 +272,9 @@ class autoptimizeVersionUpdatesHandler
|
|
272 |
autoptimizeOptionWrapper::update_option( 'autoptimize_js_exclude', $js_exclusions );
|
273 |
}
|
274 |
}
|
275 |
-
|
276 |
/**
|
277 |
-
* set an option to indicate the AO installation predates the compatibility logic, this way we
|
278 |
* can avoid adding compatibility code that is likely not needed and maybe not wanted as it
|
279 |
* can introduce performance regressions.
|
280 |
*/
|
263 |
|
264 |
/**
|
265 |
* remove CCSS request limit option + update jquery exclusion to include WordPress 5.6 jquery.min.js.
|
266 |
+
*/
|
267 |
private function upgrade_from_2_7() {
|
268 |
delete_option( 'autoptimize_ccss_rlimit' );
|
269 |
$js_exclusions = get_option( 'autoptimize_js_exclude', '' );
|
272 |
autoptimizeOptionWrapper::update_option( 'autoptimize_js_exclude', $js_exclusions );
|
273 |
}
|
274 |
}
|
275 |
+
|
276 |
/**
|
277 |
+
* set an option to indicate the AO installation predates the compatibility logic, this way we
|
278 |
* can avoid adding compatibility code that is likely not needed and maybe not wanted as it
|
279 |
* can introduce performance regressions.
|
280 |
*/
|
classes/critcss-inc/admin_settings_rules.js.php
CHANGED
@@ -112,7 +112,7 @@ function drawTable(critCssArray) {
|
|
112 |
jQuery("div.rnotice").show();
|
113 |
});
|
114 |
<?php
|
115 |
-
} else {
|
116 |
?>
|
117 |
console.log( "Autoptimize: " + rnotice + " <?php echo $_ao_ccss_review_notice_copy; ?>" );
|
118 |
<?php
|
@@ -281,11 +281,15 @@ function addEditRow(idToEdit) {
|
|
281 |
rpath = jQuery("#critcss_addedit_path").val();
|
282 |
rtype = jQuery("#critcss_addedit_pagetype option:selected").val();
|
283 |
rccss = jQuery("#critcss_addedit_css").val();
|
|
|
284 |
console.log('rpath: ' + rpath, 'rtype: ' + rtype, 'rccss: ' + rccss);
|
|
|
285 |
if (rpath === '' && rtype === '') {
|
286 |
-
alert('<?php _e( "
|
287 |
} else if (rtype !== '' && rccss == '') {
|
288 |
-
alert('<?php _e( "
|
|
|
|
|
289 |
} else {
|
290 |
saveEditCritCss();
|
291 |
jQuery(this).dialog('close');
|
112 |
jQuery("div.rnotice").show();
|
113 |
});
|
114 |
<?php
|
115 |
+
} else if ( $ao_ccss_debug ) {
|
116 |
?>
|
117 |
console.log( "Autoptimize: " + rnotice + " <?php echo $_ao_ccss_review_notice_copy; ?>" );
|
118 |
<?php
|
281 |
rpath = jQuery("#critcss_addedit_path").val();
|
282 |
rtype = jQuery("#critcss_addedit_pagetype option:selected").val();
|
283 |
rccss = jQuery("#critcss_addedit_css").val();
|
284 |
+
<?php if ( $ao_ccss_debug ) { ?>
|
285 |
console.log('rpath: ' + rpath, 'rtype: ' + rtype, 'rccss: ' + rccss);
|
286 |
+
<?php } ?>
|
287 |
if (rpath === '' && rtype === '') {
|
288 |
+
alert('<?php _e( "Rule validation error:\\n\\nBased on your rule type, you should set a path or conditional tag.", 'autoptimize' ); ?>');
|
289 |
} else if (rtype !== '' && rccss == '') {
|
290 |
+
alert('<?php _e( "Rule validation error:\\n\\nType based rules requires a minified critical CSS.", 'autoptimize' ); ?>');
|
291 |
+
} else if (rpath !== rpath.replace(/("|\'|<|>|\[|\]|{|}|\|)/,'')) {
|
292 |
+
alert('<?php _e( "Path validation error:\\n\\nThe path contains characters that are not permitted, remove or encode the unsafe characters.", 'autoptimize' ); ?>');
|
293 |
} else {
|
294 |
saveEditCritCss();
|
295 |
jQuery(this).dialog('close');
|
classes/static/exit-survey/exit-survey.js
CHANGED
@@ -72,6 +72,10 @@
|
|
72 |
$('#ao_uninstall_feedback_popup ').removeClass('active');
|
73 |
$('body').removeClass('ao-feedback-open');
|
74 |
});
|
|
|
|
|
|
|
|
|
75 |
|
76 |
$('#ao_uninstall_feedback_popup #ao-deactivate-yes').on('click', function (e) {
|
77 |
e.preventDefault();
|
72 |
$('#ao_uninstall_feedback_popup ').removeClass('active');
|
73 |
$('body').removeClass('ao-feedback-open');
|
74 |
});
|
75 |
+
|
76 |
+
$('#ao_feedback_email_toggle').on('click', function (e) {
|
77 |
+
$('#ao_feedback998').toggle();
|
78 |
+
});
|
79 |
|
80 |
$('#ao_uninstall_feedback_popup #ao-deactivate-yes').on('click', function (e) {
|
81 |
e.preventDefault();
|
readme.txt
CHANGED
@@ -3,9 +3,9 @@ Contributors: futtta, optimizingmatters, zytzagoo, turl
|
|
3 |
Tags: optimize, minify, performance, images, core web vitals, lazy-load, pagespeed, google fonts
|
4 |
Donate link: http://blog.futtta.be/2013/10/21/do-not-donate-to-me/
|
5 |
Requires at least: 4.9
|
6 |
-
Tested up to: 6.0
|
7 |
Requires PHP: 5.6
|
8 |
-
Stable tag: 3.0
|
9 |
|
10 |
Autoptimize speeds up your website by optimizing JS, CSS, images (incl. lazy-load), HTML and Google Fonts, asyncing JS, removing emoji cruft and more.
|
11 |
|
@@ -31,23 +31,23 @@ Just install from your WordPress "Plugins > Add New" screen and all will be well
|
|
31 |
|
32 |
= What does the plugin do to help speed up my site? =
|
33 |
|
34 |
-
It
|
35 |
|
36 |
= But I'm on HTTP/2, so I don't need Autoptimize? =
|
37 |
|
38 |
-
HTTP/2 is a great step forward for sure, reducing the impact of multiple requests from the same server significantly by using the same connection to perform several concurrent requests. That being said, [concatenation of CSS/ JS can still make a lot of sense](http://engineering.khanacademy.org/posts/js-packaging-http2.htm), as described in [this css-tricks.com article](https://css-tricks.com/http2-real-world-performance-test-analysis/) and this [blogpost from one of the Ebay engineers](http://calendar.perfplanet.com/2015/packaging-for-performance/). The conclusion; configure, test, reconfigure, retest, tweak and look what works best in your context. Maybe it's just HTTP/2, maybe it's HTTP/2 + aggregation and minification, maybe it's HTTP/2 + minification (which AO can do as well, simply untick the "aggregate JS-files" and/ or "aggregate CSS-files" options). And Autoptimize can do a lot more then "just" optimizing your JS & CSS off course ;-)
|
39 |
|
40 |
= Will this work with my blog? =
|
41 |
|
42 |
-
Although Autoptimize comes without any warranties, it will in general work flawlessly if you configure it correctly. See "Troubleshooting" below for info on how to configure in case of problems.
|
43 |
|
44 |
-
= Why is jquery.min.js not optimized =
|
45 |
|
46 |
Starting from AO 2.1 WordPress core's jquery.min.js is not optimized for the simple reason a lot of popular plugins inject inline JS that is not aggregated either (due to possible cache size issues with unique code in inline JS) which relies on jquery being available, so excluding jquery.min.js ensures that most sites will work out of the box. If you want optimize jquery as well, you can remove it from the JS optimization exclusion-list (you might have to enable "also aggregate inline JS" as well or switch to "force JS in head").
|
47 |
|
48 |
= Why is Autoptimized JS render blocking? =
|
49 |
|
50 |
-
|
51 |
|
52 |
= Why is the autoptimized CSS still called out as render blocking? =
|
53 |
|
@@ -128,18 +128,9 @@ Both CSS and JS optimization can skip code from being aggregated and minimized b
|
|
128 |
* if you want to exclude all files of a specific plugin, e.g. wp-content/plugins/funkyplugin/js/*, you can exclude for example "funkyplugin/js/" or "plugins/funkyplugin"
|
129 |
* if you want to exclude inline code, you'll have to find a specific, unique string in that block of code and add that to the exclusion list. Example: to exclude `<script>funky_data='Won\'t you take me to, Funky Town'</script>`, the identifier is "funky_data".
|
130 |
|
131 |
-
=
|
132 |
|
133 |
-
|
134 |
-
|
135 |
-
If your blog doesn't function normally after having turned on Autoptimize, here are some pointers to identify & solve such issues using "advanced settings":
|
136 |
-
|
137 |
-
* If all works but you notice your blog is slower, ensure you have a page caching plugin installed (WP Super Cache or similar) and check the info on cache size (the soution for that problem also impacts performance for uncached pages) in this FAQ as well.
|
138 |
-
* In case your blog looks weird, i.e. when the layout gets messed up, there is problem with CSS optimization. Try excluding one or more CSS-files from being optimized. You can also force CSS not to be aggregated by wrapping it in noptimize-tags in your theme or widget or by adding filename (for external stylesheets) or string (for inline styles) to the exclude-list.
|
139 |
-
* In case some functionality on your site stops working (a carroussel, a menu, the search input, ...) you're likely hitting JavaScript optimization trouble. Change the "Aggregate inline JS" and/ or "Force JavaScript in head?" settings and try again. Excluding 'js/jquery/jquery.min.js' from optimization (see below) and optionally activating "[Add try/catch wrapping](http://blog.futtta.be/2014/08/18/when-should-you-trycatch-javascript/)") can also help. Alternatively -for the technically savvy- you can exclude specific scripts from being treated (moved and/ or aggregated) by Autoptimize by adding a string that will match the offending Javascript or excluding it from within your template files or widgets by wrapping the code between noptimize-tags. Identifying the offending JavaScript and choosing the correct exclusion-string can be trial and error, but in the majority of cases JavaScript optimization issues can be solved this way. When debugging JavaScript issues, your browsers error console is the most important tool to help you understand what is going on.
|
140 |
-
* If your theme or plugin require jQuery, you can try either forcing all in head and/ or excluding jquery.min.js (and jQuery-plugins if needed).
|
141 |
-
* If you can't get either CSS or JS optimization working, you can off course always continue using the other two optimization-techniques.
|
142 |
-
* If you tried the troubleshooting tips above and you still can't get CSS and JS working at all, you can ask for support on the [WordPress Autoptimize support forum](http://wordpress.org/support/plugin/autoptimize). See below for a description of what information you should provide in your "trouble ticket"
|
143 |
|
144 |
= I excluded files but they are still being autoptimized? =
|
145 |
|
@@ -266,9 +257,9 @@ add_filter('autoptimize_filter_main_use_mbstring', '__return_true');`
|
|
266 |
|
267 |
Check [the FAQ on the (legacy) "power-up" here](https://wordpress.org/plugins/autoptimize-criticalcss/#faq), this info will be integrated in this FAQ at a later date.
|
268 |
|
269 |
-
= Do I still need the Critical CSS power-up when I have Autoptimize 2.7? =
|
270 |
|
271 |
-
|
272 |
|
273 |
= What does "enable 404 fallbacks" do? Why would I need this? =
|
274 |
|
@@ -324,6 +315,13 @@ Just [fork Autoptimize on Github](https://github.com/futtta/autoptimize) and cod
|
|
324 |
|
325 |
== Changelog ==
|
326 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
327 |
= 3.0.4 =
|
328 |
* fix for "undefined array key ao_post_preload” on post/ page edit screens
|
329 |
* fix for image optimization altering inline JS that contains an `<img` tag if lazyload is not active
|
@@ -337,7 +335,7 @@ Just [fork Autoptimize on Github](https://github.com/futtta/autoptimize) and cod
|
|
337 |
|
338 |
= 3.0.2 =
|
339 |
* rollback automatic "minify inline CSS/ JS" which broke more then expected, this will come back as a separate default off option later and can now be enabled with a simple filter: `add_filter( 'autoptimize_html_minify_inline_js_css', '__return_true');` .
|
340 |
-
* fix for "Call to undefined method autoptimizeOptionWrapper::delete_option()" in autoptimizeVersionUpdatesHandler.php
|
341 |
|
342 |
= 3.0.1 =
|
343 |
* fix for minification of inline script with type text/template breaking the template (e.g. ninja forms), hat tip to @bobsled.
|
@@ -356,143 +354,5 @@ Just [fork Autoptimize on Github](https://github.com/futtta/autoptimize) and cod
|
|
356 |
* fix: stop Divi from clearing Autoptimize's cache [which is pretty counter-productive](https://blog.futtta.be/2018/11/17/warning-divi-purging-autoptimizes-cache/).
|
357 |
* misc smaller fixes/ improvements, see the [GitHub commit log](https://github.com/futtta/autoptimize/commits/beta)
|
358 |
|
359 |
-
= 2.9.5.1 =
|
360 |
-
* fix for CSS cache growing too fast when inline CSS with variable selectors from WordPress 5.9 comment blocks is aggregated.
|
361 |
-
|
362 |
-
= 2.9.5 =
|
363 |
-
* Better fix for PHP notice in autoptimizeImages.php.
|
364 |
-
* Further improvements to the exit survey.
|
365 |
-
|
366 |
-
= 2.9.4 =
|
367 |
-
* Fix for 2 AMP compatibility issues (toolbar JS & lazyload JS).
|
368 |
-
* Fix for PHP notice in autoptimizeImages.php.
|
369 |
-
* Change default for "lazyload from nth image" from 0 to 2 (only applies to new installations).
|
370 |
-
* Improvements to the exit survey.
|
371 |
-
* Enjoy the end-of-year celebrations, there are great Autoptimize things to come in 2022! ;-)
|
372 |
-
|
373 |
-
= 2.9.3 =
|
374 |
-
* Improvement: add logic to autoptimize_404_handler.php to differentiate between different multisite sites.
|
375 |
-
* Improvement: remove the different feeds (and all JS to switch between them) on the settings-page, keeping only the "Autoptimize news".
|
376 |
-
* Improvement: reduced autoptimize_enable_site_config option lookups when on multisite and AO is active for network.
|
377 |
-
* Fixed wrong variable name that caused PHP notices (but did not affect normal usage) to $w3tc_minify_on.
|
378 |
-
* Fix for Autoptimize Toolbar being loaded on AMP pages for logged in administrators/ editors
|
379 |
-
* Fix for CDN replacement edge case (if the CDN has the site_url in it).
|
380 |
-
* Fix for service availability checks causing too many outgoing requests (root cause likely to be object caching resulting in the autoptimize_service_availability option not being updated)
|
381 |
-
* Added "exit survey" when Autoptimize is deactivated (with the kind help of Shakeeb of RapidLoad, thanks brother!)
|
382 |
-
|
383 |
-
= 2.9.2 =
|
384 |
-
* New: page/ post settings now have a "Generate Critical CSS"-button (critical CSS needs to be active with valid API key)
|
385 |
-
* Improvement: also check WP Rocket settings for possible conflicts
|
386 |
-
* Improvement: Image optimization CDN updated to new Autoptimize-specific subdomain
|
387 |
-
* Fix: "don't aggregate but defer" did not defer 3rd party hosted JS (can be disabled with a filter)
|
388 |
-
* Fix: the metabox per page/post logic failed when all optimizations were off (hat tip to Valenki for reporting) resulting in PHP notices
|
389 |
-
|
390 |
-
= 2.9.1 =
|
391 |
-
* New: logic to detect possibly conflicting plugins, with notification if found.
|
392 |
-
* Improvement: to be reviewed critical css rules UI change.
|
393 |
-
* Improvement: automatically save critical CSS rules when changed.
|
394 |
-
* Fix for no CCSS jobs being created when "aggregate CSS" is off and all files are minified.
|
395 |
-
* Fix for some page caches not being detected correctly leading to notification being shown when it should not (thanks @optimocha for warning me!)
|
396 |
-
* Fix for a (rare) lazyload-regression in 2.9.0.
|
397 |
-
* Fix for a (rare) image optimization issue when the same image is referenced multiple times as background-image in optimized CSS.
|
398 |
-
|
399 |
-
= 2.9.0 =
|
400 |
-
* New: per page/ post Autoptimize settings so one can disable specific optimizations (needs to be enabled on the main settings page under "Misc Options").
|
401 |
-
* New: "defer inline JS" as sub-option of "do not aggregate but defer" allowing to defer (almost) all JS.
|
402 |
-
* Improvement: Image optimization now automatically switches between AVIF & WebP & Jpeg even if lazyload is not active (AVIF has to be explicitly enabled).
|
403 |
-
* Improvement: re-ordering of "JavaScript optimization" settings & copy improvements.
|
404 |
-
* Misc. other minor fixes, see the [GitHub commit log](https://github.com/futtta/autoptimize/commits/beta)
|
405 |
-
|
406 |
-
This release coincides with my father's 76th birthday, who continues to be a big inspritation to me. He's a mechanical engineer who after retirement focused his technical insights, experience and never-ending inquisitiveness on fountain pen design and prototyping, inventing a new bulkfiller mechanism in the process. Search the web for `Fountainbel` to find out more about him (or read [this older blogpost I wrote in Dutch](https://blog.futtta.be/2008/04/09/mijn-vader-is-een-tovenaar/)). Love you pops!
|
407 |
-
|
408 |
-
= 2.8.4 =
|
409 |
-
* fix for an authenticated XSS vulnerability
|
410 |
-
|
411 |
-
= 2.8.3 =
|
412 |
-
* fix for missing ao-minify-html.php
|
413 |
-
|
414 |
-
= 2.8.2 =
|
415 |
-
* Images: only show "did you know shortpixel" notice on Autoptimize settings pages (no more littering all over the backend)
|
416 |
-
* Images: update lazysizes from upstream
|
417 |
-
* Images: misc. improvements such as fix for PHP "undefined index" notice, updated copy, ...
|
418 |
-
* HTML: rename HTML minify class from minify_HTML to AO_minify_HTML to avoid conflicts with e.g. W3TC
|
419 |
-
* Critical CSS: misc. improvements such as detect is_front_page before any other conditional, fix for conditional rules without an actual condition, improved debug logging, ...
|
420 |
-
* JS/ CSS: fix for AO not optimizing multisite child sites when CDN set
|
421 |
-
|
422 |
-
= 2.8.1 =
|
423 |
-
* Images: new option not to lazyload first X images
|
424 |
-
* fix for "array to string" conversion errors in image optimization logic of .ico files
|
425 |
-
* switch jQuery shorthand .click (in toolbar JS & PaND dismiss notice JS) to please jQuery Migrate helper (and because it's better that way)
|
426 |
-
|
427 |
-
= 2.8.0 =
|
428 |
-
* JavaScript: new option "defer but don't aggregate"
|
429 |
-
* JavaScript: ensure Autoptimize also acts on jQuery in WordPress 5.6 which is renamed to jquery.min.js from jquery.js before.
|
430 |
-
* Images: add field to exclude images from being optimized.
|
431 |
-
* Images: new filter (`autoptimize_filter_imgopt_lazyload_from_nth`) to tell AO not to lazyload the first X images (to improve LCP/ CLS).
|
432 |
-
* Critical CSS: major improvements of the job processing mechanism, reducing time spent from up to 1 minute to just a couple of seconds.
|
433 |
-
* Critical CSS: under "advanced options" replace "request limit" with "queue processing time limit" (default 30s).
|
434 |
-
* Extra | Google Fonts: better parsing of version 2 Google Font URL's (/css2/).
|
435 |
-
* Misc. other minor fixes, see the [GitHub commit log](https://github.com/futtta/autoptimize/commits/beta).
|
436 |
-
|
437 |
-
= 2.7.8 =
|
438 |
-
* Image optimization: add support for AVIF image format for browsers that support it (enabled with the existing WebP-option, also requires lazy-load to be active)
|
439 |
-
* Critical CSS: further security improvements of critical CSS import settings upload, based on the input of [Marcin Weglowski of afine.com](https://afine.com)
|
440 |
-
* Misc. other minor fixes, see the [GitHub commit log](https://github.com/futtta/autoptimize/commits/beta).
|
441 |
-
|
442 |
-
= 2.7.7 =
|
443 |
-
* critical CSS: make sure pages get a path-based rule even if a CPT or template matches (when "path based rules for pages" option is on)
|
444 |
-
* critical CSS: make sure the "unload CCSS javascript" is only added once
|
445 |
-
* settings screens: switch jQuery .attr() to .prop() as suggested by jQuery Migrate to prepare for [the great oncoming big jQuery updates](https://wptavern.com/major-jquery-changes-on-the-way-for-wordpress-5-5-and-beyond)
|
446 |
-
* HTML minify: reverse placeholder array to make sure last replaced placeholder is changed back first to fix rare issues
|
447 |
-
* security fix: kudos to [Erin Germ](https://eringerm.com/) for finding & reporting an authenticated XSS vulnerability
|
448 |
-
* security fix: props to an anonymous pentester for finding & reporting an authenticated malicous file upload vulnerability
|
449 |
-
|
450 |
-
= 2.7.6 =
|
451 |
-
* fix for top frontend admin-bar being invisible when "inline & defer" is active.
|
452 |
-
* fix for 3rd party CSS-files not being deferred when "inline & defer" is active.
|
453 |
-
* small copy changes on Extra settings screen.
|
454 |
-
|
455 |
-
= 2.7.5 =
|
456 |
-
* urgent fix for Google Fonts aggregate & preload that broke badly in 2.7.4.
|
457 |
-
|
458 |
-
= 2.7.4 =
|
459 |
-
* Image optimization: also optimize icon links
|
460 |
-
* Image optimization: fix webp-detection for Safari (contributed by @pinkasey)
|
461 |
-
* Image lazyload: remove CSS that hides the placeholder image/ sets transistion between placeholder and final image
|
462 |
-
* Critical CSS: new advanced option to unload CCSS on onLoad
|
463 |
-
* Critical CSS improvement: cache templates in a transient to avoid overhead of having to search filesystem time and time again (contributed by @pratham2003)
|
464 |
-
* Critical CSS improvement: better but still experimental jQuery deferring logic
|
465 |
-
* Critical CSS fix: prevent MANUAL template-based rules being overwritten
|
466 |
-
* CSS Inline & defer: move away from old loadCSS-based approach to [Filamentgroup's new, simpler method](https://www.filamentgroup.com/lab/load-css-simpler/)
|
467 |
-
* 404 fallback enabled by default for new installations
|
468 |
-
* changed all occurences of blacklist/ whitelist to blocklist/ allowlist. The filters `autoptimize_filter_js_whitelist` and `autoptimize_filter_css_whitelist` still work in 2.7.4 but usage is deprecated and should be replaced with `autoptimize_filter_js_allowlist` and `autoptimize_filter_css_allowlist`.
|
469 |
-
* updated readme to explicitly confirm this is GPL + praise open source projects used in Autoptimize as praise was long overdue!
|
470 |
-
* tested and confirmed working on WordPress 5.5 beta 2
|
471 |
-
|
472 |
-
= 2.7.3 =
|
473 |
-
* Critical CSS: cache settings in the PHP process instead of re-fetching them
|
474 |
-
* Critical CSS: shorter intervals between calls to criticalcss.com (shortening the asynchronous job queue processing time)
|
475 |
-
* inline & defer CSS: fix for some excluded files not being preloaded
|
476 |
-
* 404 fallback: only create fallback files for CSS/ JS, not for (background-)images
|
477 |
-
* copy changes as suggested by Cyrille (@css31), un grand merci!
|
478 |
-
* misc. other minor fixes, see the [GitHub commit log](https://github.com/futtta/autoptimize/commits/beta).
|
479 |
-
|
480 |
-
= 2.7.2 =
|
481 |
-
* Critical CSS: fix settings page issues with certain translation strings
|
482 |
-
* Critical CSS: fix "inline & defer" not being "seen" on multisite network settings
|
483 |
-
* Critical CSS: add links on path-based rules
|
484 |
-
* Critical CSS: fix for non-asci URL's not matching rules
|
485 |
-
* Improvement: auto-disable autoptimize on misc. page builder URL's
|
486 |
-
* Improvement: don't change non-aggregated CSS if it already has an onload attribute
|
487 |
-
* Image lazyload improvement: remove `"` from around background images
|
488 |
-
|
489 |
-
= 2.7.1 =
|
490 |
-
* A couple of small bugfixes, see the [GitHub commit log](https://github.com/futtta/autoptimize/commits/beta).
|
491 |
-
|
492 |
-
= 2.7.0 =
|
493 |
-
* Integration of critical CSS power-up.
|
494 |
-
* New option to ensure missing autoptimized files are served with fallback JS/ CSS.
|
495 |
-
* Batch of misc. smaller improvements & fixes, more info in the [GitHub commit log](https://github.com/futtta/autoptimize/commits/beta).
|
496 |
-
|
497 |
= older =
|
498 |
-
* see [https://plugins.svn.wordpress.org/autoptimize/tags/2.
|
3 |
Tags: optimize, minify, performance, images, core web vitals, lazy-load, pagespeed, google fonts
|
4 |
Donate link: http://blog.futtta.be/2013/10/21/do-not-donate-to-me/
|
5 |
Requires at least: 4.9
|
6 |
+
Tested up to: 6.0
|
7 |
Requires PHP: 5.6
|
8 |
+
Stable tag: 3.1.0
|
9 |
|
10 |
Autoptimize speeds up your website by optimizing JS, CSS, images (incl. lazy-load), HTML and Google Fonts, asyncing JS, removing emoji cruft and more.
|
11 |
|
31 |
|
32 |
= What does the plugin do to help speed up my site? =
|
33 |
|
34 |
+
It minifies all scripts and styles and configures your webserver to compresses them with good expires headers. JavaScript be default will be made non-render-blocking and CSS can be too by adding critical CSS. You can configure it to combine (aggregate) CSS & JS-files, in which case styles are moved to the page head, and scripts to the footer. It also minifies the HTML code and can also optimize images and Google Fonts, making your page really lightweight.
|
35 |
|
36 |
= But I'm on HTTP/2, so I don't need Autoptimize? =
|
37 |
|
38 |
+
HTTP/2 is a great step forward for sure, reducing the impact of multiple requests from the same server significantly by using the same connection to perform several concurrent requests and for that reason on new installations Autoptimize will not aggregate CSS and JS files any more. That being said, [concatenation of CSS/ JS can still make a lot of sense](http://engineering.khanacademy.org/posts/js-packaging-http2.htm), as described in [this css-tricks.com article](https://css-tricks.com/http2-real-world-performance-test-analysis/) and this [blogpost from one of the Ebay engineers](http://calendar.perfplanet.com/2015/packaging-for-performance/). The conclusion; configure, test, reconfigure, retest, tweak and look what works best in your context. Maybe it's just HTTP/2, maybe it's HTTP/2 + aggregation and minification, maybe it's HTTP/2 + minification (which AO can do as well, simply untick the "aggregate JS-files" and/ or "aggregate CSS-files" options). And Autoptimize can do a lot more then "just" optimizing your JS & CSS off course ;-)
|
39 |
|
40 |
= Will this work with my blog? =
|
41 |
|
42 |
+
Although Autoptimize comes without any warranties, it will in general work flawlessly if you configure it correctly. See "Troubleshooting" below for info on how to configure in case of problems. If you want you can [test Autoptimize on a new free dummy site, courtesy of tastewp.com](https://demo.tastewp.com/autoptimize).
|
43 |
|
44 |
+
= Why is jquery.min.js not optimized when aggregating JavaScript? =
|
45 |
|
46 |
Starting from AO 2.1 WordPress core's jquery.min.js is not optimized for the simple reason a lot of popular plugins inject inline JS that is not aggregated either (due to possible cache size issues with unique code in inline JS) which relies on jquery being available, so excluding jquery.min.js ensures that most sites will work out of the box. If you want optimize jquery as well, you can remove it from the JS optimization exclusion-list (you might have to enable "also aggregate inline JS" as well or switch to "force JS in head").
|
47 |
|
48 |
= Why is Autoptimized JS render blocking? =
|
49 |
|
50 |
+
This happens when aggregating JavaSCript and ticking the "force in head" option or when not aggregating and not deferring. Consider changing settings.
|
51 |
|
52 |
= Why is the autoptimized CSS still called out as render blocking? =
|
53 |
|
128 |
* if you want to exclude all files of a specific plugin, e.g. wp-content/plugins/funkyplugin/js/*, you can exclude for example "funkyplugin/js/" or "plugins/funkyplugin"
|
129 |
* if you want to exclude inline code, you'll have to find a specific, unique string in that block of code and add that to the exclusion list. Example: to exclude `<script>funky_data='Won\'t you take me to, Funky Town'</script>`, the identifier is "funky_data".
|
130 |
|
131 |
+
= Troubleshooting Autoptimize =
|
132 |
|
133 |
+
Have a look at the troubleshooitng instructions at https://blog.futtta.be/2022/05/05/what-to-do-when-autoptimize-breaks-your-site/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
134 |
|
135 |
= I excluded files but they are still being autoptimized? =
|
136 |
|
257 |
|
258 |
Check [the FAQ on the (legacy) "power-up" here](https://wordpress.org/plugins/autoptimize-criticalcss/#faq), this info will be integrated in this FAQ at a later date.
|
259 |
|
260 |
+
= Do I still need the Critical CSS power-up when I have Autoptimize 2.7 or higher? =
|
261 |
|
262 |
+
No, the Critical CSS power-up is not needed any more, all functionality (and many fixes/ improvements) are now part of Autoptimize.
|
263 |
|
264 |
= What does "enable 404 fallbacks" do? Why would I need this? =
|
265 |
|
315 |
|
316 |
== Changelog ==
|
317 |
|
318 |
+
= 3.1.0 =
|
319 |
+
* new: HTML sub-option: "minify inline CSS/ JS" (off by default).
|
320 |
+
* new: Misc option: permanently allow the "do not run compatibility logic" flag to be removed (which was set for users upgrading from AO 2.9.* to AO 3.0.* as the assumption was things were working anyway).
|
321 |
+
* security: improvements to the critical CSS settings page to fix authenticated cross site scripting issues as reported by WPScan Security.
|
322 |
+
* bugfix: "defer inline JS" of very large chunks of inline JS could cause server errors (PCRE crash actually) so not deferring if string is more then 200000 characters (filter available).
|
323 |
+
* some other minor changes/ improvements/ hooks, see the [GitHub commit log](https://github.com/futtta/autoptimize/commits/beta)
|
324 |
+
|
325 |
= 3.0.4 =
|
326 |
* fix for "undefined array key ao_post_preload” on post/ page edit screens
|
327 |
* fix for image optimization altering inline JS that contains an `<img` tag if lazyload is not active
|
335 |
|
336 |
= 3.0.2 =
|
337 |
* rollback automatic "minify inline CSS/ JS" which broke more then expected, this will come back as a separate default off option later and can now be enabled with a simple filter: `add_filter( 'autoptimize_html_minify_inline_js_css', '__return_true');` .
|
338 |
+
* fix for "Call to undefined method autoptimizeOptionWrapper::delete_option()" in autoptimizeVersionUpdatesHandler.php
|
339 |
|
340 |
= 3.0.1 =
|
341 |
* fix for minification of inline script with type text/template breaking the template (e.g. ninja forms), hat tip to @bobsled.
|
354 |
* fix: stop Divi from clearing Autoptimize's cache [which is pretty counter-productive](https://blog.futtta.be/2018/11/17/warning-divi-purging-autoptimizes-cache/).
|
355 |
* misc smaller fixes/ improvements, see the [GitHub commit log](https://github.com/futtta/autoptimize/commits/beta)
|
356 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
357 |
= older =
|
358 |
+
* see [https://plugins.svn.wordpress.org/autoptimize/tags/2.9.5.1/readme.txt](https://plugins.svn.wordpress.org/autoptimize/tags/2.9.5.1/readme.txt)
|