PluginProbe
Autoptimize / trunk
Autoptimize vtrunk
3.1.16 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 All 108 releases
← All changes | classes/autoptimizeExtra.php +282 -67 2.5.1 → trunk View file →
@@ -16,8 +16,15 @@
16 16 */
17 17 protected $options = array();
18 18
19 19 /**
20 + * Singleton instance.
21 + *
22 + * @var self|null
23 + */
24 + protected static $instance = null;
25 +
26 + /**
20 27 * Creates an instance and calls run().
21 28 *
22 29 * @param array $options Optional. Allows overriding options without having to specify them via admin options page.
23 30 */
@@ -29,21 +36,49 @@
29 36
30 37 $this->options = $options;
31 38 }
32 39
40 + /**
41 + * Helper for getting a singleton instance. While being an
42 + * anti-pattern generally, it comes in handy for now from a
43 + * readability/maintainability perspective, until we get some
44 + * proper dependency injection going.
45 + *
46 + * @return self
47 + */
48 + public static function instance()
49 + {
50 + if ( null === self::$instance ) {
51 + self::$instance = new self();
52 + }
53 +
54 + return self::$instance;
55 + }
56 +
33 57 public function run()
34 58 {
35 59 if ( is_admin() ) {
36 - add_action( 'admin_menu', array( $this, 'admin_menu' ) );
60 + if ( is_multisite() && is_network_admin() && autoptimizeOptionWrapper::is_ao_active_for_network() ) {
61 + add_action( 'network_admin_menu', array( $this, 'admin_menu' ) );
62 + } else {
63 + add_action( 'admin_menu', array( $this, 'admin_menu' ) );
64 + }
37 65 add_filter( 'autoptimize_filter_settingsscreen_tabs', array( $this, 'add_extra_tab' ) );
38 66 } else {
39 - $this->run_on_frontend();
67 + add_action( 'wp', array( $this, 'run_on_frontend' ) );
40 68 }
41 69 }
42 70
71 + public function set_options( array $options )
72 + {
73 + $this->options = $options;
74 +
75 + return $this;
76 + }
77 +
43 78 public static function fetch_options()
44 79 {
45 - $value = get_option( 'autoptimize_extra_settings' );
80 + $value = autoptimizeOptionWrapper::get_option( 'autoptimize_extra_settings' );
46 81 if ( empty( $value ) ) {
47 82 // Fallback to returning defaults when no stored option exists yet.
48 83 $value = autoptimizeConfig::get_ao_extra_default_options();
49 84 }
@@ -65,9 +100,9 @@
65 100 // Removes TinyMCE emojis.
66 101 add_filter( 'tiny_mce_plugins', array( $this, 'filter_disable_emojis_tinymce' ) );
67 102
68 103 // Removes emoji dns-preftech.
69 - add_filter( 'wp_resource_hints', array( $this, 'filter_remove_emoji_dns_prefetch' ), 10, 2 );
104 + add_filter( 'emoji_svg_url', '__return_false' );
70 105 }
71 106
72 107 public function filter_disable_emojis_tinymce( $plugins )
73 108 {
@@ -79,10 +114,14 @@
79 114 }
80 115
81 116 public function filter_remove_qs( $src )
82 117 {
83 - if ( strpos( $src, '?ver=' ) ) {
84 - $src = remove_query_arg( 'ver', $src );
118 + if ( ! empty( $src ) ) {
119 + if ( strpos( $src, '?ver=' ) ) {
120 + $src = remove_query_arg( 'ver', $src );
121 + } elseif ( strpos( $src, '?v=' ) ) {
122 + $src = remove_query_arg( 'v', $src );
123 + }
85 124 }
86 125
87 126 return $src;
88 127 }
@@ -93,9 +132,9 @@
93 132 if ( ! empty( $in ) ) {
94 133 $exclusions = array_fill_keys( array_filter( array_map( 'trim', explode( ',', $in ) ) ), '' );
95 134 }
96 135
97 - $settings = $this->options['autoptimize_extra_text_field_3'];
136 + $settings = wp_strip_all_tags( $this->options['autoptimize_extra_text_field_3'] );
98 137 $async = array_fill_keys( array_filter( array_map( 'trim', explode( ',', $settings ) ) ), '' );
99 138 $attr = apply_filters( 'autoptimize_filter_extra_async', 'async' );
100 139 foreach ( $async as $k => $v ) {
101 140 $async[ $k ] = $attr;
@@ -106,10 +145,18 @@
106 145
107 146 return $merged;
108 147 }
109 148
110 - protected function run_on_frontend()
149 + public function run_on_frontend()
111 150 {
151 + // only run the Extra optimizations on frontend if general conditions
152 + // for optimizations are met, this to ensure e.g. removing querystrings
153 + // is not done when optimizing for logged in users is off, breaking
154 + // some pagebuilders (Divi & Elementor).
155 + if ( false === autoptimizeMain::should_buffer() ) {
156 + return;
157 + }
158 +
112 159 $options = $this->options;
113 160
114 161 // Disable emojis if specified.
115 162 if ( ! empty( $options['autoptimize_extra_checkbox_field_1'] ) ) {
@@ -132,8 +179,17 @@
132 179 if ( ! empty( $options['autoptimize_extra_radio_field_4'] ) && ( '1' !== $options['autoptimize_extra_radio_field_4'] ) ) {
133 180 add_filter( 'wp_resource_hints', array( $this, 'filter_remove_gfonts_dnsprefetch' ), 10, 2 );
134 181 add_filter( 'autoptimize_html_after_minify', array( $this, 'filter_optimize_google_fonts' ), 10, 1 );
135 182 add_filter( 'autoptimize_extra_filter_tobepreconn', array( $this, 'filter_preconnect_google_fonts' ), 10, 1 );
183 +
184 + if ( '2' === $options['autoptimize_extra_radio_field_4'] ) {
185 + // remove Google Fonts, adding filters to also remove Google Fonts from 3rd party themes/ plugins.
186 + // inspired by https://wordpress.org/plugins/disable-remove-google-fonts/.
187 + remove_action( 'wp_footer', 'et_builder_print_font' ); // Divi.
188 + remove_action( 'wp_footer', array( 'RevSliderFront', 'load_google_fonts' ) ); // Revslider.
189 + add_filter( 'elementor/frontend/print_google_fonts', '__return_false' ); // Elementor.
190 + add_filter( 'fl_builder_google_fonts_pre_enqueue', '__return_empty_array' ); // Beaver Builder.
191 + }
136 192 }
137 193
138 194 // Preconnect!
139 195 if ( ! empty( $options['autoptimize_extra_text_field_2'] ) || has_filter( 'autoptimize_extra_filter_tobepreconn' ) ) {
@@ -138,15 +194,18 @@
138 194 // Preconnect!
139 195 if ( ! empty( $options['autoptimize_extra_text_field_2'] ) || has_filter( 'autoptimize_extra_filter_tobepreconn' ) ) {
140 196 add_filter( 'wp_resource_hints', array( $this, 'filter_preconnect' ), 10, 2 );
141 197 }
142 - }
143 198
144 - public function filter_remove_emoji_dns_prefetch( $urls, $relation_type )
145 - {
146 - $emoji_svg_url = apply_filters( 'emoji_svg_url', 'https://s.w.org/images/core/emoji/' );
199 + // Preload!
200 + if ( ! empty( $options['autoptimize_extra_text_field_7'] ) || has_filter( 'autoptimize_filter_extra_tobepreloaded' ) || ! empty( autoptimizeConfig::get_post_meta_ao_settings( 'ao_post_preload' ) ) ) {
201 + add_filter( 'autoptimize_html_after_minify', array( $this, 'filter_preload' ), 10, 2 );
202 + }
147 203
148 - return $this->filter_remove_dns_prefetch( $urls, $relation_type, $emoji_svg_url );
204 + // Remove global styles.
205 + if ( ! empty( $options['autoptimize_extra_checkbox_field_8'] ) ) {
206 + $this->disable_global_styles();
207 + }
149 208 }
150 209
151 210 public function filter_remove_gfonts_dnsprefetch( $urls, $relation_type )
152 211 {
@@ -159,9 +218,18 @@
159 218
160 219 if ( ! empty( $url_to_remove ) && 'dns-prefetch' === $relation_type ) {
161 220 $cnt = 0;
162 221 foreach ( $urls as $url ) {
163 - if ( false !== strpos( $url, $url_to_remove ) ) {
222 + // $url can be an array, in which case we need to fetch the value of the href key.
223 + if ( is_array( $url ) ) {
224 + if ( isset( $url['href'] ) ) {
225 + $url = $url['href'];
226 + } else {
227 + continue;
228 + }
229 + }
230 +
231 + if ( is_string( $url ) && false !== strpos( $url, $url_to_remove ) ) {
164 232 unset( $urls[ $cnt ] );
165 233 }
166 234 $cnt++;
167 235 }
@@ -186,8 +254,14 @@
186 254 foreach ( $matches[2] as $font ) {
187 255 if ( ! preg_match( '/rel=["\']dns-prefetch["\']/', $matches[0][ $i ] ) ) {
188 256 // Get fonts name.
189 257 $font = str_replace( array( '%7C', '%7c' ), '|', $font );
258 + if ( strpos( $font, 'fonts.googleapis.com/css2' ) !== false ) {
259 + // (Somewhat) change Google Fonts APIv2 syntax back to v1.
260 + // todo: support for 100..900
261 + $font = rawurldecode( $font );
262 + $font = str_replace( array( 'css2?', 'ital,wght@', 'wght@', 'ital@', '0,', '1,', ':1', ';', '&family=' ), array( 'css?', '', '', '', '', 'italic', ':italic', ',', '%7C' ), $font );
263 + }
190 264 $font = explode( 'family=', $font );
191 265 $font = ( isset( $font[1] ) ) ? explode( '&', $font[1] ) : array();
192 266 // Add font to $fonts[$i] but make sure not to pollute with an empty family!
193 267 $_thisfont = array_values( array_filter( explode( '|', reset( $font ) ) ) );
@@ -229,16 +303,20 @@
229 303 $fonts_string = $fonts_string . '&subset=' . $subset_string;
230 304 }
231 305
232 306 $fonts_string = apply_filters( 'autoptimize_filter_extra_gfont_fontstring', str_replace( '|', '%7C', ltrim( $fonts_string, '|' ) ) );
307 + // only add display parameter if there is none in $fonts_string (by virtue of the filter).
308 + if ( strpos( $fonts_string, 'display=' ) === false ) {
309 + $fonts_string .= apply_filters( 'autoptimize_filter_extra_gfont_display', '&display=swap' );
310 + }
233 311
234 312 if ( ! empty( $fonts_string ) ) {
235 313 if ( '5' === $options['autoptimize_extra_radio_field_4'] ) {
236 - $rel_string = 'rel="preload" as="style" onload="' . autoptimizeConfig::get_ao_css_preload_onload() . '"';
314 + $rel_string = 'rel="stylesheet" media="print" onload="' . autoptimizeConfig::get_ao_css_preload_onload() . '"';
237 315 } else {
238 316 $rel_string = 'rel="stylesheet"';
239 317 }
240 - $fonts_markup = '<link ' . $rel_string . ' id="ao_optimized_gfonts" href="https://fonts.googleapis.com/css?family=' . $fonts_string . '" />';
318 + $fonts_markup = '<link ' . $rel_string . ' id="ao_optimized_gfonts" href="https://fonts.googleapis.com/css?family=' . $fonts_string . '">';
241 319 }
242 320 } elseif ( '4' === $options['autoptimize_extra_radio_field_4'] ) {
243 321 // Aggregate & load async (webfont.js impl.)!
244 322 $fonts_array = array();
@@ -252,11 +330,24 @@
252 330 }
253 331 $fonts_array = array_merge( $fonts_array, $_fonts['fonts'] );
254 332 }
255 333
256 - $fonts_array = array_map( 'urldecode', $fonts_array );
257 - $fonts_markup = '<script data-cfasync="false" id="ao_optimized_gfonts_config" type="text/javascript">WebFontConfig={google:{families:' . wp_json_encode( $fonts_array ) . ' },classes:false, events:false, timeout:1500};</script>';
258 - $fonts_library_markup = '<script data-cfasync="false" id="ao_optimized_gfonts_webfontloader" type="text/javascript">(function() {var wf = document.createElement(\'script\');wf.src=\'https://ajax.googleapis.com/ajax/libs/webfont/1/webfont.js\';wf.type=\'text/javascript\';wf.async=\'true\';var s=document.getElementsByTagName(\'script\')[0];s.parentNode.insertBefore(wf, s);})();</script>';
334 + $fonts_array = array_map( 'urldecode', $fonts_array );
335 + $fonts_array = array_map(
336 + function( $_f ) {
337 + return trim( $_f, ',' );
338 + },
339 + $fonts_array
340 + );
341 +
342 + // type attrib on <script not added by default.
343 + $type_js = '';
344 + if ( apply_filters( 'autoptimize_filter_cssjs_addtype', false ) ) {
345 + $type_js = 'type="text/javascript" ';
346 + }
347 +
348 + $fonts_markup = '<script ' . $type_js . 'data-cfasync="false" id="ao_optimized_gfonts_config">WebFontConfig={google:{families:' . wp_json_encode( $fonts_array, JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_QUOT ) . ' },classes:false, events:false, timeout:1500};</script>';
349 + $fonts_library_markup = '<script ' . $type_js . 'data-cfasync="false" id="ao_optimized_gfonts_webfontloader">(function() {var wf = document.createElement(\'script\');wf.src=\'https://ajax.googleapis.com/ajax/libs/webfont/1/webfont.js\';wf.type=\'text/javascript\';wf.async=\'true\';var s=document.getElementsByTagName(\'script\')[0];s.parentNode.insertBefore(wf, s);})();</script>';
259 350 $in = substr_replace( $in, $fonts_library_markup . '</head>', strpos( $in, '</head>' ), strlen( '</head>' ) );
260 351 }
261 352
262 353 // Replace back in markup.
@@ -263,30 +354,29 @@
263 354 $inject_point = apply_filters( 'autoptimize_filter_extra_gfont_injectpoint', '<link' );
264 355 $out = substr_replace( $in, $fonts_markup . $inject_point, strpos( $in, $inject_point ), strlen( $inject_point ) );
265 356 unset( $fonts_collection );
266 357
267 - // and insert preload polyfill if "link preload" and if the polyfill isn't there yet (courtesy of inline&defer).
268 - $preload_polyfill = autoptimizeConfig::get_ao_css_preload_polyfill();
269 - if ( '5' === $options['autoptimize_extra_radio_field_4'] && strpos( $out, $preload_polyfill ) === false ) {
270 - $out = str_replace( '</body>', $preload_polyfill . '</body>', $out );
271 - }
272 358 return $out;
273 359 }
274 360
275 361 public function filter_preconnect( $hints, $relation_type )
276 362 {
277 - $options = $this->options;
363 + $options = $this->options;
364 + $preconns = array();
278 365
279 366 // Get settings and store in array.
280 - $preconns = array_filter( array_map( 'trim', explode( ',', $options['autoptimize_extra_text_field_2'] ) ) );
367 + if ( array_key_exists( 'autoptimize_extra_text_field_2', $options ) ) {
368 + $preconns = array_filter( array_map( 'trim', explode( ',', wp_strip_all_tags( $options['autoptimize_extra_text_field_2'] ) ) ) );
369 + }
281 370 $preconns = apply_filters( 'autoptimize_extra_filter_tobepreconn', $preconns );
282 371
283 372 // Walk array, extract domain and add to new array with crossorigin attribute.
284 373 foreach ( $preconns as $preconn ) {
374 + $domain = '';
285 375 $parsed = parse_url( $preconn );
286 - if ( is_array( $parsed ) && empty( $parsed['scheme'] ) ) {
376 + if ( is_array( $parsed ) && ! empty( $parsed['host'] ) && empty( $parsed['scheme'] ) ) {
287 377 $domain = '//' . $parsed['host'];
288 - } elseif ( is_array( $parsed ) ) {
378 + } elseif ( is_array( $parsed ) && ! empty( $parsed['host'] ) ) {
289 379 $domain = $parsed['scheme'] . '://' . $parsed['host'];
290 380 }
291 381
292 382 if ( ! empty( $domain ) ) {
@@ -324,24 +414,122 @@
324 414
325 415 return $in;
326 416 }
327 417
418 + public function filter_preload( $in ) {
419 + // make array from comma separated list.
420 + $options = $this->options;
421 + $preloads = array();
422 + if ( array_key_exists( 'autoptimize_extra_text_field_7', $options ) ) {
423 + $preloads = array_filter( array_map( 'trim', explode( ',', wp_strip_all_tags( $options['autoptimize_extra_text_field_7'] ) ) ) );
424 + }
425 +
426 + if ( false === autoptimizeImages::imgopt_active() && false === autoptimizeImages::should_lazyload_wrapper() ) {
427 + // only do this here if imgopt/ lazyload are not active?
428 + $metabox_preloads = array_filter( array_map( 'trim', explode( ',', wp_strip_all_tags( autoptimizeConfig::get_post_meta_ao_settings( 'ao_post_preload' ) ) ) ) );
429 + if ( ! empty( $metabox_preloads ) ) {
430 + $preloads = array_merge( $preloads, $metabox_preloads );
431 + }
432 + }
433 +
434 + $preloads = apply_filters( 'autoptimize_filter_extra_tobepreloaded', $preloads );
435 +
436 + // immediately return if nothing to be preloaded.
437 + if ( empty( $preloads ) ) {
438 + return $in;
439 + }
440 +
441 + // iterate through array and add preload link to tmp string.
442 + $preload_output = '';
443 + foreach ( $preloads as $preload ) {
444 + if ( filter_var( $preload, FILTER_VALIDATE_URL ) !== $preload ) {
445 + continue;
446 + }
447 + $preload = esc_url_raw( $preload );
448 + $crossorigin = '';
449 + $preload_as = '';
450 + $mime_type = '';
451 + $_preload = strtok( $preload, '?' );
452 +
453 + if ( autoptimizeUtils::str_ends_in( $_preload, '.css' ) ) {
454 + $preload_as = 'style';
455 + } elseif ( autoptimizeUtils::str_ends_in( $_preload, '.js' ) ) {
456 + $preload_as = 'script';
457 + } elseif ( autoptimizeUtils::str_ends_in( $_preload, '.woff' ) || autoptimizeUtils::str_ends_in( $_preload, '.woff2' ) || autoptimizeUtils::str_ends_in( $_preload, '.ttf' ) || autoptimizeUtils::str_ends_in( $_preload, '.eot' ) || autoptimizeUtils::str_ends_in( $_preload, '.otf' ) ) {
458 + $preload_as = 'font';
459 + $crossorigin = ' crossorigin';
460 + $mime_type = ' type="font/' . pathinfo( $_preload, PATHINFO_EXTENSION ) . '"';
461 + if ( ' type="font/eot"' === $mime_type ) {
462 + $mime_type = 'application/vnd.ms-fontobject';
463 + }
464 + } elseif ( autoptimizeUtils::str_ends_in( $_preload, '.jpeg' ) || autoptimizeUtils::str_ends_in( $_preload, '.jpg' ) || autoptimizeUtils::str_ends_in( $_preload, '.webp' ) || autoptimizeUtils::str_ends_in( $_preload, '.png' ) || autoptimizeUtils::str_ends_in( $_preload, '.gif' ) || autoptimizeUtils::str_ends_in( $_preload, '.svg' ) ) {
465 + $preload_as = 'image';
466 + } else {
467 + $preload_as = 'other';
468 + }
469 +
470 + $preload_output .= '<link rel="preload" fetchpriority="high" href="' . $preload . '" as="' . $preload_as . '"' . $mime_type . $crossorigin . '>';
471 + }
472 + $preload_output = apply_filters( 'autoptimize_filter_extra_preload_output', $preload_output );
473 +
474 + return $this->inject_preloads( $preload_output, $in );
475 + }
476 +
477 + public static function inject_preloads( $preloads, $html ) {
478 + // add string to head (before first link node by default).
479 + $preload_inject = apply_filters( 'autoptimize_filter_extra_preload_inject', '<link' );
480 + $position = autoptimizeUtils::strpos( $html, $preload_inject );
481 +
482 + return autoptimizeUtils::substr_replace( $html, $preloads . $preload_inject, $position, strlen( $preload_inject ) );
483 + }
484 +
485 + public function disable_global_styles()
486 + {
487 + remove_action( 'wp_enqueue_scripts', 'wp_enqueue_global_styles' );
488 + remove_action( 'wp_footer', 'wp_enqueue_global_styles', 1 );
489 + remove_action( 'wp_body_open', 'wp_global_styles_render_svg_filters' );
490 +
491 + if ( true === apply_filters( 'autoptimize_filter_extra_global_styles_and_block_css', true ) ) {
492 + add_action(
493 + 'wp_enqueue_scripts',
494 + function() {
495 + wp_dequeue_style( 'wp-block-library' );
496 + wp_dequeue_style( 'wp-block-library-theme' );
497 + }
498 + );
499 + }
500 +
501 + if ( true === apply_filters( 'autoptimize_filter_extra_remove_woocommerce_block_css', true ) ) {
502 + add_action(
503 + 'wp_enqueue_scripts',
504 + function() {
505 + wp_dequeue_style( 'wc-blocks-style' );
506 + }
507 + );
508 + }
509 + }
510 +
328 511 public function admin_menu()
329 512 {
330 - add_submenu_page(
331 - null,
332 - 'autoptimize_extra',
333 - 'autoptimize_extra',
334 - 'manage_options',
335 - 'autoptimize_extra',
336 - array( $this, 'options_page' )
337 - );
513 + // no acces if multisite and not network admin and no site config allowed.
514 + if ( autoptimizeConfig::should_show_menu_tabs() ) {
515 + add_submenu_page(
516 + '',
517 + 'autoptimize_extra',
518 + 'autoptimize_extra',
519 + 'manage_options',
520 + 'autoptimize_extra',
521 + array( $this, 'options_page' )
522 + );
523 + }
338 524 register_setting( 'autoptimize_extra_settings', 'autoptimize_extra_settings' );
339 525 }
340 526
341 527 public function add_extra_tab( $in )
342 528 {
343 - $in = array_merge( $in, array( 'autoptimize_extra' => __( 'Extra', 'autoptimize' ) ) );
529 + if ( autoptimizeConfig::should_show_menu_tabs() ) {
530 + $in = array_merge( $in, array( 'autoptimize_extra' => esc_html__( 'Extra', 'autoptimize' ) ) );
531 + }
344 532
345 533 return $in;
346 534 }
347 535
@@ -346,8 +534,10 @@
346 534 }
347 535
348 536 public function options_page()
349 537 {
538 + // phpcs:disable Squiz.ControlStructures.ControlSignature.NewlineAfterOpenBrace
539 +
350 540 // Working with actual option values from the database here.
351 541 // That way any saves are still processed as expected, but we can still
352 542 // override behavior by using `new autoptimizeExtra($custom_options)` and not have that custom
353 543 // behavior being persisted in the DB even if save is done here.
@@ -358,90 +548,115 @@
358 548 #ao_settings_form {background: white;border: 1px solid #ccc;padding: 1px 15px;margin: 15px 10px 10px 0;}
359 549 #ao_settings_form .form-table th {font-weight: normal;}
360 550 #autoptimize_extra_descr{font-size: 120%;}
361 551 </style>
552 + <script>document.title = "Autoptimize: <?php esc_html_e( 'Extra', 'autoptimize' ); ?> " + document.title;</script>
362 553 <div class="wrap">
363 - <h1><?php _e( 'Autoptimize Settings', 'autoptimize' ); ?></h1>
554 + <h1><?php apply_filters( 'autoptimize_filter_settings_is_pro', false ) ? esc_html_e( 'Autoptimize Pro Settings', 'autoptimize' ) : esc_html_e( 'Autoptimize Settings', 'autoptimize' ); ?></h1>
364 555 <?php echo autoptimizeConfig::ao_admin_tabs(); ?>
365 - <?php if ( 'on' !== get_option( 'autoptimize_js' ) && 'on' !== get_option( 'autoptimize_css' ) && 'on' !== get_option( 'autoptimize_html' ) && ! autoptimizeImages::imgopt_active() ) { ?>
556 + <?php if ( 'on' !== autoptimizeOptionWrapper::get_option( 'autoptimize_js' ) && 'on' !== autoptimizeOptionWrapper::get_option( 'autoptimize_css' ) && 'on' !== autoptimizeOptionWrapper::get_option( 'autoptimize_html' ) && ! autoptimizeImages::imgopt_active() ) { ?>
366 557 <div class="notice-warning notice"><p>
367 - <?php _e( 'Most of below Extra optimizations require at least one of HTML, JS, CSS or Image autoptimizations being active.', 'autoptimize' ); ?>
558 + <?php esc_html_e( 'Most of below Extra optimizations require at least one of HTML, JS, CSS or Image autoptimizations being active.', 'autoptimize' ); ?>
368 559 </p></div>
369 560 <?php } ?>
370 561
371 - <form id='ao_settings_form' action='options.php' method='post'>
562 + <form id='ao_settings_form' action='<?php echo admin_url( 'options.php' ); ?>' method='post'>
372 563 <?php settings_fields( 'autoptimize_extra_settings' ); ?>
373 - <h2><?php _e( 'Extra Auto-Optimizations', 'autoptimize' ); ?></h2>
374 - <span id='autoptimize_extra_descr'><?php _e( 'The following settings can improve your site\'s performance even more.', 'autoptimize' ); ?></span>
564 + <h2><?php esc_html_e( 'Extra Auto-Optimizations', 'autoptimize' ); ?></h2>
565 + <span id='autoptimize_extra_descr'><?php esc_html_e( 'The following settings can improve your site\'s performance even more.', 'autoptimize' ); ?></span>
375 566 <table class="form-table">
376 567 <tr>
377 - <th scope="row"><?php _e( 'Google Fonts', 'autoptimize' ); ?></th>
568 + <th scope="row"><?php esc_html_e( 'Google Fonts', 'autoptimize' ); ?></th>
378 569 <td>
379 - <input type="radio" name="autoptimize_extra_settings[autoptimize_extra_radio_field_4]" value="1" <?php if ( ! in_array( $gfonts, array( 2, 3, 4, 5 ) ) ) { echo 'checked'; } ?> ><?php _e( 'Leave as is', 'autoptimize' ); ?><br/>
380 - <input type="radio" name="autoptimize_extra_settings[autoptimize_extra_radio_field_4]" value="2" <?php checked( 2, $gfonts, true ); ?> ><?php _e( 'Remove Google Fonts', 'autoptimize' ); ?><br/>
381 - <input type="radio" name="autoptimize_extra_settings[autoptimize_extra_radio_field_4]" value="3" <?php checked( 3, $gfonts, true ); ?> ><?php _e( 'Combine and link in head (fonts load fast but are render-blocking)', 'autoptimize' ); ?><br/>
382 - <input type="radio" name="autoptimize_extra_settings[autoptimize_extra_radio_field_4]" value="5" <?php checked( 5, $gfonts, true ); ?> ><?php _e( 'Combine and preload in head (fonts load late, but are not render-blocking)', 'autoptimize' ); ?><br/>
383 - <input type="radio" name="autoptimize_extra_settings[autoptimize_extra_radio_field_4]" value="4" <?php checked( 4, $gfonts, true ); ?> ><?php _e( 'Combine and load fonts asynchronously with <a href="https://github.com/typekit/webfontloader#readme" target="_blank">webfont.js</a>', 'autoptimize' ); ?><br/>
570 + <input type="radio" name="autoptimize_extra_settings[autoptimize_extra_radio_field_4]" value="1" <?php if ( ! in_array( $gfonts, array( 2, 3, 4, 5 ) ) ) { echo 'checked'; } ?> ><?php esc_html_e( 'Leave as is', 'autoptimize' ); ?><br/>
571 + <input type="radio" name="autoptimize_extra_settings[autoptimize_extra_radio_field_4]" value="2" <?php checked( 2, $gfonts, true ); ?> ><?php esc_html_e( 'Remove Google Fonts', 'autoptimize' ); ?><br/>
572 + <?php // translators: "display:swap" should remain untranslated, will be shown in code tags. ?>
573 + <input type="radio" name="autoptimize_extra_settings[autoptimize_extra_radio_field_4]" value="3" <?php checked( 3, $gfonts, true ); ?> ><?php echo esc_html__( 'Combine and link in head (fonts load fast but are render-blocking)', 'autoptimize' ) . ', ' . sprintf( esc_html__( 'includes %1$sdisplay:swap%2$s.', 'autoptimize' ), '<code>', '</code>' ); ?><br/>
574 + <?php // translators: "display:swap" should remain untranslated, will be shown in code tags. ?>
575 + <input type="radio" name="autoptimize_extra_settings[autoptimize_extra_radio_field_4]" value="5" <?php checked( 5, $gfonts, true ); ?> ><?php echo esc_html__( 'Combine and link deferred in head (fonts load late, but are not render-blocking)', 'autoptimize' ) . ', ' . sprintf( esc_html__( 'includes %1$sdisplay:swap%2$s.', 'autoptimize' ), '<code>', '</code>' ); ?>
576 + <span <?php if ( '4' !== $gfonts ){ echo "style='display:none;' "; } ?> ><br/><input type="radio" name="autoptimize_extra_settings[autoptimize_extra_radio_field_4]" value="4" <?php checked( 4, $gfonts, true ); ?> ><?php echo sprintf( esc_html__( 'Combine and load fonts asynchronously with %1$swebfont.js%2$s', 'autoptimize' ), '<a href="https://github.com/typekit/webfontloader#readme" target="_blank">', '</a>' ) . ' ' . esc_html__( '(deprecated)', 'autoptimize' ); ?></span><br/>
384 577 </td>
385 578 </tr>
386 579 <tr>
387 - <th scope="row"><?php _e( 'Remove emojis', 'autoptimize' ); ?></th>
580 + <th scope="row"><?php esc_html_e( 'Remove emojis', 'autoptimize' ); ?></th>
388 581 <td>
389 - <label><input type='checkbox' name='autoptimize_extra_settings[autoptimize_extra_checkbox_field_1]' <?php if ( ! empty( $options['autoptimize_extra_checkbox_field_1'] ) && '1' === $options['autoptimize_extra_checkbox_field_1'] ) { echo 'checked="checked"'; } ?> value='1'><?php _e( 'Removes WordPress\' core emojis\' inline CSS, inline JavaScript, and an otherwise un-autoptimized JavaScript file.', 'autoptimize' ); ?></label>
582 + <label><input type='checkbox' name='autoptimize_extra_settings[autoptimize_extra_checkbox_field_1]' <?php if ( ! empty( $options['autoptimize_extra_checkbox_field_1'] ) && '1' === $options['autoptimize_extra_checkbox_field_1'] ) { echo 'checked="checked"'; } ?> value='1'><?php esc_html_e( 'Removes WordPress\' core emojis\' inline CSS, inline JavaScript, and an otherwise un-autoptimized JavaScript file.', 'autoptimize' ); ?></label>
390 583 </td>
391 584 </tr>
392 585 <tr>
393 - <th scope="row"><?php _e( 'Remove query strings from static resources', 'autoptimize' ); ?></th>
586 + <th scope="row"><?php esc_html_e( 'Remove query strings from static resources', 'autoptimize' ); ?></th>
394 587 <td>
395 - <label><input type='checkbox' name='autoptimize_extra_settings[autoptimize_extra_checkbox_field_0]' <?php if ( ! empty( $options['autoptimize_extra_checkbox_field_0'] ) && '1' === $options['autoptimize_extra_checkbox_field_0'] ) { echo 'checked="checked"'; } ?> value='1'><?php _e( 'Removing query strings (or more specifically the <code>ver</code> parameter) will not improve load time, but might improve performance scores.', 'autoptimize' ); ?></label>
588 + <label><input type='checkbox' name='autoptimize_extra_settings[autoptimize_extra_checkbox_field_0]' <?php if ( ! empty( $options['autoptimize_extra_checkbox_field_0'] ) && '1' === $options['autoptimize_extra_checkbox_field_0'] ) { echo 'checked="checked"'; } ?> value='1'>
589 + <?php
590 + // translators: just a code tag around "ver" which is the parameter added to CSS/ JS URL's by wordpress.
591 + printf( esc_html__( 'Removing query strings (or more specifically the %1$sver%2$s parameter) will not improve load time, but might improve performance scores.', 'autoptimize' ), '<code>', '</code>' );
592 + ?>
593 + </label>
396 594 </td>
397 595 </tr>
398 596 <tr>
399 - <th scope="row"><?php _e( 'Preconnect to 3rd party domains <em>(advanced users)</em>', 'autoptimize' ); ?></th>
597 + <th scope="row"><?php esc_html_e( 'Remove WordPress block CSS', 'autoptimize' ); ?></th>
400 598 <td>
401 - <label><input type='text' style='width:80%' name='autoptimize_extra_settings[autoptimize_extra_text_field_2]' value='<?php if ( array_key_exists( 'autoptimize_extra_text_field_2', $options ) ) { echo esc_attr( $options['autoptimize_extra_text_field_2'] ); } ?>'><br /><?php _e( 'Add 3rd party domains you want the browser to <a href="https://www.keycdn.com/support/preconnect/#primary" target="_blank">preconnect</a> to, separated by comma\'s. Make sure to include the correct protocol (HTTP or HTTPS).', 'autoptimize' ); ?></label>
599 + <label><input type='checkbox' name='autoptimize_extra_settings[autoptimize_extra_checkbox_field_8]' <?php if ( ! empty( $options['autoptimize_extra_checkbox_field_8'] ) && '1' === $options['autoptimize_extra_checkbox_field_8'] ) { echo 'checked="checked"'; } ?> value='1'><?php esc_html_e( 'WordPress adds block CSS and global styles to improve easy styling of block-based sites, but which can add a significant amount of CSS and SVG. If you are sure your site can do without the block CSS and "global styles", you can disable them here.', 'autoptimize' ); ?></label>
402 600 </td>
403 601 </tr>
404 602 <tr>
405 - <th scope="row"><?php _e( 'Async Javascript-files <em>(advanced users)</em>', 'autoptimize' ); ?></th>
603 + <th scope="row"><?php esc_html_e( 'Preconnect to 3rd party domains (advanced users)', 'autoptimize' ); ?></th>
406 604 <td>
605 + <label><input type='text' style='width:80%' name='autoptimize_extra_settings[autoptimize_extra_text_field_2]' value='<?php if ( array_key_exists( 'autoptimize_extra_text_field_2', $options ) ) { echo esc_attr( $options['autoptimize_extra_text_field_2'] ); } ?>'><br />
407 606 <?php
607 + // Translators; link to a page on keycdn blog about preconnecting.
608 + printf( esc_html__( 'Add 3rd party domains you want the browser to %1$spreconnect%2$s to, separated by comma\'s. Make sure to include the correct protocol (HTTP or HTTPS).', 'autoptimize' ), '<a href="https://www.keycdn.com/support/preconnect/#primary" target="_blank">', '</a>' );
609 + ?>
610 + </label>
611 + </td>
612 + </tr>
613 + <tr>
614 + <th scope="row"><?php esc_html_e( 'Preload specific requests (advanced users)', 'autoptimize' ); ?></th>
615 + <td>
616 + <label><input type='text' style='width:80%' name='autoptimize_extra_settings[autoptimize_extra_text_field_7]' value='<?php if ( array_key_exists( 'autoptimize_extra_text_field_7', $options ) ) { echo esc_attr( $options['autoptimize_extra_text_field_7'] ); } ?>'><br /><?php esc_html_e( 'Comma-separated list with full URL\'s of to to-be-preloaded resources. To be used sparingly!', 'autoptimize' ); ?></label>
617 + </td>
618 + </tr>
619 + <tr>
620 + <th scope="row"><?php esc_html_e( 'Async Javascript-files (advanced users)', 'autoptimize' ); ?></th>
621 + <td>
622 + <?php
408 623 if ( autoptimizeUtils::is_plugin_active( 'async-javascript/async-javascript.php' ) ) {
409 624 // translators: link points Async Javascript settings page.
410 - printf( __( 'You have "Async JavaScript" installed, %1$sconfiguration of async javascript is best done there%2$s.', 'autoptimize' ), '<a href="' . 'options-general.php?page=async-javascript' . '">', '</a>' );
625 + printf( esc_html__( 'You have "Async JavaScript" installed, %1$sconfiguration of async javascript is best done there%2$s.', 'autoptimize' ), '<a href="' . 'options-general.php?page=async-javascript' . '">', '</a>' );
411 626 } else {
412 - ?>
627 + ?>
413 628 <input type='text' style='width:80%' name='autoptimize_extra_settings[autoptimize_extra_text_field_3]' value='<?php if ( array_key_exists( 'autoptimize_extra_text_field_3', $options ) ) { echo esc_attr( $options['autoptimize_extra_text_field_3'] ); } ?>'>
414 629 <br />
415 630 <?php
416 - _e( 'Comma-separated list of local or 3rd party JS-files that should loaded with the <code>async</code> flag. JS-files from your own site will be automatically excluded if added here. ', 'autoptimize' );
631 + printf( esc_html__( 'Comma-separated list of local or 3rd party JS-files that should loaded with the %1$sasync%2$s flag. JS-files from your own site will be automatically excluded if added here. ', 'autoptimize' ), '<code>', '</code>' );
417 632 // translators: %s will be replaced by a link to the "async javascript" plugin.
418 - echo sprintf( __( 'Configuration of async javascript is easier and more flexible using the %s plugin.', 'autoptimize' ), '"<a href="https://wordpress.org/plugins/async-javascript" target="_blank">Async Javascript</a>"' );
633 + echo sprintf( esc_html__( 'Configuration of async javascript is easier and more flexible using the %s plugin.', 'autoptimize' ), '"<a href="https://wordpress.org/plugins/async-javascript" target="_blank">Async Javascript</a>"' );
419 634 $asj_install_url = network_admin_url() . 'plugin-install.php?s=async+javascript&tab=search&type=term';
420 - echo sprintf( ' <a href="' . $asj_install_url . '">%s</a>', __( 'Click here to install and activate it.', 'autoptimize' ) );
635 + echo sprintf( ' <a href="' . $asj_install_url . '">%s</a>', esc_html__( 'Click here to install and activate it.', 'autoptimize' ) );
421 636 }
422 637 ?>
423 638 </td>
424 639 </tr>
425 640 <tr>
426 - <th scope="row"><?php _e( 'Optimize YouTube videos', 'autoptimize' ); ?></th>
641 + <th scope="row"><?php esc_html_e( 'Optimize YouTube videos', 'autoptimize' ); ?></th>
427 642 <td>
428 643 <?php
429 644 if ( autoptimizeUtils::is_plugin_active( 'wp-youtube-lyte/wp-youtube-lyte.php' ) ) {
430 - _e( 'Great, you have WP YouTube Lyte installed.', 'autoptimize' );
645 + esc_html_e( 'Great, you have WP YouTube Lyte installed.', 'autoptimize' );
431 646 $lyte_config_url = 'options-general.php?page=lyte_settings_page';
432 - echo sprintf( ' <a href="' . $lyte_config_url . '">%s</a>', __( 'Click here to configure it.', 'autoptimize' ) );
647 + echo sprintf( ' <a href="' . $lyte_config_url . '">%s</a>', esc_html__( 'Click here to configure it.', 'autoptimize' ) );
433 648 } else {
434 649 // translators: %s will be replaced by a link to "wp youtube lyte" plugin.
435 - echo sprintf( __( '%s allows you to “lazy load” your videos, by inserting responsive “Lite YouTube Embeds". ', 'autoptimize' ), '<a href="https://wordpress.org/plugins/wp-youtube-lyte" target="_blank">WP YouTube Lyte</a>' );
650 + echo sprintf( esc_html__( '%s allows you to “lazy load” your videos, by inserting responsive “Lite YouTube Embeds". ', 'autoptimize' ), '<a href="https://wordpress.org/plugins/wp-youtube-lyte" target="_blank">WP YouTube Lyte</a>' );
436 651 $lyte_install_url = network_admin_url() . 'plugin-install.php?s=lyte&tab=search&type=term';
437 - echo sprintf( ' <a href="' . $lyte_install_url . '">%s</a>', __( 'Click here to install and activate it.', 'autoptimize' ) );
652 + echo sprintf( ' <a href="' . $lyte_install_url . '">%s</a>', esc_html__( 'Click here to install and activate it.', 'autoptimize' ) );
438 653 }
439 654 ?>
440 655 </td>
441 656 </tr>
442 657 </table>
443 - <p class="submit"><input type="submit" name="submit" id="submit" class="button button-primary" value="<?php _e( 'Save Changes', 'autoptimize' ); ?>" /></p>
658 + <p class="submit"><input type="submit" name="submit" id="submit" class="button button-primary" value="<?php esc_html_e( 'Save Changes', 'autoptimize' ); ?>" /></p>
444 659 </form>
445 660 <?php
446 661 }
447 662 }