EWWW Image Optimizer - Version 4.8.1

Version Description

  • added: Lazy Load background image support added for span elements
  • changed: constrain by height for background images that are taller than they are wide
  • changed: debug.log moved to more suitable location
  • fix: Lazy Load breaks when an image has an empty class attribute
  • fix: regression that caused jpegtran and pngout tests to fail on Windows
  • fix: writing to debug.log causes errors
Download this release

Release Info

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

Code changes from version 4.8.0 to 4.8.1

.travis.yml CHANGED
@@ -17,6 +17,9 @@ php:
17
  - 7.1
18
  - 7.2
19
 
 
 
 
20
  env:
21
  - WP_VERSION=latest WP_MULTISITE=0
22
  - WP_VERSION=4.9 WP_MULTISITE=0
17
  - 7.1
18
  - 7.2
19
 
20
+ services:
21
+ - mysql
22
+
23
  env:
24
  - WP_VERSION=latest WP_MULTISITE=0
25
  - WP_VERSION=4.9 WP_MULTISITE=0
aux-optimize.php CHANGED
@@ -137,7 +137,8 @@ function ewww_image_optimizer_aux_images() {
137
  */
138
  function ewww_image_optimizer_aux_images_table() {
139
  // Verify that an authorized user has called function.
140
- if ( ! wp_verify_nonce( $_REQUEST['ewww_wpnonce'], 'ewww-image-optimizer-bulk' ) ) {
 
141
  ewwwio_ob_clean();
142
  die( esc_html__( 'Access token has expired, please reload the page.', 'ewww-image-optimizer' ) );
143
  }
@@ -249,7 +250,8 @@ function ewww_image_optimizer_aux_images_table() {
249
  */
250
  function ewww_image_optimizer_aux_images_remove() {
251
  // Verify that an authorized user has called function.
252
- if ( ! wp_verify_nonce( $_REQUEST['ewww_wpnonce'], 'ewww-image-optimizer-bulk' ) ) {
 
253
  ewwwio_ob_clean();
254
  die( esc_html__( 'Access token has expired, please reload the page.', 'ewww-image-optimizer' ) );
255
  }
@@ -267,6 +269,29 @@ function ewww_image_optimizer_aux_images_remove() {
267
  die();
268
  }
269
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
270
  /**
271
  * Find the number of optimized images in the ewwwio_images table.
272
  *
137
  */
138
  function ewww_image_optimizer_aux_images_table() {
139
  // Verify that an authorized user has called function.
140
+ $permissions = apply_filters( 'ewww_image_optimizer_bulk_permissions', '' );
141
+ if ( ! wp_verify_nonce( $_REQUEST['ewww_wpnonce'], 'ewww-image-optimizer-bulk' ) || ! current_user_can( $permissions ) ) {
142
  ewwwio_ob_clean();
143
  die( esc_html__( 'Access token has expired, please reload the page.', 'ewww-image-optimizer' ) );
144
  }
250
  */
251
  function ewww_image_optimizer_aux_images_remove() {
252
  // Verify that an authorized user has called function.
253
+ $permissions = apply_filters( 'ewww_image_optimizer_bulk_permissions', '' );
254
+ if ( ! wp_verify_nonce( $_REQUEST['ewww_wpnonce'], 'ewww-image-optimizer-bulk' ) || ! current_user_can( $permissions ) ) {
255
  ewwwio_ob_clean();
256
  die( esc_html__( 'Access token has expired, please reload the page.', 'ewww-image-optimizer' ) );
257
  }
269
  die();
270
  }
271
 
272
+ /**
273
+ * Removes all images from the auxiliary images table.
274
+ *
275
+ * Called via AJAX, this function will return a '1' if successful.
276
+ *
277
+ * @global object $wpdb
278
+ */
279
+ function ewww_image_optimizer_aux_images_clear_all() {
280
+ // Verify that an authorized user has called function.
281
+ $permissions = apply_filters( 'ewww_image_optimizer_admin_permissions', '' );
282
+ if ( ! wp_verify_nonce( $_REQUEST['ewww_wpnonce'], 'ewww-image-optimizer-tools' ) || ! current_user_can( $permissions ) ) {
283
+ ewwwio_ob_clean();
284
+ die( esc_html__( 'Access token has expired, please reload the page.', 'ewww-image-optimizer' ) );
285
+ }
286
+ ewwwio_ob_clean();
287
+ global $wpdb;
288
+ if ( $wpdb->query( "TRUNCATE $wpdb->ewwwio_images" ) ) {
289
+ echo '1';
290
+ }
291
+ ewwwio_memory( __FUNCTION__ );
292
+ die();
293
+ }
294
+
295
  /**
296
  * Find the number of optimized images in the ewwwio_images table.
297
  *
changelog.txt CHANGED
@@ -1,3 +1,11 @@
 
 
 
 
 
 
 
 
1
  = 4.8.0 =
2
  * added: ability to resize images outside media library via scheduled or bulk optimization
3
  * added: compatibility with WP Stateless for GSC
@@ -1240,9 +1248,9 @@ You can find more information about overriding options in the [Documentation](ht
1240
  * prevent tool checks and cloud verification from firing on every page load, yikes...
1241
 
1242
  = 1.6.1 =
1243
- *fixed: temporary jpgs were not being deleted (leftovers from testing for last release)
1244
- *fixed: jpgs would not be converted to pngs if jpgs had already been optimized
1245
- *fixed: cloud service not converting gif to png
1246
 
1247
  = 1.6.0 =
1248
  * Cloud Optimization option (BETA: get your free API key at http://www.exactlywww.com/cloud/)
1
+ = 4.8.1 =
2
+ * added: Lazy Load background image support added for span elements
3
+ * changed: constrain by height for background images that are taller than they are wide
4
+ * changed: debug.log moved to more suitable location
5
+ * fix: Lazy Load breaks when an image has an empty class attribute
6
+ * fix: regression that caused jpegtran and pngout tests to fail on Windows
7
+ * fix: writing to debug.log causes errors
8
+
9
  = 4.8.0 =
10
  * added: ability to resize images outside media library via scheduled or bulk optimization
11
  * added: compatibility with WP Stateless for GSC
1248
  * prevent tool checks and cloud verification from firing on every page load, yikes...
1249
 
1250
  = 1.6.1 =
1251
+ * fixed: temporary jpgs were not being deleted (leftovers from testing for last release)
1252
+ * fixed: jpgs would not be converted to pngs if jpgs had already been optimized
1253
+ * fixed: cloud service not converting gif to png
1254
 
1255
  = 1.6.0 =
1256
  * Cloud Optimization option (BETA: get your free API key at http://www.exactlywww.com/cloud/)
classes/class-ewwwio-lazy-load.php CHANGED
@@ -211,10 +211,10 @@ class EWWWIO_Lazy_Load extends EWWWIO_Page_Parser {
211
  $srcset = $this->get_attribute( $image, 'srcset' );
212
 
213
  $placeholder_src = $this->placeholder_src;
214
- if ( false === strpos( $file, 'nggid' ) && ! preg_match( '#\.svg(\?|$)#', $file ) && apply_filters( 'ewww_image_optimizer_use_lqip', true ) && $this->parsing_exactdn && strpos( $file, $this->exactdn_domain ) ) {
215
  ewwwio_debug_message( 'using lqip' );
216
  $placeholder_src = add_query_arg( array( 'lazy' => 1 ), $file );
217
- } elseif ( $this->allow_piip && $srcset && apply_filters( 'ewww_image_optimizer_use_piip', true ) ) {
218
  ewwwio_debug_message( 'trying piip' );
219
  // Get image dimensions for PNG placeholder.
220
  list( $width, $height ) = $this->get_dimensions_from_filename( $file );
@@ -240,7 +240,7 @@ class EWWWIO_Lazy_Load extends EWWWIO_Page_Parser {
240
  ewwwio_debug_message( "creating piip of $width x $height" );
241
  $placeholder_src = $this->create_piip( $width, $height );
242
  }
243
- } elseif ( apply_filters( 'ewww_image_optimizer_use_siip', true ) ) {
244
  ewwwio_debug_message( 'trying siip' );
245
  $width = $this->get_attribute( $image, 'width' );
246
  $height = $this->get_attribute( $image, 'height' );
@@ -289,6 +289,8 @@ class EWWWIO_Lazy_Load extends EWWWIO_Page_Parser {
289
  $buffer = $this->parse_background_images( $buffer, 'div' );
290
  // Process background images on li elements.
291
  $buffer = $this->parse_background_images( $buffer, 'li' );
 
 
292
  // Images listed as picture/source elements. Mostly for NextGEN, but should work anywhere.
293
  $pictures = $this->get_picture_tags_from_html( $buffer );
294
  if ( ewww_image_optimizer_iterable( $pictures ) ) {
211
  $srcset = $this->get_attribute( $image, 'srcset' );
212
 
213
  $placeholder_src = $this->placeholder_src;
214
+ if ( false === strpos( $file, 'nggid' ) && ! preg_match( '#\.svg(\?|$)#', $file ) && apply_filters( 'ewww_image_optimizer_use_lqip', true, $file ) && $this->parsing_exactdn && strpos( $file, $this->exactdn_domain ) ) {
215
  ewwwio_debug_message( 'using lqip' );
216
  $placeholder_src = add_query_arg( array( 'lazy' => 1 ), $file );
217
+ } elseif ( $this->allow_piip && $srcset && apply_filters( 'ewww_image_optimizer_use_piip', true, $file ) ) {
218
  ewwwio_debug_message( 'trying piip' );
219
  // Get image dimensions for PNG placeholder.
220
  list( $width, $height ) = $this->get_dimensions_from_filename( $file );
240
  ewwwio_debug_message( "creating piip of $width x $height" );
241
  $placeholder_src = $this->create_piip( $width, $height );
242
  }
243
+ } elseif ( apply_filters( 'ewww_image_optimizer_use_siip', true, $file ) ) {
244
  ewwwio_debug_message( 'trying siip' );
245
  $width = $this->get_attribute( $image, 'width' );
246
  $height = $this->get_attribute( $image, 'height' );
289
  $buffer = $this->parse_background_images( $buffer, 'div' );
290
  // Process background images on li elements.
291
  $buffer = $this->parse_background_images( $buffer, 'li' );
292
+ // Process background images on li elements.
293
+ $buffer = $this->parse_background_images( $buffer, 'span' );
294
  // Images listed as picture/source elements. Mostly for NextGEN, but should work anywhere.
295
  $pictures = $this->get_picture_tags_from_html( $buffer );
296
  if ( ewww_image_optimizer_iterable( $pictures ) ) {
classes/class-ewwwio-page-parser.php CHANGED
@@ -246,7 +246,8 @@ class EWWWIO_Page_Parser {
246
  if ( 'class' === $name ) {
247
  $element = preg_replace( "#\s$name\s+[^=]#", ' ', $element );
248
  }
249
- $value = trim( $value );
 
250
  if ( $replace ) {
251
  // Don't forget, back references cannot be used in character classes.
252
  $new_element = preg_replace( '#\s' . $name . '\s*=\s*("|\')(?!\1).*?\1#is', " $name=$1$value$1", $element );
246
  if ( 'class' === $name ) {
247
  $element = preg_replace( "#\s$name\s+[^=]#", ' ', $element );
248
  }
249
+ $element = preg_replace( "#\s$name=\"\"#", ' ', $element );
250
+ $value = trim( $value );
251
  if ( $replace ) {
252
  // Don't forget, back references cannot be used in character classes.
253
  $new_element = preg_replace( '#\s' . $name . '\s*=\s*("|\')(?!\1).*?\1#is', " $name=$1$value$1", $element );
common.php CHANGED
@@ -22,7 +22,7 @@ if ( ! defined( 'ABSPATH' ) ) {
22
  exit;
23
  }
24
 
25
- define( 'EWWW_IMAGE_OPTIMIZER_VERSION', '480.0' );
26
 
27
  // Initialize a couple globals.
28
  $ewww_debug = '';
@@ -969,7 +969,7 @@ function ewww_image_optimizer_ajax_compat_check() {
969
  * Note that this is just a suggestion, it should be customized for your site.
970
  */
971
  function ewww_image_optimizer_privacy_policy_content() {
972
- if ( ! function_exists( 'wp_add_privacy_policy_content' ) ) {
973
  return;
974
  }
975
  $content = '<p class="privacy-policy-tutorial">';
@@ -2141,8 +2141,6 @@ function ewww_image_optimizer_admin_menu() {
2141
  add_media_page( esc_html__( 'Dynamic Image Debugging', 'ewww-image-optimizer' ), esc_html__( 'Dynamic Image Debugging', 'ewww-image-optimizer' ), $permissions, 'ewww-image-optimizer-dynamic-debug', 'ewww_image_optimizer_dynamic_image_debug' );
2142
  // Add Image Queue Debugging to allow clearing and checking queues.
2143
  add_media_page( esc_html__( 'Image Queue Debugging', 'ewww-image-optimizer' ), esc_html__( 'Image Queue Debugging', 'ewww-image-optimizer' ), $permissions, 'ewww-image-optimizer-queue-debug', 'ewww_image_optimizer_image_queue_debug' );
2144
- // Add debug log page for viewing the log on hosts where you can't directly access it.
2145
- /* add_media_page( esc_html__( 'EWWW IO Debug Log', 'ewww-image-optimizer' ), esc_html__( 'EWWW IO Debug Log', 'ewww-image-optimizer' ), $permissions, 'ewww-image-optimizer-debug-log-display', 'ewww_image_optimizer_debug_log_display' ); */
2146
  }
2147
  if ( is_plugin_active( 'image-store/ImStore.php' ) || is_plugin_active_for_network( 'image-store/ImStore.php' ) ) {
2148
  // Adds an optimize page for Image Store galleries and images.
@@ -8205,6 +8203,7 @@ function ewww_image_optimizer_options( $network = 'singlesite' ) {
8205
  "<li class='ewww-tab ewww-resize-nav'><span class='ewww-tab-hidden'>" . esc_html__( 'Resize', 'ewww-image-optimizer' ) . "</span></li>\n" .
8206
  "<li class='ewww-tab ewww-conversion-nav'><span class='ewww-tab-hidden'>" . esc_html__( 'Convert', 'ewww-image-optimizer' ) . "</span></li>\n" .
8207
  "<li class='ewww-tab ewww-webp-nav'><span class='ewww-tab-hidden'>" . esc_html__( 'WebP', 'ewww-image-optimizer' ) . "</span></li>\n" .
 
8208
  "<li class='ewww-tab ewww-overrides-nav'><span class='ewww-tab-hidden'><a href='https://docs.ewww.io/article/40-override-options' target='_blank'><span class='ewww-tab-hidden'>" . esc_html__( 'Overrides', 'ewww-image-optimizer' ) . "</a></span></li>\n" .
8209
  "<li class='ewww-tab ewww-support-nav'><span class='ewww-tab-hidden'>" . esc_html__( 'Support', 'ewww-image-optimizer' ) . "</span></li>\n" .
8210
  "<li class='ewww-tab ewww-contribute-nav'><span class='ewww-tab-hidden'>" . esc_html__( 'Contribute', 'ewww-image-optimizer' ) . "</span></li>\n" .
@@ -8737,7 +8736,7 @@ function ewww_image_optimizer_options( $network = 'singlesite' ) {
8737
  global $ewww_debug;
8738
  if ( ! empty( $ewww_debug ) ) {
8739
  $debug_output = '<p style="clear:both"><b>' . esc_html__( 'Debugging Information', 'ewww-image-optimizer' ) . ':</b> <button id="ewww-copy-debug" class="button button-secondary" type="button">' . esc_html__( 'Copy', 'ewww-image-optimizer' ) . '</button>';
8740
- if ( is_file( EWWW_IMAGE_OPTIMIZER_PLUGIN_PATH . 'debug.log' ) ) {
8741
  $debug_output .= "&emsp;<a href='admin.php?action=ewww_image_optimizer_view_debug_log'>" . esc_html( 'View Debug Log', 'ewww-image-optimizer' ) . "</a> - <a href='admin.php?action=ewww_image_optimizer_delete_debug_log'>" . esc_html( 'Remove Debug Log', 'ewww-image-optimizer' ) . '</a>';
8742
  }
8743
  $debug_output .= '</p>';
@@ -9016,19 +9015,6 @@ function ewwwio_debug_message( $message ) {
9016
  }
9017
  }
9018
 
9019
- /**
9020
- * Loads the logfile and displays it in the WP admin.
9021
- */
9022
- function ewww_image_optimizer_debug_log_display() {
9023
- if ( file_exists( EWWW_IMAGE_OPTIMIZER_PLUGIN_PATH . 'debug.log' ) ) {
9024
- $ewww_debug_log = file_get_contents( EWWW_IMAGE_OPTIMIZER_PLUGIN_PATH . 'debug.log' );
9025
- $ewww_debug_log = str_replace( "\n", '<br>', $ewww_debug_log );
9026
- echo $ewww_debug_log;
9027
- } else {
9028
- esc_html_e( 'The Debug Log is empty.', 'ewww-image-optimizer' );
9029
- }
9030
- }
9031
-
9032
  /**
9033
  * Saves the in-memory debug log to a logfile in the plugin folder.
9034
  *
@@ -9037,21 +9023,22 @@ function ewww_image_optimizer_debug_log_display() {
9037
  function ewww_image_optimizer_debug_log() {
9038
  global $ewww_debug;
9039
  global $ewwwio_temp_debug;
9040
- if ( ! empty( $ewww_debug ) && empty( $ewwwio_temp_debug ) && ewww_image_optimizer_get_option( 'ewww_image_optimizer_debug' ) ) {
 
9041
  $memory_limit = ewwwio_memory_limit();
9042
  clearstatcache();
9043
  $timestamp = date( 'Y-m-d H:i:s' ) . "\n";
9044
- if ( ! file_exists( EWWW_IMAGE_OPTIMIZER_PLUGIN_PATH . 'debug.log' ) ) {
9045
- touch( EWWW_IMAGE_OPTIMIZER_PLUGIN_PATH . 'debug.log' );
9046
  } else {
9047
- if ( filesize( EWWW_IMAGE_OPTIMIZER_PLUGIN_PATH . 'debug.log' ) + 4000000 + memory_get_usage( true ) > $memory_limit ) {
9048
- unlink( EWWW_IMAGE_OPTIMIZER_PLUGIN_PATH . 'debug.log' );
9049
- touch( EWWW_IMAGE_OPTIMIZER_PLUGIN_PATH . 'debug.log' );
9050
  }
9051
  }
9052
- if ( filesize( EWWW_IMAGE_OPTIMIZER_PLUGIN_PATH . 'debug.log' ) + strlen( $ewww_debug ) + 4000000 + memory_get_usage( true ) <= $memory_limit ) {
9053
  $ewww_debug = str_replace( '<br>', "\n", $ewww_debug );
9054
- file_put_contents( EWWW_IMAGE_OPTIMIZER_PLUGIN_PATH . 'debug.log', $timestamp . $ewww_debug, FILE_APPEND );
9055
  }
9056
  }
9057
  $ewww_debug = '';
@@ -9066,10 +9053,10 @@ function ewww_image_optimizer_view_debug_log() {
9066
  if ( false === current_user_can( $permissions ) ) {
9067
  wp_die( esc_html__( 'Access denied.', 'ewww-image-optimizer' ) );
9068
  }
9069
- if ( is_file( EWWW_IMAGE_OPTIMIZER_PLUGIN_PATH . 'debug.log' ) ) {
9070
  ewwwio_ob_clean();
9071
  header( 'Content-Type: text/plain;charset=UTF-8' );
9072
- readfile( EWWW_IMAGE_OPTIMIZER_PLUGIN_PATH . 'debug.log' );
9073
  exit;
9074
  }
9075
  wp_die( esc_html__( 'The Debug Log is empty.', 'ewww-image-optimizer' ) );
@@ -9083,8 +9070,8 @@ function ewww_image_optimizer_delete_debug_log() {
9083
  if ( false === current_user_can( $permissions ) ) {
9084
  wp_die( esc_html__( 'Access denied.', 'ewww-image-optimizer' ) );
9085
  }
9086
- if ( is_file( EWWW_IMAGE_OPTIMIZER_PLUGIN_PATH . 'debug.log' ) ) {
9087
- unlink( EWWW_IMAGE_OPTIMIZER_PLUGIN_PATH . 'debug.log' );
9088
  }
9089
  $sendback = wp_get_referer();
9090
  wp_redirect( esc_url_raw( $sendback ) );
22
  exit;
23
  }
24
 
25
+ define( 'EWWW_IMAGE_OPTIMIZER_VERSION', '481.0' );
26
 
27
  // Initialize a couple globals.
28
  $ewww_debug = '';
969
  * Note that this is just a suggestion, it should be customized for your site.
970
  */
971
  function ewww_image_optimizer_privacy_policy_content() {
972
+ if ( ! function_exists( 'wp_add_privacy_policy_content' ) || ! function_exists( 'wp_kses_post' ) ) {
973
  return;
974
  }
975
  $content = '<p class="privacy-policy-tutorial">';
2141
  add_media_page( esc_html__( 'Dynamic Image Debugging', 'ewww-image-optimizer' ), esc_html__( 'Dynamic Image Debugging', 'ewww-image-optimizer' ), $permissions, 'ewww-image-optimizer-dynamic-debug', 'ewww_image_optimizer_dynamic_image_debug' );
2142
  // Add Image Queue Debugging to allow clearing and checking queues.
2143
  add_media_page( esc_html__( 'Image Queue Debugging', 'ewww-image-optimizer' ), esc_html__( 'Image Queue Debugging', 'ewww-image-optimizer' ), $permissions, 'ewww-image-optimizer-queue-debug', 'ewww_image_optimizer_image_queue_debug' );
 
 
2144
  }
2145
  if ( is_plugin_active( 'image-store/ImStore.php' ) || is_plugin_active_for_network( 'image-store/ImStore.php' ) ) {
2146
  // Adds an optimize page for Image Store galleries and images.
8203
  "<li class='ewww-tab ewww-resize-nav'><span class='ewww-tab-hidden'>" . esc_html__( 'Resize', 'ewww-image-optimizer' ) . "</span></li>\n" .
8204
  "<li class='ewww-tab ewww-conversion-nav'><span class='ewww-tab-hidden'>" . esc_html__( 'Convert', 'ewww-image-optimizer' ) . "</span></li>\n" .
8205
  "<li class='ewww-tab ewww-webp-nav'><span class='ewww-tab-hidden'>" . esc_html__( 'WebP', 'ewww-image-optimizer' ) . "</span></li>\n" .
8206
+ // "<li class='ewww-tab ewww-tools-nav'><span class='ewww-tab-hidden'>" . esc_html__( 'Tools', 'ewww-image-optimizer' ) . "</span></li>\n" .
8207
  "<li class='ewww-tab ewww-overrides-nav'><span class='ewww-tab-hidden'><a href='https://docs.ewww.io/article/40-override-options' target='_blank'><span class='ewww-tab-hidden'>" . esc_html__( 'Overrides', 'ewww-image-optimizer' ) . "</a></span></li>\n" .
8208
  "<li class='ewww-tab ewww-support-nav'><span class='ewww-tab-hidden'>" . esc_html__( 'Support', 'ewww-image-optimizer' ) . "</span></li>\n" .
8209
  "<li class='ewww-tab ewww-contribute-nav'><span class='ewww-tab-hidden'>" . esc_html__( 'Contribute', 'ewww-image-optimizer' ) . "</span></li>\n" .
8736
  global $ewww_debug;
8737
  if ( ! empty( $ewww_debug ) ) {
8738
  $debug_output = '<p style="clear:both"><b>' . esc_html__( 'Debugging Information', 'ewww-image-optimizer' ) . ':</b> <button id="ewww-copy-debug" class="button button-secondary" type="button">' . esc_html__( 'Copy', 'ewww-image-optimizer' ) . '</button>';
8739
+ if ( is_file( WP_CONTENT_DIR . '/ewww/debug.log' ) ) {
8740
  $debug_output .= "&emsp;<a href='admin.php?action=ewww_image_optimizer_view_debug_log'>" . esc_html( 'View Debug Log', 'ewww-image-optimizer' ) . "</a> - <a href='admin.php?action=ewww_image_optimizer_delete_debug_log'>" . esc_html( 'Remove Debug Log', 'ewww-image-optimizer' ) . '</a>';
8741
  }
8742
  $debug_output .= '</p>';
9015
  }
9016
  }
9017
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9018
  /**
9019
  * Saves the in-memory debug log to a logfile in the plugin folder.
9020
  *
9023
  function ewww_image_optimizer_debug_log() {
9024
  global $ewww_debug;
9025
  global $ewwwio_temp_debug;
9026
+ $debug_log = WP_CONTENT_DIR . '/ewww/debug.log';
9027
+ if ( ! empty( $ewww_debug ) && empty( $ewwwio_temp_debug ) && ewww_image_optimizer_get_option( 'ewww_image_optimizer_debug' ) && is_writable( WP_CONTENT_DIR . '/ewww/' ) ) {
9028
  $memory_limit = ewwwio_memory_limit();
9029
  clearstatcache();
9030
  $timestamp = date( 'Y-m-d H:i:s' ) . "\n";
9031
+ if ( ! file_exists( $debug_log ) ) {
9032
+ touch( $debug_log );
9033
  } else {
9034
+ if ( filesize( $debug_log ) + 4000000 + memory_get_usage( true ) > $memory_limit ) {
9035
+ unlink( $debug_log );
9036
+ touch( $debug_log );
9037
  }
9038
  }
9039
+ if ( filesize( $debug_log ) + strlen( $ewww_debug ) + 4000000 + memory_get_usage( true ) <= $memory_limit && is_writable( $debug_log ) ) {
9040
  $ewww_debug = str_replace( '<br>', "\n", $ewww_debug );
9041
+ file_put_contents( $debug_log, $timestamp . $ewww_debug, FILE_APPEND );
9042
  }
9043
  }
9044
  $ewww_debug = '';
9053
  if ( false === current_user_can( $permissions ) ) {
9054
  wp_die( esc_html__( 'Access denied.', 'ewww-image-optimizer' ) );
9055
  }
9056
+ if ( is_file( WP_CONTENT_DIR . '/ewww/debug.log' ) ) {
9057
  ewwwio_ob_clean();
9058
  header( 'Content-Type: text/plain;charset=UTF-8' );
9059
+ readfile( WP_CONTENT_DIR . '/ewww/debug.log' );
9060
  exit;
9061
  }
9062
  wp_die( esc_html__( 'The Debug Log is empty.', 'ewww-image-optimizer' ) );
9070
  if ( false === current_user_can( $permissions ) ) {
9071
  wp_die( esc_html__( 'Access denied.', 'ewww-image-optimizer' ) );
9072
  }
9073
+ if ( is_file( WP_CONTENT_DIR . '/ewww/debug.log' ) ) {
9074
+ unlink( WP_CONTENT_DIR . '/ewww/debug.log' );
9075
  }
9076
  $sendback = wp_get_referer();
9077
  wp_redirect( esc_url_raw( $sendback ) );
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: Reduce file sizes for images within WordPress including NextGEN Gallery and GRAND FlAGallery. Uses jpegtran, optipng/pngout, and gifsicle.
15
  Author: Exactly WWW
16
- Version: 4.8.0
17
  Author URI: https://ewww.io/
18
  License: GPLv3
19
  */
13
  Plugin URI: https://wordpress.org/plugins/ewww-image-optimizer/
14
  Description: Reduce file sizes for images within WordPress including NextGEN Gallery and GRAND FlAGallery. Uses jpegtran, optipng/pngout, and gifsicle.
15
  Author: Exactly WWW
16
+ Version: 4.8.1
17
  Author URI: https://ewww.io/
18
  License: GPLv3
19
  */
includes/lazysizes-post.js CHANGED
@@ -1,5 +1,8 @@
1
  lazysizesWebP('alpha', lazySizes.init);
2
  function constrainSrc(url,objectWidth,objectHeight,objectType){
 
 
 
3
  var regW = /w=(\d+)/;
4
  var regFit = /fit=(\d+),(\d+)/;
5
  var regResize = /resize=(\d+),(\d+)/;
@@ -30,6 +33,9 @@ function constrainSrc(url,objectWidth,objectHeight,objectType){
30
  if('bg-cover'===objectType){
31
  return url + '?resize=' + objectWidth + ',' + objectHeight;
32
  }
 
 
 
33
  return url + '&w=' + objectWidth;
34
  }
35
  }
@@ -40,6 +46,9 @@ function constrainSrc(url,objectWidth,objectHeight,objectType){
40
  if('bg-cover'===objectType){
41
  return url + '?resize=' + objectWidth + ',' + objectHeight;
42
  }
 
 
 
43
  return url + '?w=' + objectWidth;
44
  }
45
  return url;
1
  lazysizesWebP('alpha', lazySizes.init);
2
  function constrainSrc(url,objectWidth,objectHeight,objectType){
3
+ if (url===null){
4
+ return url;
5
+ }
6
  var regW = /w=(\d+)/;
7
  var regFit = /fit=(\d+),(\d+)/;
8
  var regResize = /resize=(\d+),(\d+)/;
33
  if('bg-cover'===objectType){
34
  return url + '?resize=' + objectWidth + ',' + objectHeight;
35
  }
36
+ if(objectHeight>objectWidth){
37
+ return url + '&h=' + objectHeight;
38
+ }
39
  return url + '&w=' + objectWidth;
40
  }
41
  }
46
  if('bg-cover'===objectType){
47
  return url + '?resize=' + objectWidth + ',' + objectHeight;
48
  }
49
+ if(objectHeight>objectWidth){
50
+ return url + '?h=' + objectHeight;
51
+ }
52
  return url + '?w=' + objectWidth;
53
  }
54
  return url;
includes/lazysizes.min.js CHANGED
@@ -1 +1 @@
1
- var ewww_webp_supported=!1;function lazysizesWebP(e,t){var a=new Image;a.onload=function(){ewww_webp_supported=0<a.width&&0<a.height,t()},a.onerror=function(){t()},a.src="data:image/webp;base64,"+{alpha:"UklGRkoAAABXRUJQVlA4WAoAAAAQAAAAAAAAAAAAQUxQSAwAAAARBxAR/Q9ERP8DAABWUDggGAAAABQBAJ0BKgEAAQAAAP4AAA3AAP7mtQAAAA==",animation:"UklGRlIAAABXRUJQVlA4WAoAAAASAAAAAAAAAAAAQU5JTQYAAAD/////AABBTk1GJgAAAAAAAAAAAAAAAAAAAGQAAABWUDhMDQAAAC8AAAAQBxAREYiI/gcA"}[e]}function constrainSrc(e,t,a,i){var r=/w=(\d+)/,n=/fit=(\d+),(\d+)/,o=/resize=(\d+),(\d+)/,s=decodeURIComponent(e);if(0<e.search("\\?")&&0<e.search(ewww_lazy_vars.exactdn_domain)){var l=o.exec(s);if(l&&t<l[1])return s.replace(o,"resize="+t+","+a);var d=r.exec(e);if(d&&t<=d[1])return"bg-cover"===i?e.replace(r,"resize="+t+","+a):e.replace(r,"w="+t);var c=n.exec(s);if(c&&t<c[1])return"bg-cover"===i?e.replace(r,"resize="+t+","+a):s.replace(n,"fit="+t+","+a);if(!d&&!c&&!l)return"img"===i?e+"&fit="+t+","+a:"bg-cover"===i?e+"?resize="+t+","+a:e+"&w="+t}return-1==e.search("\\?")&&0<e.search(ewww_lazy_vars.exactdn_domain)?"img"===i?e+"?fit="+t+","+a:"bg-cover"===i?e+"?resize="+t+","+a:e+"?w="+t:e}window.lazySizesConfig=window.lazySizesConfig||{},window.lazySizesConfig.init=!1,function(e,t){var a=function(i,A){"use strict";if(!A.getElementsByClassName)return;var g,z,v=A.documentElement,n=i.Date,r=i.HTMLPictureElement,o="addEventListener",h="getAttribute",t=i[o],u=i.setTimeout,a=i.requestAnimationFrame||u,s=i.requestIdleCallback,f=/^picture$/i,l=["load","error","lazyincluded","_lazyloaded"],d={},p=Array.prototype.forEach,c=function(e,t){return d[t]||(d[t]=new RegExp("(\\s|^)"+t+"(\\s|$)")),d[t].test(e[h]("class")||"")&&d[t]},m=function(e,t){c(e,t)||e.setAttribute("class",(e[h]("class")||"").trim()+" "+t)},y=function(e,t){var a;(a=c(e,t))&&e.setAttribute("class",(e[h]("class")||"").replace(a," "))},b=function(t,a,e){var i=e?o:"removeEventListener";e&&b(t,a),l.forEach(function(e){t[i](e,a)})},w=function(e,t,a,i,r){var n=A.createEvent("Event");return a||(a={}),a.instance=g,n.initEvent(t,!i,!r),n.detail=a,e.dispatchEvent(n),n},C=function(e,t){var a;!r&&(a=i.picturefill||z.pf)?(t&&t.src&&!e[h]("srcset")&&e.setAttribute("srcset",t.src),a({reevaluate:!0,elements:[e]})):t&&t.src&&(e.src=t.src)},_=function(e,t){return(getComputedStyle(e,null)||{})[t]},E=function(e,t,a){for(a=a||e.offsetWidth;a<z.minSize&&t&&!e._lazysizesWidth;)a=t.offsetWidth,t=t.parentNode;return a},W=(B=[],R=[],L=B,N=function(){var e=L;for(L=B.length?R:B,M=!(S=!0);e.length;)e.shift()();S=!1},Q=function(e,t){S&&!t?e.apply(this,arguments):(L.push(e),M||(M=!0,(A.hidden?u:a)(N)))},Q._lsFlush=N,Q),e=function(a,e){return e?function(){W(a)}:function(){var e=this,t=arguments;W(function(){a.apply(e,t)})}},x=function(e){var t,a,i=function(){t=null,e()},r=function(){var e=n.now()-a;e<99?u(r,99-e):(s||i)(i)};return function(){a=n.now(),t||(t=u(r,99))}};var S,M,B,R,L,N,Q;!function(){var e,t={lazyClass:"lazyload",loadedClass:"lazyloaded",loadingClass:"lazyloading",preloadClass:"lazypreload",errorClass:"lazyerror",autosizesClass:"lazyautosizes",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 z=i.lazySizesConfig||i.lazysizesConfig||{},t)e in z||(z[e]=t[e]);i.lazySizesConfig=z,u(function(){z.init&&D()})}();var P=(se=/^img$/i,le=/^iframe$/i,de="onscroll"in i&&!/(gle|ing)bot/.test(navigator.userAgent),ce=0,ue=0,fe=-1,Ae=function(e){ue--,(!e||ue<0||!e.target)&&(ue=0)},ge=function(e){return null==Z&&(Z="hidden"==_(A.body,"visibility")),Z||"hidden"!=_(e.parentNode,"visibility")&&"hidden"!=_(e,"visibility")},ze=function(e,t){var a,i=e,r=ge(e);for(V-=t,K+=t,X-=t,Y+=t;r&&(i=i.offsetParent)&&i!=A.body&&i!=v;)(r=0<(_(i,"opacity")||1))&&"visible"!=_(i,"overflow")&&(a=i.getBoundingClientRect(),r=Y>a.left&&X<a.right&&K>a.top-1&&V<a.bottom+1);return r},ve=function(){var e,t,a,i,r,n,o,s,l,d,c,u,f=g.elements;if((G=z.loadMode)&&ue<8&&(e=f.length)){for(t=0,fe++,d=!z.expand||z.expand<1?500<v.clientHeight&&500<v.clientWidth?500:370:z.expand,g._defEx=d,c=d*z.expFactor,u=z.hFac,Z=null,ce<c&&ue<1&&2<fe&&2<G&&!A.hidden?(ce=c,fe=0):ce=1<G&&1<fe&&ue<6?d:0;t<e;t++)if(f[t]&&!f[t]._lazyRace)if(de)if((s=f[t][h]("data-expand"))&&(n=1*s)||(n=ce),l!==n&&(q=innerWidth+n*u,j=innerHeight+n,o=-1*n,l=n),a=f[t].getBoundingClientRect(),(K=a.bottom)>=o&&(V=a.top)<=j&&(Y=a.right)>=o*u&&(X=a.left)<=q&&(K||Y||X||V)&&(z.loadHidden||ge(f[t]))&&(J&&ue<3&&!s&&(G<3||fe<4)||ze(f[t],n))){if(Ce(f[t]),r=!0,9<ue)break}else!r&&J&&!i&&ue<4&&fe<4&&2<G&&(I[0]||z.preloadAfterLoad)&&(I[0]||!s&&(K||Y||X||V||"auto"!=f[t][h](z.sizesAttr)))&&(i=I[0]||f[t]);else Ce(f[t]);i&&!r&&Ce(i)}},ee=ve,ae=0,ie=z.throttleDelay,re=z.ricTimeout,ne=function(){te=!1,ae=n.now(),ee()},oe=s&&49<re?function(){s(ne,{timeout:re}),re!==z.ricTimeout&&(re=z.ricTimeout)}:e(function(){u(ne)},!0),he=function(e){var t;(e=!0===e)&&(re=33),te||(te=!0,(t=ie-(n.now()-ae))<0&&(t=0),e||t<9?oe():u(oe,t))},pe=function(e){var t=e.target;t._lazyCache?delete t._lazyCache:(Ae(e),m(t,z.loadedClass),y(t,z.loadingClass),b(t,ye),w(t,"lazyloaded"))},me=e(pe),ye=function(e){me({target:e.target})},be=function(e){var t,a=e[h](z.srcsetAttr);(t=z.customMedia[e[h]("data-media")||e[h]("media")])&&e.setAttribute("media",t),a&&e.setAttribute("srcset",a)},we=e(function(e,t,a,i,r){var n,o,s,l,d,c;(d=w(e,"lazybeforeunveil",t)).defaultPrevented||(i&&(a?m(e,z.autosizesClass):e.setAttribute("sizes",i)),o=e[h](z.srcsetAttr),n=e[h](z.srcAttr),r&&(s=e.parentNode,l=s&&f.test(s.nodeName||"")),c=t.firesLoad||"src"in e&&(o||n||l),d={target:e},m(e,z.loadingClass),c&&(clearTimeout(O),O=u(Ae,2500),b(e,ye,!0)),l&&p.call(s.getElementsByTagName("source"),be),o?e.setAttribute("srcset",o):n&&!l&&(le.test(e.nodeName)?function(t,a){try{t.contentWindow.location.replace(a)}catch(e){t.src=a}}(e,n):e.src=n),r&&(o||l)&&C(e,{src:n})),e._lazyRace&&delete e._lazyRace,y(e,z.lazyClass),W(function(){(!c||e.complete&&1<e.naturalWidth)&&(pe(d),e._lazyCache=!0,u(function(){"_lazyCache"in e&&delete e._lazyCache},9))},!0)}),Ce=function(e){var t,a=se.test(e.nodeName),i=a&&(e[h](z.sizesAttr)||e[h]("sizes")),r="auto"==i;(!r&&J||!a||!e[h]("src")&&!e.srcset||e.complete||c(e,z.errorClass)||!c(e,z.lazyClass))&&(t=w(e,"lazyunveilread").detail,r&&k.updateElem(e,!0,e.offsetWidth),e._lazyRace=!0,ue++,we(e,t,r,i,a))},_e=function(){if(!J)if(n.now()-$<999)u(_e,999);else{var e=x(function(){z.loadMode=3,he()});J=!0,z.loadMode=3,he(),t("scroll",function(){3==z.loadMode&&(z.loadMode=2),e()},!0)}},{_:function(){$=n.now(),g.elements=A.getElementsByClassName(z.lazyClass),I=A.getElementsByClassName(z.lazyClass+" "+z.preloadClass),t("scroll",he,!0),t("resize",he,!0),i.MutationObserver?new MutationObserver(he).observe(v,{childList:!0,subtree:!0,attributes:!0}):(v[o]("DOMNodeInserted",he,!0),v[o]("DOMAttrModified",he,!0),setInterval(he,999)),t("hashchange",he,!0),["focus","mouseover","click","load","transitionend","animationend","webkitAnimationEnd"].forEach(function(e){A[o](e,he,!0)}),/d$|^c/.test(A.readyState)?_e():(t("load",_e),A[o]("DOMContentLoaded",he),u(_e,2e4)),g.elements.length?(ve(),W._lsFlush()):he()},checkElems:he,unveil:Ce}),k=(H=e(function(e,t,a,i){var r,n,o;if(e._lazysizesWidth=i,i+="px",e.setAttribute("sizes",i),f.test(t.nodeName||""))for(r=t.getElementsByTagName("source"),n=0,o=r.length;n<o;n++)r[n].setAttribute("sizes",i);a.detail.dataAttr||C(e,a.detail)}),U=function(e,t,a){var i,r=e.parentNode;r&&(a=E(e,r,a),(i=w(e,"lazybeforesizes",{width:a,dataAttr:!!t})).defaultPrevented||(a=i.detail.width)&&a!==e._lazysizesWidth&&H(e,r,i,a))},F=x(function(){var e,t=T.length;if(t)for(e=0;e<t;e++)U(T[e])}),{_:function(){T=A.getElementsByClassName(z.autosizesClass),t("resize",F)},checkElems:F,updateElem:U}),D=function(){D.i||(D.i=!0,k._(),P._())};var T,H,U,F;var I,J,O,G,$,q,j,V,X,Y,K,Z,ee,te,ae,ie,re,ne,oe,se,le,de,ce,ue,fe,Ae,ge,ze,ve,he,pe,me,ye,be,we,Ce,_e;return g={cfg:z,autoSizer:k,loader:P,init:D,uP:C,aC:m,rC:y,hC:c,fire:w,gW:E,rAF:W}}(e,e.document);e.lazySizes=a,"object"==typeof module&&module.exports&&(module.exports=a)}(window),lazysizesWebP("alpha",lazySizes.init),document.addEventListener("lazybeforeunveil",function(e){var t=e.target,a=t.getAttribute("data-srcset");if(!a&&t.naturalWidth&&1<t.naturalWidth&&1<t.naturalHeight){var i=window.devicePixelRatio||1,r=1.25*t.clientWidth<t.naturalWidth,n=1.25*t.clientHeight<t.naturalHeight;if(r||n){var o=Math.round(t.offsetWidth*i),s=Math.round(t.offsetHeight*i),l=t.getAttribute("data-src"),d=t.getAttribute("data-src-webp");ewww_webp_supported&&d&&-1==l.search("webp=1")&&(l=d);var c=constrainSrc(l,o,s,"img");c&&l!=c&&t.setAttribute("data-src",c)}}if(ewww_webp_supported){if(a&&-1<a.search("webp=1"))return;if(a){var u=t.getAttribute("data-srcset-webp");u&&t.setAttribute("data-srcset",u)}if((l=t.getAttribute("data-src"))&&-1<l.search("webp=1"))return;if(!(d=t.getAttribute("data-src-webp")))return;t.setAttribute("data-src",d)}}),function(e,t){var a=function(){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(s,i,l){"use strict";var d,c;i.addEventListener&&(d=function(e,t){var a=i.createElement("img");a.onload=function(){a.onload=null,a.onerror=null,a=null,t()},a.onerror=a.onload,a.src=e,a&&a.complete&&a.onload&&a.onload()},addEventListener("lazybeforeunveil",function(e){var t,a,i;if(e.detail.instance==l&&!e.defaultPrevented){if("none"==e.target.preload&&(e.target.preload="auto"),t=e.target.getAttribute("data-bg")){ewww_webp_supported&&(a=e.target.getAttribute("data-bg-webp"))&&(t=a);var r=s.devicePixelRatio||1,n=Math.round(e.target.offsetWidth*r),o=Math.round(e.target.offsetHeight*r);t=s.lazySizes.hC(e.target,"wp-block-cover")?constrainSrc(t,n,o,"bg-cover"):constrainSrc(t,n,o,"bg"),e.detail.firesLoad=!0,d(t,function(){e.target.style.backgroundImage="url("+(c.test(t)?JSON.stringify(t):t)+")",e.detail.firesLoad=!1,l.fire(e.target,"_lazyloaded",{},!0,!0)})}(i=e.target.getAttribute("data-poster"))&&(e.detail.firesLoad=!0,d(i,function(){e.target.poster=i,e.detail.firesLoad=!1,l.fire(e.target,"_lazyloaded",{},!0,!0)}))}},!(c=/\(|\)|\s|'/)))});
1
+ var ewww_webp_supported=!1;function lazysizesWebP(e,t){var a=new Image;a.onload=function(){ewww_webp_supported=0<a.width&&0<a.height,t()},a.onerror=function(){t()},a.src="data:image/webp;base64,"+{alpha:"UklGRkoAAABXRUJQVlA4WAoAAAAQAAAAAAAAAAAAQUxQSAwAAAARBxAR/Q9ERP8DAABWUDggGAAAABQBAJ0BKgEAAQAAAP4AAA3AAP7mtQAAAA==",animation:"UklGRlIAAABXRUJQVlA4WAoAAAASAAAAAAAAAAAAQU5JTQYAAAD/////AABBTk1GJgAAAAAAAAAAAAAAAAAAAGQAAABWUDhMDQAAAC8AAAAQBxAREYiI/gcA"}[e]}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(0<e.search("\\?")&&0<e.search(ewww_lazy_vars.exactdn_domain)){var l=o.exec(s);if(l&&t<l[1])return s.replace(o,"resize="+t+","+a);var d=r.exec(e);if(d&&t<=d[1])return"bg-cover"===i?e.replace(r,"resize="+t+","+a):e.replace(r,"w="+t);var c=n.exec(s);if(c&&t<c[1])return"bg-cover"===i?e.replace(r,"resize="+t+","+a):s.replace(n,"fit="+t+","+a);if(!d&&!c&&!l)return"img"===i?e+"&fit="+t+","+a:"bg-cover"===i?e+"?resize="+t+","+a:t<a?e+"&h="+a:e+"&w="+t}return-1==e.search("\\?")&&0<e.search(ewww_lazy_vars.exactdn_domain)?"img"===i?e+"?fit="+t+","+a:"bg-cover"===i?e+"?resize="+t+","+a:t<a?e+"?h="+a:e+"?w="+t:e}window.lazySizesConfig=window.lazySizesConfig||{},window.lazySizesConfig.init=!1,function(e,t){var a=function(i,A){"use strict";if(!A.getElementsByClassName)return;var g,z,v=A.documentElement,n=i.Date,r=i.HTMLPictureElement,o="addEventListener",h="getAttribute",t=i[o],u=i.setTimeout,a=i.requestAnimationFrame||u,s=i.requestIdleCallback,f=/^picture$/i,l=["load","error","lazyincluded","_lazyloaded"],d={},p=Array.prototype.forEach,c=function(e,t){return d[t]||(d[t]=new RegExp("(\\s|^)"+t+"(\\s|$)")),d[t].test(e[h]("class")||"")&&d[t]},m=function(e,t){c(e,t)||e.setAttribute("class",(e[h]("class")||"").trim()+" "+t)},y=function(e,t){var a;(a=c(e,t))&&e.setAttribute("class",(e[h]("class")||"").replace(a," "))},b=function(t,a,e){var i=e?o:"removeEventListener";e&&b(t,a),l.forEach(function(e){t[i](e,a)})},w=function(e,t,a,i,r){var n=A.createEvent("Event");return a||(a={}),a.instance=g,n.initEvent(t,!i,!r),n.detail=a,e.dispatchEvent(n),n},C=function(e,t){var a;!r&&(a=i.picturefill||z.pf)?(t&&t.src&&!e[h]("srcset")&&e.setAttribute("srcset",t.src),a({reevaluate:!0,elements:[e]})):t&&t.src&&(e.src=t.src)},_=function(e,t){return(getComputedStyle(e,null)||{})[t]},E=function(e,t,a){for(a=a||e.offsetWidth;a<z.minSize&&t&&!e._lazysizesWidth;)a=t.offsetWidth,t=t.parentNode;return a},W=(B=[],R=[],L=B,N=function(){var e=L;for(L=B.length?R:B,M=!(S=!0);e.length;)e.shift()();S=!1},Q=function(e,t){S&&!t?e.apply(this,arguments):(L.push(e),M||(M=!0,(A.hidden?u:a)(N)))},Q._lsFlush=N,Q),e=function(a,e){return e?function(){W(a)}:function(){var e=this,t=arguments;W(function(){a.apply(e,t)})}},x=function(e){var t,a,i=function(){t=null,e()},r=function(){var e=n.now()-a;e<99?u(r,99-e):(s||i)(i)};return function(){a=n.now(),t||(t=u(r,99))}};var S,M,B,R,L,N,Q;!function(){var e,t={lazyClass:"lazyload",loadedClass:"lazyloaded",loadingClass:"lazyloading",preloadClass:"lazypreload",errorClass:"lazyerror",autosizesClass:"lazyautosizes",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 z=i.lazySizesConfig||i.lazysizesConfig||{},t)e in z||(z[e]=t[e]);i.lazySizesConfig=z,u(function(){z.init&&D()})}();var P=(se=/^img$/i,le=/^iframe$/i,de="onscroll"in i&&!/(gle|ing)bot/.test(navigator.userAgent),ce=0,ue=0,fe=-1,Ae=function(e){ue--,(!e||ue<0||!e.target)&&(ue=0)},ge=function(e){return null==Z&&(Z="hidden"==_(A.body,"visibility")),Z||"hidden"!=_(e.parentNode,"visibility")&&"hidden"!=_(e,"visibility")},ze=function(e,t){var a,i=e,r=ge(e);for(V-=t,K+=t,X-=t,Y+=t;r&&(i=i.offsetParent)&&i!=A.body&&i!=v;)(r=0<(_(i,"opacity")||1))&&"visible"!=_(i,"overflow")&&(a=i.getBoundingClientRect(),r=Y>a.left&&X<a.right&&K>a.top-1&&V<a.bottom+1);return r},ve=function(){var e,t,a,i,r,n,o,s,l,d,c,u,f=g.elements;if((G=z.loadMode)&&ue<8&&(e=f.length)){for(t=0,fe++,d=!z.expand||z.expand<1?500<v.clientHeight&&500<v.clientWidth?500:370:z.expand,g._defEx=d,c=d*z.expFactor,u=z.hFac,Z=null,ce<c&&ue<1&&2<fe&&2<G&&!A.hidden?(ce=c,fe=0):ce=1<G&&1<fe&&ue<6?d:0;t<e;t++)if(f[t]&&!f[t]._lazyRace)if(de)if((s=f[t][h]("data-expand"))&&(n=1*s)||(n=ce),l!==n&&(q=innerWidth+n*u,j=innerHeight+n,o=-1*n,l=n),a=f[t].getBoundingClientRect(),(K=a.bottom)>=o&&(V=a.top)<=j&&(Y=a.right)>=o*u&&(X=a.left)<=q&&(K||Y||X||V)&&(z.loadHidden||ge(f[t]))&&(J&&ue<3&&!s&&(G<3||fe<4)||ze(f[t],n))){if(Ce(f[t]),r=!0,9<ue)break}else!r&&J&&!i&&ue<4&&fe<4&&2<G&&(I[0]||z.preloadAfterLoad)&&(I[0]||!s&&(K||Y||X||V||"auto"!=f[t][h](z.sizesAttr)))&&(i=I[0]||f[t]);else Ce(f[t]);i&&!r&&Ce(i)}},ee=ve,ae=0,ie=z.throttleDelay,re=z.ricTimeout,ne=function(){te=!1,ae=n.now(),ee()},oe=s&&49<re?function(){s(ne,{timeout:re}),re!==z.ricTimeout&&(re=z.ricTimeout)}:e(function(){u(ne)},!0),he=function(e){var t;(e=!0===e)&&(re=33),te||(te=!0,(t=ie-(n.now()-ae))<0&&(t=0),e||t<9?oe():u(oe,t))},pe=function(e){var t=e.target;t._lazyCache?delete t._lazyCache:(Ae(e),m(t,z.loadedClass),y(t,z.loadingClass),b(t,ye),w(t,"lazyloaded"))},me=e(pe),ye=function(e){me({target:e.target})},be=function(e){var t,a=e[h](z.srcsetAttr);(t=z.customMedia[e[h]("data-media")||e[h]("media")])&&e.setAttribute("media",t),a&&e.setAttribute("srcset",a)},we=e(function(e,t,a,i,r){var n,o,s,l,d,c;(d=w(e,"lazybeforeunveil",t)).defaultPrevented||(i&&(a?m(e,z.autosizesClass):e.setAttribute("sizes",i)),o=e[h](z.srcsetAttr),n=e[h](z.srcAttr),r&&(s=e.parentNode,l=s&&f.test(s.nodeName||"")),c=t.firesLoad||"src"in e&&(o||n||l),d={target:e},m(e,z.loadingClass),c&&(clearTimeout(O),O=u(Ae,2500),b(e,ye,!0)),l&&p.call(s.getElementsByTagName("source"),be),o?e.setAttribute("srcset",o):n&&!l&&(le.test(e.nodeName)?function(t,a){try{t.contentWindow.location.replace(a)}catch(e){t.src=a}}(e,n):e.src=n),r&&(o||l)&&C(e,{src:n})),e._lazyRace&&delete e._lazyRace,y(e,z.lazyClass),W(function(){(!c||e.complete&&1<e.naturalWidth)&&(pe(d),e._lazyCache=!0,u(function(){"_lazyCache"in e&&delete e._lazyCache},9))},!0)}),Ce=function(e){var t,a=se.test(e.nodeName),i=a&&(e[h](z.sizesAttr)||e[h]("sizes")),r="auto"==i;(!r&&J||!a||!e[h]("src")&&!e.srcset||e.complete||c(e,z.errorClass)||!c(e,z.lazyClass))&&(t=w(e,"lazyunveilread").detail,r&&k.updateElem(e,!0,e.offsetWidth),e._lazyRace=!0,ue++,we(e,t,r,i,a))},_e=function(){if(!J)if(n.now()-$<999)u(_e,999);else{var e=x(function(){z.loadMode=3,he()});J=!0,z.loadMode=3,he(),t("scroll",function(){3==z.loadMode&&(z.loadMode=2),e()},!0)}},{_:function(){$=n.now(),g.elements=A.getElementsByClassName(z.lazyClass),I=A.getElementsByClassName(z.lazyClass+" "+z.preloadClass),t("scroll",he,!0),t("resize",he,!0),i.MutationObserver?new MutationObserver(he).observe(v,{childList:!0,subtree:!0,attributes:!0}):(v[o]("DOMNodeInserted",he,!0),v[o]("DOMAttrModified",he,!0),setInterval(he,999)),t("hashchange",he,!0),["focus","mouseover","click","load","transitionend","animationend","webkitAnimationEnd"].forEach(function(e){A[o](e,he,!0)}),/d$|^c/.test(A.readyState)?_e():(t("load",_e),A[o]("DOMContentLoaded",he),u(_e,2e4)),g.elements.length?(ve(),W._lsFlush()):he()},checkElems:he,unveil:Ce}),k=(H=e(function(e,t,a,i){var r,n,o;if(e._lazysizesWidth=i,i+="px",e.setAttribute("sizes",i),f.test(t.nodeName||""))for(r=t.getElementsByTagName("source"),n=0,o=r.length;n<o;n++)r[n].setAttribute("sizes",i);a.detail.dataAttr||C(e,a.detail)}),U=function(e,t,a){var i,r=e.parentNode;r&&(a=E(e,r,a),(i=w(e,"lazybeforesizes",{width:a,dataAttr:!!t})).defaultPrevented||(a=i.detail.width)&&a!==e._lazysizesWidth&&H(e,r,i,a))},F=x(function(){var e,t=T.length;if(t)for(e=0;e<t;e++)U(T[e])}),{_:function(){T=A.getElementsByClassName(z.autosizesClass),t("resize",F)},checkElems:F,updateElem:U}),D=function(){D.i||(D.i=!0,k._(),P._())};var T,H,U,F;var I,J,O,G,$,q,j,V,X,Y,K,Z,ee,te,ae,ie,re,ne,oe,se,le,de,ce,ue,fe,Ae,ge,ze,ve,he,pe,me,ye,be,we,Ce,_e;return g={cfg:z,autoSizer:k,loader:P,init:D,uP:C,aC:m,rC:y,hC:c,fire:w,gW:E,rAF:W}}(e,e.document);e.lazySizes=a,"object"==typeof module&&module.exports&&(module.exports=a)}(window),lazysizesWebP("alpha",lazySizes.init),document.addEventListener("lazybeforeunveil",function(e){var t=e.target,a=t.getAttribute("data-srcset");if(!a&&t.naturalWidth&&1<t.naturalWidth&&1<t.naturalHeight){var i=window.devicePixelRatio||1,r=1.25*t.clientWidth<t.naturalWidth,n=1.25*t.clientHeight<t.naturalHeight;if(r||n){var o=Math.round(t.offsetWidth*i),s=Math.round(t.offsetHeight*i),l=t.getAttribute("data-src"),d=t.getAttribute("data-src-webp");ewww_webp_supported&&d&&-1==l.search("webp=1")&&(l=d);var c=constrainSrc(l,o,s,"img");c&&l!=c&&t.setAttribute("data-src",c)}}if(ewww_webp_supported){if(a&&-1<a.search("webp=1"))return;if(a){var u=t.getAttribute("data-srcset-webp");u&&t.setAttribute("data-srcset",u)}if((l=t.getAttribute("data-src"))&&-1<l.search("webp=1"))return;if(!(d=t.getAttribute("data-src-webp")))return;t.setAttribute("data-src",d)}}),function(e,t){var a=function(){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(s,i,l){"use strict";var d,c;i.addEventListener&&(d=function(e,t){var a=i.createElement("img");a.onload=function(){a.onload=null,a.onerror=null,a=null,t()},a.onerror=a.onload,a.src=e,a&&a.complete&&a.onload&&a.onload()},addEventListener("lazybeforeunveil",function(e){var t,a,i;if(e.detail.instance==l&&!e.defaultPrevented){if("none"==e.target.preload&&(e.target.preload="auto"),t=e.target.getAttribute("data-bg")){ewww_webp_supported&&(a=e.target.getAttribute("data-bg-webp"))&&(t=a);var r=s.devicePixelRatio||1,n=Math.round(e.target.offsetWidth*r),o=Math.round(e.target.offsetHeight*r);t=s.lazySizes.hC(e.target,"wp-block-cover")?constrainSrc(t,n,o,"bg-cover"):constrainSrc(t,n,o,"bg"),e.detail.firesLoad=!0,d(t,function(){e.target.style.backgroundImage="url("+(c.test(t)?JSON.stringify(t):t)+")",e.detail.firesLoad=!1,l.fire(e.target,"_lazyloaded",{},!0,!0)})}(i=e.target.getAttribute("data-poster"))&&(e.detail.firesLoad=!0,d(i,function(){e.target.poster=i,e.detail.firesLoad=!1,l.fire(e.target,"_lazyloaded",{},!0,!0)}))}},!(c=/\(|\)|\s|'/)))});
readme.txt CHANGED
@@ -5,7 +5,7 @@ Tags: image, compress, resize, optimize, optimization, lossless, lossy, seo, web
5
  Requires at least: 5.0
6
  Tested up to: 5.2
7
  Requires PHP: 5.6
8
- Stable tag: 4.8.0
9
  License: GPLv3
10
 
11
  Speed up your website and improve your visitors' experience by automatically compressing and resizing images and PDFs. Boost SEO and improve sales.
@@ -18,7 +18,7 @@ EWWW I.O. will optimize images uploaded and created by any plugin, and features
18
 
19
  **Why use EWWW Image Optimizer?**
20
 
21
- 1. **No Speed Limits** and [unlimited file size](https://ewww.io/unlimited-file-size/). Using automatic Background Optimization and optional Parallel Optimization, get rid of upload delays and get back to doing what you love.
22
  1. **Smooth Handling** with pixel-perfect optimization using industry-leading tools and progressive rendering.
23
  1. **High Torque** as we bring you the best compression/quality ratio available with our lossy options for JPG, PNG, and PDF files.
24
  1. **Adaptive Steering** with intelligent conversion options to get the right image format for the job (JPG, PNG, or GIF).
@@ -174,6 +174,14 @@ http://developer.yahoo.com/performance/rules.html#opt_images
174
  * Feature requests can be viewed and submitted at https://github.com/nosilver4u/ewww-image-optimizer/labels/enhancement
175
  * If you would like to help translate this plugin in your language, get started here: https://translate.wordpress.org/projects/wp-plugins/ewww-image-optimizer/
176
 
 
 
 
 
 
 
 
 
177
  = 4.8.0 =
178
  * added: ability to resize images outside media library via scheduled or bulk optimization
179
  * added: compatibility with WP Stateless for GSC
@@ -192,67 +200,6 @@ http://developer.yahoo.com/performance/rules.html#opt_images
192
  * fixed: image optimization results in media library report file missing when using WP Stateless
193
  * fixed: plugin checking for 'nice' on Windows servers
194
 
195
- = 4.7.4 =
196
- * fixed: ExactDN modifies Autoptimize CDN setting even when Include All Resources is disabled
197
- * fixed: noscript elements with newlines being parsed incorrectly by Lazy Load and JS WebP
198
- * fixed: Lazy Load parsing breaking img elements in script blocks
199
- * fixed: Lazy Load and JS WebP bail when SVGs are wrapped in XML tags
200
- * fixed: ExactDN mixes x and w srcset descriptors
201
- * fixed: page parsers (ExactDN, Lazy, JS WebP) still fail to process some img elements that have unquoted src attributes
202
-
203
- = 4.7.3 =
204
- * added: disable WebP script block on certain pages by defining EWWW_IMAGE_OPTIMIZER_NO_JS as true
205
- * changed: use SVG inline image placeholder if width and height are known when LQIP is disabled or ExactDN is not available
206
- * changed: Lazy Load ignores images using browser-native loading attribute
207
- * fixed: page parsers (ExactDN, Lazy, JS WebP) do not properly handle attributes that start on a new line
208
- * fixed: page parsers do not recognize img elements with unquoted attributes
209
- * fixed: uninstaller cannot clear queue table due to undefined table name
210
- * fixed: implode throws notice when image sizes array is multi-dimensional
211
- * fixed: srcset url replaced incorrectly when using pixel density descriptors
212
- * fixed: srcset url added with 0 width when width attribute is empty
213
-
214
- = 4.7.2 =
215
- * changed: JS WebP no longer necessary with ExactDN
216
- * fixed: fatal error from NextGEN get_image_sizes() method
217
- * fixed: debugging mode gets stuck
218
- * fixed: ExactDN has unexpected results when content_width global equals zero
219
- * fixed: img elements with unquoted src attributes ignored by ExactDN, Lazy Load, and JS WebP
220
-
221
- = 4.7.1 =
222
- * added: CSS background image support for <li> elements
223
- * added: ExactDN + Lazy Load will auto-calculate dimensions for img elements without srcset/responsive markup
224
- * added: ExactDN parses thumbnail url for personalization.com + WooCommerce integration
225
- * added: ExactDN can use data-actual-width attribute for srcset generation
226
- * added: ExactDN + Lazy Load uses devicePixelRatio to provide clearer background images
227
- * fixed: Lazy Load for CSS background images misfires when display height is greater than width
228
- * fixed: visitors without JS see Lazy Load placeholder + fallback image
229
-
230
- = 4.7.0 =
231
- * added: lazy load (on ExactDN tab for now)
232
- * added: JS WebP supports background images via lazy load (div elements only for now)
233
- * added: ExactDN supports compression of background images (div elements only for now)
234
- * added: compat with Google Cloud Storage via WP Offload Media
235
- * added: automatic PNG to JPG conversion for ExactDN
236
- * added: ExactDN parsing for legacy WooCommerce API (current API works as-is)
237
- * changed: responsive image 'sizes' attribute can be auto-calculated by lazy load
238
- * changed: JS WebP no longer requires jQuery
239
- * changed: ExactDN srcset multipliers include fullscreen value of 1920px
240
- * changed: force resize function to ignore filesize with ewww_image_optimizer_resize_filesize_ignore filter
241
- * changed: prevent .php script/style generators from going through ExactDN
242
- * changed: ExactDN sites can dismiss exec notice to disable local compression
243
- * changed: automatic compression disabled during WooCommerce regen with admin notice
244
- * changed: use wp_resource_hints filter to include ExactDN dns-prefetch earlier in the page header
245
- * changed: gather debugging information on settings page even when debugging is not enabled yet
246
- * fixed: Bulk Optimize scanner does not update queue in some cases
247
- * fixed: ExactDN does not handle themes that support wide and full-screen images in block editor
248
- * fixed: ExactDN constrains images to 640px in Twenty Nineteen theme
249
- * fixed: ExactDN mangles Flatsome lazy load placeholder image URL
250
- * fixed: empty attributes not recognized properly by HTML parser, resulting in broken markup
251
- * fixed: table nav button styling broken in WP 5.1
252
- * fixed: ExactDN applies resizing args during image_downsize() even when full/original image is too small
253
- * fixed: animated GIF resizing breaks the use of image_resize_dimensions filter in WP_Image_Editor_GD
254
- * fixed: NextGen bulk optimizer unable to decode meta_data
255
-
256
  = Earlier versions =
257
  Please refer to the separate changelog.txt file.
258
 
5
  Requires at least: 5.0
6
  Tested up to: 5.2
7
  Requires PHP: 5.6
8
+ Stable tag: 4.8.1
9
  License: GPLv3
10
 
11
  Speed up your website and improve your visitors' experience by automatically compressing and resizing images and PDFs. Boost SEO and improve sales.
18
 
19
  **Why use EWWW Image Optimizer?**
20
 
21
+ 1. **No Speed Limits** and [unlimited file size](https://ewww.io/unlimited-file-size/).
22
  1. **Smooth Handling** with pixel-perfect optimization using industry-leading tools and progressive rendering.
23
  1. **High Torque** as we bring you the best compression/quality ratio available with our lossy options for JPG, PNG, and PDF files.
24
  1. **Adaptive Steering** with intelligent conversion options to get the right image format for the job (JPG, PNG, or GIF).
174
  * Feature requests can be viewed and submitted at https://github.com/nosilver4u/ewww-image-optimizer/labels/enhancement
175
  * If you would like to help translate this plugin in your language, get started here: https://translate.wordpress.org/projects/wp-plugins/ewww-image-optimizer/
176
 
177
+ = 4.8.1 =
178
+ * added: Lazy Load background image support added for span elements
179
+ * changed: constrain by height for background images that are taller than they are wide
180
+ * changed: debug.log moved to more suitable location
181
+ * fix: Lazy Load breaks when an image has an empty class attribute
182
+ * fix: regression that caused jpegtran and pngout tests to fail on Windows
183
+ * fix: writing to debug.log causes errors
184
+
185
  = 4.8.0 =
186
  * added: ability to resize images outside media library via scheduled or bulk optimization
187
  * added: compatibility with WP Stateless for GSC
200
  * fixed: image optimization results in media library report file missing when using WP Stateless
201
  * fixed: plugin checking for 'nice' on Windows servers
202
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
203
  = Earlier versions =
204
  Please refer to the separate changelog.txt file.
205
 
unique.php CHANGED
@@ -319,7 +319,7 @@ function ewww_image_optimizer_tool_folder_permissions_notice() {
319
  echo "<div id='ewww-image-optimizer-warning-tool-folder-permissions' class='notice notice-error'><p><strong>" .
320
  /* translators: %s: Folder location where executables should be installed */
321
  sprintf( esc_html__( 'EWWW Image Optimizer could not install tools in %s', 'ewww-image-optimizer' ), htmlentities( EWWW_IMAGE_OPTIMIZER_TOOL_PATH ) ) . '.</strong> ' .
322
- esc_html__( 'Please adjust permissions or create the folder. If you have installed the tools elsewhere on your system, check the option to Use System Paths.', 'ewww-image-optimizer' ) . ' ' .
323
  /* translators: 1: Settings Page (link) 2: Installation Instructions (link) */
324
  sprintf( esc_html__( 'For more details, visit the %1$s or the %2$s.', 'ewww-image-optimizer' ), "<a href='$settings_page'>" . esc_html__( 'Settings Page', 'ewww-image-optimizer' ) . '</a>', "<a href='https://docs.ewww.io/'>" . esc_html__( 'Installation Instructions', 'ewww-image-optimizer' ) . '</a>' ) . '</p></div>';
325
  }
@@ -1206,14 +1206,12 @@ function ewww_image_optimizer_escapeshellcmd( $path ) {
1206
  function ewww_image_optimizer_tool_found( $path, $tool ) {
1207
  ewwwio_debug_message( '<b>' . __FUNCTION__ . '()</b>' );
1208
  ewwwio_debug_message( "testing case: $tool at $path" );
1209
- $fork = '2>&1';
1210
- if ( ( defined( 'EWWW_IMAGE_OPTIMIZER_FORK' ) && ! EWWW_IMAGE_OPTIMIZER_FORK ) || 'WINNT' === PHP_OS ) {
1211
- $fork = '';
1212
- }
1213
  // '*b' cases are 'blind' testing in case we can't get at the version string, but the binaries are actually working, we run a test compression, and compare the results with what they should be.
1214
  switch ( $tool ) {
1215
  case 'j': // jpegtran.
1216
- exec( $path . ' -v ' . EWWW_IMAGE_OPTIMIZER_IMAGES_PATH . "sample.jpg $fork", $jpegtran_version );
 
1217
  if ( ewww_image_optimizer_iterable( $jpegtran_version ) ) {
1218
  ewwwio_debug_message( "$path: {$jpegtran_version[0]}" );
1219
  } else {
@@ -1242,7 +1240,7 @@ function ewww_image_optimizer_tool_found( $path, $tool ) {
1242
  }
1243
  break;
1244
  case 'o': // optipng.
1245
- exec( $path . " -v $fork", $optipng_version );
1246
  if ( ewww_image_optimizer_iterable( $optipng_version ) ) {
1247
  ewwwio_debug_message( "$path: {$optipng_version[0]}" );
1248
  } else {
@@ -1269,7 +1267,7 @@ function ewww_image_optimizer_tool_found( $path, $tool ) {
1269
  }
1270
  break;
1271
  case 'g': // gifsicle.
1272
- exec( $path . " --version $fork", $gifsicle_version );
1273
  if ( ewww_image_optimizer_iterable( $gifsicle_version ) ) {
1274
  ewwwio_debug_message( "$path: {$gifsicle_version[0]}" );
1275
  } else {
@@ -1296,7 +1294,7 @@ function ewww_image_optimizer_tool_found( $path, $tool ) {
1296
  }
1297
  break;
1298
  case 'p': // pngout.
1299
- exec( "$path $fork", $pngout_version );
1300
  if ( ewww_image_optimizer_iterable( $pngout_version ) ) {
1301
  ewwwio_debug_message( "$path: {$pngout_version[0]}" );
1302
  } else {
@@ -1323,7 +1321,7 @@ function ewww_image_optimizer_tool_found( $path, $tool ) {
1323
  }
1324
  break;
1325
  case 'q': // pngquant.
1326
- exec( $path . " -V $fork", $pngquant_version );
1327
  if ( ewww_image_optimizer_iterable( $pngquant_version ) ) {
1328
  ewwwio_debug_message( "$path: {$pngquant_version[0]}" );
1329
  } else {
@@ -1353,7 +1351,7 @@ function ewww_image_optimizer_tool_found( $path, $tool ) {
1353
  if ( PHP_OS === 'WINNT' ) {
1354
  return false;
1355
  }
1356
- exec( "$path $fork", $nice_output );
1357
  if ( ewww_image_optimizer_iterable( $nice_output ) && isset( $nice_output[0] ) ) {
1358
  ewwwio_debug_message( "$path: {$nice_output[0]}" );
1359
  } else {
@@ -1369,7 +1367,7 @@ function ewww_image_optimizer_tool_found( $path, $tool ) {
1369
  }
1370
  break;
1371
  case 'w': // cwebp.
1372
- exec( "$path -version $fork", $webp_version );
1373
  if ( ewww_image_optimizer_iterable( $webp_version ) ) {
1374
  ewwwio_debug_message( "$path: {$webp_version[0]}" );
1375
  } else {
319
  echo "<div id='ewww-image-optimizer-warning-tool-folder-permissions' class='notice notice-error'><p><strong>" .
320
  /* translators: %s: Folder location where executables should be installed */
321
  sprintf( esc_html__( 'EWWW Image Optimizer could not install tools in %s', 'ewww-image-optimizer' ), htmlentities( EWWW_IMAGE_OPTIMIZER_TOOL_PATH ) ) . '.</strong> ' .
322
+ esc_html__( 'Please adjust permissions or create the folder. If you have installed the tools elsewhere on your system, use the override which allows you to skip the bundled tools.', 'ewww-image-optimizer' ) . ' ' .
323
  /* translators: 1: Settings Page (link) 2: Installation Instructions (link) */
324
  sprintf( esc_html__( 'For more details, visit the %1$s or the %2$s.', 'ewww-image-optimizer' ), "<a href='$settings_page'>" . esc_html__( 'Settings Page', 'ewww-image-optimizer' ) . '</a>', "<a href='https://docs.ewww.io/'>" . esc_html__( 'Installation Instructions', 'ewww-image-optimizer' ) . '</a>' ) . '</p></div>';
325
  }
1206
  function ewww_image_optimizer_tool_found( $path, $tool ) {
1207
  ewwwio_debug_message( '<b>' . __FUNCTION__ . '()</b>' );
1208
  ewwwio_debug_message( "testing case: $tool at $path" );
1209
+
 
 
 
1210
  // '*b' cases are 'blind' testing in case we can't get at the version string, but the binaries are actually working, we run a test compression, and compare the results with what they should be.
1211
  switch ( $tool ) {
1212
  case 'j': // jpegtran.
1213
+ // In case you forget, it is not any slower to run jpegtran this way (with a sample file to operate on) than the other tools.
1214
+ exec( $path . ' -v ' . EWWW_IMAGE_OPTIMIZER_IMAGES_PATH . 'sample.jpg 2>&1', $jpegtran_version );
1215
  if ( ewww_image_optimizer_iterable( $jpegtran_version ) ) {
1216
  ewwwio_debug_message( "$path: {$jpegtran_version[0]}" );
1217
  } else {
1240
  }
1241
  break;
1242
  case 'o': // optipng.
1243
+ exec( $path . ' -v 2>&1', $optipng_version );
1244
  if ( ewww_image_optimizer_iterable( $optipng_version ) ) {
1245
  ewwwio_debug_message( "$path: {$optipng_version[0]}" );
1246
  } else {
1267
  }
1268
  break;
1269
  case 'g': // gifsicle.
1270
+ exec( $path . ' --version 2>&1', $gifsicle_version );
1271
  if ( ewww_image_optimizer_iterable( $gifsicle_version ) ) {
1272
  ewwwio_debug_message( "$path: {$gifsicle_version[0]}" );
1273
  } else {
1294
  }
1295
  break;
1296
  case 'p': // pngout.
1297
+ exec( "$path 2>&1", $pngout_version );
1298
  if ( ewww_image_optimizer_iterable( $pngout_version ) ) {
1299
  ewwwio_debug_message( "$path: {$pngout_version[0]}" );
1300
  } else {
1321
  }
1322
  break;
1323
  case 'q': // pngquant.
1324
+ exec( $path . ' -V 2>&1', $pngquant_version );
1325
  if ( ewww_image_optimizer_iterable( $pngquant_version ) ) {
1326
  ewwwio_debug_message( "$path: {$pngquant_version[0]}" );
1327
  } else {
1351
  if ( PHP_OS === 'WINNT' ) {
1352
  return false;
1353
  }
1354
+ exec( "$path 2>&1", $nice_output );
1355
  if ( ewww_image_optimizer_iterable( $nice_output ) && isset( $nice_output[0] ) ) {
1356
  ewwwio_debug_message( "$path: {$nice_output[0]}" );
1357
  } else {
1367
  }
1368
  break;
1369
  case 'w': // cwebp.
1370
+ exec( "$path -version 2>&1", $webp_version );
1371
  if ( ewww_image_optimizer_iterable( $webp_version ) ) {
1372
  ewwwio_debug_message( "$path: {$webp_version[0]}" );
1373
  } else {