Autoptimize - Version 3.1.0

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 Icon 128x128 Autoptimize
Version 3.1.0
Comparing to
See all releases

Code changes from version 3.0.4 to 3.1.0

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.4
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.4' );
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&#37;</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' => 0,
796
- 'autoptimize_html_keepcomments' => 0,
797
- 'autoptimize_enable_site_config' => 1,
798
- 'autoptimize_js' => 0,
799
- 'autoptimize_js_aggregate' => 0,
800
- 'autoptimize_js_defer_not_aggregate' => 1,
801
- 'autoptimize_js_defer_inline' => 1,
802
- 'autoptimize_js_exclude' => '', // 'wp-includes/js/dist/, wp-includes/js/tinymce/, js/jquery/jquery.min.js',
803
- 'autoptimize_js_trycatch' => 0,
804
- 'autoptimize_js_justhead' => 0,
805
- 'autoptimize_js_include_inline' => 0,
806
- 'autoptimize_js_forcehead' => 0,
807
- 'autoptimize_css' => 0,
808
- 'autoptimize_css_aggregate' => 0,
809
- 'autoptimize_css_exclude' => '', // admin-bar.min.css, dashicons.min.css, wp-content/cache/, wp-content/uploads/',
810
- 'autoptimize_css_justhead' => 0,
811
- 'autoptimize_css_include_inline' => 0,
812
- 'autoptimize_css_defer' => 0,
813
- 'autoptimize_css_defer_inline' => '',
814
- 'autoptimize_css_inline' => 0,
815
- 'autoptimize_css_datauris' => 0,
816
- 'autoptimize_cdn_url' => '',
817
- 'autoptimize_cache_nogzip' => 1,
818
- 'autoptimize_optimize_logged' => 1,
819
- 'autoptimize_optimize_checkout' => 0,
820
- 'autoptimize_minify_excluded' => 1,
821
- 'autoptimize_cache_fallback' => 1,
822
- 'autoptimize_enable_meta_ao_settings' => 1,
 
 
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&#37;</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 ( strpos( $ccss, $blocklisted ) !== false ) {
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
- switch ( $lvl ) {
584
- case 1:
585
- $level = 'II';
586
- break;
587
- case 2:
588
- $level = 'EE';
589
- break;
590
- case 3:
591
- // Output debug messages only if debug mode is enabled.
592
- if ( $debug ) {
593
  $level = 'DD';
594
- }
595
- break;
596
- default:
597
- $level = 'UU';
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( null, 'Critical CSS', 'Critical CSS', 'manage_options', 'ao_critcss', array( $this, 'ao_criticalcsssettings_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='autoptimize_ccss_queue' value='" . json_encode( $ao_ccss_rules, JSON_FORCE_OBJECT ) . "'>";
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' ); ?> </label>
 
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" onchange="jQuery('#ao_feedback998').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
- null,
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 ( apply_filters( 'autoptimize_html_minify_inline_js_css', false ) ) {
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", '&quot;', '&#034;', '&apos;', '&#039;' ), '', $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
- null,
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", '&quot;', '&#034;', '&apos;', '&#039;' ), '', $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' => $conf->get( 'autoptimize_html_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( null, 'AO partner', 'AO partner', 'manage_options', 'ao_partners', array( $this, 'ao_partners_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( "RULE VALIDATION ERROR!\\n\\nBased on your rule type, you SHOULD set a path or conditional tag.", 'autoptimize' ); ?>');
287
  } else if (rtype !== '' && rccss == '') {
288
- alert('<?php _e( "RULE VALIDATION ERROR!\\n\\nType based rules REQUIRES a minified critical CSS.", 'autoptimize' ); ?>');
 
 
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.4
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 concatenates all scripts and styles, minifies and compresses them, adds expires headers, caches them, and moves styles to the page head, and scripts (optionally) to the footer. It also minifies the HTML code itself, 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. 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
- If not "forced in head", Autoptimized JS is not render blocking as it has the "defer" flag added. It is however possible another plugin removes the "defer"-flag. Speed Booster Pack was reported doing this, but [the behavior has not been confirmed yet](https://wordpress.org/support/topic/speed-booster-pack-autoptimized-js-defer-flag/).
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
- = Configuring & Troubleshooting Autoptimize =
132
 
133
- After having installed and activated the plugin, you'll have access to an admin page where you can to enable HTML, CSS and JavaScript optimization. According to your liking, you can start of just enabling all of them, or if you're more cautious one at a time.
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
- When both Autoptimize 2.7 and the separate Critical CSS power-up are installed and active, the power-up will handle the critical CSS part. When you disable the power-up, the integrated critical CSS code in Autoptimize 2.7 will take over.
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 `&quot;` 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.7.2/readme.txt](https://plugins.svn.wordpress.org/autoptimize/tags/2.7.2/readme.txt)
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)