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 +286 -69 2.5.0 → 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 {
@@ -154,12 +213,23 @@
154 213 }
155 214
156 215 public function filter_remove_dns_prefetch( $urls, $relation_type, $url_to_remove )
157 216 {
158 - if ( 'dns-prefetch' === $relation_type ) {
217 + $url_to_remove = (string) $url_to_remove;
218 +
219 + if ( ! empty( $url_to_remove ) && 'dns-prefetch' === $relation_type ) {
159 220 $cnt = 0;
160 221 foreach ( $urls as $url ) {
161 - 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 ) ) {
162 232 unset( $urls[ $cnt ] );
163 233 }
164 234 $cnt++;
165 235 }
@@ -184,8 +254,14 @@
184 254 foreach ( $matches[2] as $font ) {
185 255 if ( ! preg_match( '/rel=["\']dns-prefetch["\']/', $matches[0][ $i ] ) ) {
186 256 // Get fonts name.
187 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 + }
188 264 $font = explode( 'family=', $font );
189 265 $font = ( isset( $font[1] ) ) ? explode( '&', $font[1] ) : array();
190 266 // Add font to $fonts[$i] but make sure not to pollute with an empty family!
191 267 $_thisfont = array_values( array_filter( explode( '|', reset( $font ) ) ) );
@@ -226,17 +302,21 @@
226 302 $subset_string = str_replace( ',', '%2C', ltrim( $subset_string, ',' ) );
227 303 $fonts_string = $fonts_string . '&subset=' . $subset_string;
228 304 }
229 305
230 - $fonts_string = str_replace( '|', '%7C', ltrim( $fonts_string, '|' ) );
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 + }
231 311
232 312 if ( ! empty( $fonts_string ) ) {
233 313 if ( '5' === $options['autoptimize_extra_radio_field_4'] ) {
234 - $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() . '"';
235 315 } else {
236 316 $rel_string = 'rel="stylesheet"';
237 317 }
238 - $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 . '">';
239 319 }
240 320 } elseif ( '4' === $options['autoptimize_extra_radio_field_4'] ) {
241 321 // Aggregate & load async (webfont.js impl.)!
242 322 $fonts_array = array();
@@ -250,11 +330,24 @@
250 330 }
251 331 $fonts_array = array_merge( $fonts_array, $_fonts['fonts'] );
252 332 }
253 333
254 - $fonts_array = array_map( 'urldecode', $fonts_array );
255 - $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>';
256 - $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>';
257 350 $in = substr_replace( $in, $fonts_library_markup . '</head>', strpos( $in, '</head>' ), strlen( '</head>' ) );
258 351 }
259 352
260 353 // Replace back in markup.
@@ -261,30 +354,29 @@
261 354 $inject_point = apply_filters( 'autoptimize_filter_extra_gfont_injectpoint', '<link' );
262 355 $out = substr_replace( $in, $fonts_markup . $inject_point, strpos( $in, $inject_point ), strlen( $inject_point ) );
263 356 unset( $fonts_collection );
264 357
265 - // and insert preload polyfill if "link preload" and if the polyfill isn't there yet (courtesy of inline&defer).
266 - $preload_polyfill = autoptimizeConfig::get_ao_css_preload_polyfill();
267 - if ( '5' === $options['autoptimize_extra_radio_field_4'] && strpos( $out, $preload_polyfill ) === false ) {
268 - $out = str_replace( '</body>', $preload_polyfill . '</body>', $out );
269 - }
270 358 return $out;
271 359 }
272 360
273 361 public function filter_preconnect( $hints, $relation_type )
274 362 {
275 - $options = $this->options;
363 + $options = $this->options;
364 + $preconns = array();
276 365
277 366 // Get settings and store in array.
278 - $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 + }
279 370 $preconns = apply_filters( 'autoptimize_extra_filter_tobepreconn', $preconns );
280 371
281 372 // Walk array, extract domain and add to new array with crossorigin attribute.
282 373 foreach ( $preconns as $preconn ) {
374 + $domain = '';
283 375 $parsed = parse_url( $preconn );
284 - if ( is_array( $parsed ) && empty( $parsed['scheme'] ) ) {
376 + if ( is_array( $parsed ) && ! empty( $parsed['host'] ) && empty( $parsed['scheme'] ) ) {
285 377 $domain = '//' . $parsed['host'];
286 - } elseif ( is_array( $parsed ) ) {
378 + } elseif ( is_array( $parsed ) && ! empty( $parsed['host'] ) ) {
287 379 $domain = $parsed['scheme'] . '://' . $parsed['host'];
288 380 }
289 381
290 382 if ( ! empty( $domain ) ) {
@@ -322,24 +414,122 @@
322 414
323 415 return $in;
324 416 }
325 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 +
326 511 public function admin_menu()
327 512 {
328 - add_submenu_page(
329 - null,
330 - 'autoptimize_extra',
331 - 'autoptimize_extra',
332 - 'manage_options',
333 - 'autoptimize_extra',
334 - array( $this, 'options_page' )
335 - );
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 + }
336 524 register_setting( 'autoptimize_extra_settings', 'autoptimize_extra_settings' );
337 525 }
338 526
339 527 public function add_extra_tab( $in )
340 528 {
341 - $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 + }
342 532
343 533 return $in;
344 534 }
345 535
@@ -344,8 +534,10 @@
344 534 }
345 535
346 536 public function options_page()
347 537 {
538 + // phpcs:disable Squiz.ControlStructures.ControlSignature.NewlineAfterOpenBrace
539 +
348 540 // Working with actual option values from the database here.
349 541 // That way any saves are still processed as expected, but we can still
350 542 // override behavior by using `new autoptimizeExtra($custom_options)` and not have that custom
351 543 // behavior being persisted in the DB even if save is done here.
@@ -356,90 +548,115 @@
356 548 #ao_settings_form {background: white;border: 1px solid #ccc;padding: 1px 15px;margin: 15px 10px 10px 0;}
357 549 #ao_settings_form .form-table th {font-weight: normal;}
358 550 #autoptimize_extra_descr{font-size: 120%;}
359 551 </style>
552 + <script>document.title = "Autoptimize: <?php esc_html_e( 'Extra', 'autoptimize' ); ?> " + document.title;</script>
360 553 <div class="wrap">
361 - <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>
362 555 <?php echo autoptimizeConfig::ao_admin_tabs(); ?>
363 - <?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() ) { ?>
364 557 <div class="notice-warning notice"><p>
365 - <?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' ); ?>
366 559 </p></div>
367 560 <?php } ?>
368 561
369 - <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'>
370 563 <?php settings_fields( 'autoptimize_extra_settings' ); ?>
371 - <h2><?php _e( 'Extra Auto-Optimizations', 'autoptimize' ); ?></h2>
372 - <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>
373 566 <table class="form-table">
374 567 <tr>
375 - <th scope="row"><?php _e( 'Google Fonts', 'autoptimize' ); ?></th>
568 + <th scope="row"><?php esc_html_e( 'Google Fonts', 'autoptimize' ); ?></th>
376 569 <td>
377 - <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/>
378 - <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/>
379 - <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/>
380 - <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/>
381 - <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/>
382 577 </td>
383 578 </tr>
384 579 <tr>
385 - <th scope="row"><?php _e( 'Remove emojis', 'autoptimize' ); ?></th>
580 + <th scope="row"><?php esc_html_e( 'Remove emojis', 'autoptimize' ); ?></th>
386 581 <td>
387 - <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>
388 583 </td>
389 584 </tr>
390 585 <tr>
391 - <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>
392 587 <td>
393 - <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>
394 594 </td>
395 595 </tr>
396 596 <tr>
397 - <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>
398 598 <td>
399 - <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>
400 600 </td>
401 601 </tr>
402 602 <tr>
403 - <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>
404 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 />
405 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
406 623 if ( autoptimizeUtils::is_plugin_active( 'async-javascript/async-javascript.php' ) ) {
407 624 // translators: link points Async Javascript settings page.
408 - 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>' );
409 626 } else {
410 - ?>
627 + ?>
411 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'] ); } ?>'>
412 629 <br />
413 630 <?php
414 - _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>' );
415 632 // translators: %s will be replaced by a link to the "async javascript" plugin.
416 - 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>"' );
417 634 $asj_install_url = network_admin_url() . 'plugin-install.php?s=async+javascript&tab=search&type=term';
418 - 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' ) );
419 636 }
420 637 ?>
421 638 </td>
422 639 </tr>
423 640 <tr>
424 - <th scope="row"><?php _e( 'Optimize YouTube videos', 'autoptimize' ); ?></th>
641 + <th scope="row"><?php esc_html_e( 'Optimize YouTube videos', 'autoptimize' ); ?></th>
425 642 <td>
426 643 <?php
427 644 if ( autoptimizeUtils::is_plugin_active( 'wp-youtube-lyte/wp-youtube-lyte.php' ) ) {
428 - _e( 'Great, you have WP YouTube Lyte installed.', 'autoptimize' );
645 + esc_html_e( 'Great, you have WP YouTube Lyte installed.', 'autoptimize' );
429 646 $lyte_config_url = 'options-general.php?page=lyte_settings_page';
430 - 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' ) );
431 648 } else {
432 649 // translators: %s will be replaced by a link to "wp youtube lyte" plugin.
433 - 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>' );
434 651 $lyte_install_url = network_admin_url() . 'plugin-install.php?s=lyte&tab=search&type=term';
435 - 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' ) );
436 653 }
437 654 ?>
438 655 </td>
439 656 </tr>
440 657 </table>
441 - <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>
442 659 </form>
443 660 <?php
444 661 }
445 662 }