| @@ -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 | } |