Version Description
- Images: only show "did you know shortpixel" notice on Autoptimize settings pages (no more littering all over the backend)
- Images: update lazysizes from upstream
- Images: misc. improvements such as fix for PHP "undefined index" notice, updated copy, ...
- HTML: rename HTML minify class from minify_HTML to AO_minify_HTML to avoid conflicts with e.g. W3TC
- 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, ...
- JS/ CSS: fix for AO not optimizing multisite child sites when CDN set
Download this release
Release Info
Developer | futtta |
Plugin | Autoptimize |
Version | 2.8.2 |
Comparing to | |
See all releases |
Code changes from version 2.8.1 to 2.8.2
- autoptimize.php +3 -3
- classes/autoptimizeBase.php +9 -1
- classes/autoptimizeCache.php +3 -0
- classes/autoptimizeCriticalCSSCron.php +6 -6
- classes/autoptimizeCriticalCSSEnqueue.php +19 -1
- classes/autoptimizeHTML.php +1 -1
- classes/autoptimizeImages.php +48 -23
- classes/autoptimizeMain.php +3 -2
- classes/autoptimizeScripts.php +2 -0
- classes/critcss-inc/admin_settings_adv.php +1 -1
- classes/critcss-inc/admin_settings_rules.php +1 -1
- classes/external/js/lazysizes.min.js +3 -3
- classes/external/php/{minify-html.php → ao-minify-html.php} +2 -2
- readme.txt +9 -1
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: 2.8.
|
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', '2.8.
|
25 |
|
26 |
// plugin_dir_path() returns the trailing slash!
|
27 |
define( 'AUTOPTIMIZE_PLUGIN_DIR', plugin_dir_path( __FILE__ ) );
|
@@ -44,7 +44,7 @@ if ( version_compare( PHP_VERSION, '5.6', '<' ) ) {
|
|
44 |
}
|
45 |
|
46 |
function autoptimize_autoload( $class_name ) {
|
47 |
-
if ( in_array( $class_name, array( '
|
48 |
$file = strtolower( $class_name );
|
49 |
$file = str_replace( '_', '-', $file );
|
50 |
$path = dirname( __FILE__ ) . '/classes/external/php/';
|
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: 2.8.2
|
7 |
* Author: Frank Goossens (futtta)
|
8 |
* Author URI: https://autoptimize.com/
|
9 |
* Text Domain: autoptimize
|
21 |
exit;
|
22 |
}
|
23 |
|
24 |
+
define( 'AUTOPTIMIZE_PLUGIN_VERSION', '2.8.2' );
|
25 |
|
26 |
// plugin_dir_path() returns the trailing slash!
|
27 |
define( 'AUTOPTIMIZE_PLUGIN_DIR', plugin_dir_path( __FILE__ ) );
|
44 |
}
|
45 |
|
46 |
function autoptimize_autoload( $class_name ) {
|
47 |
+
if ( in_array( $class_name, array( 'AO_Minify_HTML', 'JSMin' ) ) ) {
|
48 |
$file = strtolower( $class_name );
|
49 |
$file = str_replace( '_', '-', $file );
|
50 |
$path = dirname( __FILE__ ) . '/classes/external/php/';
|
classes/autoptimizeBase.php
CHANGED
@@ -144,6 +144,14 @@ abstract class autoptimizeBase
|
|
144 |
// As we replaced the content-domain with the site-domain, we should match against that.
|
145 |
$tmp_ao_root = preg_replace( '/https?:/', '', AUTOPTIMIZE_WP_SITE_URL );
|
146 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
147 |
|
148 |
$tmp_url = preg_replace( '/https?:/', '', $url );
|
149 |
$path = str_replace( $tmp_ao_root, '', $tmp_url );
|
@@ -156,7 +164,7 @@ abstract class autoptimizeBase
|
|
156 |
}
|
157 |
|
158 |
// Prepend with WP_ROOT_DIR to have full path to file.
|
159 |
-
$path = str_replace( '//', '/', WP_ROOT_DIR . $path );
|
160 |
|
161 |
// Final check: does file exist and is it readable?
|
162 |
if ( file_exists( $path ) && is_file( $path ) && is_readable( $path ) ) {
|
144 |
// As we replaced the content-domain with the site-domain, we should match against that.
|
145 |
$tmp_ao_root = preg_replace( '/https?:/', '', AUTOPTIMIZE_WP_SITE_URL );
|
146 |
}
|
147 |
+
|
148 |
+
if ( is_multisite() && ! is_main_site() && ! empty( $this->cdn_url ) ) {
|
149 |
+
// multisite child sites with CDN need the network_site_url as tmp_ao_root but only if directory-based multisite.
|
150 |
+
$_network_site_url = network_site_url();
|
151 |
+
if ( strpos( AUTOPTIMIZE_WP_SITE_URL, $_network_site_url ) !== false ) {
|
152 |
+
$tmp_ao_root = preg_replace( '/https?:/', '', $_network_site_url );
|
153 |
+
}
|
154 |
+
}
|
155 |
|
156 |
$tmp_url = preg_replace( '/https?:/', '', $url );
|
157 |
$path = str_replace( $tmp_ao_root, '', $tmp_url );
|
164 |
}
|
165 |
|
166 |
// Prepend with WP_ROOT_DIR to have full path to file.
|
167 |
+
$path = str_replace( '//', '/', trailingslashit( WP_ROOT_DIR ) . $path );
|
168 |
|
169 |
// Final check: does file exist and is it readable?
|
170 |
if ( file_exists( $path ) && is_file( $path ) && is_readable( $path ) ) {
|
classes/autoptimizeCache.php
CHANGED
@@ -827,6 +827,9 @@ class autoptimizeCache
|
|
827 |
prune_super_cache( $cache_path . 'supercache/', true );
|
828 |
prune_super_cache( $cache_path, true );
|
829 |
}
|
|
|
|
|
|
|
830 |
}
|
831 |
}
|
832 |
// @codingStandardsIgnoreEnd
|
827 |
prune_super_cache( $cache_path . 'supercache/', true );
|
828 |
prune_super_cache( $cache_path, true );
|
829 |
}
|
830 |
+
} elseif ( class_exists( 'NginxCache' ) ) {
|
831 |
+
$nginx_cache = new NginxCache();
|
832 |
+
$nginx_cache->purge_zone_once();
|
833 |
}
|
834 |
}
|
835 |
// @codingStandardsIgnoreEnd
|
classes/autoptimizeCriticalCSSCron.php
CHANGED
@@ -227,8 +227,8 @@ class autoptimizeCriticalCSSCron {
|
|
227 |
$apireq['resultStatus'] = 'GOOD';
|
228 |
}
|
229 |
|
230 |
-
if ( 'GOOD' == $apireq['resultStatus'] && 'GOOD' == $apireq['validationStatus'] ) {
|
231 |
-
// SUCCESS: GOOD job with GOOD validation
|
232 |
// Update job properties.
|
233 |
$jprops['file'] = $this->ao_ccss_save_file( $apireq['css'], $trule, false );
|
234 |
$jprops['jqstat'] = $apireq['status'];
|
@@ -237,8 +237,8 @@ class autoptimizeCriticalCSSCron {
|
|
237 |
$jprops['jftime'] = microtime( true );
|
238 |
$rule_update = true;
|
239 |
autoptimizeCriticalCSSCore::ao_ccss_log( 'Job id <' . $jprops['ljid'] . '> result request successful, remote id <' . $jprops['jid'] . '>, status <' . $jprops['jqstat'] . '>, file saved <' . $jprops['file'] . '>', 3 );
|
240 |
-
} elseif ( 'GOOD' == $apireq['resultStatus'] && ( '
|
241 |
-
// SUCCESS: GOOD job with
|
242 |
// Update job properties.
|
243 |
$jprops['jqstat'] = $apireq['status'];
|
244 |
$jprops['jrstat'] = $apireq['resultStatus'];
|
@@ -249,7 +249,7 @@ class autoptimizeCriticalCSSCron {
|
|
249 |
$rule_update = true;
|
250 |
autoptimizeCriticalCSSCore::ao_ccss_log( 'Job id <' . $jprops['ljid'] . '> result request successful, remote id <' . $jprops['jid'] . '>, status <' . $jprops['jqstat'] . ', file saved <' . $jprops['file'] . '> but requires REVIEW', 3 );
|
251 |
} else {
|
252 |
-
autoptimizeCriticalCSSCore::ao_ccss_log( 'Job id <' . $jprops['ljid'] . '> result request successful, remote id <' . $jprops['jid'] . '>, status <' . $jprops['jqstat'] . ', file saved
|
253 |
}
|
254 |
} elseif ( 'GOOD' != $apireq['resultStatus'] && ( 'GOOD' != $apireq['validationStatus'] || 'WARN' != $apireq['validationStatus'] || 'BAD' != $apireq['validationStatus'] || 'SCREENSHOT_WARN_BLANK' != $apireq['validationStatus'] ) ) {
|
255 |
// ERROR: no GOOD, WARN or BAD results
|
@@ -722,7 +722,7 @@ class autoptimizeCriticalCSSCron {
|
|
722 |
} else {
|
723 |
// If rule doesn't exist, create an AUTO rule
|
724 |
// AUTO rules were only for types, but will now also work for paths.
|
725 |
-
if ( 'types' == $trule[0] || 'paths' == $trule[0] ) {
|
726 |
// Set rule hash and file and action flag.
|
727 |
$rule['hash'] = $hash;
|
728 |
$rule['file'] = $file;
|
227 |
$apireq['resultStatus'] = 'GOOD';
|
228 |
}
|
229 |
|
230 |
+
if ( 'GOOD' == $apireq['resultStatus'] && ( 'GOOD' == $apireq['validationStatus'] || 'WARN' == $apireq['validationStatus'] ) ) {
|
231 |
+
// SUCCESS: GOOD job with GOOD or WARN validation
|
232 |
// Update job properties.
|
233 |
$jprops['file'] = $this->ao_ccss_save_file( $apireq['css'], $trule, false );
|
234 |
$jprops['jqstat'] = $apireq['status'];
|
237 |
$jprops['jftime'] = microtime( true );
|
238 |
$rule_update = true;
|
239 |
autoptimizeCriticalCSSCore::ao_ccss_log( 'Job id <' . $jprops['ljid'] . '> result request successful, remote id <' . $jprops['jid'] . '>, status <' . $jprops['jqstat'] . '>, file saved <' . $jprops['file'] . '>', 3 );
|
240 |
+
} elseif ( 'GOOD' == $apireq['resultStatus'] && ( 'BAD' == $apireq['validationStatus'] || 'SCREENSHOT_WARN_BLANK' == $apireq['validationStatus'] ) ) {
|
241 |
+
// SUCCESS: GOOD job with BAD or SCREENSHOT_WARN_BLANK validation
|
242 |
// Update job properties.
|
243 |
$jprops['jqstat'] = $apireq['status'];
|
244 |
$jprops['jrstat'] = $apireq['resultStatus'];
|
249 |
$rule_update = true;
|
250 |
autoptimizeCriticalCSSCore::ao_ccss_log( 'Job id <' . $jprops['ljid'] . '> result request successful, remote id <' . $jprops['jid'] . '>, status <' . $jprops['jqstat'] . ', file saved <' . $jprops['file'] . '> but requires REVIEW', 3 );
|
251 |
} else {
|
252 |
+
autoptimizeCriticalCSSCore::ao_ccss_log( 'Job id <' . $jprops['ljid'] . '> result request successful, remote id <' . $jprops['jid'] . '>, status <' . $jprops['jqstat'] . ', file not saved because it required REVIEW.', 3 );
|
253 |
}
|
254 |
} elseif ( 'GOOD' != $apireq['resultStatus'] && ( 'GOOD' != $apireq['validationStatus'] || 'WARN' != $apireq['validationStatus'] || 'BAD' != $apireq['validationStatus'] || 'SCREENSHOT_WARN_BLANK' != $apireq['validationStatus'] ) ) {
|
255 |
// ERROR: no GOOD, WARN or BAD results
|
722 |
} else {
|
723 |
// If rule doesn't exist, create an AUTO rule
|
724 |
// AUTO rules were only for types, but will now also work for paths.
|
725 |
+
if ( ( 'types' == $trule[0] || 'paths' == $trule[0] ) && ! empty( $trule[1] ) ) {
|
726 |
// Set rule hash and file and action flag.
|
727 |
$rule['hash'] = $hash;
|
728 |
$rule['file'] = $file;
|
classes/autoptimizeCriticalCSSEnqueue.php
CHANGED
@@ -41,7 +41,21 @@ class autoptimizeCriticalCSSEnqueue {
|
|
41 |
global $ao_ccss_forcepath;
|
42 |
|
43 |
// Get request path and page type, and initialize the queue update flag.
|
44 |
-
$
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
45 |
$req_type = $self->ao_ccss_get_type();
|
46 |
$job_qualify = false;
|
47 |
$target_rule = false;
|
@@ -199,6 +213,10 @@ class autoptimizeCriticalCSSEnqueue {
|
|
199 |
if ( is_404() ) {
|
200 |
$page_type = 'is_404';
|
201 |
break;
|
|
|
|
|
|
|
|
|
202 |
} elseif ( strpos( $type, 'custom_post_' ) !== false && ( ! $ao_ccss_forcepath || ! is_page() ) ) {
|
203 |
// Match custom post types and not page or page not forced to path-based.
|
204 |
if ( get_post_type( get_the_ID() ) === substr( $type, 12 ) ) {
|
41 |
global $ao_ccss_forcepath;
|
42 |
|
43 |
// Get request path and page type, and initialize the queue update flag.
|
44 |
+
$req_orig = $_SERVER['REQUEST_URI'];
|
45 |
+
$req_path = strtok( $req_orig, '?' );
|
46 |
+
|
47 |
+
// Check if we have a lang param. we need to keep as WPML can switch languages based on that
|
48 |
+
// and that includes RTL -> LTR so diff. structure, so rules would be RTL vs LTR
|
49 |
+
// but this needs changes in the structur of the rule object so off by default for now
|
50 |
+
// as now this will simply result in conditional rules being overwritten.
|
51 |
+
if ( apply_filters( 'autoptimize_filter_ccss_coreenqueue_honor_lang', false ) && strpos( $req_orig, 'lang=' ) !== false ) {
|
52 |
+
$req_params = strtok( '?' );
|
53 |
+
parse_str( $req_params, $req_params_arr );
|
54 |
+
if ( array_key_exists( 'lang', $req_params_arr ) && !empty( $req_params_arr['lang'] ) ) {
|
55 |
+
$req_path .= '?lang=' . $req_params_arr['lang'];
|
56 |
+
}
|
57 |
+
}
|
58 |
+
|
59 |
$req_type = $self->ao_ccss_get_type();
|
60 |
$job_qualify = false;
|
61 |
$target_rule = false;
|
213 |
if ( is_404() ) {
|
214 |
$page_type = 'is_404';
|
215 |
break;
|
216 |
+
} elseif ( is_front_page() ) {
|
217 |
+
// identify frontpage immediately to avoid it also matching a CPT or template.
|
218 |
+
$page_type = 'is_front_page';
|
219 |
+
break;
|
220 |
} elseif ( strpos( $type, 'custom_post_' ) !== false && ( ! $ao_ccss_forcepath || ! is_page() ) ) {
|
221 |
// Match custom post types and not page or page not forced to path-based.
|
222 |
if ( get_post_type( get_the_ID() ) === substr( $type, 12 ) ) {
|
classes/autoptimizeHTML.php
CHANGED
@@ -82,7 +82,7 @@ class autoptimizeHTML extends autoptimizeBase
|
|
82 |
$options['xhtml'] = true;
|
83 |
}
|
84 |
|
85 |
-
$tmp_content =
|
86 |
if ( ! empty( $tmp_content ) ) {
|
87 |
$this->content = $tmp_content;
|
88 |
unset( $tmp_content );
|
82 |
$options['xhtml'] = true;
|
83 |
}
|
84 |
|
85 |
+
$tmp_content = AO_Minify_HTML::minify( $this->content, $options );
|
86 |
if ( ! empty( $tmp_content ) ) {
|
87 |
$this->content = $tmp_content;
|
88 |
unset( $tmp_content );
|
classes/autoptimizeImages.php
CHANGED
@@ -231,7 +231,7 @@ class autoptimizeImages
|
|
231 |
|
232 |
public static function get_service_url_suffix()
|
233 |
{
|
234 |
-
$suffix = '/af/
|
235 |
|
236 |
return $suffix;
|
237 |
}
|
@@ -346,9 +346,7 @@ class autoptimizeImages
|
|
346 |
$result = trim( $in );
|
347 |
|
348 |
// Some silly plugins wrap background images in html-encoded quotes, so remove those from the img url.
|
349 |
-
|
350 |
-
$result = str_replace( '"', '', $result );
|
351 |
-
}
|
352 |
|
353 |
if ( autoptimizeUtils::is_protocol_relative( $result ) ) {
|
354 |
$result = $parsed_site_url['scheme'] . ':' . $result;
|
@@ -466,7 +464,13 @@ class autoptimizeImages
|
|
466 |
return $filtered_url;
|
467 |
}
|
468 |
|
469 |
-
$
|
|
|
|
|
|
|
|
|
|
|
|
|
470 |
$imgopt_base_url = $this->get_imgopt_base_url();
|
471 |
$imgopt_size = '';
|
472 |
|
@@ -478,7 +482,7 @@ class autoptimizeImages
|
|
478 |
$imgopt_size .= ',h_' . $height;
|
479 |
}
|
480 |
|
481 |
-
$url = $imgopt_base_url . $imgopt_size . '/' . $
|
482 |
|
483 |
return $url;
|
484 |
}
|
@@ -539,6 +543,8 @@ class autoptimizeImages
|
|
539 |
// extract img tags.
|
540 |
if ( preg_match_all( '#<img[^>]*src[^>]*>#Usmi', $in, $matches ) ) {
|
541 |
foreach ( $matches[0] as $tag ) {
|
|
|
|
|
542 |
$orig_tag = $tag;
|
543 |
$imgopt_w = '';
|
544 |
$imgopt_h = '';
|
@@ -574,7 +580,7 @@ class autoptimizeImages
|
|
574 |
foreach ( $urls as $url ) {
|
575 |
$full_src_orig = $url[0];
|
576 |
$url = $url[1];
|
577 |
-
if ( $this->can_optimize_image( $url, $
|
578 |
$imgopt_url = $this->build_imgopt_url( $url, $imgopt_w, $imgopt_h );
|
579 |
$full_imgopt_src = str_replace( $url, $imgopt_url, $full_src_orig );
|
580 |
$tag = str_replace( $full_src_orig, $full_imgopt_src, $tag );
|
@@ -611,6 +617,8 @@ class autoptimizeImages
|
|
611 |
$tag = $this->add_lazyload( $tag, $placeholder );
|
612 |
}
|
613 |
|
|
|
|
|
614 |
// and add tag to array for later replacement.
|
615 |
if ( $tag !== $orig_tag ) {
|
616 |
$to_replace[ $orig_tag ] = $tag;
|
@@ -770,7 +778,13 @@ class autoptimizeImages
|
|
770 |
public function add_lazyload( $tag, $placeholder = '' ) {
|
771 |
// adds actual lazyload-attributes to an image node.
|
772 |
$this->lazyload_counter++;
|
773 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
774 |
if ( str_ireplace( $this->get_lazyload_exclusions(), '', $tag ) === $tag && $this->lazyload_counter >= $_lazyload_from_nth ) {
|
775 |
$tag = $this->maybe_fix_missing_quotes( $tag );
|
776 |
|
@@ -965,7 +979,7 @@ class autoptimizeImages
|
|
965 |
public function process_bgimage( $in ) {
|
966 |
if ( strpos( $in, 'background-image:' ) !== false && apply_filters( 'autoptimize_filter_imgopt_lazyload_backgroundimages', true ) ) {
|
967 |
$out = preg_replace_callback(
|
968 |
-
'/(<(?:article|aside|body|div|footer|header|p|section|table)[^>]*)\sstyle=(?:"|\')[^<>]*?background-image:\s?url\((?:"|\')?([^"\')]*)(?:"|\')?\)[^>]*/',
|
969 |
array( $this, 'lazyload_bgimg_callback' ),
|
970 |
$in
|
971 |
);
|
@@ -980,15 +994,22 @@ class autoptimizeImages
|
|
980 |
$placeholder = apply_filters( 'autoptimize_filter_imgopt_lazyload_placeholder', $this->get_default_lazyload_placeholder( 500, 300 ) );
|
981 |
$lazyload_class = apply_filters( 'autoptimize_filter_imgopt_lazyload_class', 'lazyload' );
|
982 |
// replace background-image URL with SVG placeholder.
|
983 |
-
$out = str_replace( $matches[2], $placeholder, $matches[0] );
|
|
|
|
|
984 |
// add data-bg attribute with real background-image URL for lazyload to pick up.
|
985 |
-
$out = str_replace( $matches[1], $matches[1] . ' data-bg="' .
|
986 |
-
// add lazyload class to tag.
|
987 |
$out = $this->inject_classes_in_tag( $out, "$lazyload_class " );
|
988 |
return $out;
|
989 |
}
|
990 |
return $matches[0];
|
991 |
}
|
|
|
|
|
|
|
|
|
|
|
992 |
|
993 |
public function maybe_fix_missing_quotes( $tag_in ) {
|
994 |
// W3TC's Minify_HTML class removes quotes around attribute value, this re-adds them for the class and width/height attributes so we can lazyload properly.
|
@@ -1033,7 +1054,7 @@ class autoptimizeImages
|
|
1033 |
{
|
1034 |
// Check querystring for "refreshCacheChecker" and call cachechecker if so.
|
1035 |
if ( array_key_exists( 'refreshImgProvStats', $_GET ) && 1 == $_GET['refreshImgProvStats'] ) {
|
1036 |
-
$this->query_img_provider_stats();
|
1037 |
}
|
1038 |
|
1039 |
$options = $this->fetch_options();
|
@@ -1102,18 +1123,18 @@ class autoptimizeImages
|
|
1102 |
echo apply_filters( 'autoptimize_filter_imgopt_settings_status', '<p><strong><span style="color:' . $_notice_color . ';">' . __( 'Shortpixel status: ', 'autoptimize' ) . '</span></strong>' . $_notice['notice'] . '</p>' );
|
1103 |
} else {
|
1104 |
// translators: link points to shortpixel.
|
1105 |
-
$upsell_msg_1 = '<p>' . sprintf( __( 'Get more Google love
|
1106 |
if ( 'launch' === $options['availabilities']['extra_imgopt']['status'] ) {
|
1107 |
$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' );
|
1108 |
} else {
|
1109 |
// translators: link points to shortpixel.
|
1110 |
-
$upsell_msg_2 = sprintf( __( '%1$sSign-up now%2$s to receive
|
1111 |
}
|
1112 |
echo apply_filters( 'autoptimize_imgopt_imgopt_settings_copy', $upsell_msg_1 . ' ' . $upsell_msg_2 . '</p>' );
|
1113 |
}
|
1114 |
// translators: link points to shortpixel FAQ.
|
1115 |
-
$faqcopy = sprintf( __( '<strong>Questions</strong>? Have a look at the %1$
|
1116 |
-
$faqcopy = $faqcopy . ' ' . __( 'Only works for
|
1117 |
// translators: links points to shortpixel TOS & Privacy Policy.
|
1118 |
$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>' );
|
1119 |
echo apply_filters( 'autoptimize_imgopt_imgopt_settings_tos', '<p>' . $faqcopy . ' ' . $toscopy . '</p>' );
|
@@ -1221,7 +1242,7 @@ class autoptimizeImages
|
|
1221 |
$_imgopt_notice = '';
|
1222 |
$_stat = autoptimizeOptionWrapper::get_option( 'autoptimize_imgopt_provider_stat', '' );
|
1223 |
$_site_host = AUTOPTIMIZE_SITE_DOMAIN;
|
1224 |
-
$_imgopt_upsell = 'https://shortpixel.com/aospai/af/
|
1225 |
$_imgopt_assoc = 'https://shortpixel.helpscoutdocs.com/article/94-how-to-associate-a-domain-to-my-account';
|
1226 |
$_imgopt_unreach = 'https://shortpixel.helpscoutdocs.com/article/148-why-are-my-images-redirected-from-cdn-shortpixel-ai';
|
1227 |
|
@@ -1233,12 +1254,12 @@ class autoptimizeImages
|
|
1233 |
// translators: "add more credits" will appear in a "a href".
|
1234 |
$_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>' );
|
1235 |
// translators: "associate your domain" will appear in a "a href".
|
1236 |
-
$_imgopt_notice = $_imgopt_notice . ' ' . sprintf( __( 'If you have enough
|
1237 |
} elseif ( -3 == $_stat['Status'] ) {
|
1238 |
// translators: "check the documentation here" will appear in a "a href".
|
1239 |
$_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>' );
|
1240 |
} else {
|
1241 |
-
$_imgopt_upsell = 'https://shortpixel.com/g/af/
|
1242 |
// translators: "log in to check your account" will appear in a "a href".
|
1243 |
$_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>' );
|
1244 |
}
|
@@ -1256,7 +1277,7 @@ class autoptimizeImages
|
|
1256 |
}
|
1257 |
$_imgopt_notice .= ' (' . $_imgopt_stats_last_run . ', ';
|
1258 |
// translators: "here to refresh" links to the Autoptimize Extra page and forces a refresh of the img opt stats.
|
1259 |
-
$_imgopt_notice .= sprintf( __( 'click %1$shere to refresh%2$s', 'autoptimize' ), '<a href="' . $_imgopt_stats_refresh_url . '">', '</a>).' );
|
1260 |
}
|
1261 |
|
1262 |
// and make the full notice filterable.
|
@@ -1280,15 +1301,19 @@ class autoptimizeImages
|
|
1280 |
/**
|
1281 |
* Get img provider stats (used to display notice).
|
1282 |
*/
|
1283 |
-
public function query_img_provider_stats() {
|
1284 |
if ( ! empty( $this->options['autoptimize_imgopt_checkbox_field_1'] ) ) {
|
1285 |
$url = '';
|
1286 |
-
$
|
|
|
1287 |
$domain = AUTOPTIMIZE_SITE_DOMAIN;
|
1288 |
|
1289 |
// make sure parse_url result makes sense, keeping $url empty if not.
|
1290 |
if ( $domain && ! empty( $domain ) ) {
|
1291 |
$url = $endpoint . $domain;
|
|
|
|
|
|
|
1292 |
}
|
1293 |
|
1294 |
$url = apply_filters(
|
231 |
|
232 |
public static function get_service_url_suffix()
|
233 |
{
|
234 |
+
$suffix = '/af/SPZURYE109483/' . AUTOPTIMIZE_SITE_DOMAIN;
|
235 |
|
236 |
return $suffix;
|
237 |
}
|
346 |
$result = trim( $in );
|
347 |
|
348 |
// Some silly plugins wrap background images in html-encoded quotes, so remove those from the img url.
|
349 |
+
$result = $this->fix_silly_bgimg_quotes( $result );
|
|
|
|
|
350 |
|
351 |
if ( autoptimizeUtils::is_protocol_relative( $result ) ) {
|
352 |
$result = $parsed_site_url['scheme'] . ':' . $result;
|
464 |
return $filtered_url;
|
465 |
}
|
466 |
|
467 |
+
$normalized_url = $this->normalize_img_url( $orig_url );
|
468 |
+
|
469 |
+
// if the URL is ascii we check if we have a real URL with filter_var (which only works on ascii url's) and if not a real URL we return the original one.
|
470 |
+
if ( apply_filters( 'autoptimize_filter_imgopt_check_normalized_url', true ) && ! preg_match( '/[^\x20-\x7e]/', $normalized_url ) && false === filter_var( $normalized_url, FILTER_VALIDATE_URL ) ) {
|
471 |
+
return $orig_url;
|
472 |
+
}
|
473 |
+
|
474 |
$imgopt_base_url = $this->get_imgopt_base_url();
|
475 |
$imgopt_size = '';
|
476 |
|
482 |
$imgopt_size .= ',h_' . $height;
|
483 |
}
|
484 |
|
485 |
+
$url = $imgopt_base_url . $imgopt_size . '/' . $normalized_url;
|
486 |
|
487 |
return $url;
|
488 |
}
|
543 |
// extract img tags.
|
544 |
if ( preg_match_all( '#<img[^>]*src[^>]*>#Usmi', $in, $matches ) ) {
|
545 |
foreach ( $matches[0] as $tag ) {
|
546 |
+
$tag = apply_filters( 'autoptimize_filter_imgopt_tag_preopt' , $tag );
|
547 |
+
|
548 |
$orig_tag = $tag;
|
549 |
$imgopt_w = '';
|
550 |
$imgopt_h = '';
|
580 |
foreach ( $urls as $url ) {
|
581 |
$full_src_orig = $url[0];
|
582 |
$url = $url[1];
|
583 |
+
if ( $this->can_optimize_image( $url, $tag, $testing ) ) {
|
584 |
$imgopt_url = $this->build_imgopt_url( $url, $imgopt_w, $imgopt_h );
|
585 |
$full_imgopt_src = str_replace( $url, $imgopt_url, $full_src_orig );
|
586 |
$tag = str_replace( $full_src_orig, $full_imgopt_src, $tag );
|
617 |
$tag = $this->add_lazyload( $tag, $placeholder );
|
618 |
}
|
619 |
|
620 |
+
$tag = apply_filters( 'autoptimize_filter_imgopt_tag_postopt' , $tag );
|
621 |
+
|
622 |
// and add tag to array for later replacement.
|
623 |
if ( $tag !== $orig_tag ) {
|
624 |
$to_replace[ $orig_tag ] = $tag;
|
778 |
public function add_lazyload( $tag, $placeholder = '' ) {
|
779 |
// adds actual lazyload-attributes to an image node.
|
780 |
$this->lazyload_counter++;
|
781 |
+
|
782 |
+
$_lazyload_from_nth = '';
|
783 |
+
if ( array_key_exists( 'autoptimize_imgopt_number_field_7', $this->options ) ) {
|
784 |
+
$_lazyload_from_nth = $this->options['autoptimize_imgopt_number_field_7'];
|
785 |
+
}
|
786 |
+
$_lazyload_from_nth = apply_filters( 'autoptimize_filter_imgopt_lazyload_from_nth', $_lazyload_from_nth );
|
787 |
+
|
788 |
if ( str_ireplace( $this->get_lazyload_exclusions(), '', $tag ) === $tag && $this->lazyload_counter >= $_lazyload_from_nth ) {
|
789 |
$tag = $this->maybe_fix_missing_quotes( $tag );
|
790 |
|
979 |
public function process_bgimage( $in ) {
|
980 |
if ( strpos( $in, 'background-image:' ) !== false && apply_filters( 'autoptimize_filter_imgopt_lazyload_backgroundimages', true ) ) {
|
981 |
$out = preg_replace_callback(
|
982 |
+
'/(<(?:article|aside|body|div|footer|header|p|section|span|table)[^>]*)\sstyle=(?:"|\')[^<>]*?background-image:\s?url\((?:"|\')?([^"\')]*)(?:"|\')?\)[^>]*/',
|
983 |
array( $this, 'lazyload_bgimg_callback' ),
|
984 |
$in
|
985 |
);
|
994 |
$placeholder = apply_filters( 'autoptimize_filter_imgopt_lazyload_placeholder', $this->get_default_lazyload_placeholder( 500, 300 ) );
|
995 |
$lazyload_class = apply_filters( 'autoptimize_filter_imgopt_lazyload_class', 'lazyload' );
|
996 |
// replace background-image URL with SVG placeholder.
|
997 |
+
$out = str_replace( 'url(' . $matches[2], 'url(' . $placeholder, $matches[0] );
|
998 |
+
// sanitize bgimg src for quote sillyness.
|
999 |
+
$bgimg_src = $this->fix_silly_bgimg_quotes( $matches[2] );
|
1000 |
// add data-bg attribute with real background-image URL for lazyload to pick up.
|
1001 |
+
$out = str_replace( $matches[1], $matches[1] . ' data-bg="' . $bgimg_src . '"', $out );
|
1002 |
+
// and finally add lazyload class to tag.
|
1003 |
$out = $this->inject_classes_in_tag( $out, "$lazyload_class " );
|
1004 |
return $out;
|
1005 |
}
|
1006 |
return $matches[0];
|
1007 |
}
|
1008 |
+
|
1009 |
+
public function fix_silly_bgimg_quotes( $tag_in ) {
|
1010 |
+
// some themes/ pagebuilders wrap backgroundimages in HTML-encoded quotes (or linebreaks) which breaks imgopt/ lazyloading, this removes them.
|
1011 |
+
return trim( str_replace( array( "\r\n", '"', '"', ''', ''' ), '', $tag_in ) );
|
1012 |
+
}
|
1013 |
|
1014 |
public function maybe_fix_missing_quotes( $tag_in ) {
|
1015 |
// W3TC's Minify_HTML class removes quotes around attribute value, this re-adds them for the class and width/height attributes so we can lazyload properly.
|
1054 |
{
|
1055 |
// Check querystring for "refreshCacheChecker" and call cachechecker if so.
|
1056 |
if ( array_key_exists( 'refreshImgProvStats', $_GET ) && 1 == $_GET['refreshImgProvStats'] ) {
|
1057 |
+
$this->query_img_provider_stats( true );
|
1058 |
}
|
1059 |
|
1060 |
$options = $this->fetch_options();
|
1123 |
echo apply_filters( 'autoptimize_filter_imgopt_settings_status', '<p><strong><span style="color:' . $_notice_color . ';">' . __( 'Shortpixel status: ', 'autoptimize' ) . '</span></strong>' . $_notice['notice'] . '</p>' );
|
1124 |
} else {
|
1125 |
// translators: link points to shortpixel.
|
1126 |
+
$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. The optimized images are 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">' );
|
1127 |
if ( 'launch' === $options['availabilities']['extra_imgopt']['status'] ) {
|
1128 |
$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' );
|
1129 |
} else {
|
1130 |
// translators: link points to shortpixel.
|
1131 |
+
$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>' );
|
1132 |
}
|
1133 |
echo apply_filters( 'autoptimize_imgopt_imgopt_settings_copy', $upsell_msg_1 . ' ' . $upsell_msg_2 . '</p>' );
|
1134 |
}
|
1135 |
// translators: link points to shortpixel FAQ.
|
1136 |
+
$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>' );
|
1137 |
+
$faqcopy = $faqcopy . ' ' . __( 'Only works for websites and images that are publicly available.', 'autoptimize' );
|
1138 |
// translators: links points to shortpixel TOS & Privacy Policy.
|
1139 |
$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>' );
|
1140 |
echo apply_filters( 'autoptimize_imgopt_imgopt_settings_tos', '<p>' . $faqcopy . ' ' . $toscopy . '</p>' );
|
1242 |
$_imgopt_notice = '';
|
1243 |
$_stat = autoptimizeOptionWrapper::get_option( 'autoptimize_imgopt_provider_stat', '' );
|
1244 |
$_site_host = AUTOPTIMIZE_SITE_DOMAIN;
|
1245 |
+
$_imgopt_upsell = 'https://shortpixel.com/aospai/af/SPZURYE109483/' . $_site_host;
|
1246 |
$_imgopt_assoc = 'https://shortpixel.helpscoutdocs.com/article/94-how-to-associate-a-domain-to-my-account';
|
1247 |
$_imgopt_unreach = 'https://shortpixel.helpscoutdocs.com/article/148-why-are-my-images-redirected-from-cdn-shortpixel-ai';
|
1248 |
|
1254 |
// translators: "add more credits" will appear in a "a href".
|
1255 |
$_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>' );
|
1256 |
// translators: "associate your domain" will appear in a "a href".
|
1257 |
+
$_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>' );
|
1258 |
} elseif ( -3 == $_stat['Status'] ) {
|
1259 |
// translators: "check the documentation here" will appear in a "a href".
|
1260 |
$_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>' );
|
1261 |
} else {
|
1262 |
+
$_imgopt_upsell = 'https://shortpixel.com/g/af/SPZURYE109483';
|
1263 |
// translators: "log in to check your account" will appear in a "a href".
|
1264 |
$_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>' );
|
1265 |
}
|
1277 |
}
|
1278 |
$_imgopt_notice .= ' (' . $_imgopt_stats_last_run . ', ';
|
1279 |
// translators: "here to refresh" links to the Autoptimize Extra page and forces a refresh of the img opt stats.
|
1280 |
+
$_imgopt_notice .= sprintf( __( 'you can click %1$shere to refresh your quota status%2$s', 'autoptimize' ), '<a href="' . $_imgopt_stats_refresh_url . '">', '</a>).' );
|
1281 |
}
|
1282 |
|
1283 |
// and make the full notice filterable.
|
1301 |
/**
|
1302 |
* Get img provider stats (used to display notice).
|
1303 |
*/
|
1304 |
+
public function query_img_provider_stats( $_refresh = false ) {
|
1305 |
if ( ! empty( $this->options['autoptimize_imgopt_checkbox_field_1'] ) ) {
|
1306 |
$url = '';
|
1307 |
+
$stat_dom = 'https://no-cdn.shortpixel.ai/';
|
1308 |
+
$endpoint = $stat_dom . 'read-domain/';
|
1309 |
$domain = AUTOPTIMIZE_SITE_DOMAIN;
|
1310 |
|
1311 |
// make sure parse_url result makes sense, keeping $url empty if not.
|
1312 |
if ( $domain && ! empty( $domain ) ) {
|
1313 |
$url = $endpoint . $domain;
|
1314 |
+
if ( true === $_refresh ) {
|
1315 |
+
$url = $url . '/refresh';
|
1316 |
+
}
|
1317 |
}
|
1318 |
|
1319 |
$url = apply_filters(
|
classes/autoptimizeMain.php
CHANGED
@@ -684,13 +684,14 @@ class autoptimizeMain
|
|
684 |
public static function notice_plug_imgopt()
|
685 |
{
|
686 |
// Translators: the URL added points to the Autopmize Extra settings.
|
687 |
-
$_ao_imgopt_plug_notice = sprintf( __( 'Did you know Autoptimize includes on-the-fly image optimization (with support for WebP) 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>' );
|
688 |
$_ao_imgopt_plug_notice = apply_filters( 'autoptimize_filter_main_imgopt_plug_notice', $_ao_imgopt_plug_notice );
|
689 |
$_ao_imgopt_launch_ok = autoptimizeImages::launch_ok_wrapper();
|
690 |
$_ao_imgopt_plug_dismissible = 'ao-img-opt-plug-123';
|
691 |
$_ao_imgopt_active = autoptimizeImages::imgopt_active();
|
|
|
692 |
|
693 |
-
if ( current_user_can( 'manage_options' ) && '' !== $_ao_imgopt_plug_notice && ! $_ao_imgopt_active && $_ao_imgopt_launch_ok && PAnD::is_admin_notice_active( $_ao_imgopt_plug_dismissible ) ) {
|
694 |
echo '<div class="notice notice-info is-dismissible" data-dismissible="' . $_ao_imgopt_plug_dismissible . '"><p>';
|
695 |
echo $_ao_imgopt_plug_notice;
|
696 |
echo '</p></div>';
|
684 |
public static function notice_plug_imgopt()
|
685 |
{
|
686 |
// Translators: the URL added points to the Autopmize Extra settings.
|
687 |
+
$_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>' );
|
688 |
$_ao_imgopt_plug_notice = apply_filters( 'autoptimize_filter_main_imgopt_plug_notice', $_ao_imgopt_plug_notice );
|
689 |
$_ao_imgopt_launch_ok = autoptimizeImages::launch_ok_wrapper();
|
690 |
$_ao_imgopt_plug_dismissible = 'ao-img-opt-plug-123';
|
691 |
$_ao_imgopt_active = autoptimizeImages::imgopt_active();
|
692 |
+
$_is_ao_settings_page = ( str_replace( array( 'autoptimize', 'autoptimize_imgopt', 'ao_critcss', 'autoptimize_extra', 'ao_partners' ), '', $_SERVER['REQUEST_URI'] ) !== $_SERVER['REQUEST_URI'] ? true : false );
|
693 |
|
694 |
+
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 ) ) {
|
695 |
echo '<div class="notice notice-info is-dismissible" data-dismissible="' . $_ao_imgopt_plug_dismissible . '"><p>';
|
696 |
echo $_ao_imgopt_plug_notice;
|
697 |
echo '</p></div>';
|
classes/autoptimizeScripts.php
CHANGED
@@ -60,6 +60,8 @@ class autoptimizeScripts extends autoptimizeBase
|
|
60 |
'data-noptimize',
|
61 |
'logHuman',
|
62 |
'amp-mobile-version-switcher',
|
|
|
|
|
63 |
);
|
64 |
|
65 |
/**
|
60 |
'data-noptimize',
|
61 |
'logHuman',
|
62 |
'amp-mobile-version-switcher',
|
63 |
+
'data-rocketlazyloadscript',
|
64 |
+
'rocket-browser-checker-js-after',
|
65 |
);
|
66 |
|
67 |
/**
|
classes/critcss-inc/admin_settings_adv.php
CHANGED
@@ -86,7 +86,7 @@ function ao_ccss_render_adv() {
|
|
86 |
<td>
|
87 |
<input type="checkbox" id="autoptimize_ccss_loggedin" name="autoptimize_ccss_loggedin" value="1" <?php checked( 1 == $ao_ccss_loggedin ); ?>>
|
88 |
<p class="notes">
|
89 |
-
<?php _e( 'Critical CSS is generated by criticalcss.com from your pages as seen
|
90 |
</p>
|
91 |
</td>
|
92 |
</tr>
|
86 |
<td>
|
87 |
<input type="checkbox" id="autoptimize_ccss_loggedin" name="autoptimize_ccss_loggedin" value="1" <?php checked( 1 == $ao_ccss_loggedin ); ?>>
|
88 |
<p class="notes">
|
89 |
+
<?php _e( 'Critical CSS is generated by criticalcss.com from your pages as seen by an "anonymous visitor". Disable this option if you don\'t want the "visitor" critical CSS to be used for logged in users.', 'autoptimize' ); ?>
|
90 |
</p>
|
91 |
</td>
|
92 |
</tr>
|
classes/critcss-inc/admin_settings_rules.php
CHANGED
@@ -180,7 +180,7 @@ function ao_ccss_render_rules() {
|
|
180 |
<li><?php _e( 'If you want to make any fine tunning in the critical CSS file of an <span class="badge auto">AUTO</span> rule, click on "Edit" button of that rule, change what you need, submit and save it. The rule you\'ve just edited becomes a <span class="badge manual">MANUAL</span> rule then.', 'autoptimize' ); ?></li>
|
181 |
<li><?php _e( 'You can create <span class="badge manual">MANUAL</span> rules for specific page paths (URL). Longer, more specific paths have higher priority over shorter ones, which in turn have higher priority over <span class="badge auto">AUTO</span> rules. Also, critical CSS files from <span class="badge manual">MANUAL</span> <strong>rules are NEVER updated automatically.</strong>', 'autoptimize' ); ?></li>
|
182 |
<li><?php _e( 'You can also create an <span class="badge auto">AUTO</span> rule for a path by leaving its critical CSS content empty. The critical CSS for that path will be automatically fetched from <a href="https://criticalcss.com/?aff=1" target="_blank">criticalcss.com</a> for you and updated whenever it changes.', 'autoptimize' ); ?></li>
|
183 |
-
<li><?php _e( "If you see an <span class='badge auto'>AUTO</span> rule with a <span class='badge review'>R</span> besides it (R is after REVIEW), it means that the fetched critical CSS for that rule is not 100%
|
184 |
<li><?php _e( 'At any time you can delete an <span class="badge auto">AUTO</span> or <span class="badge manual">MANUAL</span> rule by cliking on "Remove" button of the desired rule and saving your changes.', 'autoptimize' ); ?></li>
|
185 |
</ol>
|
186 |
</div>
|
180 |
<li><?php _e( 'If you want to make any fine tunning in the critical CSS file of an <span class="badge auto">AUTO</span> rule, click on "Edit" button of that rule, change what you need, submit and save it. The rule you\'ve just edited becomes a <span class="badge manual">MANUAL</span> rule then.', 'autoptimize' ); ?></li>
|
181 |
<li><?php _e( 'You can create <span class="badge manual">MANUAL</span> rules for specific page paths (URL). Longer, more specific paths have higher priority over shorter ones, which in turn have higher priority over <span class="badge auto">AUTO</span> rules. Also, critical CSS files from <span class="badge manual">MANUAL</span> <strong>rules are NEVER updated automatically.</strong>', 'autoptimize' ); ?></li>
|
182 |
<li><?php _e( 'You can also create an <span class="badge auto">AUTO</span> rule for a path by leaving its critical CSS content empty. The critical CSS for that path will be automatically fetched from <a href="https://criticalcss.com/?aff=1" target="_blank">criticalcss.com</a> for you and updated whenever it changes.', 'autoptimize' ); ?></li>
|
183 |
+
<li><?php _e( "If you see an <span class='badge auto'>AUTO</span> rule with a <span class='badge review'>R</span> besides it (R is after REVIEW), it means that the fetched critical CSS for that rule is not 100% guaranteed to work according to <a href='https://criticalcss.com/?aff=1' target='_blank'>criticalcss.com</a> analysis. It's advised that you edit and review that rule to make any required adjustments.", 'autoptimize' ); ?></li>
|
184 |
<li><?php _e( 'At any time you can delete an <span class="badge auto">AUTO</span> or <span class="badge manual">MANUAL</span> rule by cliking on "Remove" button of the desired rule and saving your changes.', 'autoptimize' ); ?></li>
|
185 |
</ol>
|
186 |
</div>
|
classes/external/js/lazysizes.min.js
CHANGED
@@ -1,3 +1,3 @@
|
|
1 |
-
/*! lazysizes + ls unveilhooks - v5.
|
2 |
-
!function(e){var t=function(u,D,f){"use strict";var k,H;if(function(){var e;var t={lazyClass:"lazyload",loadedClass:"lazyloaded",loadingClass:"lazyloading",preloadClass:"lazypreload",errorClass:"lazyerror",autosizesClass:"lazyautosizes",srcAttr:"data-src",srcsetAttr:"data-srcset",sizesAttr:"data-sizes",minSize:40,customMedia:{},init:true,expFactor:1.5,hFac:.8,loadMode:2,loadHidden:true,ricTimeout:0,throttleDelay:125};H=u.lazySizesConfig||u.lazysizesConfig||{};for(e in t){if(!(e in H)){H[e]=t[e]}}}(),!D||!D.getElementsByClassName){return{init:function(){},cfg:H,noSupport:true}}var O=D.documentElement,
|
3 |
-
!function(e,t){var a=function(){t(e.lazySizes),e.removeEventListener("lazyunveilread",a,!0)};t=t.bind(null,e,e.document),"object"==typeof module&&module.exports?t(require("lazysizes")):"function"==typeof define&&define.amd?define(["lazysizes"],t):e.lazySizes?a():e.addEventListener("lazyunveilread",a,!0)}(window,function(e,
|
1 |
+
/*! lazysizes + ls unveilhooks - v5.3.1 (incl. ls-uvh data-link fix) */
|
2 |
+
!function(e){var t=function(u,D,f){"use strict";var k,H;if(function(){var e;var t={lazyClass:"lazyload",loadedClass:"lazyloaded",loadingClass:"lazyloading",preloadClass:"lazypreload",errorClass:"lazyerror",autosizesClass:"lazyautosizes",fastLoadedClass:"ls-is-cached",iframeLoadMode:0,srcAttr:"data-src",srcsetAttr:"data-srcset",sizesAttr:"data-sizes",minSize:40,customMedia:{},init:true,expFactor:1.5,hFac:.8,loadMode:2,loadHidden:true,ricTimeout:0,throttleDelay:125};H=u.lazySizesConfig||u.lazysizesConfig||{};for(e in t){if(!(e in H)){H[e]=t[e]}}}(),!D||!D.getElementsByClassName){return{init:function(){},cfg:H,noSupport:true}}var O=D.documentElement,i=u.HTMLPictureElement,P="addEventListener",$="getAttribute",q=u[P].bind(u),I=u.setTimeout,U=u.requestAnimationFrame||I,o=u.requestIdleCallback,j=/^picture$/i,r=["load","error","lazyincluded","_lazyloaded"],a={},G=Array.prototype.forEach,J=function(e,t){if(!a[t]){a[t]=new RegExp("(\\s|^)"+t+"(\\s|$)")}return a[t].test(e[$]("class")||"")&&a[t]},K=function(e,t){if(!J(e,t)){e.setAttribute("class",(e[$]("class")||"").trim()+" "+t)}},Q=function(e,t){var a;if(a=J(e,t)){e.setAttribute("class",(e[$]("class")||"").replace(a," "))}},V=function(t,a,e){var i=e?P:"removeEventListener";if(e){V(t,a)}r.forEach(function(e){t[i](e,a)})},X=function(e,t,a,i,r){var n=D.createEvent("Event");if(!a){a={}}a.instance=k;n.initEvent(t,!i,!r);n.detail=a;e.dispatchEvent(n);return n},Y=function(e,t){var a;if(!i&&(a=u.picturefill||H.pf)){if(t&&t.src&&!e[$]("srcset")){e.setAttribute("srcset",t.src)}a({reevaluate:true,elements:[e]})}else if(t&&t.src){e.src=t.src}},Z=function(e,t){return(getComputedStyle(e,null)||{})[t]},s=function(e,t,a){a=a||e.offsetWidth;while(a<H.minSize&&t&&!e._lazysizesWidth){a=t.offsetWidth;t=t.parentNode}return a},ee=function(){var a,i;var t=[];var r=[];var n=t;var s=function(){var e=n;n=t.length?r:t;a=true;i=false;while(e.length){e.shift()()}a=false};var e=function(e,t){if(a&&!t){e.apply(this,arguments)}else{n.push(e);if(!i){i=true;(D.hidden?I:U)(s)}}};e._lsFlush=s;return e}(),te=function(a,e){return e?function(){ee(a)}:function(){var e=this;var t=arguments;ee(function(){a.apply(e,t)})}},ae=function(e){var a;var i=0;var r=H.throttleDelay;var n=H.ricTimeout;var t=function(){a=false;i=f.now();e()};var s=o&&n>49?function(){o(t,{timeout:n});if(n!==H.ricTimeout){n=H.ricTimeout}}:te(function(){I(t)},true);return function(e){var t;if(e=e===true){n=33}if(a){return}a=true;t=r-(f.now()-i);if(t<0){t=0}if(e||t<9){s()}else{I(s,t)}}},ie=function(e){var t,a;var i=99;var r=function(){t=null;e()};var n=function(){var e=f.now()-a;if(e<i){I(n,i-e)}else{(o||r)(r)}};return function(){a=f.now();if(!t){t=I(n,i)}}},e=function(){var v,m,c,h,e;var y,z,g,p,C,b,A;var n=/^img$/i;var d=/^iframe$/i;var E="onscroll"in u&&!/(gle|ing)bot/.test(navigator.userAgent);var _=0;var w=0;var M=0;var N=-1;var L=function(e){M--;if(!e||M<0||!e.target){M=0}};var x=function(e){if(A==null){A=Z(D.body,"visibility")=="hidden"}return A||!(Z(e.parentNode,"visibility")=="hidden"&&Z(e,"visibility")=="hidden")};var W=function(e,t){var a;var i=e;var r=x(e);g-=t;b+=t;p-=t;C+=t;while(r&&(i=i.offsetParent)&&i!=D.body&&i!=O){r=(Z(i,"opacity")||1)>0;if(r&&Z(i,"overflow")!="visible"){a=i.getBoundingClientRect();r=C>a.left&&p<a.right&&b>a.top-1&&g<a.bottom+1}}return r};var t=function(){var e,t,a,i,r,n,s,o,l,u,f,c;var d=k.elements;if((h=H.loadMode)&&M<8&&(e=d.length)){t=0;N++;for(;t<e;t++){if(!d[t]||d[t]._lazyRace){continue}if(!E||k.prematureUnveil&&k.prematureUnveil(d[t])){R(d[t]);continue}if(!(o=d[t][$]("data-expand"))||!(n=o*1)){n=w}if(!u){u=!H.expand||H.expand<1?O.clientHeight>500&&O.clientWidth>500?500:370:H.expand;k._defEx=u;f=u*H.expFactor;c=H.hFac;A=null;if(w<f&&M<1&&N>2&&h>2&&!D.hidden){w=f;N=0}else if(h>1&&N>1&&M<6){w=u}else{w=_}}if(l!==n){y=innerWidth+n*c;z=innerHeight+n;s=n*-1;l=n}a=d[t].getBoundingClientRect();if((b=a.bottom)>=s&&(g=a.top)<=z&&(C=a.right)>=s*c&&(p=a.left)<=y&&(b||C||p||g)&&(H.loadHidden||x(d[t]))&&(m&&M<3&&!o&&(h<3||N<4)||W(d[t],n))){R(d[t]);r=true;if(M>9){break}}else if(!r&&m&&!i&&M<4&&N<4&&h>2&&(v[0]||H.preloadAfterLoad)&&(v[0]||!o&&(b||C||p||g||d[t][$](H.sizesAttr)!="auto"))){i=v[0]||d[t]}}if(i&&!r){R(i)}}};var a=ae(t);var S=function(e){var t=e.target;if(t._lazyCache){delete t._lazyCache;return}L(e);K(t,H.loadedClass);Q(t,H.loadingClass);V(t,B);X(t,"lazyloaded")};var i=te(S);var B=function(e){i({target:e.target})};var T=function(e,t){var a=e.getAttribute("data-load-mode")||H.iframeLoadMode;if(a==0){e.contentWindow.location.replace(t)}else if(a==1){e.src=t}};var F=function(e){var t;var a=e[$](H.srcsetAttr);if(t=H.customMedia[e[$]("data-media")||e[$]("media")]){e.setAttribute("media",t)}if(a){e.setAttribute("srcset",a)}};var s=te(function(t,e,a,i,r){var n,s,o,l,u,f;if(!(u=X(t,"lazybeforeunveil",e)).defaultPrevented){if(i){if(a){K(t,H.autosizesClass)}else{t.setAttribute("sizes",i)}}s=t[$](H.srcsetAttr);n=t[$](H.srcAttr);if(r){o=t.parentNode;l=o&&j.test(o.nodeName||"")}f=e.firesLoad||"src"in t&&(s||n||l);u={target:t};K(t,H.loadingClass);if(f){clearTimeout(c);c=I(L,2500);V(t,B,true)}if(l){G.call(o.getElementsByTagName("source"),F)}if(s){t.setAttribute("srcset",s)}else if(n&&!l){if(d.test(t.nodeName)){T(t,n)}else{t.src=n}}if(r&&(s||l)){Y(t,{src:n})}}if(t._lazyRace){delete t._lazyRace}Q(t,H.lazyClass);ee(function(){var e=t.complete&&t.naturalWidth>1;if(!f||e){if(e){K(t,H.fastLoadedClass)}S(u);t._lazyCache=true;I(function(){if("_lazyCache"in t){delete t._lazyCache}},9)}if(t.loading=="lazy"){M--}},true)});var R=function(e){if(e._lazyRace){return}var t;var a=n.test(e.nodeName);var i=a&&(e[$](H.sizesAttr)||e[$]("sizes"));var r=i=="auto";if((r||!m)&&a&&(e[$]("src")||e.srcset)&&!e.complete&&!J(e,H.errorClass)&&J(e,H.lazyClass)){return}t=X(e,"lazyunveilread").detail;if(r){re.updateElem(e,true,e.offsetWidth)}e._lazyRace=true;M++;s(e,t,r,i,a)};var r=ie(function(){H.loadMode=3;a()});var o=function(){if(H.loadMode==3){H.loadMode=2}r()};var l=function(){if(m){return}if(f.now()-e<999){I(l,999);return}m=true;H.loadMode=3;a();q("scroll",o,true)};return{_:function(){e=f.now();k.elements=D.getElementsByClassName(H.lazyClass);v=D.getElementsByClassName(H.lazyClass+" "+H.preloadClass);q("scroll",a,true);q("resize",a,true);q("pageshow",function(e){if(e.persisted){var t=D.querySelectorAll("."+H.loadingClass);if(t.length&&t.forEach){U(function(){t.forEach(function(e){if(e.complete){R(e)}})})}}});if(u.MutationObserver){new MutationObserver(a).observe(O,{childList:true,subtree:true,attributes:true})}else{O[P]("DOMNodeInserted",a,true);O[P]("DOMAttrModified",a,true);setInterval(a,999)}q("hashchange",a,true);["focus","mouseover","click","load","transitionend","animationend"].forEach(function(e){D[P](e,a,true)});if(/d$|^c/.test(D.readyState)){l()}else{q("load",l);D[P]("DOMContentLoaded",a);I(l,2e4)}if(k.elements.length){t();ee._lsFlush()}else{a()}},checkElems:a,unveil:R,_aLSL:o}}(),re=function(){var a;var n=te(function(e,t,a,i){var r,n,s;e._lazysizesWidth=i;i+="px";e.setAttribute("sizes",i);if(j.test(t.nodeName||"")){r=t.getElementsByTagName("source");for(n=0,s=r.length;n<s;n++){r[n].setAttribute("sizes",i)}}if(!a.detail.dataAttr){Y(e,a.detail)}});var i=function(e,t,a){var i;var r=e.parentNode;if(r){a=s(e,r,a);i=X(e,"lazybeforesizes",{width:a,dataAttr:!!t});if(!i.defaultPrevented){a=i.detail.width;if(a&&a!==e._lazysizesWidth){n(e,r,i,a)}}}};var e=function(){var e;var t=a.length;if(t){e=0;for(;e<t;e++){i(a[e])}}};var t=ie(e);return{_:function(){a=D.getElementsByClassName(H.autosizesClass);q("resize",t)},checkElems:t,updateElem:i}}(),t=function(){if(!t.i&&D.getElementsByClassName){t.i=true;re._();e._()}};return I(function(){H.init&&t()}),k={cfg:H,autoSizer:re,loader:e,init:t,uP:Y,aC:K,rC:Q,hC:J,fire:X,gW:s,rAF:ee}}(e,e.document,Date);e.lazySizes=t,"object"==typeof module&&module.exports&&(module.exports=t)}("undefined"!=typeof window?window:{});
|
3 |
+
!function(e,t){var a=function(){t(e.lazySizes),e.removeEventListener("lazyunveilread",a,!0)};t=t.bind(null,e,e.document),"object"==typeof module&&module.exports?t(require("lazysizes")):"function"==typeof define&&define.amd?define(["lazysizes"],t):e.lazySizes?a():e.addEventListener("lazyunveilread",a,!0)}(window,function(e,i,o){"use strict";var l,d,u={};function s(e,t,a){var n,r;u[e]||(n=i.createElement(t?"link":"script"),r=i.getElementsByTagName("script")[0],t?(n.rel="stylesheet",n.href=e):(n.onload=function(){n.onerror=null,n.onload=null,a()},n.onerror=n.onload,n.src=e),u[e]=!0,u[n.src||n.href]=!0,r.parentNode.insertBefore(n,r))}i.addEventListener&&(l=function(e,t){var a=i.createElement("img");a.onload=function(){a.onload=null,a.onerror=null,a=null,t()},a.onerror=a.onload,a.src=e,a&&a.complete&&a.onload&&a.onload()},addEventListener("lazybeforeunveil",function(e){var t,a,n;if(e.detail.instance==o&&!e.defaultPrevented){var r=e.target;if("none"==r.preload&&(r.preload=r.getAttribute("data-preload")||"auto"),null!=r.getAttribute("data-autoplay"))if(r.getAttribute("data-expand")&&!r.autoplay)try{r.play()}catch(e){}else requestAnimationFrame(function(){r.setAttribute("data-expand","-10"),o.aC(r,o.cfg.lazyClass)});(t=r.getAttribute("data-link"))&&"img"!=r.tagName.toLowerCase()&&s(t,!0),(t=r.getAttribute("data-script"))&&(e.detail.firesLoad=!0,s(t,null,function(){e.detail.firesLoad=!1,o.fire(r,"_lazyloaded",{},!0,!0)})),(t=r.getAttribute("data-require"))&&(o.cfg.requireJs?o.cfg.requireJs([t]):s(t)),(a=r.getAttribute("data-bg"))&&(e.detail.firesLoad=!0,l(a,function(){r.style.backgroundImage="url("+(d.test(a)?JSON.stringify(a):a)+")",e.detail.firesLoad=!1,o.fire(r,"_lazyloaded",{},!0,!0)})),(n=r.getAttribute("data-poster"))&&(e.detail.firesLoad=!0,l(n,function(){r.poster=n,e.detail.firesLoad=!1,o.fire(r,"_lazyloaded",{},!0,!0)}))}},!(d=/\(|\)|\s|'/)))});
|
classes/external/php/{minify-html.php → ao-minify-html.php}
RENAMED
@@ -16,7 +16,7 @@
|
|
16 |
* @package Minify
|
17 |
* @author Stephen Clay <steve@mrclay.org>
|
18 |
*/
|
19 |
-
class
|
20 |
|
21 |
/** @var string */
|
22 |
private $_html;
|
@@ -43,7 +43,7 @@ class Minify_HTML {
|
|
43 |
* @return string
|
44 |
*/
|
45 |
public static function minify($html, $options = array()) {
|
46 |
-
$min = new
|
47 |
return $min->process();
|
48 |
}
|
49 |
|
16 |
* @package Minify
|
17 |
* @author Stephen Clay <steve@mrclay.org>
|
18 |
*/
|
19 |
+
class AO_Minify_HTML {
|
20 |
|
21 |
/** @var string */
|
22 |
private $_html;
|
43 |
* @return string
|
44 |
*/
|
45 |
public static function minify($html, $options = array()) {
|
46 |
+
$min = new AO_Minify_HTML($html, $options);
|
47 |
return $min->process();
|
48 |
}
|
49 |
|
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: 5.7
|
7 |
Requires PHP: 5.6
|
8 |
-
Stable tag: 2.8.
|
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,14 @@ Just [fork Autoptimize on Github](https://github.com/futtta/autoptimize) and cod
|
|
319 |
|
320 |
== Changelog ==
|
321 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
322 |
= 2.8.1 =
|
323 |
* Images: new option not to lazyload first X images
|
324 |
* fix for "array to string" conversion errors in image optimization logic of .ico files
|
5 |
Requires at least: 4.9
|
6 |
Tested up to: 5.7
|
7 |
Requires PHP: 5.6
|
8 |
+
Stable tag: 2.8.2
|
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 |
+
= 2.8.2 =
|
323 |
+
* Images: only show "did you know shortpixel" notice on Autoptimize settings pages (no more littering all over the backend)
|
324 |
+
* Images: update lazysizes from upstream
|
325 |
+
* Images: misc. improvements such as fix for PHP "undefined index" notice, updated copy, ...
|
326 |
+
* HTML: rename HTML minify class from minify_HTML to AO_minify_HTML to avoid conflicts with e.g. W3TC
|
327 |
+
* 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, ...
|
328 |
+
* JS/ CSS: fix for AO not optimizing multisite child sites when CDN set
|
329 |
+
|
330 |
= 2.8.1 =
|
331 |
* Images: new option not to lazyload first X images
|
332 |
* fix for "array to string" conversion errors in image optimization logic of .ico files
|