Autoptimize - Version 3.1.4

Version Description

  • Improvement: when all CSS is inlined, try doing so after SEO meta-tags (just before ld+json script tag which most SEO plugins add as last item on their list).
  • Img opt: also optimize images set in data-background and data-retina attributes (+ filter to easily add other attributes)
  • CSS opt: filter to enable AO to skip minification of calc formulas in CSS (as the CSS minifier on rare occasions breaks those)
  • Multiple other filters added
  • Some other minor changes/ improvements/ filters, see the GitHub commit log.
Download this release

Release Info

Developer futtta
Plugin Icon 128x128 Autoptimize
Version 3.1.4
Comparing to
See all releases

Code changes from version 3.1.3 to 3.1.4

autoptimize.php CHANGED
@@ -3,7 +3,7 @@
3
  * Plugin Name: Autoptimize
4
  * Plugin URI: https://autoptimize.com/pro/
5
  * Description: Makes your site faster by optimizing CSS, JS, Images, Google fonts and more.
6
- * Version: 3.1.3
7
  * Author: Frank Goossens (futtta)
8
  * Author URI: https://autoptimize.com/pro/
9
  * Text Domain: autoptimize
@@ -21,7 +21,7 @@ if ( ! defined( 'ABSPATH' ) ) {
21
  exit;
22
  }
23
 
24
- define( 'AUTOPTIMIZE_PLUGIN_VERSION', '3.1.3' );
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/pro/
5
  * Description: Makes your site faster by optimizing CSS, JS, Images, Google fonts and more.
6
+ * Version: 3.1.4
7
  * Author: Frank Goossens (futtta)
8
  * Author URI: https://autoptimize.com/pro/
9
  * Text Domain: autoptimize
21
  exit;
22
  }
23
 
24
+ define( 'AUTOPTIMIZE_PLUGIN_VERSION', '3.1.4' );
25
 
26
  // plugin_dir_path() returns the trailing slash!
27
  define( 'AUTOPTIMIZE_PLUGIN_DIR', plugin_dir_path( __FILE__ ) );
classes/autoptimizeCSSmin.php CHANGED
@@ -36,8 +36,19 @@ class autoptimizeCSSmin
36
  */
37
  public function run( $css )
38
  {
 
 
 
 
 
 
39
  $result = $this->minifier->run( $css );
40
 
 
 
 
 
 
41
  return $result;
42
  }
43
 
36
  */
37
  public function run( $css )
38
  {
39
+ // hide calc() if filter says yes.
40
+ if ( apply_filters( 'autoptimize_filter_css_hide_calc', false ) ) {
41
+ $css = autoptimizeBase::replace_contents_with_marker_if_exists( 'CALC', 'calc(', '#calc\([^\)]*\)#m', $css );
42
+ }
43
+
44
+ // minify.
45
  $result = $this->minifier->run( $css );
46
 
47
+ // restore calc() if filter says yes.
48
+ if ( apply_filters( 'autoptimize_filter_css_hide_calc', false ) ) {
49
+ $result = autoptimizeBase::restore_marked_content( 'CALC', $result );
50
+ }
51
+
52
  return $result;
53
  }
54
 
classes/autoptimizeImages.php CHANGED
@@ -271,7 +271,7 @@ class autoptimizeImages
271
 
272
  public static function get_service_url_suffix()
273
  {
274
- $suffix = '/af/SPZURYE109483/' . AUTOPTIMIZE_SITE_DOMAIN;
275
 
276
  return $suffix;
277
  }
@@ -444,6 +444,11 @@ class autoptimizeImages
444
  return $imgopt_base_url;
445
  }
446
 
 
 
 
 
 
447
  private function can_optimize_image( $url, $tag = '', $testing = false )
448
  {
449
  static $cdn_url = null;
@@ -489,6 +494,12 @@ class autoptimizeImages
489
  return true;
490
  }
491
 
 
 
 
 
 
 
492
  private function build_imgopt_url( $orig_url, $width = 0, $height = 0 )
493
  {
494
  // sanitize width and height.
@@ -593,6 +604,7 @@ class autoptimizeImages
593
  // get img preloads as set in post metabox, exploding ", " instead of "," because LCP preload
594
  // could be a shortpixel URL, which has comma's and results in way too many preloads.
595
  $metabox_preloads = array_filter( array_map( 'trim', explode( ', ', wp_strip_all_tags( autoptimizeConfig::get_post_meta_ao_settings( 'ao_post_preload' ) ) ) ) );
 
596
 
597
  // extract img tags.
598
  if ( preg_match_all( '#<img[^>]*src[^>]*>#Usmi', $in, $matches ) ) {
@@ -693,13 +705,19 @@ class autoptimizeImages
693
  // and replace all.
694
  $out = str_replace( array_keys( $to_replace ), array_values( $to_replace ), $in );
695
 
696
- // img thumbnails in e.g. woocommerce.
697
- if ( strpos( $out, 'data-thumb' ) !== false && apply_filters( 'autoptimize_filter_imgopt_datathumbs', true ) ) {
698
- $out = preg_replace_callback(
699
- '/\<div(?:[^>]?)\sdata-thumb\=(?:\"|\')(.+?)(?:\"|\')(?:[^>]*)?\>/s',
700
- array( $this, 'replace_data_thumbs' ),
701
- $out
702
- );
 
 
 
 
 
 
703
  }
704
 
705
  // background-image in inline style.
@@ -933,6 +951,8 @@ class autoptimizeImages
933
  // add the noscript-tag from earlier.
934
  $tag = $noscript_tag . $tag;
935
  $tag = apply_filters( 'autoptimize_filter_imgopt_lazyloaded_img', $tag );
 
 
936
  }
937
 
938
  return $tag;
@@ -1236,12 +1256,12 @@ class autoptimizeImages
1236
  <form id='ao_settings_form' action='<?php echo admin_url( 'options.php' ); ?>' method='post'>
1237
  <?php settings_fields( 'autoptimize_imgopt_settings' ); ?>
1238
  <h2><?php _e( 'Image optimization', 'autoptimize' ); ?></h2>
1239
- <span id='autoptimize_imgopt_descr'><?php echo apply_filters( 'autoptimize_filter_imgopt_intro_copy', __( 'Make your site significantly faster by just ticking a couple of checkboxes to optimize and lazy load your images, modern image format support included! No additional plugins or services needed.', 'autoptimize' ) ); ?></span>
1240
  <table class="form-table">
1241
  <tr>
1242
- <th scope="row"><?php _e( 'Optimize Images', 'autoptimize' ); ?></th>
1243
  <td>
1244
- <label><input id='autoptimize_imgopt_checkbox' type='checkbox' name='autoptimize_imgopt_settings[autoptimize_imgopt_checkbox_field_1]' <?php if ( ! empty( $options['autoptimize_imgopt_checkbox_field_1'] ) && '1' === $options['autoptimize_imgopt_checkbox_field_1'] ) { echo 'checked="checked"'; } ?> value='1'><?php echo apply_filters( 'autoptimize_filter_imgopt_main_setting_copy', __( 'Optimize images on the fly and serve them from Shortpixel\'s global CDN.', 'autoptimize' ) ); ?></label>
1245
  <?php
1246
  // show shortpixel status.
1247
  $_notice = autoptimizeImages::instance()->get_imgopt_status_notice();
@@ -1264,20 +1284,20 @@ class autoptimizeImages
1264
  echo apply_filters( 'autoptimize_filter_imgopt_settings_status', '<p><strong><span style="color:' . $_notice_color . ';">' . __( 'Shortpixel status: ', 'autoptimize' ) . '</span></strong>' . $_notice['notice'] . '</p>' );
1265
  } else {
1266
  // translators: link points to shortpixel.
1267
- $upsell_msg_1 = '<p>' . sprintf( __( 'Get more Google love by speeding up your website. Start serving on-the-fly optimized images (also in the "next-gen" <strong>WebP</strong> and <strong>AVIF</strong> image formats) by %1$sShortPixel%2$s. No additional image optimization plugins are needed: your images are optimized, cached and served from %3$sShortPixel\'s global CDN%2$s.', 'autoptimize' ), '<a href="https://shortpixel.com/aospai' . $sp_url_suffix . '" target="_blank">', '</a>', '<a href="https://help.shortpixel.com/article/62-where-does-the-cdn-has-pops" target="_blank">' );
1268
  if ( 'launch' === $options['availabilities']['extra_imgopt']['status'] ) {
1269
  $upsell_msg_2 = __( 'For a limited time only, this service is offered free for all Autoptimize users, <b>don\'t miss the chance to test it</b> and see how much it could improve your site\'s speed.', 'autoptimize' );
1270
  } else {
1271
- // translators: link points to shortpixel.
1272
- $upsell_msg_2 = sprintf( __( '%1$sSign-up now%2$s to receive x2 more CDN traffic or image optimization credits for free! This offer also applies to any future plan that you\'ll choose to purchase.', 'autoptimize' ), '<a href="https://shortpixel.com/aospai' . $sp_url_suffix . '" target="_blank">', '</a>' );
1273
  }
1274
  echo apply_filters( 'autoptimize_filter_imgopt_settings_copy', $upsell_msg_1 . ' ' . $upsell_msg_2 . '</p>' );
1275
  }
1276
  // translators: link points to shortpixel FAQ.
1277
- $faqcopy = sprintf( __( '<strong>Questions</strong>? Have a look at the %1$sAutoptimize + ShortPixel FAQ%2$s!', 'autoptimize' ), '<strong><a href="https://help.shortpixel.com/category/405-autoptimize" target="_blank">', '</strong></a>' );
1278
  $faqcopy = $faqcopy . ' ' . __( 'Only works for websites and images that are publicly available.', 'autoptimize' );
1279
  // translators: links points to shortpixel TOS & Privacy Policy.
1280
- $toscopy = sprintf( __( 'Usage of this feature is subject to Shortpixel\'s %1$sTerms of Use%2$s and %3$sPrivacy policy%4$s.', 'autoptimize' ), '<a href="https://shortpixel.com/tos' . $sp_url_suffix . '" target="_blank">', '</a>', '<a href="https://shortpixel.com/pp' . $sp_url_suffix . '" target="_blank">', '</a>' );
1281
  echo apply_filters( 'autoptimize_filter_imgopt_settings_tos', '<p>' . $faqcopy . ' ' . $toscopy . '</p>' );
1282
  ?>
1283
  </td>
@@ -1311,7 +1331,7 @@ class autoptimizeImages
1311
  <p>
1312
  <?php
1313
  // translators: link points to shortpixel image test page.
1314
- echo apply_filters( 'autoptimize_filter_imgopt_quality_copy', sprintf( __( 'You can %1$stest compression levels here%2$s.', 'autoptimize' ), '<a href="https://shortpixel.com/oic' . $sp_url_suffix . '" target="_blank">', '</a>' ) );
1315
  ?>
1316
  </p>
1317
  </td>
@@ -1386,24 +1406,24 @@ class autoptimizeImages
1386
  $_imgopt_notice = '';
1387
  $_stat = autoptimizeOptionWrapper::get_option( 'autoptimize_imgopt_provider_stat', '' );
1388
  $_site_host = AUTOPTIMIZE_SITE_DOMAIN;
1389
- $_imgopt_upsell = 'https://shortpixel.com/aospai/af/SPZURYE109483/' . $_site_host;
1390
  $_imgopt_assoc = 'https://shortpixel.helpscoutdocs.com/article/94-how-to-associate-a-domain-to-my-account';
1391
  $_imgopt_unreach = 'https://shortpixel.helpscoutdocs.com/article/148-why-are-my-images-redirected-from-cdn-shortpixel-ai';
1392
 
1393
  if ( is_array( $_stat ) ) {
1394
  if ( 1 == $_stat['Status'] ) {
1395
  // translators: "add more credits" will appear in a "a href".
1396
- $_imgopt_notice = sprintf( __( 'Your ShortPixel image optimization and CDN quota is almost used, make sure you %1$sadd more credits%2$s to avoid slowing down your website.', 'autoptimize' ), '<a href="' . $_imgopt_upsell . '" target="_blank">', '</a>' );
1397
  } elseif ( -1 == $_stat['Status'] || -2 == $_stat['Status'] ) {
1398
  // translators: "add more credits" will appear in a "a href".
1399
- $_imgopt_notice = sprintf( __( 'Your ShortPixel image optimization and CDN quota was used, %1$sadd more credits%2$s to keep fast serving optimized images on your site', 'autoptimize' ), '<a href="' . $_imgopt_upsell . '" target="_blank">', '</a>' );
1400
  // translators: "associate your domain" will appear in a "a href".
1401
  $_imgopt_notice = $_imgopt_notice . ' ' . sprintf( __( 'If you have enough CDN quota remaining, then you may need to %1$sassociate your domain%2$s to your Shortpixel account.', 'autoptimize' ), '<a rel="noopener noreferrer" href="' . $_imgopt_assoc . '" target="_blank">', '</a>' );
1402
  } elseif ( -3 == $_stat['Status'] ) {
1403
  // translators: "check the documentation here" will appear in a "a href".
1404
  $_imgopt_notice = sprintf( __( 'It seems ShortPixel image optimization is not able to fetch images from your site, %1$scheck the documentation here%2$s for more information', 'autoptimize' ), '<a href="' . $_imgopt_unreach . '" target="_blank">', '</a>' );
1405
  } else {
1406
- $_imgopt_upsell = 'https://shortpixel.com/g/af/SPZURYE109483';
1407
  // translators: "log in to check your account" will appear in a "a href".
1408
  $_imgopt_notice = sprintf( __( 'Your ShortPixel image optimization and CDN quota are in good shape, %1$slog in to check your account%2$s.', 'autoptimize' ), '<a href="' . $_imgopt_upsell . '" target="_blank">', '</a>' );
1409
  }
271
 
272
  public static function get_service_url_suffix()
273
  {
274
+ $suffix = '/af/U0ZIWMK109483/' . AUTOPTIMIZE_SITE_DOMAIN;
275
 
276
  return $suffix;
277
  }
444
  return $imgopt_base_url;
445
  }
446
 
447
+ public static function can_optimize_image_wrapper( $url, $tag = '', $testing = false ) {
448
+ $self = new self();
449
+ return $self->can_optimize_image( $url, $tag = '', $testing = false );
450
+ }
451
+
452
  private function can_optimize_image( $url, $tag = '', $testing = false )
453
  {
454
  static $cdn_url = null;
494
  return true;
495
  }
496
 
497
+ // wrapper for reuse in AOPro.
498
+ public static function build_imgopt_url_wrapper( $orig_url, $width = 0, $height = 0 ) {
499
+ $self = new self();
500
+ return $self->build_imgopt_url( $orig_url, $width = 0, $height = 0 );
501
+ }
502
+
503
  private function build_imgopt_url( $orig_url, $width = 0, $height = 0 )
504
  {
505
  // sanitize width and height.
604
  // get img preloads as set in post metabox, exploding ", " instead of "," because LCP preload
605
  // could be a shortpixel URL, which has comma's and results in way too many preloads.
606
  $metabox_preloads = array_filter( array_map( 'trim', explode( ', ', wp_strip_all_tags( autoptimizeConfig::get_post_meta_ao_settings( 'ao_post_preload' ) ) ) ) );
607
+ $metabox_preloads = apply_filters( 'autoptimize_filter_images_metabox_preloads', $metabox_preloads );
608
 
609
  // extract img tags.
610
  if ( preg_match_all( '#<img[^>]*src[^>]*>#Usmi', $in, $matches ) ) {
705
  // and replace all.
706
  $out = str_replace( array_keys( $to_replace ), array_values( $to_replace ), $in );
707
 
708
+ // misc. node attributes that might hold image url's (incl. the previously separate data-thumb).
709
+ $extra_attr_with_img = apply_filters( 'autoptimize_filter_imgopt_attr_with_img', array( array( 'div', 'data-thumb'), array( 'div', 'data-background' ), array( 'img', 'data-retina' ) ) );
710
+ if ( ! empty( $extra_attr_with_img ) && is_array( $extra_attr_with_img ) ) {
711
+ foreach ( $extra_attr_with_img as $candidate ) {
712
+ if ( is_array( $candidate ) && strpos( $out, $candidate[1] ) !== false ) {
713
+ $_regex = '/\<' . $candidate[0] . '(?:[^>]*)?\s' . $candidate[1] . '=(?:"|\')(.+?)(?:"|\')(?:[^>]*)?>/s';
714
+ $out = preg_replace_callback(
715
+ $_regex,
716
+ array( $this, 'replace_img_callback' ),
717
+ $out
718
+ );
719
+ }
720
+ }
721
  }
722
 
723
  // background-image in inline style.
951
  // add the noscript-tag from earlier.
952
  $tag = $noscript_tag . $tag;
953
  $tag = apply_filters( 'autoptimize_filter_imgopt_lazyloaded_img', $tag );
954
+ } else {
955
+ $tag = apply_filters( 'autoptimize_filter_imgopt_not_lazyloaded_img', $tag );
956
  }
957
 
958
  return $tag;
1256
  <form id='ao_settings_form' action='<?php echo admin_url( 'options.php' ); ?>' method='post'>
1257
  <?php settings_fields( 'autoptimize_imgopt_settings' ); ?>
1258
  <h2><?php _e( 'Image optimization', 'autoptimize' ); ?></h2>
1259
+ <span id='autoptimize_imgopt_descr'><?php echo apply_filters( 'autoptimize_filter_imgopt_intro_copy', __( 'Make your site significantly faster by simply ticking a few boxes and start serving CDN powered, optimized images in next-get formats like WebP and AVIF! No additional plugins or services needed.', 'autoptimize' ) ); ?></span>
1260
  <table class="form-table">
1261
  <tr>
1262
+ <th scope="row"><?php _e( 'Image optimization & CDN', 'autoptimize' ); ?></th>
1263
  <td>
1264
+ <label><input id='autoptimize_imgopt_checkbox' type='checkbox' name='autoptimize_imgopt_settings[autoptimize_imgopt_checkbox_field_1]' <?php if ( ! empty( $options['autoptimize_imgopt_checkbox_field_1'] ) && '1' === $options['autoptimize_imgopt_checkbox_field_1'] ) { echo 'checked="checked"'; } ?> value='1'><?php echo apply_filters( 'autoptimize_filter_imgopt_main_setting_copy', __( 'On-the-fly image optimization and fast delivery via the Shortpixel global CDN.', 'autoptimize' ) ); ?></label>
1265
  <?php
1266
  // show shortpixel status.
1267
  $_notice = autoptimizeImages::instance()->get_imgopt_status_notice();
1284
  echo apply_filters( 'autoptimize_filter_imgopt_settings_status', '<p><strong><span style="color:' . $_notice_color . ';">' . __( 'Shortpixel status: ', 'autoptimize' ) . '</span></strong>' . $_notice['notice'] . '</p>' );
1285
  } else {
1286
  // translators: link points to shortpixel.
1287
+ $upsell_msg_1 = '<p>' . sprintf( __( 'Get more Google love by speeding up your website. Start serving on-the-fly optimized images (also in the "next-gen" <strong>WebP</strong> and <strong>AVIF</strong> image formats) by %1$sShortPixel%2$s. No additional image optimization plugins are needed: your images are optimized, cached and served from %3$sShortPixel\'s global CDN%2$s.', 'autoptimize' ), '<a href="https://autoptimize.shortpixel.com/" target="_blank">', '</a>', '<a href="https://help.shortpixel.com/article/62-where-does-the-cdn-has-pops" target="_blank">' );
1288
  if ( 'launch' === $options['availabilities']['extra_imgopt']['status'] ) {
1289
  $upsell_msg_2 = __( 'For a limited time only, this service is offered free for all Autoptimize users, <b>don\'t miss the chance to test it</b> and see how much it could improve your site\'s speed.', 'autoptimize' );
1290
  } else {
1291
+ // translators: 1st link points to autoptimize.com.pro, 2nd to shortpixel.
1292
+ $upsell_msg_2 = sprintf( __( 'For <strong>unlimited image optimizations %1$sbuy Autoptimize Pro%2$s</strong> which also includes Critical CSS and extra "booster" options or %3$ssign up at Shortpixel%4$s.', 'autoptimize' ), '<a href="https://autoptimize.com/pro/" target="_blank">', '</a>', '<a href="https://autoptimize.shortpixel.com/' . $sp_url_suffix . '" target="_blank">', '</a>' );
1293
  }
1294
  echo apply_filters( 'autoptimize_filter_imgopt_settings_copy', $upsell_msg_1 . ' ' . $upsell_msg_2 . '</p>' );
1295
  }
1296
  // translators: link points to shortpixel FAQ.
1297
+ $faqcopy = sprintf( __( '<strong>Questions</strong>? Take a look at the %1$sAutoptimize + ShortPixel FAQ%2$s!', 'autoptimize' ), '<strong><a href="https://help.shortpixel.com/category/405-autoptimize" target="_blank">', '</strong></a>' );
1298
  $faqcopy = $faqcopy . ' ' . __( 'Only works for websites and images that are publicly available.', 'autoptimize' );
1299
  // translators: links points to shortpixel TOS & Privacy Policy.
1300
+ $toscopy = sprintf( __( 'Usage of this feature is subject to Shortpixel\'s %1$sTerms of Use%2$s and %3$sPrivacy policy%4$s.', 'autoptimize' ), '<a href="https://shortpixel.com/tos' . $sp_url_suffix . '" target="_blank">', '</a>', '<a href="https://shortpixel.com/privacy' . $sp_url_suffix . '" target="_blank">', '</a>' );
1301
  echo apply_filters( 'autoptimize_filter_imgopt_settings_tos', '<p>' . $faqcopy . ' ' . $toscopy . '</p>' );
1302
  ?>
1303
  </td>
1331
  <p>
1332
  <?php
1333
  // translators: link points to shortpixel image test page.
1334
+ echo apply_filters( 'autoptimize_filter_imgopt_quality_copy', sprintf( __( 'You can %1$stest compression levels here%2$s.', 'autoptimize' ), '<a href="https://shortpixel.com/online-image-compression' . $sp_url_suffix . '" target="_blank">', '</a>' ) );
1335
  ?>
1336
  </p>
1337
  </td>
1406
  $_imgopt_notice = '';
1407
  $_stat = autoptimizeOptionWrapper::get_option( 'autoptimize_imgopt_provider_stat', '' );
1408
  $_site_host = AUTOPTIMIZE_SITE_DOMAIN;
1409
+ $_imgopt_upsell = 'https://autoptimize.shortpixel.com/' . $_site_host;
1410
  $_imgopt_assoc = 'https://shortpixel.helpscoutdocs.com/article/94-how-to-associate-a-domain-to-my-account';
1411
  $_imgopt_unreach = 'https://shortpixel.helpscoutdocs.com/article/148-why-are-my-images-redirected-from-cdn-shortpixel-ai';
1412
 
1413
  if ( is_array( $_stat ) ) {
1414
  if ( 1 == $_stat['Status'] ) {
1415
  // translators: "add more credits" will appear in a "a href".
1416
+ $_imgopt_notice = sprintf( __( 'Your ShortPixel image optimization and CDN quota is almost used, make sure you %1$sadd more credits%2$s to avoid slowing down your website <strong>or consider using %3$sAutoptimize Pro%2$s which comes with (nearly) unlimited image optimization</strong> but also automated critical CSS and extra booster options.', 'autoptimize' ), '<a href="' . $_imgopt_upsell . '" target="_blank">', '</a>', '<a href="https://autoptimize.com/pro/" target="_blank">' );
1417
  } elseif ( -1 == $_stat['Status'] || -2 == $_stat['Status'] ) {
1418
  // translators: "add more credits" will appear in a "a href".
1419
+ $_imgopt_notice = sprintf( __( 'Your ShortPixel image optimization and CDN quota has been exhausted, %1$sadd more credits%2$s to continue to quickly deliver optimized images on your website <strong>or consider using %3$sAutoptimize Pro%2$s which comes with (nearly) unlimited image optimization</strong> but also automated critical CSS and extra booster options.', 'autoptimize' ), '<a href="' . $_imgopt_upsell . '" target="_blank">', '</a>', '<a href="https://autoptimize.com/pro/" target="_blank">' );
1420
  // translators: "associate your domain" will appear in a "a href".
1421
  $_imgopt_notice = $_imgopt_notice . ' ' . sprintf( __( 'If you have enough CDN quota remaining, then you may need to %1$sassociate your domain%2$s to your Shortpixel account.', 'autoptimize' ), '<a rel="noopener noreferrer" href="' . $_imgopt_assoc . '" target="_blank">', '</a>' );
1422
  } elseif ( -3 == $_stat['Status'] ) {
1423
  // translators: "check the documentation here" will appear in a "a href".
1424
  $_imgopt_notice = sprintf( __( 'It seems ShortPixel image optimization is not able to fetch images from your site, %1$scheck the documentation here%2$s for more information', 'autoptimize' ), '<a href="' . $_imgopt_unreach . '" target="_blank">', '</a>' );
1425
  } else {
1426
+ $_imgopt_upsell = 'https://autoptimize.shortpixel.com/';
1427
  // translators: "log in to check your account" will appear in a "a href".
1428
  $_imgopt_notice = sprintf( __( 'Your ShortPixel image optimization and CDN quota are in good shape, %1$slog in to check your account%2$s.', 'autoptimize' ), '<a href="' . $_imgopt_upsell . '" target="_blank">', '</a>' );
1429
  }
classes/autoptimizeMain.php CHANGED
@@ -393,7 +393,7 @@ class autoptimizeMain
393
  // Misc. querystring paramaters that will stop AO from doing optimizations (pagebuilders +
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 ) ) {
@@ -756,14 +756,14 @@ class autoptimizeMain
756
  public static function notice_plug_imgopt()
757
  {
758
  // Translators: the URL added points to the Autopmize Extra settings.
759
- $_ao_imgopt_plug_notice = sprintf( __( 'Did you know Autoptimize includes on-the-fly image optimization (with support for WebP and AVIF) and CDN via ShortPixel? Check out the %1$sAutoptimize Image settings%2$s to activate this option.', 'autoptimize' ), '<a href="options-general.php?page=autoptimize_imgopt">', '</a>' );
760
  $_ao_imgopt_plug_notice = apply_filters( 'autoptimize_filter_main_imgopt_plug_notice', $_ao_imgopt_plug_notice );
761
  $_ao_imgopt_launch_ok = autoptimizeImages::launch_ok_wrapper();
762
  $_ao_imgopt_plug_dismissible = 'ao-img-opt-plug-123';
763
  $_ao_imgopt_active = autoptimizeImages::imgopt_active();
764
  $_is_ao_settings_page = autoptimizeUtils::is_ao_settings();
765
 
766
- if ( current_user_can( 'manage_options' ) && $_is_ao_settings_page && '' !== $_ao_imgopt_plug_notice && ! $_ao_imgopt_active && $_ao_imgopt_launch_ok && PAnD::is_admin_notice_active( $_ao_imgopt_plug_dismissible ) ) {
767
  echo '<div class="notice notice-info is-dismissible" data-dismissible="' . $_ao_imgopt_plug_dismissible . '"><p>';
768
  echo $_ao_imgopt_plug_notice;
769
  echo '</p></div>';
393
  // Misc. querystring paramaters that will stop AO from doing optimizations (pagebuilders +
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', 'td_action' );
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 ) ) {
756
  public static function notice_plug_imgopt()
757
  {
758
  // Translators: the URL added points to the Autopmize Extra settings.
759
+ $_ao_imgopt_plug_notice = sprintf( __( 'Did you know Autoptimize that Autoptimize offers on-the-fly image optimization (with support for WebP and AVIF) and CDN via ShortPixel? Check out the %1$sAutoptimize Image settings%2$s to enable this option.', 'autoptimize' ), '<a href="options-general.php?page=autoptimize_imgopt">', '</a>' );
760
  $_ao_imgopt_plug_notice = apply_filters( 'autoptimize_filter_main_imgopt_plug_notice', $_ao_imgopt_plug_notice );
761
  $_ao_imgopt_launch_ok = autoptimizeImages::launch_ok_wrapper();
762
  $_ao_imgopt_plug_dismissible = 'ao-img-opt-plug-123';
763
  $_ao_imgopt_active = autoptimizeImages::imgopt_active();
764
  $_is_ao_settings_page = autoptimizeUtils::is_ao_settings();
765
 
766
+ if ( current_user_can( 'manage_options' ) && ! defined( 'AO_PRO_VERSION' ) && $_is_ao_settings_page && '' !== $_ao_imgopt_plug_notice && ! $_ao_imgopt_active && $_ao_imgopt_launch_ok && PAnD::is_admin_notice_active( $_ao_imgopt_plug_dismissible ) ) {
767
  echo '<div class="notice notice-info is-dismissible" data-dismissible="' . $_ao_imgopt_plug_dismissible . '"><p>';
768
  echo $_ao_imgopt_plug_notice;
769
  echo '</p></div>';
classes/autoptimizeStyles.php CHANGED
@@ -1003,8 +1003,18 @@ class autoptimizeStyles extends autoptimizeBase
1003
  $type_css = 'type="text/css" ';
1004
  }
1005
 
1006
- // Inject the new stylesheets.
1007
- $replace_tag = array( '<title', 'before' );
 
 
 
 
 
 
 
 
 
 
1008
  $replace_tag = apply_filters( 'autoptimize_filter_css_replacetag', $replace_tag, $this->content );
1009
 
1010
  if ( $this->inline ) {
1003
  $type_css = 'type="text/css" ';
1004
  }
1005
 
1006
+ // Inject the new stylesheets, if possible after SEO stuff, but we need to
1007
+ // already restore script to be able to inject before ld+json instead of title
1008
+ // this should be safe here as all has been extracted already but behind a filter anyway.
1009
+ if ( $this->inline && true === apply_filters( 'autoptimize_filter_css_restore_js_early', true ) ) {
1010
+ $this->content = $this->restore_marked_content( 'SCRIPT', $this->content );
1011
+ }
1012
+ $_strpos_ldjson = strpos( $this->content, '<script type="application/ld+json"' );
1013
+ if ( false !== $_strpos_ldjson && $_strpos_ldjson < strpos( $this->content, '</head' ) ) {
1014
+ $replace_tag = array( '<script type="application/ld+json"', 'before' );
1015
+ } else {
1016
+ $replace_tag = array( '<title', 'before' );
1017
+ }
1018
  $replace_tag = apply_filters( 'autoptimize_filter_css_replacetag', $replace_tag, $this->content );
1019
 
1020
  if ( $this->inline ) {
readme.txt CHANGED
@@ -5,7 +5,7 @@ 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.1
7
  Requires PHP: 5.6
8
- Stable tag: 3.1.3
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
 
@@ -319,6 +319,13 @@ Just [fork Autoptimize on Github](https://github.com/futtta/autoptimize) and cod
319
 
320
  == Changelog ==
321
 
 
 
 
 
 
 
 
322
  = 3.1.3 =
323
  * Multiple fixes for metabox LCP image preloads (thanks [Kishorchand](https://foxscribbler.com/) for notifying & providing a staging environment to debug on).
324
  * Fix in revslider compatibility (hat tip [Waqar Ahmed for reporting & helping out](https://wordpress.org/support/topic/issue-with-latest-version-of-slider-revolution/) ).
5
  Requires at least: 4.9
6
  Tested up to: 6.1
7
  Requires PHP: 5.6
8
+ Stable tag: 3.1.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
 
319
 
320
  == Changelog ==
321
 
322
+ = 3.1.4 =
323
+ * Improvement: when all CSS is inlined, try doing so after SEO meta-tags (just before ld+json script tag which most SEO plugins add as last item on their list).
324
+ * Img opt: also optimize images set in data-background and data-retina attributes (+ filter to easily add other attributes)
325
+ * CSS opt: filter to enable AO to skip minification of calc formulas in CSS (as the CSS minifier on rare occasions breaks those)
326
+ * Multiple other filters added
327
+ * Some other minor changes/ improvements/ filters, see the [GitHub commit log](https://github.com/futtta/autoptimize/commits/beta).
328
+
329
  = 3.1.3 =
330
  * Multiple fixes for metabox LCP image preloads (thanks [Kishorchand](https://foxscribbler.com/) for notifying & providing a staging environment to debug on).
331
  * Fix in revslider compatibility (hat tip [Waqar Ahmed for reporting & helping out](https://wordpress.org/support/topic/issue-with-latest-version-of-slider-revolution/) ).