EWWW Image Optimizer - Version 6.6.0

Version Description

  • added: AVIF support via Easy IO, enable on site management at ewww.io
  • added: sharpening setting to improve WP resizing via ImageMagick and WebP conversion
  • added: AVIF quality setting on Advanced tab
  • added: ability for Easy IO to get full-size path when using offloaded media
  • changed: JPG quality and WebP quality moved to Advanced tab
  • changed: allow .htaccess rules on Cloudways with notice about WebP Redirection toggle
  • fixed: front-end HTML parsers running within Bricks editor
  • fixed: Easy IO not finding scaled full-size for dynamic size generation
  • fixed: cover images not cropped properly by Easy IO
  • fixed: Easy IO URLs leaking into post editor with WP 6.0
Download this release

Release Info

Developer nosilver4u
Plugin Icon 128x128 EWWW Image Optimizer
Version 6.6.0
Comparing to
See all releases

Code changes from version 6.5.2 to 6.6.0

bulk.php CHANGED
@@ -193,6 +193,7 @@ function ewww_image_optimizer_tool_script( $hook ) {
193
  if ( 'tools_page_ewww-image-optimizer-tools' !== $hook ) {
194
  return;
195
  }
 
196
  wp_enqueue_script( 'ewww-tool-script', plugins_url( '/includes/eio-tools.js', __FILE__ ), array( 'jquery', 'jquery-ui-progressbar' ), EWWW_IMAGE_OPTIMIZER_VERSION, true );
197
  // Number of images in the ewwwio_table (previously optimized images).
198
  $image_count = ewww_image_optimizer_aux_images_table_count();
@@ -668,6 +669,7 @@ function ewww_image_optimizer_bulk_script( $hook ) {
668
  if ( 'media_page_ewww-image-optimizer-bulk' !== $hook ) {
669
  return;
670
  }
 
671
  global $wpdb;
672
  global $ewww_force;
673
  global $ewww_webp_only;
193
  if ( 'tools_page_ewww-image-optimizer-tools' !== $hook ) {
194
  return;
195
  }
196
+ add_filter( 'admin_footer_text', 'ewww_image_optimizer_footer_review_text' );
197
  wp_enqueue_script( 'ewww-tool-script', plugins_url( '/includes/eio-tools.js', __FILE__ ), array( 'jquery', 'jquery-ui-progressbar' ), EWWW_IMAGE_OPTIMIZER_VERSION, true );
198
  // Number of images in the ewwwio_table (previously optimized images).
199
  $image_count = ewww_image_optimizer_aux_images_table_count();
669
  if ( 'media_page_ewww-image-optimizer-bulk' !== $hook ) {
670
  return;
671
  }
672
+ add_filter( 'admin_footer_text', 'ewww_image_optimizer_footer_review_text' );
673
  global $wpdb;
674
  global $ewww_force;
675
  global $ewww_webp_only;
changelog.txt CHANGED
@@ -1,3 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
  = 6.5.2 =
2
  * added: automatic optimization for Crop Thumbnails plugin
3
  * added: filters to adjust sharpening parameters for core WP (ImageMagick) image resizing
1
+ = 6.6.0 =
2
+ * added: AVIF support via Easy IO, enable on site management at ewww.io
3
+ * added: sharpening setting to improve WP resizing via ImageMagick and WebP conversion
4
+ * added: AVIF quality setting on Advanced tab
5
+ * added: ability for Easy IO to get full-size path when using offloaded media
6
+ * changed: JPG quality and WebP quality moved to Advanced tab
7
+ * changed: allow .htaccess rules on Cloudways with notice about WebP Redirection toggle
8
+ * fixed: front-end HTML parsers running within Bricks editor
9
+ * fixed: Easy IO not finding scaled full-size for dynamic size generation
10
+ * fixed: cover images not cropped properly by Easy IO
11
+ * fixed: Easy IO URLs leaking into post editor with WP 6.0
12
+
13
  = 6.5.2 =
14
  * added: automatic optimization for Crop Thumbnails plugin
15
  * added: filters to adjust sharpening parameters for core WP (ImageMagick) image resizing
classes/class-eio-js-webp.php CHANGED
@@ -166,6 +166,9 @@ class EIO_JS_Webp extends EIO_Page_Parser {
166
  if ( empty( $uri ) ) {
167
  $uri = $this->request_uri;
168
  }
 
 
 
169
  if ( false !== strpos( $uri, '?brizy-edit' ) ) {
170
  return false;
171
  }
@@ -383,7 +386,7 @@ class EIO_JS_Webp extends EIO_Page_Parser {
383
  }
384
 
385
  $body_tags = $this->get_elements_from_html( $buffer, 'body' );
386
- $body_webp_script = '<script data-cfasync="false">if(ewww_webp_supported){document.body.classList.add("webp-support");}</script>';
387
  if ( $this->is_iterable( $body_tags ) && ! empty( $body_tags[0] ) && false !== strpos( $body_tags[0], '<body' ) ) {
388
  // Add the WebP script right after the opening tag.
389
  $buffer = str_replace( $body_tags[0], $body_tags[0] . "\n" . $body_webp_script, $buffer );
@@ -1103,7 +1106,7 @@ class EIO_JS_Webp extends EIO_Page_Parser {
1103
  return;
1104
  }
1105
  $this->debug_message( 'inlining check webp script' );
1106
- echo '<script data-cfasync="false" type="text/javascript">' . $this->check_webp_script . '</script>'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
1107
  }
1108
 
1109
  /**
@@ -1120,7 +1123,7 @@ class EIO_JS_Webp extends EIO_Page_Parser {
1120
  return;
1121
  }
1122
  $this->debug_message( 'inlining load webp script' );
1123
- echo '<script data-cfasync="false" type="text/javascript">' . $this->load_webp_script . '</script>'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
1124
  }
1125
  }
1126
 
166
  if ( empty( $uri ) ) {
167
  $uri = $this->request_uri;
168
  }
169
+ if ( false !== strpos( $uri, 'bricks=run' ) ) {
170
+ return false;
171
+ }
172
  if ( false !== strpos( $uri, '?brizy-edit' ) ) {
173
  return false;
174
  }
386
  }
387
 
388
  $body_tags = $this->get_elements_from_html( $buffer, 'body' );
389
+ $body_webp_script = '<script data-cfasync="false" data-no-defer="1">if(ewww_webp_supported){document.body.classList.add("webp-support");}</script>';
390
  if ( $this->is_iterable( $body_tags ) && ! empty( $body_tags[0] ) && false !== strpos( $body_tags[0], '<body' ) ) {
391
  // Add the WebP script right after the opening tag.
392
  $buffer = str_replace( $body_tags[0], $body_tags[0] . "\n" . $body_webp_script, $buffer );
1106
  return;
1107
  }
1108
  $this->debug_message( 'inlining check webp script' );
1109
+ echo '<script data-cfasync="false" data-no-defer="1">' . $this->check_webp_script . '</script>'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
1110
  }
1111
 
1112
  /**
1123
  return;
1124
  }
1125
  $this->debug_message( 'inlining load webp script' );
1126
+ echo '<script data-cfasync="false" data-no-defer="1">' . $this->load_webp_script . '</script>'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
1127
  }
1128
  }
1129
 
classes/class-eio-lazy-load.php CHANGED
@@ -199,6 +199,9 @@ if ( ! class_exists( 'EIO_Lazy_Load' ) ) {
199
  if ( empty( $uri ) ) {
200
  $uri = $this->request_uri;
201
  }
 
 
 
202
  if ( false !== strpos( $uri, '?brizy-edit' ) ) {
203
  return false;
204
  }
@@ -326,7 +329,7 @@ if ( ! class_exists( 'EIO_Lazy_Load' ) ) {
326
  // If JS WebP isn't running, set ewww_webp_supported to false so we have something defined.
327
  if ( ! class_exists( 'EIO_JS_Webp' ) ) {
328
  $body_tags = $this->get_elements_from_html( $buffer, 'body' );
329
- $body_webp_script = '<script data-cfasync="false">var ewww_webp_supported=false;</script>';
330
  if ( $this->is_iterable( $body_tags ) && ! empty( $body_tags[0] ) && false !== strpos( $body_tags[0], '<body' ) ) {
331
  // Add the WebP script right after the opening tag.
332
  $buffer = str_replace( $body_tags[0], $body_tags[0] . "\n" . $body_webp_script, $buffer );
@@ -1316,12 +1319,12 @@ if ( ! class_exists( 'EIO_Lazy_Load' ) ) {
1316
  . ';';
1317
 
1318
  $lazysizes_script .= file_get_contents( $lazysizes_file );
1319
- echo '<script data-cfasync="false" type="text/javascript" id="eio-lazy-load">' . $lazysizes_script . '</script>'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
1320
  if ( defined( strtoupper( $this->prefix ) . 'LAZY_PRINT' ) && constant( strtoupper( $this->prefix ) . 'LAZY_PRINT' ) ) {
1321
  $lsprint_file = constant( strtoupper( $this->prefix ) . 'PLUGIN_PATH' ) . 'includes/ls.print.min.js';
1322
  if ( $this->is_file( $lsprint_file ) ) {
1323
  $lsprint_script = file_get_contents( $lsprint_file );
1324
- echo '<script data-cfasync="false" id="eio-lazy-load-print">' . $lsprint_script . '</script>'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
1325
  }
1326
  }
1327
  }
199
  if ( empty( $uri ) ) {
200
  $uri = $this->request_uri;
201
  }
202
+ if ( false !== strpos( $uri, 'bricks=run' ) ) {
203
+ return false;
204
+ }
205
  if ( false !== strpos( $uri, '?brizy-edit' ) ) {
206
  return false;
207
  }
329
  // If JS WebP isn't running, set ewww_webp_supported to false so we have something defined.
330
  if ( ! class_exists( 'EIO_JS_Webp' ) ) {
331
  $body_tags = $this->get_elements_from_html( $buffer, 'body' );
332
+ $body_webp_script = '<script data-cfasync="false" data-no-defer="1">var ewww_webp_supported=false;</script>';
333
  if ( $this->is_iterable( $body_tags ) && ! empty( $body_tags[0] ) && false !== strpos( $body_tags[0], '<body' ) ) {
334
  // Add the WebP script right after the opening tag.
335
  $buffer = str_replace( $body_tags[0], $body_tags[0] . "\n" . $body_webp_script, $buffer );
1319
  . ';';
1320
 
1321
  $lazysizes_script .= file_get_contents( $lazysizes_file );
1322
+ echo '<script data-cfasync="false" data-no-defer="1" id="eio-lazy-load">' . $lazysizes_script . '</script>'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
1323
  if ( defined( strtoupper( $this->prefix ) . 'LAZY_PRINT' ) && constant( strtoupper( $this->prefix ) . 'LAZY_PRINT' ) ) {
1324
  $lsprint_file = constant( strtoupper( $this->prefix ) . 'PLUGIN_PATH' ) . 'includes/ls.print.min.js';
1325
  if ( $this->is_file( $lsprint_file ) ) {
1326
  $lsprint_script = file_get_contents( $lsprint_file );
1327
+ echo '<script data-cfasync="false" data-no-defer="1" id="eio-lazy-load-print">' . $lsprint_script . '</script>'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
1328
  }
1329
  }
1330
  }
classes/class-eio-picture-webp.php CHANGED
@@ -124,6 +124,9 @@ class EIO_Picture_Webp extends EIO_Page_Parser {
124
  if ( empty( $uri ) ) {
125
  $uri = $this->request_uri;
126
  }
 
 
 
127
  if ( false !== strpos( $uri, '?brizy-edit' ) ) {
128
  return false;
129
  }
124
  if ( empty( $uri ) ) {
125
  $uri = $this->request_uri;
126
  }
127
+ if ( false !== strpos( $uri, 'bricks=run' ) ) {
128
+ return false;
129
+ }
130
  if ( false !== strpos( $uri, '?brizy-edit' ) ) {
131
  return false;
132
  }
classes/class-exactdn.php CHANGED
@@ -1866,6 +1866,9 @@ if ( ! class_exists( 'ExactDN' ) ) {
1866
  if ( ! empty( $_POST['action'] ) && 'filter_listing' === $_POST['action'] && ! empty( $_POST['layout'] ) && ! empty( $_POST['paged'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification
1867
  return true;
1868
  }
 
 
 
1869
  if ( ! empty( $_POST['action'] ) && 'mabel-rpn-getnew-purchased-products' === $_POST['action'] ) { // phpcs:ignore WordPress.Security.NonceVerification
1870
  return true;
1871
  }
@@ -2682,6 +2685,12 @@ if ( ! class_exists( 'ExactDN' ) ) {
2682
  add_filter( 'exactdn_override_image_downsize', '__return_true', PHP_INT_MAX );
2683
  add_filter( 'exactdn_skip_image', '__return_true', PHP_INT_MAX ); // This skips existing srcset indices.
2684
  add_filter( 'exactdn_srcset_multipliers', '__return_false', PHP_INT_MAX ); // This one skips the additional multipliers.
 
 
 
 
 
 
2685
  } elseif ( is_string( $route ) && false !== strpos( $route, 'wp/v2/media' ) && ! empty( $request['post'] ) && ! empty( $request->get_file_params() ) ) {
2686
  $this->debug_message( 'REST API media endpoint (new upload)' );
2687
  // We don't want ExactDN urls anywhere near the editor, so disable everything we can.
@@ -2832,15 +2841,28 @@ if ( ! class_exists( 'ExactDN' ) ) {
2832
  // Build URL, first removing WP's resized string so we pass the original image to ExactDN.
2833
  if ( preg_match( '#(-\d+x\d+)\.(' . implode( '|', $this->extensions ) . '){1}(?:\?.+)?$#i', $src, $src_parts ) ) {
2834
  $stripped_src = str_replace( $src_parts[1], '', $src );
2835
- $upload_dir = wp_get_upload_dir();
2836
 
2837
- // Extracts the file path to the image minus the base url.
2838
- $file_path = substr( $stripped_src, strlen( $upload_dir['baseurl'] ) );
 
 
 
 
 
 
 
 
 
2839
 
2840
- if ( is_file( $upload_dir['basedir'] . $file_path ) ) {
2841
- $src = $stripped_src;
 
 
 
 
 
2842
  }
2843
- $this->debug_message( 'stripped dims' );
2844
  }
2845
  return $src;
2846
  }
@@ -3099,6 +3121,9 @@ if ( ! class_exists( 'ExactDN' ) ) {
3099
  * @return boolean True to skip the page, unchanged otherwise.
3100
  */
3101
  function skip_page( $skip = false, $uri = '' ) {
 
 
 
3102
  if ( false !== strpos( $uri, '?brizy-edit' ) ) {
3103
  return true;
3104
  }
@@ -3346,7 +3371,10 @@ if ( ! class_exists( 'ExactDN' ) ) {
3346
  }
3347
  if ( defined( 'EIO_WEBP_SHARP_YUV' ) && EIO_WEBP_SHARP_YUV ) {
3348
  $more_args['sharp'] = 1;
 
 
3349
  }
 
3350
  // Merge given args with the automatic (option-based) args, and also makes sure args is an array if it was previously a string.
3351
  $args = wp_parse_args( $args, $more_args );
3352
 
1866
  if ( ! empty( $_POST['action'] ) && 'filter_listing' === $_POST['action'] && ! empty( $_POST['layout'] ) && ! empty( $_POST['paged'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification
1867
  return true;
1868
  }
1869
+ if ( ! empty( $_POST['action'] ) && 'load_more_posts' === $_POST['action'] ) { // phpcs:ignore WordPress.Security.NonceVerification
1870
+ return true;
1871
+ }
1872
  if ( ! empty( $_POST['action'] ) && 'mabel-rpn-getnew-purchased-products' === $_POST['action'] ) { // phpcs:ignore WordPress.Security.NonceVerification
1873
  return true;
1874
  }
2685
  add_filter( 'exactdn_override_image_downsize', '__return_true', PHP_INT_MAX );
2686
  add_filter( 'exactdn_skip_image', '__return_true', PHP_INT_MAX ); // This skips existing srcset indices.
2687
  add_filter( 'exactdn_srcset_multipliers', '__return_false', PHP_INT_MAX ); // This one skips the additional multipliers.
2688
+ } elseif ( is_string( $route ) && false !== strpos( $route, 'wp/v2/media/' ) && ! empty( $request['context'] ) && 'view' === $request['context'] ) {
2689
+ $this->debug_message( 'REST API media endpoint (could be post editor with WP >= 6.0)' );
2690
+ // We don't want ExactDN urls anywhere near the editor, so disable everything we can.
2691
+ add_filter( 'exactdn_override_image_downsize', '__return_true', PHP_INT_MAX );
2692
+ add_filter( 'exactdn_skip_image', '__return_true', PHP_INT_MAX ); // This skips existing srcset indices.
2693
+ add_filter( 'exactdn_srcset_multipliers', '__return_false', PHP_INT_MAX ); // This one skips the additional multipliers.
2694
  } elseif ( is_string( $route ) && false !== strpos( $route, 'wp/v2/media' ) && ! empty( $request['post'] ) && ! empty( $request->get_file_params() ) ) {
2695
  $this->debug_message( 'REST API media endpoint (new upload)' );
2696
  // We don't want ExactDN urls anywhere near the editor, so disable everything we can.
2841
  // Build URL, first removing WP's resized string so we pass the original image to ExactDN.
2842
  if ( preg_match( '#(-\d+x\d+)\.(' . implode( '|', $this->extensions ) . '){1}(?:\?.+)?$#i', $src, $src_parts ) ) {
2843
  $stripped_src = str_replace( $src_parts[1], '', $src );
2844
+ $scaled_src = str_replace( $src_parts[1], '-scaled', $src );
2845
 
2846
+ $file = false;
2847
+ if ( $this->allowed_urls && $this->allowed_domains ) {
2848
+ $file = $this->cdn_to_local( $src );
2849
+ }
2850
+ if ( ! $file ) {
2851
+ $file = $this->url_to_path_exists( $src );
2852
+ }
2853
+ if ( $file ) {
2854
+ // Extracts the file path to the image minus the base url.
2855
+ $file_path = str_replace( $src_parts[1], '', $file );
2856
+ $scaled_path = str_replace( $src_parts[1], '-scaled', $file );
2857
 
2858
+ if ( $this->is_file( $file_path ) ) {
2859
+ $src = $stripped_src;
2860
+ $this->debug_message( 'stripped dims to original' );
2861
+ } elseif ( $this->is_file( $scaled_path ) ) {
2862
+ $src = $scaled_src;
2863
+ $this->debug_message( 'stripped dims to scaled' );
2864
+ }
2865
  }
 
2866
  }
2867
  return $src;
2868
  }
3121
  * @return boolean True to skip the page, unchanged otherwise.
3122
  */
3123
  function skip_page( $skip = false, $uri = '' ) {
3124
+ if ( false !== strpos( $uri, 'bricks=run' ) ) {
3125
+ return true;
3126
+ }
3127
  if ( false !== strpos( $uri, '?brizy-edit' ) ) {
3128
  return true;
3129
  }
3371
  }
3372
  if ( defined( 'EIO_WEBP_SHARP_YUV' ) && EIO_WEBP_SHARP_YUV ) {
3373
  $more_args['sharp'] = 1;
3374
+ } elseif ( $this->get_option( $this->prefix . 'sharpen' ) ) {
3375
+ $more_args['sharp'] = 1;
3376
  }
3377
+
3378
  // Merge given args with the automatic (option-based) args, and also makes sure args is an array if it was previously a string.
3379
  $args = wp_parse_args( $args, $more_args );
3380
 
common.php CHANGED
@@ -14,7 +14,7 @@ if ( ! defined( 'ABSPATH' ) ) {
14
  exit;
15
  }
16
 
17
- define( 'EWWW_IMAGE_OPTIMIZER_VERSION', '652' );
18
 
19
  // Initialize a couple globals.
20
  $eio_debug = '';
@@ -120,6 +120,8 @@ add_filter( 'load_image_to_edit_path', 'ewww_image_optimizer_editor_save_pre' );
120
  add_filter( 'jpeg_quality', 'ewww_image_optimizer_set_jpg_quality', PHP_INT_MAX - 1 );
121
  // Allows the user to override the default WebP quality used by EWWW IO.
122
  add_filter( 'webp_quality', 'ewww_image_optimizer_set_webp_quality' );
 
 
123
  // Prevent WP from over-riding EWWW IO's resize settings.
124
  add_filter( 'big_image_size_threshold', 'ewww_image_optimizer_adjust_big_image_threshold', 10, 3 );
125
  // Makes sure the plugin bypasses any files affected by the Folders to Ignore setting.
@@ -192,6 +194,8 @@ add_action( 'wp_ajax_ewww_dismiss_lr_sync', 'ewww_image_optimizer_dismiss_lr_syn
192
  add_action( 'wp_ajax_ewww_dismiss_media_notice', 'ewww_image_optimizer_dismiss_media_notice' );
193
  // AJAX action hook to disable the 'review request' notice.
194
  add_action( 'wp_ajax_ewww_dismiss_review_notice', 'ewww_image_optimizer_dismiss_review_notice' );
 
 
195
  // Adds script to highlight mis-sized images on the front-end (for logged in admins only).
196
  add_action( 'wp_head', 'ewww_image_optimizer_resize_detection_script' );
197
  // Adds a button on the admin bar to allow highlighting mis-sized images on-demand.
@@ -682,10 +686,14 @@ function ewww_image_optimizer_save_network_settings() {
682
  update_site_option( 'ewww_image_optimizer_webp', $ewww_image_optimizer_webp );
683
  $ewww_image_optimizer_jpg_background = empty( $_POST['ewww_image_optimizer_jpg_background'] ) ? '' : sanitize_text_field( wp_unslash( $_POST['ewww_image_optimizer_jpg_background'] ) );
684
  update_site_option( 'ewww_image_optimizer_jpg_background', ewww_image_optimizer_jpg_background( $ewww_image_optimizer_jpg_background ) );
 
 
685
  $ewww_image_optimizer_jpg_quality = empty( $_POST['ewww_image_optimizer_jpg_quality'] ) ? '' : (int) $_POST['ewww_image_optimizer_jpg_quality'];
686
  update_site_option( 'ewww_image_optimizer_jpg_quality', ewww_image_optimizer_jpg_quality( $ewww_image_optimizer_jpg_quality ) );
687
  $ewww_image_optimizer_webp_quality = empty( $_POST['ewww_image_optimizer_webp_quality'] ) ? '' : (int) $_POST['ewww_image_optimizer_webp_quality'];
688
  update_site_option( 'ewww_image_optimizer_webp_quality', ewww_image_optimizer_webp_quality( $ewww_image_optimizer_webp_quality ) );
 
 
689
  $ewww_image_optimizer_disable_convert_links = ( empty( $_POST['ewww_image_optimizer_disable_convert_links'] ) ? false : true );
690
  update_site_option( 'ewww_image_optimizer_disable_convert_links', $ewww_image_optimizer_disable_convert_links );
691
  $ewww_image_optimizer_backup_files = ( empty( $_POST['ewww_image_optimizer_backup_files'] ) ? false : true );
@@ -1064,9 +1072,10 @@ function ewww_image_optimizer_admin_init() {
1064
  register_setting( 'ewww_image_optimizer_options', 'ewww_image_optimizer_svg_level', 'intval' );
1065
  register_setting( 'ewww_image_optimizer_options', 'ewww_image_optimizer_backup_files', 'boolval' );
1066
  register_setting( 'ewww_image_optimizer_options', 'ewww_image_optimizer_enable_cloudinary', 'boolval' );
 
1067
  register_setting( 'ewww_image_optimizer_options', 'ewww_image_optimizer_jpg_quality', 'ewww_image_optimizer_jpg_quality' );
1068
  register_setting( 'ewww_image_optimizer_options', 'ewww_image_optimizer_webp_quality', 'ewww_image_optimizer_webp_quality' );
1069
- register_setting( 'ewww_image_optimizer_options', 'ewww_image_optimizer_parallel_optimization', 'boolval' );
1070
  register_setting( 'ewww_image_optimizer_options', 'ewww_image_optimizer_auto', 'boolval' );
1071
  register_setting( 'ewww_image_optimizer_options', 'ewww_image_optimizer_include_media_paths', 'boolval' );
1072
  register_setting( 'ewww_image_optimizer_options', 'ewww_image_optimizer_include_originals', 'boolval' );
@@ -2364,6 +2373,20 @@ function ewww_image_optimizer_notice_review() {
2364
  '</p></div>';
2365
  }
2366
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2367
  /**
2368
  * Loads the inline script to dismiss the review notice.
2369
  */
@@ -2464,6 +2487,9 @@ function ewww_image_optimizer_load_editor( $editors ) {
2464
  if ( class_exists( 'WP_Image_Editor_Gmagick' ) ) {
2465
  require_once( plugin_dir_path( __FILE__ ) . '/classes/class-ewwwio-gmagick-editor.php' );
2466
  }
 
 
 
2467
  }
2468
  if ( ! in_array( 'EWWWIO_GD_Editor', $editors, true ) ) {
2469
  array_unshift( $editors, 'EWWWIO_GD_Editor' );
@@ -2481,6 +2507,81 @@ function ewww_image_optimizer_load_editor( $editors ) {
2481
  return $editors;
2482
  }
2483
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2484
  /**
2485
  * Registers the filter that will remove the image_editor hooks when an attachment is added.
2486
  */
@@ -3360,7 +3461,10 @@ function ewww_image_optimizer_imagick_supports_webp() {
3360
  function ewww_image_optimizer_imagick_create_webp( $file, $type, $webpfile ) {
3361
  ewwwio_debug_message( '<b>' . __FUNCTION__ . '()</b>' );
3362
  $sharp_yuv = defined( 'EIO_WEBP_SHARP_YUV' ) && EIO_WEBP_SHARP_YUV ? true : false;
3363
- $quality = (int) apply_filters( 'webp_quality', 75, 'image/webp' );
 
 
 
3364
  if ( $quality < 50 || $quality > 100 ) {
3365
  $quality = 75;
3366
  }
@@ -3709,7 +3813,7 @@ function ewww_image_optimizer_jpg_background( $background = null ) {
3709
  * Retrieves/sanitizes the jpg quality setting for png2jpg conversion or returns null.
3710
  *
3711
  * @param int $quality The JPG quality level as set by the user.
3712
- * @return int The sanitize JPG quality level.
3713
  */
3714
  function ewww_image_optimizer_jpg_quality( $quality = null ) {
3715
  ewwwio_debug_message( '<b>' . __FUNCTION__ . '()</b>' );
@@ -3751,12 +3855,12 @@ function ewww_image_optimizer_set_jpg_quality( $quality ) {
3751
  * Retrieves/sanitizes the WebP quality setting or returns null.
3752
  *
3753
  * @param int $quality The WebP quality level as set by the user.
3754
- * @return int The sanitize WebP quality level.
3755
  */
3756
  function ewww_image_optimizer_webp_quality( $quality = null ) {
3757
  ewwwio_debug_message( '<b>' . __FUNCTION__ . '()</b>' );
3758
  if ( is_null( $quality ) ) {
3759
- // Retrieve the user-supplied value for jpg quality.
3760
  $quality = ewww_image_optimizer_get_option( 'ewww_image_optimizer_webp_quality' );
3761
  }
3762
  // Verify that the quality level is an integer, 1-100.
@@ -3787,6 +3891,46 @@ function ewww_image_optimizer_set_webp_quality( $quality ) {
3787
  return min( 92, $quality );
3788
  }
3789
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3790
  /**
3791
  * Check default WP threshold and adjust to comply with normal EWWW IO behavior.
3792
  *
@@ -5464,6 +5608,9 @@ function ewww_image_optimizer_cloud_optimizer( $file, $type, $convert = false, $
5464
  $lossy_fast = 0;
5465
  }
5466
  $sharp_yuv = defined( 'EIO_WEBP_SHARP_YUV' ) && EIO_WEBP_SHARP_YUV ? 1 : 0;
 
 
 
5467
  if ( 'image/webp' === $newtype ) {
5468
  $webp = 1;
5469
  $jpg_quality = apply_filters( 'webp_quality', 75, 'image/webp' );
@@ -10415,6 +10562,21 @@ function ewww_image_optimizer_dismiss_review_notice() {
10415
  die();
10416
  }
10417
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
10418
  /**
10419
  * Add our bulk optimize action to the bulk actions drop-down menu.
10420
  *
@@ -10628,6 +10790,7 @@ function ewww_image_optimizer_settings_script( $hook ) {
10628
  if ( 'settings_page_ewww-image-optimizer-options' !== $hook ) {
10629
  return;
10630
  }
 
10631
  if (
10632
  ! ewww_image_optimizer_get_option( 'ewww_image_optimizer_wizard_complete' ) &&
10633
  ! is_network_admin() &&
@@ -10686,6 +10849,21 @@ function ewww_image_optimizer_settings_script( $hook ) {
10686
  'ewww_vars.save_space = ' . ( get_option( 'ewww_image_optimizer_goal_save_space' ) ? 1 : 0 ) . ";\n" .
10687
  'ewww_vars.site_speed = ' . ( get_option( 'ewww_image_optimizer_goal_site_speed' ) ? 1 : 0 ) . ";\n"
10688
  );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
10689
  ewwwio_memory( __FUNCTION__ );
10690
  }
10691
 
@@ -10938,7 +11116,7 @@ function ewww_image_optimizer_webp_unwrite() {
10938
  */
10939
  function ewww_image_optimizer_webp_rewrite_verify() {
10940
  ewwwio_debug_message( '<b>' . __FUNCTION__ . '()</b>' );
10941
- if ( ewww_image_optimizer_easy_active() || ewwwio_is_cf_host() || isset( $_SERVER['cw_allowed_ip'] ) ) {
10942
  if ( ewwwio_extract_from_markers( ewww_image_optimizer_htaccess_path(), 'EWWWIO' ) ) {
10943
  ewwwio_debug_message( 'removing htaccess webp to prevent EasyIO/Cloudflare/Clouways problems' );
10944
  insert_with_markers( ewww_image_optimizer_htaccess_path(), 'EWWWIO', '' );
@@ -12344,24 +12522,19 @@ function ewww_image_optimizer_options( $network = 'singlesite' ) {
12344
  <!--<h2 class='ewww-hndle'><?php esc_html_e( 'Optimization Status', 'ewww-image-optimizer' ); ?></h2>-->
12345
  <div class='ewww-hndle' id="ewwwio-banner">
12346
  <img height="95" width="167" src="<?php echo esc_url( plugins_url( '/images/ewwwio-logo.png', __FILE__ ) ); ?>">
12347
- <div>
 
12348
  <div class='ewwwio-flex-space-between'>
12349
  <p>
12350
  <?php esc_html_e( 'Get performance tips, exclusive discounts, and the latest news when you signup for our newsletter!', 'ewww-image-optimizer' ); ?>
12351
  </p>
12352
- <?php if ( ! ewww_image_optimizer_get_option( 'ewww_image_optimizer_dismiss_review_notice' ) ) : ?>
12353
- <p id='ewww-review'>
12354
- <a target="_blank" href="https://wordpress.org/support/plugin/ewww-image-optimizer/reviews/#new-post"><?php esc_html_e( 'Write a Review', 'ewww-image-optimizer' ); ?></a>
12355
- <a target="_blank" href="https://wordpress.org/support/plugin/ewww-image-optimizer/reviews/#new-post">
12356
- <span class="dashicons dashicons-star-filled"></span><span class="dashicons dashicons-star-filled"></span><span class="dashicons dashicons-star-filled"></span><span class="dashicons dashicons-star-filled"></span><span class="dashicons dashicons-star-filled"></span>
12357
- </a>
12358
- </p>
12359
- <?php endif; ?>
12360
  </div>
12361
  <p id='ewww-news-button'>
12362
  <a href="https://eepurl.com/gKyU6L?TB_iframe=true&width=600&height=610" class="thickbox button-secondary"><?php esc_html_e( 'Subscribe now!', 'ewww-image-optimizer' ); ?></a>
 
12363
  </p>
12364
  </div>
 
12365
  </div>
12366
  <div class='inside'>
12367
  <div class='ewww-row ewww-blocks'>
@@ -12559,7 +12732,7 @@ function ewww_image_optimizer_options( $network = 'singlesite' ) {
12559
  }
12560
  // Make sure .htaccess rules are terminated when ExactDN is enabled or if Cloudflare is detected.
12561
  $cf_host = ewwwio_is_cf_host();
12562
- if ( ewww_image_optimizer_easy_active() || $cf_host || $cloudways_host ) {
12563
  ewww_image_optimizer_webp_rewrite_verify();
12564
  }
12565
  $webp_available = ewww_image_optimizer_webp_available();
@@ -12851,7 +13024,10 @@ function ewww_image_optimizer_options( $network = 'singlesite' ) {
12851
  <label for='exactdn_lossy'><strong><?php esc_html_e( 'Premium Compression', 'ewww-image-optimizer' ); ?></strong></label>
12852
  <?php ewwwio_help_link( 'https://docs.ewww.io/article/47-getting-more-from-exactdn', '59de6631042863379ddc953c' ); ?>
12853
  <p class='description'>
12854
- <?php esc_html_e( 'Enable high quality premium compression for all images on Easy IO. Disable to use Pixel Perfect mode instead.', 'ewww-image-optimizer' ); ?>
 
 
 
12855
  </p>
12856
  </td>
12857
  </tr>
@@ -12890,21 +13066,6 @@ function ewww_image_optimizer_options( $network = 'singlesite' ) {
12890
  <p class ='description'><?php esc_html_e( 'Color profiles are preserved when using the API or Easy IO.', 'ewww-image-optimizer' ); ?></p>
12891
  </td>
12892
  </tr>
12893
- <?php if ( $current_jpeg_quality > 90 || $current_jpeg_quality < 50 || ewww_image_optimizer_get_option( 'ewww_image_optimizer_jpg_quality' ) ) : ?>
12894
- <tr>
12895
- <th scope='row'>
12896
- <label for='ewww_image_optimizer_jpg_quality'><?php esc_html_e( 'JPG Quality Level', 'ewww-image-optimizer' ); ?></label>
12897
- <?php ewwwio_help_link( 'https://docs.ewww.io/article/11-advanced-configuration', '58542afac697912ffd6c18c0,58543c69c697912ffd6c19a7' ); ?>
12898
- </th>
12899
- <td>
12900
- <input type='text' id='ewww_image_optimizer_jpg_quality' name='ewww_image_optimizer_jpg_quality' class='small-text' value='<?php echo esc_attr( ewww_image_optimizer_jpg_quality() ); ?>' />
12901
- <?php esc_html_e( 'Valid values are 1-100.', 'ewww-image-optimizer' ); ?>
12902
- <p class='description'>
12903
- <?php esc_html_e( 'Use this to override the default WordPress quality level of 82. Applies to image editing, resizing, and PNG to JPG conversion. Does not affect the original uploaded image unless maximum dimensions are set and resizing occurs.', 'ewww-image-optimizer' ); ?>
12904
- </p>
12905
- </td>
12906
- </tr>
12907
- <?php endif; ?>
12908
  <tr>
12909
  <th scope='row'>
12910
  <?php esc_html_e( 'Resize Images', 'ewww-image-optimizer' ); ?>
@@ -13135,21 +13296,9 @@ function ewww_image_optimizer_options( $network = 'singlesite' ) {
13135
  <?php esc_html_e( 'WebP Delivery Method', 'ewww-image-optimizer' ); ?>
13136
  </th>
13137
  <td>
13138
- <!-- This will be handled further down now, with fully-functional rule inserter. -->
13139
- <?php if ( false && ! $cf_host && ! $cloudways_host && ! ewww_image_optimizer_get_option( 'ewww_image_optimizer_webp' ) ) : ?>
13140
- <?php
13141
- printf(
13142
- /* translators: %s: documentation */
13143
- esc_html__( 'The recommended delivery method is to use Apache/LiteSpeed rewrite rules. Nginx users may reference the %s for configuration instructions.', 'ewww-image-optimizer' ),
13144
- '<a class="ewww-help-beacon-single" href="https://docs.ewww.io/article/16-ewww-io-and-webp-images" target="_blank" data-beacon-article="5854745ac697912ffd6c1c89">' . esc_html__( 'documentation', 'ewww-image-optimizer' ) . '</a>'
13145
- );
13146
- ?>
13147
- <?php else : ?>
13148
- <?php endif; ?>
13149
  <?php
13150
  if (
13151
  ! $cf_host &&
13152
- ! $cloudways_host &&
13153
  ! ewww_image_optimizer_get_option( 'ewww_image_optimizer_webp_for_cdn' ) &&
13154
  ! ewww_image_optimizer_get_option( 'ewww_image_optimizer_picture_webp' )
13155
  ) :
@@ -13158,19 +13307,22 @@ function ewww_image_optimizer_options( $network = 'singlesite' ) {
13158
  // Only check the rules for problems if WebP is enabled, otherwise this is a blank slate.
13159
  if ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_webp' ) ) :
13160
  $false_positive_headers = '';
13161
- if ( defined( 'PHP_SAPI' ) && false === strpos( PHP_SAPI, 'apache' ) && false === strpos( PHP_SAPI, 'litespeed' ) ) {
13162
- $false_positive_headers = esc_html( 'This may be a false positive. If so, the warning should go away once you implement the rewrite rules.' );
13163
- }
13164
- $header_error = '';
13165
- if ( ! apache_mod_loaded( 'mod_rewrite' ) ) {
13166
- /* translators: %s: mod_rewrite or mod_headers */
13167
- $header_error = '<p class="ewww-webp-rewrite-info"><strong>' . sprintf( esc_html__( 'Your site appears to be missing %s, please contact your webhost or system administrator to enable this Apache module.', 'ewww-image-optimizer' ), 'mod_rewrite' ) . "</strong><br>$false_positive_headers</p>\n";
13168
- }
13169
- if ( ! apache_mod_loaded( 'mod_headers' ) ) {
13170
- /* translators: %s: mod_rewrite or mod_headers */
13171
- $header_error = '<p class="ewww-webp-rewrite-info"><strong>' . sprintf( esc_html__( 'Your site appears to be missing %s, please contact your webhost or system administrator to enable this Apache module.', 'ewww-image-optimizer' ), 'mod_headers' ) . "</strong><br>$false_positive_headers</p>\n";
13172
- }
13173
-
 
 
 
13174
  $webp_mime_error = ewww_image_optimizer_test_webp_mime_error();
13175
  if ( $webp_mime_error ) {
13176
  echo wp_kses_post( $header_error );
@@ -13233,8 +13385,6 @@ AddType image/webp .webp</pre>
13233
  <?php endif; ?>
13234
  <?php elseif ( $cf_host && ewww_image_optimizer_get_option( 'ewww_image_optimizer_webp' ) ) : ?>
13235
  <p><?php esc_html_e( 'Your site is using Cloudflare, please use JS WebP or Picture WebP rewriting to prevent broken images on older browsers.', 'ewww-image-optimizer' ); ?></p>
13236
- <?php elseif ( $cloudways_host && ewww_image_optimizer_get_option( 'ewww_image_optimizer_webp' ) ) : ?>
13237
- <p><?php esc_html_e( 'Cloudways sites should use JS WebP or Picture WebP rewriting to prevent broken images on older browsers.', 'ewww-image-optimizer' ); ?></p>
13238
  <?php endif; ?>
13239
  </td>
13240
  </tr>
@@ -13331,15 +13481,6 @@ AddType image/webp .webp</pre>
13331
  <?php endif; ?>
13332
  </td>
13333
  </tr>
13334
- <tr class='ewww_image_optimizer_webp_setting_container' <?php echo ewww_image_optimizer_get_option( 'ewww_image_optimizer_webp' ) ? '' : ' style="display:none"'; ?>>
13335
- <th scope='row'>
13336
- <label for='ewww_image_optimizer_webp_quality'><?php esc_html_e( 'WebP Quality Level', 'ewww-image-optimizer' ); ?></label>
13337
- </th>
13338
- <td>
13339
- <input type='text' id='ewww_image_optimizer_webp_quality' name='ewww_image_optimizer_webp_quality' class='small-text' value='<?php echo esc_attr( ewww_image_optimizer_webp_quality() ); ?>' />
13340
- <?php esc_html_e( 'Default is 75, allowed range is 50-100.', 'ewww-image-optimizer' ); ?>
13341
- </td>
13342
- </tr>
13343
  <?php elseif ( ewww_image_optimizer_cloud_based_media() ) : ?>
13344
  <tr class='ewww_image_optimizer_webp_setting_container' <?php echo ewww_image_optimizer_get_option( 'ewww_image_optimizer_webp' ) ? '' : ' style="display:none"'; ?>>
13345
  <th>&nbsp;</th>
@@ -13535,16 +13676,6 @@ AddType image/webp .webp</pre>
13535
  <div id='ewww-advanced-settings'>
13536
  <noscript><h2><?php esc_html_e( 'Advanced', 'ewww-image-optimizer' ); ?></h2></noscript>
13537
  <table class='form-table'>
13538
- <tr>
13539
- <th scope='row'>
13540
- <label for='ewww_image_optimizer_parallel_optimization'><?php esc_html_e( 'Parallel Optimization', 'ewww-image-optimizer' ); ?></label>
13541
- <?php ewwwio_help_link( 'https://docs.ewww.io/article/11-advanced-configuration', '58542afac697912ffd6c18c0,598cb8be2c7d3a73488be237' ); ?>
13542
- </th>
13543
- <td>
13544
- <input type='checkbox' id='ewww_image_optimizer_parallel_optimization' name='ewww_image_optimizer_parallel_optimization' value='true' <?php checked( ewww_image_optimizer_get_option( 'ewww_image_optimizer_parallel_optimization' ) ); ?> />
13545
- <?php esc_html_e( 'All resizes generated from a single upload are optimized in parallel for faster optimization. If this is causing performance issues, disable parallel optimization to reduce the load on your server.', 'ewww-image-optimizer' ); ?>
13546
- </td>
13547
- </tr>
13548
  <tr>
13549
  <th scope='row'>
13550
  <label for='ewww_image_optimizer_auto'><?php esc_html_e( 'Scheduled Optimization', 'ewww-image-optimizer' ); ?></label>
@@ -13600,14 +13731,71 @@ AddType image/webp .webp</pre>
13600
  </tr>
13601
  <tr>
13602
  <th scope='row'>
13603
- <label for='ewww_image_optimizer_exclude_paths'><?php esc_html_e( 'Folders to Ignore', 'ewww-image-optimizer' ); ?></label>
13604
  <?php ewwwio_help_link( 'https://docs.ewww.io/article/11-advanced-configuration', '58542afac697912ffd6c18c0,5853713bc697912ffd6c0b98' ); ?>
13605
  </th>
13606
  <td>
13607
- <?php esc_html_e( 'One path per line, partial paths allowed, but no urls.', 'ewww-image-optimizer' ); ?><br>
13608
  <textarea id='ewww_image_optimizer_exclude_paths' name='ewww_image_optimizer_exclude_paths' rows='3' cols='60'><?php echo esc_html( $exclude_paths ); ?></textarea>
13609
  <p class='description'>
13610
- <?php esc_html_e( 'A file that matches any pattern or path provided will not be optimized.', 'ewww-image-optimizer' ); ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
13611
  </p>
13612
  </td>
13613
  </tr>
14
  exit;
15
  }
16
 
17
+ define( 'EWWW_IMAGE_OPTIMIZER_VERSION', '660.0' );
18
 
19
  // Initialize a couple globals.
20
  $eio_debug = '';
120
  add_filter( 'jpeg_quality', 'ewww_image_optimizer_set_jpg_quality', PHP_INT_MAX - 1 );
121
  // Allows the user to override the default WebP quality used by EWWW IO.
122
  add_filter( 'webp_quality', 'ewww_image_optimizer_set_webp_quality' );
123
+ // Allows the user to override the default AVIF quality used by EWWW IO.
124
+ add_filter( 'avif_quality', 'ewww_image_optimizer_set_avif_quality' );
125
  // Prevent WP from over-riding EWWW IO's resize settings.
126
  add_filter( 'big_image_size_threshold', 'ewww_image_optimizer_adjust_big_image_threshold', 10, 3 );
127
  // Makes sure the plugin bypasses any files affected by the Folders to Ignore setting.
194
  add_action( 'wp_ajax_ewww_dismiss_media_notice', 'ewww_image_optimizer_dismiss_media_notice' );
195
  // AJAX action hook to disable the 'review request' notice.
196
  add_action( 'wp_ajax_ewww_dismiss_review_notice', 'ewww_image_optimizer_dismiss_review_notice' );
197
+ // AJAX action hook to disable the newsletter signup banner.
198
+ add_action( 'wp_ajax_ewww_dismiss_newsletter', 'ewww_image_optimizer_dismiss_newsletter_signup' );
199
  // Adds script to highlight mis-sized images on the front-end (for logged in admins only).
200
  add_action( 'wp_head', 'ewww_image_optimizer_resize_detection_script' );
201
  // Adds a button on the admin bar to allow highlighting mis-sized images on-demand.
686
  update_site_option( 'ewww_image_optimizer_webp', $ewww_image_optimizer_webp );
687
  $ewww_image_optimizer_jpg_background = empty( $_POST['ewww_image_optimizer_jpg_background'] ) ? '' : sanitize_text_field( wp_unslash( $_POST['ewww_image_optimizer_jpg_background'] ) );
688
  update_site_option( 'ewww_image_optimizer_jpg_background', ewww_image_optimizer_jpg_background( $ewww_image_optimizer_jpg_background ) );
689
+ $ewww_image_optimizer_sharpen = empty( $_POST['ewww_image_optimizer_sharpen'] ) ? false : true;
690
+ update_site_option( 'ewww_image_optimizer_sharpen', $ewww_image_optimizer_sharpen );
691
  $ewww_image_optimizer_jpg_quality = empty( $_POST['ewww_image_optimizer_jpg_quality'] ) ? '' : (int) $_POST['ewww_image_optimizer_jpg_quality'];
692
  update_site_option( 'ewww_image_optimizer_jpg_quality', ewww_image_optimizer_jpg_quality( $ewww_image_optimizer_jpg_quality ) );
693
  $ewww_image_optimizer_webp_quality = empty( $_POST['ewww_image_optimizer_webp_quality'] ) ? '' : (int) $_POST['ewww_image_optimizer_webp_quality'];
694
  update_site_option( 'ewww_image_optimizer_webp_quality', ewww_image_optimizer_webp_quality( $ewww_image_optimizer_webp_quality ) );
695
+ $ewww_image_optimizer_avif_quality = empty( $_POST['ewww_image_optimizer_avif_quality'] ) ? '' : (int) $_POST['ewww_image_optimizer_avif_quality'];
696
+ update_site_option( 'ewww_image_optimizer_avif_quality', ewww_image_optimizer_avif_quality( $ewww_image_optimizer_avif_quality ) );
697
  $ewww_image_optimizer_disable_convert_links = ( empty( $_POST['ewww_image_optimizer_disable_convert_links'] ) ? false : true );
698
  update_site_option( 'ewww_image_optimizer_disable_convert_links', $ewww_image_optimizer_disable_convert_links );
699
  $ewww_image_optimizer_backup_files = ( empty( $_POST['ewww_image_optimizer_backup_files'] ) ? false : true );
1072
  register_setting( 'ewww_image_optimizer_options', 'ewww_image_optimizer_svg_level', 'intval' );
1073
  register_setting( 'ewww_image_optimizer_options', 'ewww_image_optimizer_backup_files', 'boolval' );
1074
  register_setting( 'ewww_image_optimizer_options', 'ewww_image_optimizer_enable_cloudinary', 'boolval' );
1075
+ register_setting( 'ewww_image_optimizer_options', 'ewww_image_optimizer_sharpen', 'boolval' );
1076
  register_setting( 'ewww_image_optimizer_options', 'ewww_image_optimizer_jpg_quality', 'ewww_image_optimizer_jpg_quality' );
1077
  register_setting( 'ewww_image_optimizer_options', 'ewww_image_optimizer_webp_quality', 'ewww_image_optimizer_webp_quality' );
1078
+ register_setting( 'ewww_image_optimizer_options', 'ewww_image_optimizer_avif_quality', 'ewww_image_optimizer_avif_quality' );
1079
  register_setting( 'ewww_image_optimizer_options', 'ewww_image_optimizer_auto', 'boolval' );
1080
  register_setting( 'ewww_image_optimizer_options', 'ewww_image_optimizer_include_media_paths', 'boolval' );
1081
  register_setting( 'ewww_image_optimizer_options', 'ewww_image_optimizer_include_originals', 'boolval' );
2373
  '</p></div>';
2374
  }
2375
 
2376
+ /**
2377
+ * Add review link to the footer on our pages.
2378
+ *
2379
+ * @param string $footer_text The existing footer text.
2380
+ * @return string The modified footer text.
2381
+ */
2382
+ function ewww_image_optimizer_footer_review_text( $footer_text ) {
2383
+ if ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_dismiss_review_notice' ) ) {
2384
+ return $footer_text;
2385
+ }
2386
+ $review_text = esc_html( 'Thank you for using EWWW Image Optimizer!', 'ewww-image-optimizer' ) . ' <a target="_blank" href="https://wordpress.org/support/plugin/ewww-image-optimizer/reviews/#new-post">' . esc_html__( 'Please rate us on WordPress.org', 'ewww-image-optimizer' ) . '</a>';
2387
+ return str_replace( '</span>', '', $footer_text ) . ' | ' . $review_text . '</span>';
2388
+ }
2389
+
2390
  /**
2391
  * Loads the inline script to dismiss the review notice.
2392
  */
2487
  if ( class_exists( 'WP_Image_Editor_Gmagick' ) ) {
2488
  require_once( plugin_dir_path( __FILE__ ) . '/classes/class-ewwwio-gmagick-editor.php' );
2489
  }
2490
+ if ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_sharpen' ) ) {
2491
+ ewww_image_optimizer_sharpen_filters();
2492
+ }
2493
  }
2494
  if ( ! in_array( 'EWWWIO_GD_Editor', $editors, true ) ) {
2495
  array_unshift( $editors, 'EWWWIO_GD_Editor' );
2507
  return $editors;
2508
  }
2509
 
2510
+ /**
2511
+ * Override the default resizing filter.
2512
+ *
2513
+ * @param string $filter_name The name of the constant for the specified filter.
2514
+ * @param int $dst_w The width (in pixels) to which an image is being resized.
2515
+ * @param int $dst_h The height (in pixels) to which an image is being resized.
2516
+ * @return string The Lanczos filter by default, unless changed by the user.
2517
+ */
2518
+ function eio_change_image_resize_filter( $filter_name, $dst_w, $dst_h ) {
2519
+ /*
2520
+ * Valid options:
2521
+ * 'FILTER_POINT',
2522
+ * 'FILTER_BOX',
2523
+ * 'FILTER_TRIANGLE',
2524
+ * 'FILTER_HERMITE',
2525
+ * 'FILTER_HANNING',
2526
+ * 'FILTER_HAMMING',
2527
+ * 'FILTER_BLACKMAN',
2528
+ * 'FILTER_GAUSSIAN',
2529
+ * 'FILTER_QUADRATIC',
2530
+ * 'FILTER_CUBIC',
2531
+ * 'FILTER_CATROM',
2532
+ * 'FILTER_MITCHELL',
2533
+ * 'FILTER_LANCZOS',
2534
+ * 'FILTER_BESSEL',
2535
+ * 'FILTER_SINC'
2536
+ */
2537
+ if ( $dst_w * $dst_h > apply_filters( 'eio_image_resize_threshold', 2000000 ) ) {
2538
+ return $filter_name;
2539
+ }
2540
+ return 'FILTER_LANCZOS';
2541
+ }
2542
+
2543
+ /**
2544
+ * Enables the use of the adaptiveSharpenImage() function.
2545
+ *
2546
+ * @param bool $use_adaptive Whether to use the adaptiveSharpenImage() function, false by default.
2547
+ * @param int $dst_w The width (in pixels) to which an image is being resized.
2548
+ * @param int $dst_h The height (in pixels) to which an image is being resized.
2549
+ * @return bool True if the new image will be under 1.5 MP, false otherwise.
2550
+ */
2551
+ function eio_enable_adaptive_sharpen( $use_adaptive, $dst_w, $dst_h ) {
2552
+ if ( $dst_w * $dst_h > apply_filters( 'eio_adaptive_sharpen_threshold', 1500000 ) ) {
2553
+ return false;
2554
+ }
2555
+ return true;
2556
+ }
2557
+
2558
+ /**
2559
+ * Adjusts the sigma value for the adaptiveSharpenImage() function.
2560
+ *
2561
+ * @param float $param The sigma value for adaptiveSharpenImage().
2562
+ * @param int $dst_w The width (in pixels) to which an image is being resized.
2563
+ * @param int $dst_h The height (in pixels) to which an image is being resized.
2564
+ * @return float The new sigma value.
2565
+ */
2566
+ function eio_adjust_adaptive_sharpen_sigma( $param, $dst_w, $dst_h ) {
2567
+ if ( $dst_w * $dst_h > apply_filters( 'eio_adaptive_sharpen_sigma_threshold', 250000 ) ) {
2568
+ return 0.5;
2569
+ }
2570
+ return $param;
2571
+ }
2572
+
2573
+ /**
2574
+ * Add filters to improve image resizing with ImageMagick.
2575
+ */
2576
+ function ewww_image_optimizer_sharpen_filters() {
2577
+ ewwwio_debug_message( '<b>' . __FUNCTION__ . '()</b>' );
2578
+ add_filter( 'eio_image_resize_filter', 'eio_change_image_resize_filter', 9, 3 );
2579
+
2580
+ add_filter( 'eio_use_adaptive_sharpen', 'eio_enable_adaptive_sharpen', 9, 3 );
2581
+
2582
+ add_filter( 'eio_adaptive_sharpen_sigma', 'eio_adjust_adaptive_sharpen_sigma', 9, 3 );
2583
+ }
2584
+
2585
  /**
2586
  * Registers the filter that will remove the image_editor hooks when an attachment is added.
2587
  */
3461
  function ewww_image_optimizer_imagick_create_webp( $file, $type, $webpfile ) {
3462
  ewwwio_debug_message( '<b>' . __FUNCTION__ . '()</b>' );
3463
  $sharp_yuv = defined( 'EIO_WEBP_SHARP_YUV' ) && EIO_WEBP_SHARP_YUV ? true : false;
3464
+ if ( empty( $sharp_yuv ) && ewww_image_optimizer_get_option( 'ewww_image_optimizer_sharpen' ) ) {
3465
+ $sharp_yuv = true;
3466
+ }
3467
+ $quality = (int) apply_filters( 'webp_quality', 75, 'image/webp' );
3468
  if ( $quality < 50 || $quality > 100 ) {
3469
  $quality = 75;
3470
  }
3813
  * Retrieves/sanitizes the jpg quality setting for png2jpg conversion or returns null.
3814
  *
3815
  * @param int $quality The JPG quality level as set by the user.
3816
+ * @return int The sanitized JPG quality level.
3817
  */
3818
  function ewww_image_optimizer_jpg_quality( $quality = null ) {
3819
  ewwwio_debug_message( '<b>' . __FUNCTION__ . '()</b>' );
3855
  * Retrieves/sanitizes the WebP quality setting or returns null.
3856
  *
3857
  * @param int $quality The WebP quality level as set by the user.
3858
+ * @return int The sanitized WebP quality level.
3859
  */
3860
  function ewww_image_optimizer_webp_quality( $quality = null ) {
3861
  ewwwio_debug_message( '<b>' . __FUNCTION__ . '()</b>' );
3862
  if ( is_null( $quality ) ) {
3863
+ // Retrieve the user-supplied value for WebP quality.
3864
  $quality = ewww_image_optimizer_get_option( 'ewww_image_optimizer_webp_quality' );
3865
  }
3866
  // Verify that the quality level is an integer, 1-100.
3891
  return min( 92, $quality );
3892
  }
3893
 
3894
+ /**
3895
+ * Retrieves/sanitizes the AVIF quality setting or returns null.
3896
+ *
3897
+ * @param int $quality The AVIF quality level as set by the user.
3898
+ * @return int The sanitized AVIF quality level.
3899
+ */
3900
+ function ewww_image_optimizer_avif_quality( $quality = null ) {
3901
+ ewwwio_debug_message( '<b>' . __FUNCTION__ . '()</b>' );
3902
+ if ( is_null( $quality ) ) {
3903
+ // Retrieve the user-supplied value for AVIF quality.
3904
+ $quality = ewww_image_optimizer_get_option( 'ewww_image_optimizer_avif_quality' );
3905
+ }
3906
+ // Verify that the quality level is an integer, 1-100.
3907
+ if ( preg_match( '/^(100|[1-9][0-9]?)$/', $quality ) ) {
3908
+ ewwwio_debug_message( "avif quality: $quality" );
3909
+ // Send back the valid quality level.
3910
+ return $quality;
3911
+ } else {
3912
+ if ( ! empty( $quality ) ) {
3913
+ add_settings_error( 'ewww_image_optimizer_avif_quality', 'ewwwio-avif-quality', esc_html__( 'Could not save the AVIF quality, please enter an integer between 50 and 100.', 'ewww-image-optimizer' ) );
3914
+ }
3915
+ // Send back nothing.
3916
+ return null;
3917
+ }
3918
+ }
3919
+
3920
+ /**
3921
+ * Overrides the default AVIF quality (if a user-defined value is set).
3922
+ *
3923
+ * @param int $quality The default AVIF quality level.
3924
+ * @return int The default quality, or the user configured level.
3925
+ */
3926
+ function ewww_image_optimizer_set_avif_quality( $quality ) {
3927
+ $new_quality = ewww_image_optimizer_avif_quality();
3928
+ if ( ! empty( $new_quality ) ) {
3929
+ return min( 92, $new_quality );
3930
+ }
3931
+ return min( 92, $quality );
3932
+ }
3933
+
3934
  /**
3935
  * Check default WP threshold and adjust to comply with normal EWWW IO behavior.
3936
  *
5608
  $lossy_fast = 0;
5609
  }
5610
  $sharp_yuv = defined( 'EIO_WEBP_SHARP_YUV' ) && EIO_WEBP_SHARP_YUV ? 1 : 0;
5611
+ if ( empty( $sharp_yuv ) && ewww_image_optimizer_get_option( 'ewww_image_optimizer_sharpen' ) ) {
5612
+ $sharp_yuv = 1;
5613
+ }
5614
  if ( 'image/webp' === $newtype ) {
5615
  $webp = 1;
5616
  $jpg_quality = apply_filters( 'webp_quality', 75, 'image/webp' );
10562
  die();
10563
  }
10564
 
10565
+ /**
10566
+ * Disables the newsletter signup banner.
10567
+ */
10568
+ function ewww_image_optimizer_dismiss_newsletter_signup() {
10569
+ ewwwio_ob_clean();
10570
+ ewwwio_debug_message( '<b>' . __FUNCTION__ . '()</b>' );
10571
+ // Verify that the user is properly authorized.
10572
+ if ( ! current_user_can( apply_filters( 'ewww_image_optimizer_admin_permissions', '' ) ) ) {
10573
+ wp_die( esc_html__( 'Access denied.', 'ewww-image-optimizer' ) );
10574
+ }
10575
+ update_option( 'ewww_image_optimizer_hide_newsletter_signup', true, false );
10576
+ update_site_option( 'ewww_image_optimizer_hide_newsletter_signup', true );
10577
+ die( 'done' );
10578
+ }
10579
+
10580
  /**
10581
  * Add our bulk optimize action to the bulk actions drop-down menu.
10582
  *
10790
  if ( 'settings_page_ewww-image-optimizer-options' !== $hook ) {
10791
  return;
10792
  }
10793
+ add_filter( 'admin_footer_text', 'ewww_image_optimizer_footer_review_text' );
10794
  if (
10795
  ! ewww_image_optimizer_get_option( 'ewww_image_optimizer_wizard_complete' ) &&
10796
  ! is_network_admin() &&
10849
  'ewww_vars.save_space = ' . ( get_option( 'ewww_image_optimizer_goal_save_space' ) ? 1 : 0 ) . ";\n" .
10850
  'ewww_vars.site_speed = ' . ( get_option( 'ewww_image_optimizer_goal_site_speed' ) ? 1 : 0 ) . ";\n"
10851
  );
10852
+ wp_add_inline_script(
10853
+ 'ewww-settings-script',
10854
+ "jQuery(document).on('click', '#ewww-news-dismiss-link', function() {\n" .
10855
+ "\tvar ewww_dismiss_news_data = {\n" .
10856
+ "\t\taction: 'ewww_dismiss_newsletter',\n" .
10857
+ "\t};\n" .
10858
+ "\tjQuery.post(ajaxurl, ewww_dismiss_news_data, function(response) {\n" .
10859
+ "\t\tif (response) {\n" .
10860
+ "\t\t\tconsole.log(response);\n" .
10861
+ "\t\t}\n" .
10862
+ "\tjQuery('#ewww-newsletter-banner').hide();\n" .
10863
+ "\t});\n" .
10864
+ "\treturn false;\n" .
10865
+ "});\n"
10866
+ );
10867
  ewwwio_memory( __FUNCTION__ );
10868
  }
10869
 
11116
  */
11117
  function ewww_image_optimizer_webp_rewrite_verify() {
11118
  ewwwio_debug_message( '<b>' . __FUNCTION__ . '()</b>' );
11119
+ if ( ewww_image_optimizer_easy_active() || ewwwio_is_cf_host() ) {
11120
  if ( ewwwio_extract_from_markers( ewww_image_optimizer_htaccess_path(), 'EWWWIO' ) ) {
11121
  ewwwio_debug_message( 'removing htaccess webp to prevent EasyIO/Cloudflare/Clouways problems' );
11122
  insert_with_markers( ewww_image_optimizer_htaccess_path(), 'EWWWIO', '' );
12522
  <!--<h2 class='ewww-hndle'><?php esc_html_e( 'Optimization Status', 'ewww-image-optimizer' ); ?></h2>-->
12523
  <div class='ewww-hndle' id="ewwwio-banner">
12524
  <img height="95" width="167" src="<?php echo esc_url( plugins_url( '/images/ewwwio-logo.png', __FILE__ ) ); ?>">
12525
+ <?php if ( ! ewww_image_optimizer_get_option( 'ewww_image_optimizer_hide_newsletter_signup' ) ) : ?>
12526
+ <div id="ewww-newsletter-banner">
12527
  <div class='ewwwio-flex-space-between'>
12528
  <p>
12529
  <?php esc_html_e( 'Get performance tips, exclusive discounts, and the latest news when you signup for our newsletter!', 'ewww-image-optimizer' ); ?>
12530
  </p>
 
 
 
 
 
 
 
 
12531
  </div>
12532
  <p id='ewww-news-button'>
12533
  <a href="https://eepurl.com/gKyU6L?TB_iframe=true&width=600&height=610" class="thickbox button-secondary"><?php esc_html_e( 'Subscribe now!', 'ewww-image-optimizer' ); ?></a>
12534
+ &emsp;<a id="ewww-news-dismiss-link" href="#"><?php esc_html_e( 'No Thanks', 'ewww-image-optimizer' ); ?></a>
12535
  </p>
12536
  </div>
12537
+ <?php endif; ?>
12538
  </div>
12539
  <div class='inside'>
12540
  <div class='ewww-row ewww-blocks'>
12732
  }
12733
  // Make sure .htaccess rules are terminated when ExactDN is enabled or if Cloudflare is detected.
12734
  $cf_host = ewwwio_is_cf_host();
12735
+ if ( ewww_image_optimizer_easy_active() || $cf_host ) {
12736
  ewww_image_optimizer_webp_rewrite_verify();
12737
  }
12738
  $webp_available = ewww_image_optimizer_webp_available();
13024
  <label for='exactdn_lossy'><strong><?php esc_html_e( 'Premium Compression', 'ewww-image-optimizer' ); ?></strong></label>
13025
  <?php ewwwio_help_link( 'https://docs.ewww.io/article/47-getting-more-from-exactdn', '59de6631042863379ddc953c' ); ?>
13026
  <p class='description'>
13027
+ <?php esc_html_e( 'Enable high quality compression and WebP/AVIF conversion for all images on Easy IO. Disable to use Pixel Perfect mode instead.', 'ewww-image-optimizer' ); ?><br>
13028
+ <a href='https://ewww.io/manage-sites/' target='_blank'>
13029
+ <?php esc_html_e( 'Manage WebP/AVIF in the site settings at ewww.io.', 'ewww-image-optimizer' ); ?>
13030
+ </a>
13031
  </p>
13032
  </td>
13033
  </tr>
13066
  <p class ='description'><?php esc_html_e( 'Color profiles are preserved when using the API or Easy IO.', 'ewww-image-optimizer' ); ?></p>
13067
  </td>
13068
  </tr>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
13069
  <tr>
13070
  <th scope='row'>
13071
  <?php esc_html_e( 'Resize Images', 'ewww-image-optimizer' ); ?>
13296
  <?php esc_html_e( 'WebP Delivery Method', 'ewww-image-optimizer' ); ?>
13297
  </th>
13298
  <td>
 
 
 
 
 
 
 
 
 
 
 
13299
  <?php
13300
  if (
13301
  ! $cf_host &&
 
13302
  ! ewww_image_optimizer_get_option( 'ewww_image_optimizer_webp_for_cdn' ) &&
13303
  ! ewww_image_optimizer_get_option( 'ewww_image_optimizer_picture_webp' )
13304
  ) :
13307
  // Only check the rules for problems if WebP is enabled, otherwise this is a blank slate.
13308
  if ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_webp' ) ) :
13309
  $false_positive_headers = '';
13310
+ $header_error = '';
13311
+ if ( $cloudways_host ) :
13312
+ $header_error = '<p class="ewww-webp-rewrite-info"><strong>' . esc_html__( 'In order to use server-based delivery, Cloudways sites must have WebP Redirection enabled in their Application Settings.', 'ewww-image-optimizer' ) . "</strong></p>\n";
13313
+ else :
13314
+ if ( defined( 'PHP_SAPI' ) && false === strpos( PHP_SAPI, 'apache' ) && false === strpos( PHP_SAPI, 'litespeed' ) ) {
13315
+ $false_positive_headers = esc_html__( 'This may be a false positive. If so, the warning should go away once you implement the rewrite rules.', 'ewww-image-optimizer' );
13316
+ }
13317
+ if ( ! apache_mod_loaded( 'mod_rewrite' ) ) {
13318
+ /* translators: %s: mod_rewrite or mod_headers */
13319
+ $header_error = '<p class="ewww-webp-rewrite-info"><strong>' . sprintf( esc_html__( 'Your site appears to be missing %s, please contact your webhost or system administrator to enable this Apache module.', 'ewww-image-optimizer' ), 'mod_rewrite' ) . "</strong><br>$false_positive_headers</p>\n";
13320
+ }
13321
+ if ( ! apache_mod_loaded( 'mod_headers' ) ) {
13322
+ /* translators: %s: mod_rewrite or mod_headers */
13323
+ $header_error = '<p class="ewww-webp-rewrite-info"><strong>' . sprintf( esc_html__( 'Your site appears to be missing %s, please contact your webhost or system administrator to enable this Apache module.', 'ewww-image-optimizer' ), 'mod_headers' ) . "</strong><br>$false_positive_headers</p>\n";
13324
+ }
13325
+ endif;
13326
  $webp_mime_error = ewww_image_optimizer_test_webp_mime_error();
13327
  if ( $webp_mime_error ) {
13328
  echo wp_kses_post( $header_error );
13385
  <?php endif; ?>
13386
  <?php elseif ( $cf_host && ewww_image_optimizer_get_option( 'ewww_image_optimizer_webp' ) ) : ?>
13387
  <p><?php esc_html_e( 'Your site is using Cloudflare, please use JS WebP or Picture WebP rewriting to prevent broken images on older browsers.', 'ewww-image-optimizer' ); ?></p>
 
 
13388
  <?php endif; ?>
13389
  </td>
13390
  </tr>
13481
  <?php endif; ?>
13482
  </td>
13483
  </tr>
 
 
 
 
 
 
 
 
 
13484
  <?php elseif ( ewww_image_optimizer_cloud_based_media() ) : ?>
13485
  <tr class='ewww_image_optimizer_webp_setting_container' <?php echo ewww_image_optimizer_get_option( 'ewww_image_optimizer_webp' ) ? '' : ' style="display:none"'; ?>>
13486
  <th>&nbsp;</th>
13676
  <div id='ewww-advanced-settings'>
13677
  <noscript><h2><?php esc_html_e( 'Advanced', 'ewww-image-optimizer' ); ?></h2></noscript>
13678
  <table class='form-table'>
 
 
 
 
 
 
 
 
 
 
13679
  <tr>
13680
  <th scope='row'>
13681
  <label for='ewww_image_optimizer_auto'><?php esc_html_e( 'Scheduled Optimization', 'ewww-image-optimizer' ); ?></label>
13731
  </tr>
13732
  <tr>
13733
  <th scope='row'>
13734
+ <label for='ewww_image_optimizer_exclude_paths'><?php esc_html_e( 'Exclude Images', 'ewww-image-optimizer' ); ?></label>
13735
  <?php ewwwio_help_link( 'https://docs.ewww.io/article/11-advanced-configuration', '58542afac697912ffd6c18c0,5853713bc697912ffd6c0b98' ); ?>
13736
  </th>
13737
  <td>
13738
+ <?php esc_html_e( 'One exclusion per line, no wildcards (*) needed.', 'ewww-image-optimizer' ); ?><br>
13739
  <textarea id='ewww_image_optimizer_exclude_paths' name='ewww_image_optimizer_exclude_paths' rows='3' cols='60'><?php echo esc_html( $exclude_paths ); ?></textarea>
13740
  <p class='description'>
13741
+ <?php esc_html_e( 'Applies to optimization of local files, rather than front-end operations like Lazy Load or Easy IO. Thus exclusions must match filesystem paths instead of URLs.', 'ewww-image-optimizer' ); ?>
13742
+ </p>
13743
+ </td>
13744
+ </tr>
13745
+ </table>
13746
+ <hr>
13747
+ <table class='form-table'>
13748
+ <tr>
13749
+ <th scope='row'>
13750
+ <label for='ewww_image_optimizer_sharpen'><?php esc_html_e( 'Sharpen Images', 'ewww-image-optimizer' ); ?></label>
13751
+ <?php ewwwio_help_link( 'https://docs.ewww.io/article/124-sharpening-images', '629a6dfa92cb8c175b469bb3' ); ?>
13752
+ </th>
13753
+ <td>
13754
+ <input type='checkbox' id='ewww_image_optimizer_sharpen' name='ewww_image_optimizer_sharpen' value='true' <?php checked( ewww_image_optimizer_get_option( 'ewww_image_optimizer_sharpen' ) ); ?> />
13755
+ <?php if ( ewww_image_optimizer_imagick_support() ) : ?>
13756
+ <?php esc_html_e( 'Apply improved sharpening to resize operations in WordPress and WebP Conversion.', 'ewww-image-optimizer' ); ?><br>
13757
+ <p class='description'>
13758
+ <?php esc_html_e( 'Uses additional CPU resources and may cause thumbnail generation for large images to fail.', 'ewww-image-optimizer' ); ?>
13759
+ </p>
13760
+ <?php else : ?>
13761
+ <?php esc_html_e( 'Apply improved sharpening during WebP Conversion.', 'ewww-image-optimizer' ); ?><br>
13762
+ <p class='description'>
13763
+ <?php esc_html_e( 'Improve thumbnail generation by enabling the ImageMagick module for PHP.', 'ewww-image-optimizer' ); ?>
13764
+ </p>
13765
+ <?php endif; ?>
13766
+ </td>
13767
+ </tr>
13768
+ <tr>
13769
+ <th scope='row'>
13770
+ <label for='ewww_image_optimizer_jpg_quality'><?php esc_html_e( 'JPG Quality Level', 'ewww-image-optimizer' ); ?></label>
13771
+ <?php ewwwio_help_link( 'https://docs.ewww.io/article/11-advanced-configuration', '58542afac697912ffd6c18c0,58543c69c697912ffd6c19a7' ); ?>
13772
+ </th>
13773
+ <td>
13774
+ <input type='text' id='ewww_image_optimizer_jpg_quality' name='ewww_image_optimizer_jpg_quality' class='small-text' value='<?php echo esc_attr( ewww_image_optimizer_jpg_quality() ); ?>' />
13775
+ <?php esc_html_e( 'Valid values are 1-100.', 'ewww-image-optimizer' ); ?>
13776
+ <p class='description'>
13777
+ <?php esc_html_e( 'Use this to override the default WordPress quality level of 82. Applies to image editing, resizing, and PNG to JPG conversion. Does not affect the original uploaded image unless maximum dimensions are set and resizing occurs.', 'ewww-image-optimizer' ); ?>
13778
+ </p>
13779
+ </td>
13780
+ </tr>
13781
+ <tr>
13782
+ <th scope='row'>
13783
+ <label for='ewww_image_optimizer_webp_quality'><?php esc_html_e( 'WebP Quality Level', 'ewww-image-optimizer' ); ?></label>
13784
+ </th>
13785
+ <td>
13786
+ <input type='text' id='ewww_image_optimizer_webp_quality' name='ewww_image_optimizer_webp_quality' class='small-text' value='<?php echo esc_attr( ewww_image_optimizer_webp_quality() ); ?>' />
13787
+ <?php esc_html_e( 'Default is 75, allowed range is 50-100.', 'ewww-image-optimizer' ); ?>
13788
+ </td>
13789
+ </tr>
13790
+ <tr>
13791
+ <th scope='row'>
13792
+ <label for='ewww_image_optimizer_avif_quality'><?php esc_html_e( 'AVIF Quality Level', 'ewww-image-optimizer' ); ?></label>
13793
+ </th>
13794
+ <td>
13795
+ <input type='text' id='ewww_image_optimizer_avif_quality' name='ewww_image_optimizer_avif_quality' class='small-text' value='<?php echo esc_attr( ewww_image_optimizer_avif_quality() ); ?>' <?php disabled( ! ewww_image_optimizer_get_option( 'ewww_image_optimizer_exactdn' ) ); ?> />
13796
+ <?php esc_html_e( 'Default is 45, recommended range is 30-60.', 'ewww-image-optimizer' ); ?>
13797
+ <p class='description'>
13798
+ <?php esc_html_e( 'AVIF conversion is enabled via the Easy IO CDN.', 'ewww-image-optimizer' ); ?>
13799
  </p>
13800
  </td>
13801
  </tr>
ewww-image-optimizer.php CHANGED
@@ -13,7 +13,7 @@ Plugin Name: EWWW Image Optimizer
13
  Plugin URI: https://wordpress.org/plugins/ewww-image-optimizer/
14
  Description: Smaller Images, Faster Sites, Happier Visitors. Comprehensive image optimization that doesn't require a degree in rocket science.
15
  Author: Exactly WWW
16
- Version: 6.5.2
17
  Requires at least: 5.7
18
  Requires PHP: 7.2
19
  Author URI: https://ewww.io/
13
  Plugin URI: https://wordpress.org/plugins/ewww-image-optimizer/
14
  Description: Smaller Images, Faster Sites, Happier Visitors. Comprehensive image optimization that doesn't require a degree in rocket science.
15
  Author: Exactly WWW
16
+ Version: 6.6.0
17
  Requires at least: 5.7
18
  Requires PHP: 7.2
19
  Author URI: https://ewww.io/
includes/lazysizes.min.js CHANGED
@@ -1 +1 @@
1
- var ewww_webp_supported;function shouldAutoScale(e){if(1==eio_lazy_vars.skip_autoscale)return!1;if(e.hasAttributes())for(var t=e.attributes,a=/skip-autoscale/,i=t.length-1;0<=i;i--){if(a.test(t[i].name))return!1;if(a.test(t[i].value))return!1}return!0}function constrainSrc(e,t,a,i){if(null===e)return e;var r=/w=(\d+)/,n=/fit=(\d+),(\d+)/,o=/resize=(\d+),(\d+)/,s=decodeURIComponent(e);if("undefined"==typeof eio_lazy_vars&&(eio_lazy_vars={exactdn_domain:".exactdn.com"}),0<e.search("\\?")&&0<e.search(eio_lazy_vars.exactdn_domain)){var l=o.exec(s);if(l&&t<l[1])return s.replace(o,"resize="+t+","+a);o=r.exec(e);if(o&&t<=o[1]){if("bg-cover"!==i&&"img-crop"!==i)return e.replace(r,"w="+t);var d=o[1]-t;return 20<d||a<1080?e.replace(r,"resize="+t+","+a):e}d=n.exec(s);if(d&&t<d[1]){if("bg-cover"!==i&&"img-crop"!==i)return s.replace(n,"fit="+t+","+a);s=d[1]-t,n=d[2]-a;return 20<s||20<n?e.replace(r,"resize="+t+","+a):e}if(!o&&!d&&!l)return"img"===i?e+"&fit="+t+","+a:"bg-cover"===i||"img-crop"===i?e+"&resize="+t+","+a:t<a?e+"&h="+a:e+"&w="+t}return-1==e.search("\\?")&&0<e.search(eio_lazy_vars.exactdn_domain)?"img"===i?e+"?fit="+t+","+a:"bg-cover"===i||"img-crop"===i?e+"?resize="+t+","+a:t<a?e+"?h="+a:e+"?w="+t:e}void 0===ewww_webp_supported&&(ewww_webp_supported=!1),window.lazySizesConfig=window.lazySizesConfig||{},window.lazySizesConfig.expand=500<document.documentElement.clientHeight&&500<document.documentElement.clientWidth?1e3:740,50<eio_lazy_vars.threshold&&(window.lazySizesConfig.expand=eio_lazy_vars.threshold),function(e,t){function a(){t(e.lazySizes),e.removeEventListener("lazyunveilread",a,!0)}t=t.bind(null,e,e.document),"object"==typeof module&&module.exports?t(require("lazysizes")):e.lazySizes?a():e.addEventListener("lazyunveilread",a,!0)}(window,function(n,e,o){"use strict";var s;e.addEventListener&&(s=/\(|\)|\s|'/,addEventListener("lazybeforeunveil",function(e){var t,a,i,r;e.detail.instance==o&&(e.defaultPrevented||("none"==e.target.preload&&(e.target.preload="auto"),(i=e.target.getAttribute("data-bg"))&&(ewww_webp_supported&&(r=e.target.getAttribute("data-bg-webp"))&&(i=r),t=n.devicePixelRatio||1,a=Math.round(e.target.offsetWidth*t),r=Math.round(e.target.offsetHeight*t),0===i.search(/\[/)||shouldAutoScale(e.target)&&shouldAutoScale(e.target.parentNode)&&(i=n.lazySizes.hC(e.target,"wp-block-cover")?(n.lazySizes.hC(e.target,"has-parallax")?(a=Math.round(n.screen.width*t),r=Math.round(n.screen.height*t)):r<300&&(r=430),constrainSrc(i,a,r,"bg-cover")):n.lazySizes.hC(e.target,"elementor-bg")||n.lazySizes.hC(e.target,"et_parallax_bg")||n.lazySizes.hC(e.target,"bg-image-crop")?constrainSrc(i,a,r,"bg-cover"):constrainSrc(i,a,r,"bg")),e.target.style.backgroundImage&&-1===e.target.style.backgroundImage.search(/^initial/)?0===i.search(/\[/)?((i=JSON.parse(i)).forEach(function(e){s.test(e)&&JSON.stringify(e)}),i='url("'+i.join('"), url("')+'"',r=e.target.style.backgroundImage+", "+i,e.target.style.backgroundImage=r):e.target.style.backgroundImage=e.target.style.backgroundImage+', url("'+(s.test(i)?JSON.stringify(i):i)+'")':0===i.search(/\[/)?((i=JSON.parse(i)).forEach(function(e){s.test(e)&&JSON.stringify(e)}),i='url("'+i.join('"), url("')+'"',e.target.style.backgroundImage=i):e.target.style.backgroundImage="url("+(s.test(i)?JSON.stringify(i):i)+")")))},!1))}),document.addEventListener("lazybeforesizes",function(e){e.target.getAttribute("data-src");void 0!==e.target._lazysizesWidth&&e.detail.width<e.target._lazysizesWidth&&(e.detail.width=e.target._lazysizesWidth)}),document.addEventListener("lazybeforeunveil",function(e){var t,a,i,r,n,o=e.target,s=o.getAttribute("data-srcset");o.naturalWidth&&!s&&1<o.naturalWidth&&1<o.naturalHeight&&(i=window.devicePixelRatio||1,a=o.naturalWidth,r=o.naturalHeight,t=o.getAttribute("data-eio-rwidth"),e=o.getAttribute("data-eio-rheight"),t&&a<t&&(a=t,r=e),a=o.clientWidth&&1.25*o.clientWidth<a,r=o.clientHeight&&1.25*o.clientHeight<r,(a||r)&&(a=Math.round(o.offsetWidth*i),r=Math.round(o.offsetHeight*i),i=o.getAttribute("data-src"),n=o.getAttribute("data-src-webp"),ewww_webp_supported&&n&&-1==i.search("webp=1")&&(i=n),(r=!(!shouldAutoScale(o)||!shouldAutoScale(o.parentNode))&&(window.lazySizes.hC(o,"et_pb_jt_filterable_grid_item_image")||window.lazySizes.hC(o,"ss-foreground-image")||window.lazySizes.hC(o,"img-crop")||window.lazySizes.hC(o,"ct-image")&&window.lazySizes.hC(o,"object-cover")?constrainSrc(i,a,r,"img-crop"):constrainSrc(i,a,r,"img")))&&i!=r&&o.setAttribute("data-src",r))),ewww_webp_supported&&(!s||(s=o.getAttribute("data-srcset-webp"))&&o.setAttribute("data-srcset",s),(n=o.getAttribute("data-src-webp"))&&o.setAttribute("data-src",n))}),function(e,t){t=t(e,e.document,Date);e.lazySizes=t,"object"==typeof module&&module.exports&&(module.exports=t)}("undefined"!=typeof window?window:{},function(i,f,n){"use strict";var g,h;if(!function(){var e,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:!0,expFactor:1.5,hFac:.8,loadMode:2,loadHidden:!0,ricTimeout:0,throttleDelay:125};for(e in h=i.lazySizesConfig||i.lazysizesConfig||{},t)e in h||(h[e]=t[e])}(),!f||!f.getElementsByClassName)return{init:function(){},cfg:h,noSupport:!0};function c(e,t){S(e,t)||e.setAttribute("class",(e[y]("class")||"").trim()+" "+t)}function u(e,t){(t=S(e,t))&&e.setAttribute("class",(e[y]("class")||"").replace(t," "))}function z(e,t){var a;!l&&(a=i.picturefill||h.pf)?(t&&t.src&&!e[y]("srcset")&&e.setAttribute("srcset",t.src),a({reevaluate:!0,elements:[e]})):t&&t.src&&(e.src=t.src)}var a,r,t,o,s,m=f.documentElement,l=i.HTMLPictureElement,d="addEventListener",y="getAttribute",e=i[d].bind(i),p=i.setTimeout,v=i.requestAnimationFrame||p,b=i.requestIdleCallback,w=/^picture$/i,_=["load","error","lazyincluded","_lazyloaded"],C={},A=Array.prototype.forEach,S=function(e,t){return C[t]||(C[t]=new RegExp("(\\s|^)"+t+"(\\s|$)")),C[t].test(e[y]("class")||"")&&C[t]},E=function(t,a,e){var i=e?d:"removeEventListener";e&&E(t,a),_.forEach(function(e){t[i](e,a)})},x=function(e,t,a,i,r){var n=f.createEvent("Event");return(a=a||{}).instance=g,n.initEvent(t,!i,!r),n.detail=a,e.dispatchEvent(n),n},N=function(e,t){return(getComputedStyle(e,null)||{})[t]},M=function(e,t,a){for(a=a||e.offsetWidth;a<h.minSize&&t&&!e._lazysizesWidth;)a=t.offsetWidth,t=t.parentNode;return a},W=(o=[],s=t=[],k._lsFlush=L,k);function L(){var e=s;for(s=t.length?o:t,r=!(a=!0);e.length;)e.shift()();a=!1}function k(e,t){a&&!t?e.apply(this,arguments):(s.push(e),r||(r=!0,(f.hidden?p:v)(L)))}function H(a,e){return e?function(){W(a)}:function(){var e=this,t=arguments;W(function(){a.apply(e,t)})}}function I(e){function t(){var e=n.now()-i;e<99?p(t,99-e):(b||r)(r)}var a,i,r=function(){a=null,e()};return function(){i=n.now(),a=a||p(t,99)}}var O,R,B,T,F,P,j,D,J,$,q,U,G,K,Q,V,X,Y,Z,ee,te,ae,ie,re,ne,oe,se,le,de,ce,ue,fe=(Z=/^img$/i,ee=/^iframe$/i,te="onscroll"in i&&!/(gle|ing)bot/.test(navigator.userAgent),re=-1,ne=function(e){return(U=null==U?"hidden"==N(f.body,"visibility"):U)||!("hidden"==N(e.parentNode,"visibility")&&"hidden"==N(e,"visibility"))},G=he,Q=ie=ae=0,V=h.throttleDelay,X=h.ricTimeout,Y=b&&49<X?function(){b(ze,{timeout:X}),X!==h.ricTimeout&&(X=h.ricTimeout)}:H(function(){p(ze)},!0),se=H(me),le=function(e){se({target:e.target})},de=H(function(t,e,a,i,r){var n,o,s,l,d;(s=x(t,"lazybeforeunveil",e)).defaultPrevented||(i&&(a?c(t,h.autosizesClass):t.setAttribute("sizes",i)),n=t[y](h.srcsetAttr),a=t[y](h.srcAttr),r&&(o=(d=t.parentNode)&&w.test(d.nodeName||"")),l=e.firesLoad||"src"in t&&(n||a||o),s={target:t},c(t,h.loadingClass),l&&(clearTimeout(B),B=p(ge,2500),E(t,le,!0)),o&&A.call(d.getElementsByTagName("source"),ye),n?t.setAttribute("srcset",n):a&&!o&&(ee.test(t.nodeName)?(i=a,0==(d=(e=t).getAttribute("data-load-mode")||h.iframeLoadMode)?e.contentWindow.location.replace(i):1==d&&(e.src=i)):t.src=a),r&&(n||o)&&z(t,{src:a})),t._lazyRace&&delete t._lazyRace,u(t,h.lazyClass),W(function(){var e=t.complete&&1<t.naturalWidth;l&&!e||(e&&c(t,h.fastLoadedClass),me(s),t._lazyCache=!0,p(function(){"_lazyCache"in t&&delete t._lazyCache},9)),"lazy"==t.loading&&ie--},!0)}),ue=I(function(){h.loadMode=3,oe()}),{_:function(){F=n.now(),g.elements=f.getElementsByClassName(h.lazyClass),O=f.getElementsByClassName(h.lazyClass+" "+h.preloadClass),e("scroll",oe,!0),e("resize",oe,!0),e("pageshow",function(e){var t;!e.persisted||(t=f.querySelectorAll("."+h.loadingClass)).length&&t.forEach&&v(function(){t.forEach(function(e){e.complete&&ce(e)})})}),i.MutationObserver?new MutationObserver(oe).observe(m,{childList:!0,subtree:!0,attributes:!0}):(m[d]("DOMNodeInserted",oe,!0),m[d]("DOMAttrModified",oe,!0),setInterval(oe,999)),e("hashchange",oe,!0),["focus","mouseover","click","load","transitionend","animationend"].forEach(function(e){f[d](e,oe,!0)}),/d$|^c/.test(f.readyState)?ve():(e("load",ve),f[d]("DOMContentLoaded",oe),p(ve,2e4)),g.elements.length?(he(),W._lsFlush()):oe()},checkElems:oe=function(e){var t;(e=!0===e)&&(X=33),K||(K=!0,(t=V-(n.now()-Q))<0&&(t=0),e||t<9?Y():p(Y,t))},unveil:ce=function(e){var t,a,i,r;e._lazyRace||(!(r="auto"==(i=(a=Z.test(e.nodeName))&&(e[y](h.sizesAttr)||e[y]("sizes"))))&&R||!a||!e[y]("src")&&!e.srcset||e.complete||S(e,h.errorClass)||!S(e,h.lazyClass))&&(t=x(e,"lazyunveilread").detail,r&&Ce.updateElem(e,!0,e.offsetWidth),e._lazyRace=!0,ie++,de(e,t,r,i,a))},_aLSL:pe});function ge(e){ie--,e&&!(ie<0)&&e.target||(ie=0)}function he(){var e,t,a,i,r,n,o,s,l,d,c,u=g.elements;if((T=h.loadMode)&&ie<8&&(e=u.length)){for(t=0,re++;t<e;t++)if(u[t]&&!u[t]._lazyRace)if(!te||g.prematureUnveil&&g.prematureUnveil(u[t]))ce(u[t]);else if((o=u[t][y]("data-expand"))&&(r=+o)||(r=ae),l||(l=!h.expand||h.expand<1?500<m.clientHeight&&500<m.clientWidth?500:370:h.expand,d=(g._defEx=l)*h.expFactor,c=h.hFac,U=null,ae<d&&ie<1&&2<re&&2<T&&!f.hidden?(ae=d,re=0):ae=1<T&&1<re&&ie<6?l:0),s!==r&&(P=innerWidth+r*c,j=innerHeight+r,n=-1*r,s=r),d=u[t].getBoundingClientRect(),(q=d.bottom)>=n&&(D=d.top)<=j&&($=d.right)>=n*c&&(J=d.left)<=P&&(q||$||J||D)&&(h.loadHidden||ne(u[t]))&&(R&&ie<3&&!o&&(T<3||re<4)||function(e,t){var a,i=e,r=ne(e);for(D-=t,q+=t,J-=t,$+=t;r&&(i=i.offsetParent)&&i!=f.body&&i!=m;)(r=0<(N(i,"opacity")||1))&&"visible"!=N(i,"overflow")&&(a=i.getBoundingClientRect(),r=$>a.left&&J<a.right&&q>a.top-1&&D<a.bottom+1);return r}(u[t],r))){if(ce(u[t]),i=!0,9<ie)break}else!i&&R&&!a&&ie<4&&re<4&&2<T&&(O[0]||h.preloadAfterLoad)&&(O[0]||!o&&(q||$||J||D||"auto"!=u[t][y](h.sizesAttr)))&&(a=O[0]||u[t]);a&&!i&&ce(a)}}function ze(){K=!1,Q=n.now(),G()}function me(e){var t=e.target;t._lazyCache?delete t._lazyCache:(ge(e),c(t,h.loadedClass),u(t,h.loadingClass),E(t,le),x(t,"lazyloaded"))}function ye(e){var t,a=e[y](h.srcsetAttr);(t=h.customMedia[e[y]("data-media")||e[y]("media")])&&e.setAttribute("media",t),a&&e.setAttribute("srcset",a)}function pe(){3==h.loadMode&&(h.loadMode=2),ue()}function ve(){R||(n.now()-F<999?p(ve,999):(R=!0,h.loadMode=3,oe(),e("scroll",pe,!0)))}var be,we,_e,Ce=(we=H(function(e,t,a,i){var r,n,o;if(e._lazysizesWidth=i,e.setAttribute("sizes",i+="px"),w.test(t.nodeName||""))for(n=0,o=(r=t.getElementsByTagName("source")).length;n<o;n++)r[n].setAttribute("sizes",i);a.detail.dataAttr||z(e,a.detail)}),{_:function(){be=f.getElementsByClassName(h.autosizesClass),e("resize",_e)},checkElems:_e=I(function(){var e,t=be.length;if(t)for(e=0;e<t;e++)Ae(be[e])}),updateElem:Ae});function Ae(e,t,a){var i=e.parentNode;i&&(a=M(e,i,a),(t=x(e,"lazybeforesizes",{width:a,dataAttr:!!t})).defaultPrevented||(a=t.detail.width)&&a!==e._lazysizesWidth&&we(e,i,t,a))}function Se(){!Se.i&&f.getElementsByClassName&&(Se.i=!0,Ce._(),fe._())}return p(function(){h.init&&Se()}),g={cfg:h,autoSizer:Ce,loader:fe,init:Se,uP:z,aC:c,rC:u,hC:S,fire:x,gW:M,rAF:W}});
1
+ var ewww_webp_supported;function shouldAutoScale(e){if(1==eio_lazy_vars.skip_autoscale)return!1;if(e.hasAttributes())for(var t=e.attributes,a=/skip-autoscale/,i=t.length-1;0<=i;i--){if(a.test(t[i].name))return!1;if(a.test(t[i].value))return!1}return!0}function constrainSrc(e,t,a,i){if(null===e)return e;var r=/w=(\d+)/,n=/fit=(\d+),(\d+)/,o=/resize=(\d+),(\d+)/,s=decodeURIComponent(e);if("undefined"==typeof eio_lazy_vars&&(eio_lazy_vars={exactdn_domain:".exactdn.com"}),0<e.search("\\?")&&0<e.search(eio_lazy_vars.exactdn_domain)){var l=o.exec(s);if(l&&t<l[1])return s.replace(o,"resize="+t+","+a);o=r.exec(e);if(o&&t<=o[1]){if("bg-cover"!==i&&"img-crop"!==i)return e.replace(r,"w="+t);var d=o[1]-t;return 20<d||a<1080?e.replace(r,"resize="+t+","+a):e}d=n.exec(s);if(d&&t<d[1]){if("bg-cover"!==i&&"img-crop"!==i)return s.replace(n,"fit="+t+","+a);s=d[1]-t,n=d[2]-a;return 20<s||20<n?e.replace(r,"resize="+t+","+a):e}if(!o&&!d&&!l)return"img"===i?e+"&fit="+t+","+a:"bg-cover"===i||"img-crop"===i?e+"&resize="+t+","+a:t<a?e+"&h="+a:e+"&w="+t}return-1==e.search("\\?")&&0<e.search(eio_lazy_vars.exactdn_domain)?"img"===i?e+"?fit="+t+","+a:"bg-cover"===i||"img-crop"===i?e+"?resize="+t+","+a:t<a?e+"?h="+a:e+"?w="+t:e}void 0===ewww_webp_supported&&(ewww_webp_supported=!1),window.lazySizesConfig=window.lazySizesConfig||{},window.lazySizesConfig.expand=500<document.documentElement.clientHeight&&500<document.documentElement.clientWidth?1e3:740,50<eio_lazy_vars.threshold&&(window.lazySizesConfig.expand=eio_lazy_vars.threshold),function(e,t){function a(){t(e.lazySizes),e.removeEventListener("lazyunveilread",a,!0)}t=t.bind(null,e,e.document),"object"==typeof module&&module.exports?t(require("lazysizes")):e.lazySizes?a():e.addEventListener("lazyunveilread",a,!0)}(window,function(n,e,o){"use strict";var s;e.addEventListener&&(s=/\(|\)|\s|'/,addEventListener("lazybeforeunveil",function(e){var t,a,i,r;e.detail.instance==o&&(e.defaultPrevented||("none"==e.target.preload&&(e.target.preload="auto"),(i=e.target.getAttribute("data-bg"))&&(ewww_webp_supported&&(r=e.target.getAttribute("data-bg-webp"))&&(i=r),t=n.devicePixelRatio||1,a=Math.round(e.target.offsetWidth*t),r=Math.round(e.target.offsetHeight*t),0===i.search(/\[/)||shouldAutoScale(e.target)&&shouldAutoScale(e.target.parentNode)&&(i=n.lazySizes.hC(e.target,"wp-block-cover")?(n.lazySizes.hC(e.target,"has-parallax")?(a=Math.round(n.screen.width*t),r=Math.round(n.screen.height*t)):r<300&&(r=430),constrainSrc(i,a,r,"bg-cover")):n.lazySizes.hC(e.target,"cover-image")||n.lazySizes.hC(e.target,"elementor-bg")||n.lazySizes.hC(e.target,"et_parallax_bg")||n.lazySizes.hC(e.target,"bg-image-crop")?constrainSrc(i,a,r,"bg-cover"):constrainSrc(i,a,r,"bg")),e.target.style.backgroundImage&&-1===e.target.style.backgroundImage.search(/^initial/)?0===i.search(/\[/)?((i=JSON.parse(i)).forEach(function(e){s.test(e)&&JSON.stringify(e)}),i='url("'+i.join('"), url("')+'"',r=e.target.style.backgroundImage+", "+i,e.target.style.backgroundImage=r):e.target.style.backgroundImage=e.target.style.backgroundImage+', url("'+(s.test(i)?JSON.stringify(i):i)+'")':0===i.search(/\[/)?((i=JSON.parse(i)).forEach(function(e){s.test(e)&&JSON.stringify(e)}),i='url("'+i.join('"), url("')+'"',e.target.style.backgroundImage=i):e.target.style.backgroundImage="url("+(s.test(i)?JSON.stringify(i):i)+")")))},!1))}),document.addEventListener("lazybeforesizes",function(e){e.target.getAttribute("data-src");void 0!==e.target._lazysizesWidth&&e.detail.width<e.target._lazysizesWidth&&(e.detail.width=e.target._lazysizesWidth)}),document.addEventListener("lazybeforeunveil",function(e){var t,a,i,r,n,o=e.target,s=o.getAttribute("data-srcset");o.naturalWidth&&!s&&1<o.naturalWidth&&1<o.naturalHeight&&(i=window.devicePixelRatio||1,a=o.naturalWidth,r=o.naturalHeight,t=o.getAttribute("data-eio-rwidth"),e=o.getAttribute("data-eio-rheight"),t&&a<t&&(a=t,r=e),a=o.clientWidth&&1.25*o.clientWidth<a,r=o.clientHeight&&1.25*o.clientHeight<r,(a||r)&&(a=Math.round(o.offsetWidth*i),r=Math.round(o.offsetHeight*i),i=o.getAttribute("data-src"),n=o.getAttribute("data-src-webp"),ewww_webp_supported&&n&&-1==i.search("webp=1")&&(i=n),(r=!(!shouldAutoScale(o)||!shouldAutoScale(o.parentNode))&&(window.lazySizes.hC(o,"et_pb_jt_filterable_grid_item_image")||window.lazySizes.hC(o,"ss-foreground-image")||window.lazySizes.hC(o,"img-crop")||window.lazySizes.hC(o,"ct-image")&&window.lazySizes.hC(o,"object-cover")?constrainSrc(i,a,r,"img-crop"):constrainSrc(i,a,r,"img")))&&i!=r&&o.setAttribute("data-src",r))),ewww_webp_supported&&(!s||(s=o.getAttribute("data-srcset-webp"))&&o.setAttribute("data-srcset",s),(n=o.getAttribute("data-src-webp"))&&o.setAttribute("data-src",n))}),function(e,t){t=t(e,e.document,Date);e.lazySizes=t,"object"==typeof module&&module.exports&&(module.exports=t)}("undefined"!=typeof window?window:{},function(i,f,n){"use strict";var g,h;if(!function(){var e,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:!0,expFactor:1.5,hFac:.8,loadMode:2,loadHidden:!0,ricTimeout:0,throttleDelay:125};for(e in h=i.lazySizesConfig||i.lazysizesConfig||{},t)e in h||(h[e]=t[e])}(),!f||!f.getElementsByClassName)return{init:function(){},cfg:h,noSupport:!0};function c(e,t){S(e,t)||e.setAttribute("class",(e[y]("class")||"").trim()+" "+t)}function u(e,t){(t=S(e,t))&&e.setAttribute("class",(e[y]("class")||"").replace(t," "))}function z(e,t){var a;!l&&(a=i.picturefill||h.pf)?(t&&t.src&&!e[y]("srcset")&&e.setAttribute("srcset",t.src),a({reevaluate:!0,elements:[e]})):t&&t.src&&(e.src=t.src)}var a,r,t,o,s,m=f.documentElement,l=i.HTMLPictureElement,d="addEventListener",y="getAttribute",e=i[d].bind(i),p=i.setTimeout,v=i.requestAnimationFrame||p,b=i.requestIdleCallback,w=/^picture$/i,_=["load","error","lazyincluded","_lazyloaded"],C={},A=Array.prototype.forEach,S=function(e,t){return C[t]||(C[t]=new RegExp("(\\s|^)"+t+"(\\s|$)")),C[t].test(e[y]("class")||"")&&C[t]},E=function(t,a,e){var i=e?d:"removeEventListener";e&&E(t,a),_.forEach(function(e){t[i](e,a)})},x=function(e,t,a,i,r){var n=f.createEvent("Event");return(a=a||{}).instance=g,n.initEvent(t,!i,!r),n.detail=a,e.dispatchEvent(n),n},N=function(e,t){return(getComputedStyle(e,null)||{})[t]},M=function(e,t,a){for(a=a||e.offsetWidth;a<h.minSize&&t&&!e._lazysizesWidth;)a=t.offsetWidth,t=t.parentNode;return a},W=(o=[],s=t=[],k._lsFlush=L,k);function L(){var e=s;for(s=t.length?o:t,r=!(a=!0);e.length;)e.shift()();a=!1}function k(e,t){a&&!t?e.apply(this,arguments):(s.push(e),r||(r=!0,(f.hidden?p:v)(L)))}function H(a,e){return e?function(){W(a)}:function(){var e=this,t=arguments;W(function(){a.apply(e,t)})}}function I(e){function t(){var e=n.now()-i;e<99?p(t,99-e):(b||r)(r)}var a,i,r=function(){a=null,e()};return function(){i=n.now(),a=a||p(t,99)}}var O,R,B,T,F,P,j,D,J,$,q,U,G,K,Q,V,X,Y,Z,ee,te,ae,ie,re,ne,oe,se,le,de,ce,ue,fe=(Z=/^img$/i,ee=/^iframe$/i,te="onscroll"in i&&!/(gle|ing)bot/.test(navigator.userAgent),re=-1,ne=function(e){return(U=null==U?"hidden"==N(f.body,"visibility"):U)||!("hidden"==N(e.parentNode,"visibility")&&"hidden"==N(e,"visibility"))},G=he,Q=ie=ae=0,V=h.throttleDelay,X=h.ricTimeout,Y=b&&49<X?function(){b(ze,{timeout:X}),X!==h.ricTimeout&&(X=h.ricTimeout)}:H(function(){p(ze)},!0),se=H(me),le=function(e){se({target:e.target})},de=H(function(t,e,a,i,r){var n,o,s,l,d;(s=x(t,"lazybeforeunveil",e)).defaultPrevented||(i&&(a?c(t,h.autosizesClass):t.setAttribute("sizes",i)),n=t[y](h.srcsetAttr),a=t[y](h.srcAttr),r&&(o=(d=t.parentNode)&&w.test(d.nodeName||"")),l=e.firesLoad||"src"in t&&(n||a||o),s={target:t},c(t,h.loadingClass),l&&(clearTimeout(B),B=p(ge,2500),E(t,le,!0)),o&&A.call(d.getElementsByTagName("source"),ye),n?t.setAttribute("srcset",n):a&&!o&&(ee.test(t.nodeName)?(i=a,0==(d=(e=t).getAttribute("data-load-mode")||h.iframeLoadMode)?e.contentWindow.location.replace(i):1==d&&(e.src=i)):t.src=a),r&&(n||o)&&z(t,{src:a})),t._lazyRace&&delete t._lazyRace,u(t,h.lazyClass),W(function(){var e=t.complete&&1<t.naturalWidth;l&&!e||(e&&c(t,h.fastLoadedClass),me(s),t._lazyCache=!0,p(function(){"_lazyCache"in t&&delete t._lazyCache},9)),"lazy"==t.loading&&ie--},!0)}),ue=I(function(){h.loadMode=3,oe()}),{_:function(){F=n.now(),g.elements=f.getElementsByClassName(h.lazyClass),O=f.getElementsByClassName(h.lazyClass+" "+h.preloadClass),e("scroll",oe,!0),e("resize",oe,!0),e("pageshow",function(e){var t;!e.persisted||(t=f.querySelectorAll("."+h.loadingClass)).length&&t.forEach&&v(function(){t.forEach(function(e){e.complete&&ce(e)})})}),i.MutationObserver?new MutationObserver(oe).observe(m,{childList:!0,subtree:!0,attributes:!0}):(m[d]("DOMNodeInserted",oe,!0),m[d]("DOMAttrModified",oe,!0),setInterval(oe,999)),e("hashchange",oe,!0),["focus","mouseover","click","load","transitionend","animationend"].forEach(function(e){f[d](e,oe,!0)}),/d$|^c/.test(f.readyState)?ve():(e("load",ve),f[d]("DOMContentLoaded",oe),p(ve,2e4)),g.elements.length?(he(),W._lsFlush()):oe()},checkElems:oe=function(e){var t;(e=!0===e)&&(X=33),K||(K=!0,(t=V-(n.now()-Q))<0&&(t=0),e||t<9?Y():p(Y,t))},unveil:ce=function(e){var t,a,i,r;e._lazyRace||(!(r="auto"==(i=(a=Z.test(e.nodeName))&&(e[y](h.sizesAttr)||e[y]("sizes"))))&&R||!a||!e[y]("src")&&!e.srcset||e.complete||S(e,h.errorClass)||!S(e,h.lazyClass))&&(t=x(e,"lazyunveilread").detail,r&&Ce.updateElem(e,!0,e.offsetWidth),e._lazyRace=!0,ie++,de(e,t,r,i,a))},_aLSL:pe});function ge(e){ie--,e&&!(ie<0)&&e.target||(ie=0)}function he(){var e,t,a,i,r,n,o,s,l,d,c,u=g.elements;if((T=h.loadMode)&&ie<8&&(e=u.length)){for(t=0,re++;t<e;t++)if(u[t]&&!u[t]._lazyRace)if(!te||g.prematureUnveil&&g.prematureUnveil(u[t]))ce(u[t]);else if((o=u[t][y]("data-expand"))&&(r=+o)||(r=ae),l||(l=!h.expand||h.expand<1?500<m.clientHeight&&500<m.clientWidth?500:370:h.expand,d=(g._defEx=l)*h.expFactor,c=h.hFac,U=null,ae<d&&ie<1&&2<re&&2<T&&!f.hidden?(ae=d,re=0):ae=1<T&&1<re&&ie<6?l:0),s!==r&&(P=innerWidth+r*c,j=innerHeight+r,n=-1*r,s=r),d=u[t].getBoundingClientRect(),(q=d.bottom)>=n&&(D=d.top)<=j&&($=d.right)>=n*c&&(J=d.left)<=P&&(q||$||J||D)&&(h.loadHidden||ne(u[t]))&&(R&&ie<3&&!o&&(T<3||re<4)||function(e,t){var a,i=e,r=ne(e);for(D-=t,q+=t,J-=t,$+=t;r&&(i=i.offsetParent)&&i!=f.body&&i!=m;)(r=0<(N(i,"opacity")||1))&&"visible"!=N(i,"overflow")&&(a=i.getBoundingClientRect(),r=$>a.left&&J<a.right&&q>a.top-1&&D<a.bottom+1);return r}(u[t],r))){if(ce(u[t]),i=!0,9<ie)break}else!i&&R&&!a&&ie<4&&re<4&&2<T&&(O[0]||h.preloadAfterLoad)&&(O[0]||!o&&(q||$||J||D||"auto"!=u[t][y](h.sizesAttr)))&&(a=O[0]||u[t]);a&&!i&&ce(a)}}function ze(){K=!1,Q=n.now(),G()}function me(e){var t=e.target;t._lazyCache?delete t._lazyCache:(ge(e),c(t,h.loadedClass),u(t,h.loadingClass),E(t,le),x(t,"lazyloaded"))}function ye(e){var t,a=e[y](h.srcsetAttr);(t=h.customMedia[e[y]("data-media")||e[y]("media")])&&e.setAttribute("media",t),a&&e.setAttribute("srcset",a)}function pe(){3==h.loadMode&&(h.loadMode=2),ue()}function ve(){R||(n.now()-F<999?p(ve,999):(R=!0,h.loadMode=3,oe(),e("scroll",pe,!0)))}var be,we,_e,Ce=(we=H(function(e,t,a,i){var r,n,o;if(e._lazysizesWidth=i,e.setAttribute("sizes",i+="px"),w.test(t.nodeName||""))for(n=0,o=(r=t.getElementsByTagName("source")).length;n<o;n++)r[n].setAttribute("sizes",i);a.detail.dataAttr||z(e,a.detail)}),{_:function(){be=f.getElementsByClassName(h.autosizesClass),e("resize",_e)},checkElems:_e=I(function(){var e,t=be.length;if(t)for(e=0;e<t;e++)Ae(be[e])}),updateElem:Ae});function Ae(e,t,a){var i=e.parentNode;i&&(a=M(e,i,a),(t=x(e,"lazybeforesizes",{width:a,dataAttr:!!t})).defaultPrevented||(a=t.detail.width)&&a!==e._lazysizesWidth&&we(e,i,t,a))}function Se(){!Se.i&&f.getElementsByClassName&&(Se.i=!0,Ce._(),fe._())}return p(function(){h.init&&Se()}),g={cfg:h,autoSizer:Ce,loader:fe,init:Se,uP:z,aC:c,rC:u,hC:S,fire:x,gW:M,rAF:W}});
includes/ls.unveilhooks.js CHANGED
@@ -58,6 +58,9 @@
58
  targetHeight = 430;
59
  }
60
  bg = constrainSrc(bg,targetWidth,targetHeight,'bg-cover');
 
 
 
61
  } else if (window.lazySizes.hC(e.target,'elementor-bg')){
62
  console.log('found elementor-bg with data-bg');
63
  bg = constrainSrc(bg,targetWidth,targetHeight,'bg-cover');
58
  targetHeight = 430;
59
  }
60
  bg = constrainSrc(bg,targetWidth,targetHeight,'bg-cover');
61
+ } else if (window.lazySizes.hC(e.target,'cover-image')){
62
+ console.log('found .cover-image with data-bg');
63
+ bg = constrainSrc(bg,targetWidth,targetHeight,'bg-cover');
64
  } else if (window.lazySizes.hC(e.target,'elementor-bg')){
65
  console.log('found elementor-bg with data-bg');
66
  bg = constrainSrc(bg,targetWidth,targetHeight,'bg-cover');
readme.txt CHANGED
@@ -5,7 +5,7 @@ Tags: optimize, image, convert, webp, resize, compress, lazy load, optimization,
5
  Requires at least: 5.7
6
  Tested up to: 6.0
7
  Requires PHP: 7.2
8
- Stable tag: 6.5.2
9
  License: GPLv3
10
 
11
  Smaller Images, Faster Sites, Happier Visitors. Comprehensive image optimization that doesn't require a degree in rocket science.
@@ -137,6 +137,18 @@ That's not a question, but since I made it up, I'll answer it. See this resource
137
  * Feature requests can be viewed and submitted on our [feedback portal](https://feedback.ewww.io/b/features)
138
  * If you would like to help translate this plugin in your language, [join the team](https://translate.wordpress.org/projects/wp-plugins/ewww-image-optimizer/)
139
 
 
 
 
 
 
 
 
 
 
 
 
 
140
  = 6.5.2 =
141
  * added: automatic optimization for Crop Thumbnails plugin
142
  * added: filters to adjust sharpening parameters for core WP (ImageMagick) image resizing
5
  Requires at least: 5.7
6
  Tested up to: 6.0
7
  Requires PHP: 7.2
8
+ Stable tag: 6.6.0
9
  License: GPLv3
10
 
11
  Smaller Images, Faster Sites, Happier Visitors. Comprehensive image optimization that doesn't require a degree in rocket science.
137
  * Feature requests can be viewed and submitted on our [feedback portal](https://feedback.ewww.io/b/features)
138
  * If you would like to help translate this plugin in your language, [join the team](https://translate.wordpress.org/projects/wp-plugins/ewww-image-optimizer/)
139
 
140
+ = 6.6.0 =
141
+ * added: AVIF support via Easy IO, enable on site management at ewww.io
142
+ * added: sharpening setting to improve WP resizing via ImageMagick and WebP conversion
143
+ * added: AVIF quality setting on Advanced tab
144
+ * added: ability for Easy IO to get full-size path when using offloaded media
145
+ * changed: JPG quality and WebP quality moved to Advanced tab
146
+ * changed: allow .htaccess rules on Cloudways with notice about WebP Redirection toggle
147
+ * fixed: front-end HTML parsers running within Bricks editor
148
+ * fixed: Easy IO not finding scaled full-size for dynamic size generation
149
+ * fixed: cover images not cropped properly by Easy IO
150
+ * fixed: Easy IO URLs leaking into post editor with WP 6.0
151
+
152
  = 6.5.2 =
153
  * added: automatic optimization for Crop Thumbnails plugin
154
  * added: filters to adjust sharpening parameters for core WP (ImageMagick) image resizing
unique.php CHANGED
@@ -227,7 +227,7 @@ function ewww_image_optimizer_notice_hosting_requires_api() {
227
  }
228
  echo "<div id='ewww-image-optimizer-warning-exec' class='notice notice-warning is-dismissible'><p>" .
229
  /* translators: %s: Name of a web host, like WordPress.com or Pantheon. */
230
- sprintf( esc_html__( '%s sites require cloud-based optimization, because server-based optimization is disallowed. Those who upgrade to our premium service receive much higher compression, PNG/GIF/PDF compression, and image backups.', 'ewww-image-optimizer' ), esc_html( $webhost ) ) .
231
  '<br><strong>' .
232
  /* translators: %s: link to 'start your free trial' */
233
  sprintf( esc_html__( 'Dismiss this notice to continue with free cloud-based JPG compression or %s.', 'ewww-image-optimizer' ), "<a href='https://ewww.io/plans/'>" . esc_html__( 'start your premium trial', 'ewww-image-optimizer' ) . '</a>' );
@@ -627,7 +627,7 @@ function ewww_image_optimizer_notice_utils( $quiet = null ) {
627
  echo "<div id='ewww-image-optimizer-warning-exec' class='notice notice-warning is-dismissible'><p>";
628
  printf(
629
  /* translators: %s: link to 'start your premium trial' */
630
- esc_html__( 'Your web server does not meet the requirements for free server-based compression. You may %s for 5x more compression, PNG/GIF/PDF compression, and more. Otherwise, continue with free cloud-based JPG compression.', 'ewww-image-optimizer' ),
631
  "<a href='https://ewww.io/plans/'>" . esc_html__( 'start your premium trial', 'ewww-image-optimizer' ) . '</a>'
632
  );
633
  }
@@ -771,7 +771,7 @@ function ewww_image_optimizer_notice_utils( $quiet = null ) {
771
  echo "<div id='ewww-image-optimizer-warning-opt-missing' class='notice notice-warning'><p>" .
772
  sprintf(
773
  /* translators: 1: automatically (link) 2: manually (link) */
774
- esc_html__( 'You are missing pngout. Install %1$s or %2$s.', 'ewww-image-optimizer' ),
775
  "<a href='" . esc_url( $pngout_install_url ) . "'>" . esc_html__( 'automatically', 'ewww-image-optimizer' ) . '</a>',
776
  '<a href="https://docs.ewww.io/article/13-installing-pngout" data-beacon-article="5854531bc697912ffd6c1afa">' . esc_html__( 'manually', 'ewww-image-optimizer' ) . '</a>'
777
  ) .
@@ -786,7 +786,7 @@ function ewww_image_optimizer_notice_utils( $quiet = null ) {
786
  echo "<div id='ewww-image-optimizer-warning-opt-missing' class='notice notice-warning'><p>" .
787
  sprintf(
788
  /* translators: 1: automatically (link) 2: manually (link) */
789
- esc_html__( 'You are missing svgleaner. Install %1$s or %2$s.', 'ewww-image-optimizer' ),
790
  "<a href='" . esc_url( $svgcleaner_install_url ) . "'>" . esc_html__( 'automatically', 'ewww-image-optimizer' ) . '</a>',
791
  '<a href="https://docs.ewww.io/article/95-installing-svgcleaner" data-beacon-article="5f7921c9cff47e001a58adbc">' . esc_html__( 'manually', 'ewww-image-optimizer' ) . '</a>'
792
  ) .
@@ -3061,7 +3061,10 @@ function ewww_image_optimizer_webp_create( $file, $orig_size, $type, $tool, $rec
3061
  $quality = 75;
3062
  }
3063
  $sharp_yuv = defined( 'EIO_WEBP_SHARP_YUV' ) && EIO_WEBP_SHARP_YUV ? '-sharp_yuv' : '';
3064
- $lossless = '-lossless';
 
 
 
3065
  if ( defined( 'EWWW_IMAGE_OPTIMIZER_LOSSY_PNG2WEBP' ) && EWWW_IMAGE_OPTIMIZER_LOSSY_PNG2WEBP ) {
3066
  $lossless = "-q $quality $sharp_yuv";
3067
  }
227
  }
228
  echo "<div id='ewww-image-optimizer-warning-exec' class='notice notice-warning is-dismissible'><p>" .
229
  /* translators: %s: Name of a web host, like WordPress.com or Pantheon. */
230
+ sprintf( esc_html__( 'EWWW Image Optimizer cannot use server-based optimization on %s sites. Activate our premium service for 5x more compression, PNG/GIF/PDF compression, and image backups.', 'ewww-image-optimizer' ), esc_html( $webhost ) ) .
231
  '<br><strong>' .
232
  /* translators: %s: link to 'start your free trial' */
233
  sprintf( esc_html__( 'Dismiss this notice to continue with free cloud-based JPG compression or %s.', 'ewww-image-optimizer' ), "<a href='https://ewww.io/plans/'>" . esc_html__( 'start your premium trial', 'ewww-image-optimizer' ) . '</a>' );
627
  echo "<div id='ewww-image-optimizer-warning-exec' class='notice notice-warning is-dismissible'><p>";
628
  printf(
629
  /* translators: %s: link to 'start your premium trial' */
630
+ esc_html__( 'Your web server does not meet the requirements for free server-based compression with EWWW Image Optimizer. You may %s for 5x more compression, PNG/GIF/PDF compression, and more. Otherwise, continue with free cloud-based JPG compression.', 'ewww-image-optimizer' ),
631
  "<a href='https://ewww.io/plans/'>" . esc_html__( 'start your premium trial', 'ewww-image-optimizer' ) . '</a>'
632
  );
633
  }
771
  echo "<div id='ewww-image-optimizer-warning-opt-missing' class='notice notice-warning'><p>" .
772
  sprintf(
773
  /* translators: 1: automatically (link) 2: manually (link) */
774
+ esc_html__( 'EWWW Image Optimizer is missing pngout. Install %1$s or %2$s.', 'ewww-image-optimizer' ),
775
  "<a href='" . esc_url( $pngout_install_url ) . "'>" . esc_html__( 'automatically', 'ewww-image-optimizer' ) . '</a>',
776
  '<a href="https://docs.ewww.io/article/13-installing-pngout" data-beacon-article="5854531bc697912ffd6c1afa">' . esc_html__( 'manually', 'ewww-image-optimizer' ) . '</a>'
777
  ) .
786
  echo "<div id='ewww-image-optimizer-warning-opt-missing' class='notice notice-warning'><p>" .
787
  sprintf(
788
  /* translators: 1: automatically (link) 2: manually (link) */
789
+ esc_html__( 'EWWW Image Optimizer is missing svgleaner. Install %1$s or %2$s.', 'ewww-image-optimizer' ),
790
  "<a href='" . esc_url( $svgcleaner_install_url ) . "'>" . esc_html__( 'automatically', 'ewww-image-optimizer' ) . '</a>',
791
  '<a href="https://docs.ewww.io/article/95-installing-svgcleaner" data-beacon-article="5f7921c9cff47e001a58adbc">' . esc_html__( 'manually', 'ewww-image-optimizer' ) . '</a>'
792
  ) .
3061
  $quality = 75;
3062
  }
3063
  $sharp_yuv = defined( 'EIO_WEBP_SHARP_YUV' ) && EIO_WEBP_SHARP_YUV ? '-sharp_yuv' : '';
3064
+ if ( empty( $sharp_yuv ) && ewww_image_optimizer_get_option( 'ewww_image_optimizer_sharpen' ) ) {
3065
+ $sharp_yuv = '-sharp_yuv';
3066
+ }
3067
+ $lossless = '-lossless';
3068
  if ( defined( 'EWWW_IMAGE_OPTIMIZER_LOSSY_PNG2WEBP' ) && EWWW_IMAGE_OPTIMIZER_LOSSY_PNG2WEBP ) {
3069
  $lossless = "-q $quality $sharp_yuv";
3070
  }