PluginProbe
Autoptimize / 3.1.4
Autoptimize v3.1.4
2.2.2 2.3.0 2.3.1 2.3.2 2.3.3 2.3.4 2.4.0 2.4.1 2.4.2 2.4.3 2.4.4 2.5.0 2.5.1 2.6.0 2.6.1 2.6.2 2.7.0 2.7.1 2.7.2 2.7.3 2.7.4 2.7.5 2.7.6 2.7.7 2.7.8 All 107 releases
← All changes | classes/autoptimizeScripts.php +77 -10 2.7.53.1.4 View file →
@@ -57,9 +57,14 @@
57 57 '_stq',
58 58 'nonce',
59 59 'post_id',
60 60 'data-noptimize',
61 + 'data-cfasync',
62 + 'data-pagespeed-no-defer',
61 63 'logHuman',
64 + 'amp-mobile-version-switcher',
65 + 'data-rocketlazyloadscript',
66 + 'rocket-browser-checker-js-after',
62 67 );
63 68
64 69 /**
65 70 * List of to be moved JS.
@@ -108,8 +113,22 @@
108 113 */
109 114 private $aggregate = true;
110 115
111 116 /**
117 + * Setting; if not aggregated, should we defer?
118 + *
119 + * @var bool
120 + */
121 + private $defer_not_aggregate = false;
122 +
123 + /**
124 + * Setting; defer inline JS?
125 + *
126 + * @var bool
127 + */
128 + private $defer_inline = false;
129 +
130 + /**
112 131 * Setting; try/catch wrapping or not.
113 132 *
114 133 * @var bool
115 134 */
@@ -199,9 +218,19 @@
199 218 * @param array $options all options.
200 219 */
201 220 public function read( $options )
202 221 {
203 - $noptimize_js = apply_filters( 'autoptimize_filter_js_noptimize', false, $this->content );
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;
227 + }
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.
204 233 if ( $noptimize_js ) {
205 234 return false;
206 235 }
207 236
@@ -206,9 +235,8 @@
206 235 }
207 236
208 237 // only optimize known good JS?
209 238 $allowlist_js = apply_filters( 'autoptimize_filter_js_allowlist', '', $this->content );
210 - $allowlist_js = apply_filters( 'autoptimize_filter_js_whitelist', $allowlist_js, $this->content ); // fixme: to be removed in next version.
211 239 if ( ! empty( $allowlist_js ) ) {
212 240 $this->allowlist = array_filter( array_map( 'trim', explode( ',', $allowlist_js ) ) );
213 241 }
214 242
@@ -232,9 +260,21 @@
232 260 // Returning true for "dontaggregate" turns off aggregation.
233 261 if ( $this->aggregate && apply_filters( 'autoptimize_filter_js_dontaggregate', false ) ) {
234 262 $this->aggregate = false;
235 263 }
264 + // and the filter that should have been there to begin with.
265 + $this->aggregate = apply_filters( 'autoptimize_filter_js_aggregate', $this->aggregate );
236 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;
275 + }
276 +
237 277 // include inline?
238 278 if ( apply_filters( 'autoptimize_js_include_inline', $options['include_inline'] ) ) {
239 279 $this->include_inline = true;
240 280 }
@@ -335,8 +375,13 @@
335 375 }
336 376 }
337 377 }
338 378
379 + // not aggregating but deferring?
380 + if ( $this->defer_not_aggregate && false === $this->aggregate && ( str_replace( $this->dontmove, '', $path ) === $path || ( apply_filters( 'autoptimize_filter_js_defer_external', true ) && str_replace( $this->dontmove, '', $orig_tag ) === $orig_tag ) ) && strpos( $new_tag, ' defer' ) === false && strpos( $new_tag, ' async' ) === false ) {
381 + $new_tag = str_replace( '<script ', '<script defer ', $new_tag );
382 + }
383 +
339 384 // Should we minify the non-aggregated script?
340 385 // -> if aggregate is on and exclude minify is on
341 386 // -> if aggregate is off and the file is not in dontmove.
342 387 if ( $path && $this->minify_excluded ) {
@@ -353,8 +398,13 @@
353 398 }
354 399 }
355 400 }
356 401
402 + // Check if we still need to CDN (esp. for already minified resources).
403 + if ( ! empty( $this->cdn_url ) || has_filter( 'autoptimize_filter_base_replace_cdn' ) ) {
404 + $new_tag = str_replace( $url, $this->url_replace_cdn( $url ), $new_tag );
405 + }
406 +
357 407 if ( $this->ismovable( $new_tag ) ) {
358 408 // can be moved, flags and all.
359 409 if ( $this->movetolast( $new_tag ) ) {
360 410 $this->move['last'][] = $new_tag;
@@ -385,18 +435,35 @@
385 435 $code = preg_replace( '#.*<!\[CDATA\[(?:\s*\*/)?(.*)(?://|/\*)\s*?\]\]>.*#sm', '$1', $code[1] );
386 436 $code = preg_replace( '/(?:^\\s*<!--\\s*|\\s*(?:\\/\\/)?\\s*-->\\s*$)/', '', $code );
387 437 $this->scripts[] = 'INLINE;' . $code;
388 438 } else {
389 - // Can we move this?
390 - $autoptimize_js_moveable = apply_filters( 'autoptimize_js_moveable', '', $tag );
391 - if ( $this->ismovable( $tag ) || '' !== $autoptimize_js_moveable ) {
392 - if ( $this->movetolast( $tag ) || 'last' === $autoptimize_js_moveable ) {
393 - $this->move['last'][] = $tag;
439 + $_inline_deferable = apply_filters( 'autoptimize_filters_js_inline_deferable', array( 'nonce', 'post_id', 'syntaxhighlighter' ) );
440 + $_inline_dontmove = array_values( array_diff( $this->dontmove, $_inline_deferable ) );
441 + if ( false === $this->defer_inline ) {
442 + // Can we move this?
443 + $autoptimize_js_moveable = apply_filters( 'autoptimize_js_moveable', '', $tag );
444 + if ( $this->ismovable( $tag ) || '' !== $autoptimize_js_moveable ) {
445 + if ( $this->movetolast( $tag ) || 'last' === $autoptimize_js_moveable ) {
446 + $this->move['last'][] = $tag;
447 + } else {
448 + $this->move['first'][] = $tag;
449 + }
394 450 } else {
395 - $this->move['first'][] = $tag;
451 + $tag = '';
396 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] . '" ';
458 + } else {
459 + $_id = '';
460 + }
461 +
462 + $new_tag = '<script defer ' . $_id . 'src="data:text/javascript;base64,' . base64_encode( $match[3] ) . '"></script>';
463 + $this->content = str_replace( $tag, $new_tag, $this->content );
464 + $tag = '';
397 465 } else {
398 - // We shouldn't touch this.
399 466 $tag = '';
400 467 }
401 468 }
402 469 // Re-hide comments to be able to do the removal based on tag from $this->content.
@@ -428,9 +495,9 @@
428 495 *
429 496 * @param string $tag Script node & child(ren).
430 497 * @return bool
431 498 */
432 - public function should_aggregate( $tag )
499 + public static function should_aggregate( $tag )
433 500 {
434 501 if ( empty( $tag ) ) {
435 502 return false;
436 503 }