EWWW Image Optimizer - Version 6.9.0

Version Description

  • added: allow translation plugins to filter attachment IDs for retrieving Media Library results via ewwwio_primary_translated_media_id/ewwwio_translated_media_ids
  • changed: include upstream lazysizes unveilhooks for use by developers, props @saas786
  • fixed: Easy IO compatibility with S3 Uploads 3.x
  • fixed: better compatibility with S3 Uploads when using autoload
  • fixed: PHP notices when removing images and backups are disabled
  • fixed: trailing comma after parameters in WP-CLI remove_originals function
  • fixed: Easy IO srcset URL construction not accounting for object versioning with S3 (or other cloud storage)
Download this release

Release Info

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

Code changes from version 6.8.0 to 6.9.0

aux-optimize.php CHANGED
@@ -732,7 +732,7 @@ function ewww_image_optimizer_delete_webp( $id ) {
732
  }
733
  $s3_path = false;
734
  $s3_dir = false;
735
- if ( class_exists( 'S3_Uploads' ) || class_exists( 'S3_Uploads\Plugin' ) ) {
736
  $s3_path = get_attached_file( $id );
737
  if ( 0 === strpos( $s3_path, 's3://' ) ) {
738
  ewwwio_debug_message( 'removing: ' . $s3_path . '.webp' );
732
  }
733
  $s3_path = false;
734
  $s3_dir = false;
735
+ if ( ewww_image_optimizer_s3_uploads_enabled() ) {
736
  $s3_path = get_attached_file( $id );
737
  if ( 0 === strpos( $s3_path, 's3://' ) ) {
738
  ewwwio_debug_message( 'removing: ' . $s3_path . '.webp' );
bulk.php CHANGED
@@ -171,7 +171,7 @@ function ewww_image_optimizer_display_tools() {
171
  $as3cf_remove = true;
172
  }
173
  }
174
- if ( ! class_exists( 'S3_Uploads' ) && ! class_exists( 'S3_Uploads\Plugin' ) && ! function_exists( 'ud_get_stateless_media' ) && ! $as3cf_remove ) {
175
  echo '<hr class="ewww-tool-divider">';
176
  echo "<div>\n<p id='ewww-clean-table-info' class='ewww-tool-info'>" .
177
  esc_html__( 'Older sites may have duplicate records or references to deleted files. Use the cleanup tool to remove such records.', 'ewww-image-optimizer' ) . '<br>' .
@@ -1241,29 +1241,28 @@ function ewww_image_optimizer_media_scan( $hook = '' ) {
1241
  (
1242
  class_exists( 'WindowsAzureStorageUtil' ) ||
1243
  class_exists( 'Amazon_S3_And_CloudFront' ) ||
1244
- class_exists( 'S3_Uploads' ) ||
1245
- class_exists( 'S3_Uploads\Plugin' ) ||
1246
  class_exists( 'wpCloud\StatelessMedia\EWWW' )
1247
  )
1248
  ) {
1249
  // Construct a $file_path and proceed IF a supported CDN plugin is installed.
1250
  ewwwio_debug_message( 'Azure or S3 detected and no local file found' );
1251
  $file_path = get_attached_file( $selected_id );
1252
- if ( class_exists( 'S3_Uploads' ) && method_exists( 'S3_Uploads', 'filter_upload_dir' ) ) {
1253
  $s3_uploads = S3_Uploads::get_instance();
1254
  remove_filter( 'upload_dir', array( $s3_uploads, 'filter_upload_dir' ) );
1255
  }
1256
- if ( class_exists( 'S3_Uploads\Plugin' ) && method_exists( 'S3_Uploads\Plugin', 'filter_upload_dir' ) ) {
1257
  $s3_uploads = \S3_Uploads\Plugin::get_instance();
1258
  remove_filter( 'upload_dir', array( $s3_uploads, 'filter_upload_dir' ) );
1259
  }
1260
  if ( ewww_image_optimizer_stream_wrapped( $file_path ) || 0 === strpos( $file_path, 'http' ) ) {
1261
  $file_path = get_attached_file( $selected_id, true );
1262
  }
1263
- if ( class_exists( 'S3_Uploads' ) && method_exists( 'S3_Uploads', 'filter_upload_dir' ) ) {
1264
  add_filter( 'upload_dir', array( $s3_uploads, 'filter_upload_dir' ) );
1265
  }
1266
- if ( class_exists( 'S3_Uploads\Plugin' ) && method_exists( 'S3_Uploads\Plugin', 'filter_upload_dir' ) ) {
1267
  add_filter( 'upload_dir', array( $s3_uploads, 'filter_upload_dir' ) );
1268
  }
1269
  ewwwio_debug_message( "remote file possible: $file_path" );
@@ -1958,7 +1957,7 @@ function ewww_image_optimizer_bulk_loop( $hook = '', $delay = 0 ) {
1958
  $output['new_nonce'] = '';
1959
  }
1960
  }
1961
- $batch_image_limit = ( empty( $_REQUEST['ewww_batch_limit'] ) && ! class_exists( 'S3_Uploads' ) && ! class_exists( 'S3_Uploads\Plugin' ) ? 999 : 1 );
1962
  // Get the 'bulk attachments' with a list of IDs remaining.
1963
  $attachments = ewww_image_optimizer_get_queued_attachments( 'media', $batch_image_limit );
1964
  if ( ! empty( $attachments ) && is_array( $attachments ) ) {
@@ -2110,7 +2109,7 @@ function ewww_image_optimizer_bulk_loop( $hook = '', $delay = 0 ) {
2110
  if ( defined( 'WP_CLI' ) && WP_CLI ) {
2111
  ewwwio_debug_message( 'saving attachment meta' );
2112
  $meta = wp_get_attachment_metadata( $image->attachment_id );
2113
- if ( class_exists( 'S3_Uploads' ) || class_exists( 'S3_Uploads\Plugin' ) ) {
2114
  ewwwio_debug_message( 're-uploading to S3(_Uploads)' );
2115
  ewww_image_optimizer_remote_push( $meta, $image->attachment_id );
2116
  }
@@ -2217,7 +2216,7 @@ function ewww_image_optimizer_bulk_update_meta() {
2217
  $meta = wp_get_attachment_metadata( $attachment_id );
2218
  $meta = ewww_image_optimizer_update_filesize_metadata( $meta, $attachment_id );
2219
  remove_filter( 'wp_update_attachment_metadata', 'ewww_image_optimizer_update_filesize_metadata', 9 );
2220
- if ( class_exists( 'S3_Uploads' ) || class_exists( 'S3_Uploads\Plugin' ) ) {
2221
  ewwwio_debug_message( 're-uploading to S3(_Uploads)' );
2222
  ewww_image_optimizer_remote_push( $meta, $attachment_id );
2223
  }
171
  $as3cf_remove = true;
172
  }
173
  }
174
+ if ( ! ewww_image_optimizer_s3_uploads_enabled() && ! function_exists( 'ud_get_stateless_media' ) && ! $as3cf_remove ) {
175
  echo '<hr class="ewww-tool-divider">';
176
  echo "<div>\n<p id='ewww-clean-table-info' class='ewww-tool-info'>" .
177
  esc_html__( 'Older sites may have duplicate records or references to deleted files. Use the cleanup tool to remove such records.', 'ewww-image-optimizer' ) . '<br>' .
1241
  (
1242
  class_exists( 'WindowsAzureStorageUtil' ) ||
1243
  class_exists( 'Amazon_S3_And_CloudFront' ) ||
1244
+ ewww_image_optimizer_s3_uploads_enabled() ||
 
1245
  class_exists( 'wpCloud\StatelessMedia\EWWW' )
1246
  )
1247
  ) {
1248
  // Construct a $file_path and proceed IF a supported CDN plugin is installed.
1249
  ewwwio_debug_message( 'Azure or S3 detected and no local file found' );
1250
  $file_path = get_attached_file( $selected_id );
1251
+ if ( class_exists( 'S3_Uploads', false ) && method_exists( 'S3_Uploads', 'filter_upload_dir' ) ) {
1252
  $s3_uploads = S3_Uploads::get_instance();
1253
  remove_filter( 'upload_dir', array( $s3_uploads, 'filter_upload_dir' ) );
1254
  }
1255
+ if ( class_exists( 'S3_Uploads\Plugin', false ) && method_exists( 'S3_Uploads\Plugin', 'filter_upload_dir' ) ) {
1256
  $s3_uploads = \S3_Uploads\Plugin::get_instance();
1257
  remove_filter( 'upload_dir', array( $s3_uploads, 'filter_upload_dir' ) );
1258
  }
1259
  if ( ewww_image_optimizer_stream_wrapped( $file_path ) || 0 === strpos( $file_path, 'http' ) ) {
1260
  $file_path = get_attached_file( $selected_id, true );
1261
  }
1262
+ if ( class_exists( 'S3_Uploads', false ) && method_exists( 'S3_Uploads', 'filter_upload_dir' ) ) {
1263
  add_filter( 'upload_dir', array( $s3_uploads, 'filter_upload_dir' ) );
1264
  }
1265
+ if ( class_exists( 'S3_Uploads\Plugin', false ) && method_exists( 'S3_Uploads\Plugin', 'filter_upload_dir' ) ) {
1266
  add_filter( 'upload_dir', array( $s3_uploads, 'filter_upload_dir' ) );
1267
  }
1268
  ewwwio_debug_message( "remote file possible: $file_path" );
1957
  $output['new_nonce'] = '';
1958
  }
1959
  }
1960
+ $batch_image_limit = ( empty( $_REQUEST['ewww_batch_limit'] ) && ! ewww_image_optimizer_s3_uploads_enabled() ? 999 : 1 );
1961
  // Get the 'bulk attachments' with a list of IDs remaining.
1962
  $attachments = ewww_image_optimizer_get_queued_attachments( 'media', $batch_image_limit );
1963
  if ( ! empty( $attachments ) && is_array( $attachments ) ) {
2109
  if ( defined( 'WP_CLI' ) && WP_CLI ) {
2110
  ewwwio_debug_message( 'saving attachment meta' );
2111
  $meta = wp_get_attachment_metadata( $image->attachment_id );
2112
+ if ( ewww_image_optimizer_s3_uploads_enabled() ) {
2113
  ewwwio_debug_message( 're-uploading to S3(_Uploads)' );
2114
  ewww_image_optimizer_remote_push( $meta, $image->attachment_id );
2115
  }
2216
  $meta = wp_get_attachment_metadata( $attachment_id );
2217
  $meta = ewww_image_optimizer_update_filesize_metadata( $meta, $attachment_id );
2218
  remove_filter( 'wp_update_attachment_metadata', 'ewww_image_optimizer_update_filesize_metadata', 9 );
2219
+ if ( ewww_image_optimizer_s3_uploads_enabled() ) {
2220
  ewwwio_debug_message( 're-uploading to S3(_Uploads)' );
2221
  ewww_image_optimizer_remote_push( $meta, $attachment_id );
2222
  }
changelog.txt CHANGED
@@ -1,3 +1,12 @@
 
 
 
 
 
 
 
 
 
1
  = 6.8.0 =
2
  * added: ability to store image backups on local storage
3
  * added: tool to bulk restore images under Tools menu and WP-CLI
@@ -385,7 +394,7 @@
385
  = 5.3.1 =
386
  * added: defer JS with Easy IO via EXACTDN_DEFER_SCRIPTS override
387
  * fixed: warning related to user-defined exclusions in JS and picture WebP
388
- * fixed: AMP compatiblity for Lazy Load and WebP rewriters was broken
389
  * fixed: images not loading on WPURP/WPRM print recipe pages
390
 
391
  = 5.3.0 =
@@ -1720,12 +1729,12 @@ You can find more information about overriding options in the [Documentation](ht
1720
  * fixed: attempt to convert PNGs with empty alpha channels after optimization on first pass, instead of on re-optimization
1721
 
1722
  = 1.7.6 =
1723
- * fixed: color of progressbar for 4 more admin themes in WP 3.8
1724
  * changed: metadata stripping now applies to PNG images, but only if using optipng 0.7.x
1725
  * added: ability to remove individual images from the Optimize More table
1726
  * fixed: Optimize More was using case-insensitive queries for matching paths
1727
  * fixed: Optimize More was unable to record image sizes over 8388607 bytes
1728
- * removed: obsolete jquery 1.9.1 file used for maintaining backwards compatiblity with really old versions of WP
1729
  * fixed: weirdness with paths preventing Windows servers from activating, and cleanup of plugin path code
1730
 
1731
  = 1.7.5 =
1
+ = 6.9.0 =
2
+ * added: allow translation plugins to filter attachment IDs for retrieving Media Library results via ewwwio_primary_translated_media_id/ewwwio_translated_media_ids
3
+ * changed: include upstream lazysizes unveilhooks for use by developers, props @saas786
4
+ * fixed: Easy IO compatibility with S3 Uploads 3.x
5
+ * fixed: better compatibility with S3 Uploads when using autoload
6
+ * fixed: PHP notices when removing images and backups are disabled
7
+ * fixed: trailing comma after parameters in WP-CLI remove_originals function
8
+ * fixed: Easy IO srcset URL construction not accounting for object versioning with S3 (or other cloud storage)
9
+
10
  = 6.8.0 =
11
  * added: ability to store image backups on local storage
12
  * added: tool to bulk restore images under Tools menu and WP-CLI
394
  = 5.3.1 =
395
  * added: defer JS with Easy IO via EXACTDN_DEFER_SCRIPTS override
396
  * fixed: warning related to user-defined exclusions in JS and picture WebP
397
+ * fixed: AMP compatibility for Lazy Load and WebP rewriters was broken
398
  * fixed: images not loading on WPURP/WPRM print recipe pages
399
 
400
  = 5.3.0 =
1729
  * fixed: attempt to convert PNGs with empty alpha channels after optimization on first pass, instead of on re-optimization
1730
 
1731
  = 1.7.6 =
1732
+ * fixed: color of progress bar for 4 more admin themes in WP 3.8
1733
  * changed: metadata stripping now applies to PNG images, but only if using optipng 0.7.x
1734
  * added: ability to remove individual images from the Optimize More table
1735
  * fixed: Optimize More was using case-insensitive queries for matching paths
1736
  * fixed: Optimize More was unable to record image sizes over 8388607 bytes
1737
+ * removed: obsolete jQuery 1.9.1 file used for maintaining backwards compatibility with really old versions of WP
1738
  * fixed: weirdness with paths preventing Windows servers from activating, and cleanup of plugin path code
1739
 
1740
  = 1.7.5 =
classes/class-eio-backup.php CHANGED
@@ -111,7 +111,7 @@ class EIO_Backup extends EIO_Base {
111
  */
112
  public function get_backup_location( $file ) {
113
  $this->debug_message( '<b>' . __FUNCTION__ . '()</b>' );
114
- if ( \ewww_image_optimizer_stream_wrapped( $file ) ) {
115
  return '';
116
  }
117
  $upload_dir = wp_get_upload_dir();
@@ -188,7 +188,7 @@ class EIO_Backup extends EIO_Base {
188
  */
189
  public function store_local_backup( $file ) {
190
  $this->debug_message( '<b>' . __FUNCTION__ . '()</b>' );
191
- if ( 'local' !== $this->get_option( 'ewww_image_optimizer_backup_files' ) ) {
192
  return;
193
  }
194
  if ( ! $this->is_file( $file ) || ! $this->is_readable( $file ) ) {
@@ -268,7 +268,7 @@ class EIO_Backup extends EIO_Base {
268
  */
269
  protected function restore_from_local( $image ) {
270
  $this->debug_message( '<b>' . __FUNCTION__ . '()</b>' );
271
- if ( 'local' !== $this->get_option( 'ewww_image_optimizer_backup_files' ) ) {
272
  return false;
273
  }
274
  $file = $image['path'];
@@ -342,6 +342,9 @@ class EIO_Backup extends EIO_Base {
342
  if ( ! $file ) {
343
  return;
344
  }
 
 
 
345
  $backup_file = $this->get_backup_location( $file );
346
  if ( ! $backup_file || $backup_file === $file ) {
347
  return;
@@ -368,7 +371,7 @@ class EIO_Backup extends EIO_Base {
368
  $this->debug_message( '<b>' . __FUNCTION__ . '()</b>' );
369
  global $wpdb;
370
  if ( strpos( $wpdb->charset, 'utf8' ) === false ) {
371
- ewww_image_optimizer_db_init();
372
  global $ewwwdb;
373
  } else {
374
  $ewwwdb = $wpdb;
@@ -376,11 +379,11 @@ class EIO_Backup extends EIO_Base {
376
  $images = $ewwwdb->get_results( "SELECT id,path,resize,backup FROM $ewwwdb->ewwwio_images WHERE attachment_id = $id AND gallery = '$gallery'", ARRAY_A );
377
  foreach ( $images as $image ) {
378
  if ( ! empty( $image['path'] ) ) {
379
- $image['path'] = ewww_image_optimizer_absolutize_path( $image['path'] );
380
  }
381
  $this->restore_file( $image );
382
  if ( 'media' === $gallery && 'full' === $image['resize'] && ! empty( $meta['width'] ) && ! empty( $meta['height'] ) ) {
383
- list( $width, $height ) = wp_getimagesize( $image['path'] );
384
  if ( (int) $width !== (int) $meta['width'] || (int) $height !== (int) $meta['height'] ) {
385
  $meta['height'] = $height;
386
  $meta['width'] = $width;
@@ -389,10 +392,10 @@ class EIO_Backup extends EIO_Base {
389
  }
390
  if ( 'media' === $gallery ) {
391
  remove_filter( 'wp_update_attachment_metadata', 'ewww_image_optimizer_update_filesize_metadata', 9 );
392
- $meta = ewww_image_optimizer_update_filesize_metadata( $meta, $id );
393
  }
394
- if ( class_exists( 'S3_Uploads' ) || class_exists( 'S3_uploads\Plugin' ) ) {
395
- ewww_image_optimizer_remote_push( $meta, $id );
396
  $this->debug_message( 're-uploading to S3(_Uploads)' );
397
  }
398
  return $meta;
111
  */
112
  public function get_backup_location( $file ) {
113
  $this->debug_message( '<b>' . __FUNCTION__ . '()</b>' );
114
+ if ( \ewww_image_optimizer_stream_wrapped( $file ) || 'local' !== $this->backup_mode ) {
115
  return '';
116
  }
117
  $upload_dir = wp_get_upload_dir();
188
  */
189
  public function store_local_backup( $file ) {
190
  $this->debug_message( '<b>' . __FUNCTION__ . '()</b>' );
191
+ if ( 'local' !== $this->backup_mode ) {
192
  return;
193
  }
194
  if ( ! $this->is_file( $file ) || ! $this->is_readable( $file ) ) {
268
  */
269
  protected function restore_from_local( $image ) {
270
  $this->debug_message( '<b>' . __FUNCTION__ . '()</b>' );
271
+ if ( 'local' !== $this->backup_mode ) {
272
  return false;
273
  }
274
  $file = $image['path'];
342
  if ( ! $file ) {
343
  return;
344
  }
345
+ if ( 'local' !== $this->backup_mode ) {
346
+ return;
347
+ }
348
  $backup_file = $this->get_backup_location( $file );
349
  if ( ! $backup_file || $backup_file === $file ) {
350
  return;
371
  $this->debug_message( '<b>' . __FUNCTION__ . '()</b>' );
372
  global $wpdb;
373
  if ( strpos( $wpdb->charset, 'utf8' ) === false ) {
374
+ \ewww_image_optimizer_db_init();
375
  global $ewwwdb;
376
  } else {
377
  $ewwwdb = $wpdb;
379
  $images = $ewwwdb->get_results( "SELECT id,path,resize,backup FROM $ewwwdb->ewwwio_images WHERE attachment_id = $id AND gallery = '$gallery'", ARRAY_A );
380
  foreach ( $images as $image ) {
381
  if ( ! empty( $image['path'] ) ) {
382
+ $image['path'] = \ewww_image_optimizer_absolutize_path( $image['path'] );
383
  }
384
  $this->restore_file( $image );
385
  if ( 'media' === $gallery && 'full' === $image['resize'] && ! empty( $meta['width'] ) && ! empty( $meta['height'] ) ) {
386
+ list( $width, $height ) = \wp_getimagesize( $image['path'] );
387
  if ( (int) $width !== (int) $meta['width'] || (int) $height !== (int) $meta['height'] ) {
388
  $meta['height'] = $height;
389
  $meta['width'] = $width;
392
  }
393
  if ( 'media' === $gallery ) {
394
  remove_filter( 'wp_update_attachment_metadata', 'ewww_image_optimizer_update_filesize_metadata', 9 );
395
+ $meta = \ewww_image_optimizer_update_filesize_metadata( $meta, $id );
396
  }
397
+ if ( $this->s3_uploads_enabled() ) {
398
+ \ewww_image_optimizer_remote_push( $meta, $id );
399
  $this->debug_message( 're-uploading to S3(_Uploads)' );
400
  }
401
  return $meta;
classes/class-eio-base.php CHANGED
@@ -310,6 +310,23 @@ if ( ! class_exists( 'EIO_Base' ) ) {
310
  return false;
311
  }
312
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
313
  /**
314
  * Retrieve option: use 'site' setting if plugin is network activated, otherwise use 'blog' setting.
315
  *
@@ -907,32 +924,21 @@ if ( ! class_exists( 'EIO_Base' ) ) {
907
  }
908
  }
909
 
910
- if (
911
- class_exists( 'S3_Uploads' ) &&
912
- function_exists( 's3_uploads_enabled' ) && s3_uploads_enabled() &&
913
- method_exists( 'S3_Uploads', 'get_instance' ) && method_exists( 'S3_Uploads', 'get_s3_url' )
914
- ) {
915
- $s3_uploads_instance = \S3_Uploads::get_instance();
916
- $s3_uploads_url = $s3_uploads_instance->get_s3_url();
917
- $this->allowed_urls[] = $s3_uploads_url;
918
- $this->debug_message( "found S3 URL from S3_Uploads: $s3_uploads_url" );
919
- $s3_domain = $this->parse_url( $s3_uploads_url, PHP_URL_HOST );
920
- $s3_scheme = $this->parse_url( $s3_uploads_url, PHP_URL_SCHEME );
921
- $this->s3_active = $s3_domain;
922
- }
923
-
924
- if (
925
- class_exists( 'S3_Uploads\Plugin' ) &&
926
- function_exists( 's3_uploads_enabled' ) && s3_uploads_enabled() &&
927
- method_exists( 'S3_Uploads\Plugin', 'get_instance' ) && method_exists( 'S3_Uploads', 'get_s3_url\Plugin' )
928
- ) {
929
- $s3_uploads_instance = \S3_Uploads\Plugin::get_instance();
930
- $s3_uploads_url = $s3_uploads_instance->get_s3_url();
931
- $this->allowed_urls[] = $s3_uploads_url;
932
- $this->debug_message( "found S3 URL from S3_Uploads: $s3_uploads_url" );
933
- $s3_domain = $this->parse_url( $s3_uploads_url, PHP_URL_HOST );
934
- $s3_scheme = $this->parse_url( $s3_uploads_url, PHP_URL_SCHEME );
935
- $this->s3_active = $s3_domain;
936
  }
937
 
938
  if ( class_exists( 'wpCloud\StatelessMedia\EWWW' ) && function_exists( 'ud_get_stateless_media' ) ) {
310
  return false;
311
  }
312
 
313
+ /**
314
+ * Checks if the S3 Uploads plugin is installed and active.
315
+ *
316
+ * @return bool True if it is fully active and rewriting/offloading media, false otherwise.
317
+ */
318
+ function s3_uploads_enabled() {
319
+ // For version 3.x.
320
+ if ( class_exists( 'S3_Uploads\Plugin', false ) && function_exists( 'S3_Uploads\enabled' ) && \S3_Uploads\enabled() ) {
321
+ return true;
322
+ }
323
+ // Pre version 3.
324
+ if ( class_exists( 'S3_Uploads', false ) && function_exists( 's3_uploads_enabled' ) && \s3_uploads_enabled() ) {
325
+ return true;
326
+ }
327
+ return false;
328
+ }
329
+
330
  /**
331
  * Retrieve option: use 'site' setting if plugin is network activated, otherwise use 'blog' setting.
332
  *
924
  }
925
  }
926
 
927
+ if ( $this->s3_uploads_enabled() ) {
928
+ if ( method_exists( 'S3_Uploads\Plugin', 'get_instance' ) && method_exists( 'S3_Uploads\Plugin', 'get_s3_url' ) ) {
929
+ $s3_uploads_instance = \S3_Uploads\Plugin::get_instance();
930
+ $s3_uploads_url = $s3_uploads_instance->get_s3_url();
931
+ } elseif ( method_exists( 'S3_Uploads', 'get_instance' ) && method_exists( 'S3_Uploads', 'get_s3_url' ) ) {
932
+ $s3_uploads_instance = \S3_Uploads::get_instance();
933
+ $s3_uploads_url = $s3_uploads_instance->get_s3_url();
934
+ }
935
+ if ( ! empty( $s3_uploads_url ) ) {
936
+ $this->allowed_urls[] = $s3_uploads_url;
937
+ $this->debug_message( "found S3 URL from S3_Uploads: $s3_uploads_url" );
938
+ $s3_domain = $this->parse_url( $s3_uploads_url, PHP_URL_HOST );
939
+ $s3_scheme = $this->parse_url( $s3_uploads_url, PHP_URL_SCHEME );
940
+ $this->s3_active = $s3_domain;
941
+ }
 
 
 
 
 
 
 
 
 
 
 
942
  }
943
 
944
  if ( class_exists( 'wpCloud\StatelessMedia\EWWW' ) && function_exists( 'ud_get_stateless_media' ) ) {
classes/class-eio-js-webp.php CHANGED
@@ -672,13 +672,13 @@ class EIO_JS_Webp extends EIO_Page_Parser {
672
  ewwwio_debug_message( "found webp for ngg data-thumbnail: $thumb" );
673
  }
674
  }
675
- $bg_image = $this->get_attribute( $link, 'data-bg' );
676
  $link_class = $this->get_attribute( $link, 'class' );
677
  if ( $link_class && $bg_image && false !== strpos( $link_class, 'lazyload' ) ) {
678
- ewwwio_debug_message( "checking a/link for LL data-bg: $bg_image" );
679
  if ( $this->validate_image_url( $bg_image ) ) {
680
- $this->set_attribute( $link, 'data-bg-webp', $this->generate_url( $bg_image ) );
681
- ewwwio_debug_message( 'found webp for LL data-bg' );
682
  }
683
  }
684
  if ( $link !== $links[ $index ] ) {
@@ -720,13 +720,13 @@ class EIO_JS_Webp extends EIO_Page_Parser {
720
  $buffer = str_replace( $listitems[ $index ], $listitem, $buffer );
721
  }
722
  }
723
- $bg_image = $this->get_attribute( $listitem, 'data-bg' );
724
  $li_class = $this->get_attribute( $listitem, 'class' );
725
  if ( $li_class && $bg_image && false !== strpos( $li_class, 'lazyload' ) ) {
726
- ewwwio_debug_message( "checking div for LL data-bg: $bg_image" );
727
  if ( $this->validate_image_url( $bg_image ) ) {
728
- $this->set_attribute( $listitem, 'data-bg-webp', $this->generate_url( $bg_image ) );
729
- ewwwio_debug_message( 'found webp for LL data-bg' );
730
  $buffer = str_replace( $listitems[ $index ], $listitem, $buffer );
731
  }
732
  }
@@ -750,12 +750,12 @@ class EIO_JS_Webp extends EIO_Page_Parser {
750
  $buffer = str_replace( $divs[ $index ], $div, $buffer );
751
  }
752
  }
753
- $bg_image = $this->get_attribute( $div, 'data-bg' );
754
  if ( $div_class && $bg_image && false !== strpos( $div_class, 'lazyload' ) ) {
755
- ewwwio_debug_message( "checking div for LL data-bg: $bg_image" );
756
  if ( $this->validate_image_url( $bg_image ) ) {
757
- $this->set_attribute( $div, 'data-bg-webp', $this->generate_url( $bg_image ) );
758
- ewwwio_debug_message( 'found webp for LL data-bg' );
759
  $buffer = str_replace( $divs[ $index ], $div, $buffer );
760
  }
761
  }
@@ -770,12 +770,12 @@ class EIO_JS_Webp extends EIO_Page_Parser {
770
  continue;
771
  }
772
  $class = $this->get_attribute( $section, 'class' );
773
- $bg_image = $this->get_attribute( $section, 'data-bg' );
774
  if ( $class && $bg_image && false !== strpos( $class, 'lazyload' ) ) {
775
- ewwwio_debug_message( "checking section for LL data-bg: $bg_image" );
776
  if ( $this->validate_image_url( $bg_image ) ) {
777
- $this->set_attribute( $section, 'data-bg-webp', $this->generate_url( $bg_image ) );
778
- ewwwio_debug_message( 'found webp for LL data-bg' );
779
  $buffer = str_replace( $sections[ $index ], $section, $buffer );
780
  }
781
  }
@@ -790,12 +790,12 @@ class EIO_JS_Webp extends EIO_Page_Parser {
790
  continue;
791
  }
792
  $class = $this->get_attribute( $span, 'class' );
793
- $bg_image = $this->get_attribute( $span, 'data-bg' );
794
  if ( $class && $bg_image && false !== strpos( $class, 'lazyload' ) ) {
795
- ewwwio_debug_message( "checking span for LL data-bg: $bg_image" );
796
  if ( $this->validate_image_url( $bg_image ) ) {
797
- $this->set_attribute( $span, 'data-bg-webp', $this->generate_url( $bg_image ) );
798
- ewwwio_debug_message( 'found webp for LL data-bg' );
799
  $buffer = str_replace( $spans[ $index ], $span, $buffer );
800
  }
801
  }
672
  ewwwio_debug_message( "found webp for ngg data-thumbnail: $thumb" );
673
  }
674
  }
675
+ $bg_image = $this->get_attribute( $link, 'data-back' );
676
  $link_class = $this->get_attribute( $link, 'class' );
677
  if ( $link_class && $bg_image && false !== strpos( $link_class, 'lazyload' ) ) {
678
+ ewwwio_debug_message( "checking a/link for LL data-back: $bg_image" );
679
  if ( $this->validate_image_url( $bg_image ) ) {
680
+ $this->set_attribute( $link, 'data-back-webp', $this->generate_url( $bg_image ) );
681
+ ewwwio_debug_message( 'found webp for LL data-back' );
682
  }
683
  }
684
  if ( $link !== $links[ $index ] ) {
720
  $buffer = str_replace( $listitems[ $index ], $listitem, $buffer );
721
  }
722
  }
723
+ $bg_image = $this->get_attribute( $listitem, 'data-back' );
724
  $li_class = $this->get_attribute( $listitem, 'class' );
725
  if ( $li_class && $bg_image && false !== strpos( $li_class, 'lazyload' ) ) {
726
+ ewwwio_debug_message( "checking div for LL data-back: $bg_image" );
727
  if ( $this->validate_image_url( $bg_image ) ) {
728
+ $this->set_attribute( $listitem, 'data-back-webp', $this->generate_url( $bg_image ) );
729
+ ewwwio_debug_message( 'found webp for LL data-back' );
730
  $buffer = str_replace( $listitems[ $index ], $listitem, $buffer );
731
  }
732
  }
750
  $buffer = str_replace( $divs[ $index ], $div, $buffer );
751
  }
752
  }
753
+ $bg_image = $this->get_attribute( $div, 'data-back' );
754
  if ( $div_class && $bg_image && false !== strpos( $div_class, 'lazyload' ) ) {
755
+ ewwwio_debug_message( "checking div for LL data-back: $bg_image" );
756
  if ( $this->validate_image_url( $bg_image ) ) {
757
+ $this->set_attribute( $div, 'data-back-webp', $this->generate_url( $bg_image ) );
758
+ ewwwio_debug_message( 'found webp for LL data-back' );
759
  $buffer = str_replace( $divs[ $index ], $div, $buffer );
760
  }
761
  }
770
  continue;
771
  }
772
  $class = $this->get_attribute( $section, 'class' );
773
+ $bg_image = $this->get_attribute( $section, 'data-back' );
774
  if ( $class && $bg_image && false !== strpos( $class, 'lazyload' ) ) {
775
+ ewwwio_debug_message( "checking section for LL data-back: $bg_image" );
776
  if ( $this->validate_image_url( $bg_image ) ) {
777
+ $this->set_attribute( $section, 'data-back-webp', $this->generate_url( $bg_image ) );
778
+ ewwwio_debug_message( 'found webp for LL data-back' );
779
  $buffer = str_replace( $sections[ $index ], $section, $buffer );
780
  }
781
  }
790
  continue;
791
  }
792
  $class = $this->get_attribute( $span, 'class' );
793
+ $bg_image = $this->get_attribute( $span, 'data-back' );
794
  if ( $class && $bg_image && false !== strpos( $class, 'lazyload' ) ) {
795
+ ewwwio_debug_message( "checking span for LL data-back: $bg_image" );
796
  if ( $this->validate_image_url( $bg_image ) ) {
797
+ $this->set_attribute( $span, 'data-back-webp', $this->generate_url( $bg_image ) );
798
+ ewwwio_debug_message( 'found webp for LL data-back' );
799
  $buffer = str_replace( $spans[ $index ], $span, $buffer );
800
  }
801
  }
classes/class-eio-lazy-load.php CHANGED
@@ -168,7 +168,10 @@ if ( ! class_exists( 'EIO_Lazy_Load' ) ) {
168
  add_filter( 'eio_allow_admin_lazyload', array( $this, 'allow_admin_lazyload' ) );
169
 
170
  // Load the appropriate JS.
171
- if ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ) {
 
 
 
172
  // Load the non-minified and separate versions of the lazy load scripts.
173
  add_action( 'wp_enqueue_scripts', array( $this, 'debug_script' ), 1 );
174
  } else {
@@ -767,12 +770,12 @@ if ( ! class_exists( 'EIO_Lazy_Load' ) ) {
767
  $webp_image_urls = apply_filters( 'eio_ll_multiple_bg_images_for_webp', $bg_image_urls );
768
  $bg_image_urls = wp_json_encode( $bg_image_urls );
769
  $webp_image_urls = wp_json_encode( $webp_image_urls );
770
- $this->set_attribute( $element, 'data-bg', $bg_image_urls );
771
  if ( $bg_image_urls !== $webp_image_urls ) {
772
- $this->set_attribute( $element, 'data-bg-webp', $webp_image_urls );
773
  }
774
  } elseif ( ! empty( $bg_image_urls[0] ) ) {
775
- $this->set_attribute( $element, 'data-bg', $bg_image_urls[0] );
776
  }
777
  $element = str_replace( $style, $new_style, $element );
778
  }
@@ -1260,6 +1263,7 @@ if ( ! class_exists( 'EIO_Lazy_Load' ) ) {
1260
  $plugin_file = constant( strtoupper( $this->prefix ) . 'PLUGIN_FILE' );
1261
  wp_enqueue_script( 'eio-lazy-load-pre', plugins_url( '/includes/lazysizes-pre.js', $plugin_file ), array(), $this->version, EIO_LL_FOOTER );
1262
  wp_enqueue_script( 'eio-lazy-load-uvh', plugins_url( '/includes/ls.unveilhooks.js', $plugin_file ), array(), $this->version, EIO_LL_FOOTER );
 
1263
  wp_enqueue_script( 'eio-lazy-load-post', plugins_url( '/includes/lazysizes-post.js', $plugin_file ), array(), $this->version, EIO_LL_FOOTER );
1264
  wp_enqueue_script( 'eio-lazy-load', plugins_url( '/includes/lazysizes.js', $plugin_file ), array(), $this->version, EIO_LL_FOOTER );
1265
  if ( defined( strtoupper( $this->prefix ) . 'LAZY_PRINT' ) && constant( strtoupper( $this->prefix ) . 'LAZY_PRINT' ) ) {
168
  add_filter( 'eio_allow_admin_lazyload', array( $this, 'allow_admin_lazyload' ) );
169
 
170
  // Load the appropriate JS.
171
+ if (
172
+ defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG
173
+ || defined( strtoupper( $this->prefix ) . 'SCRIPT_DEBUG' ) && constant( strtoupper( $this->prefix ) . 'SCRIPT_DEBUG' )
174
+ ) {
175
  // Load the non-minified and separate versions of the lazy load scripts.
176
  add_action( 'wp_enqueue_scripts', array( $this, 'debug_script' ), 1 );
177
  } else {
770
  $webp_image_urls = apply_filters( 'eio_ll_multiple_bg_images_for_webp', $bg_image_urls );
771
  $bg_image_urls = wp_json_encode( $bg_image_urls );
772
  $webp_image_urls = wp_json_encode( $webp_image_urls );
773
+ $this->set_attribute( $element, 'data-back', $bg_image_urls );
774
  if ( $bg_image_urls !== $webp_image_urls ) {
775
+ $this->set_attribute( $element, 'data-back-webp', $webp_image_urls );
776
  }
777
  } elseif ( ! empty( $bg_image_urls[0] ) ) {
778
+ $this->set_attribute( $element, 'data-back', $bg_image_urls[0] );
779
  }
780
  $element = str_replace( $style, $new_style, $element );
781
  }
1263
  $plugin_file = constant( strtoupper( $this->prefix ) . 'PLUGIN_FILE' );
1264
  wp_enqueue_script( 'eio-lazy-load-pre', plugins_url( '/includes/lazysizes-pre.js', $plugin_file ), array(), $this->version, EIO_LL_FOOTER );
1265
  wp_enqueue_script( 'eio-lazy-load-uvh', plugins_url( '/includes/ls.unveilhooks.js', $plugin_file ), array(), $this->version, EIO_LL_FOOTER );
1266
+ wp_enqueue_script( 'eio-lazy-load-uvh-addon', plugins_url( '/includes/ls.unveilhooks-addon.js', $plugin_file ), array(), $this->version, EIO_LL_FOOTER );
1267
  wp_enqueue_script( 'eio-lazy-load-post', plugins_url( '/includes/lazysizes-post.js', $plugin_file ), array(), $this->version, EIO_LL_FOOTER );
1268
  wp_enqueue_script( 'eio-lazy-load', plugins_url( '/includes/lazysizes.js', $plugin_file ), array(), $this->version, EIO_LL_FOOTER );
1269
  if ( defined( strtoupper( $this->prefix ) . 'LAZY_PRINT' ) && constant( strtoupper( $this->prefix ) . 'LAZY_PRINT' ) ) {
classes/class-ewwwio-cli.php CHANGED
@@ -323,7 +323,7 @@ class EWWWIO_CLI extends WP_CLI_Command {
323
  $wpdb->prepare(
324
  "SELECT count(ID) FROM $wpdb->posts WHERE ID > %d AND (post_type = 'attachment' OR post_type = 'ims_image') AND post_mime_type LIKE %s",
325
  (int) $position,
326
- '%image%',
327
  )
328
  );
329
 
323
  $wpdb->prepare(
324
  "SELECT count(ID) FROM $wpdb->posts WHERE ID > %d AND (post_type = 'attachment' OR post_type = 'ims_image') AND post_mime_type LIKE %s",
325
  (int) $position,
326
+ '%image%'
327
  )
328
  );
329
 
classes/class-exactdn.php CHANGED
@@ -2333,7 +2333,6 @@ if ( ! class_exists( 'ExactDN' ) ) {
2333
  }
2334
 
2335
  $this->debug_message( "image_src = $image_src" );
2336
- $upload_dir = wp_get_upload_dir();
2337
  $resize_existing = defined( 'EXACTDN_RESIZE_EXISTING' ) && EXACTDN_RESIZE_EXISTING;
2338
  $w_descriptor = true;
2339
 
@@ -2372,10 +2371,16 @@ if ( ! class_exists( 'ExactDN' ) ) {
2372
  $this->debug_message( 'continuing: ' . $width . ' vs. ' . $source['value'] );
2373
 
2374
  // It's quicker to get the full size with the data we have already, if available.
2375
- if ( ! empty( $attachment_id ) ) {
2376
- $url = wp_get_attachment_url( $attachment_id );
 
 
 
2377
  } else {
2378
- $url = $this->strip_image_dimensions_maybe( $url );
 
 
 
2379
  }
2380
  $this->debug_message( "building srcs from $url" );
2381
 
@@ -2406,8 +2411,35 @@ if ( ! class_exists( 'ExactDN' ) ) {
2406
  */
2407
  $multipliers = apply_filters( 'exactdn_srcset_multipliers', array( .2, .4, .6, .8, 1, 2, 3, 1920 ) );
2408
 
2409
- $this->debug_message( "building url from {$upload_dir['baseurl']} and {$image_meta['file']}" );
2410
- $url = trailingslashit( $upload_dir['baseurl'] ) . $image_meta['file'];
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2411
 
2412
  if ( ! $w_descriptor ) {
2413
  $this->debug_message( 'using x descriptors instead of w' );
2333
  }
2334
 
2335
  $this->debug_message( "image_src = $image_src" );
 
2336
  $resize_existing = defined( 'EXACTDN_RESIZE_EXISTING' ) && EXACTDN_RESIZE_EXISTING;
2337
  $w_descriptor = true;
2338
 
2371
  $this->debug_message( 'continuing: ' . $width . ' vs. ' . $source['value'] );
2372
 
2373
  // It's quicker to get the full size with the data we have already, if available.
2374
+ if ( ! empty( $full_url ) ) {
2375
+ $url = $full_url;
2376
+ } elseif ( ! empty( $attachment_id ) ) {
2377
+ $full_url = wp_get_attachment_url( $attachment_id );
2378
+ $url = $full_url;
2379
  } else {
2380
+ $full_url = $this->strip_image_dimensions_maybe( $url );
2381
+ if ( $full_url === $url ) {
2382
+ $full_url = '';
2383
+ }
2384
  }
2385
  $this->debug_message( "building srcs from $url" );
2386
 
2411
  */
2412
  $multipliers = apply_filters( 'exactdn_srcset_multipliers', array( .2, .4, .6, .8, 1, 2, 3, 1920 ) );
2413
 
2414
+ if ( ! empty( $full_url ) ) {
2415
+ $this->debug_message( "already built url via db: $full_url" );
2416
+ $url = $full_url;
2417
+ } elseif ( 0 === strpos( $image_meta['file'], '/' ) ) {
2418
+ $this->debug_message( 'full meta appears to be absolute path, retrieving URL via wp_get_attachment_url()' );
2419
+ $url = \wp_get_attachment_url( $attachment_id );
2420
+ } else {
2421
+ $base_dir = \dirname( $url );
2422
+ $meta_file = $image_meta['file'];
2423
+ $this->debug_message( "checking to see if we can join $base_dir with $meta_file" );
2424
+ if ( false !== \strpos( $meta_file, '/' ) ) {
2425
+ $meta_dir = \dirname( $meta_file );
2426
+ if ( \str_ends_with( $base_dir, $meta_dir ) ) {
2427
+ $meta_file = \wp_basename( $meta_file );
2428
+ $this->debug_message( "trimmed file down to $meta_file" );
2429
+ } else {
2430
+ // This happens if there is object versioning, or thumbs in a sub-folder.
2431
+ $this->debug_message( "could not splice $base_dir and $meta_file" );
2432
+ $base_dir = false;
2433
+ }
2434
+ }
2435
+ if ( $base_dir ) {
2436
+ $this->debug_message( "building url from $base_dir and $meta_file" );
2437
+ $url = \trailingslashit( $base_dir ) . $meta_file;
2438
+ } else {
2439
+ $this->debug_message( 'splicing disabled previously, or empty base_dir, so retrieving URL via wp_get_attachment_url()' );
2440
+ $url = \wp_get_attachment_url( $attachment_id );
2441
+ }
2442
+ }
2443
 
2444
  if ( ! $w_descriptor ) {
2445
  $this->debug_message( 'using x descriptors instead of w' );
common.php CHANGED
@@ -1,8 +1,8 @@
1
  <?php
2
  /**
3
- * Common functions for Standard and Cloud plugins
4
  *
5
- * This file contains functions that are shared by both EWWW IO plugin(s), useful when we had a
6
  * Cloud version. Functions that differed between the two are stored in unique.php.
7
  *
8
  * @link https://ewww.io
@@ -13,7 +13,7 @@ if ( ! defined( 'ABSPATH' ) ) {
13
  exit;
14
  }
15
 
16
- define( 'EWWW_IMAGE_OPTIMIZER_VERSION', 680 );
17
 
18
  // Initialize a couple globals.
19
  $eio_debug = '';
@@ -555,6 +555,30 @@ if ( ! function_exists( 'wp_getimagesize' ) ) {
555
  }
556
  }
557
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
558
  /**
559
  * Wrapper around json_encode to handle non-utf8 characters.
560
  *
@@ -820,7 +844,7 @@ function ewww_image_optimizer_init() {
820
  if ( ! empty( $_GET['uncomplete_wizard'] ) && ! empty( $_REQUEST['_wpnonce'] ) && wp_verify_nonce( sanitize_key( $_REQUEST['_wpnonce'] ), 'ewww_image_optimizer_options-options' ) ) {
821
  update_option( 'ewww_image_optimizer_wizard_complete', false, false );
822
  }
823
- if ( class_exists( 'S3_Uploads' ) || class_exists( 'S3_Uploads\Plugin' ) ) {
824
  ewwwio_debug_message( 's3-uploads detected, deferring resize_upload' );
825
  add_filter( 'ewww_image_optimizer_defer_resizing', '__return_true' );
826
  }
@@ -1484,21 +1508,6 @@ function ewww_image_optimizer_single_size_optimize( $id, $size ) {
1484
  } // End if().
1485
  }
1486
 
1487
- if ( ! function_exists( 'wp_doing_ajax' ) ) {
1488
- /**
1489
- * Checks to see if this is an AJAX request.
1490
- *
1491
- * For backwards compatiblity with WordPress < 4.7.0.
1492
- *
1493
- * @since 3.3.0
1494
- *
1495
- * @return bool True if this is an AJAX request.
1496
- */
1497
- function wp_doing_ajax() {
1498
- return apply_filters( 'wp_doing_ajax', defined( 'DOING_AJAX' ) && DOING_AJAX );
1499
- }
1500
- }
1501
-
1502
  /**
1503
  * Checks to see if this is a REST API request, and whether the WP_Image_Editor hooks should be undone.
1504
  *
@@ -2450,10 +2459,27 @@ function ewww_image_optimizer_notice_reoptimization() {
2450
  }
2451
  }
2452
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2453
  /**
2454
  * Checks if a plugin is offloading media to cloud storage and removing local copies.
2455
  *
2456
- * @return bool True if a plugin is removing local files, false otherwise..
2457
  */
2458
  function ewww_image_optimizer_cloud_based_media() {
2459
  if ( class_exists( 'Amazon_S3_And_CloudFront' ) ) {
@@ -2462,10 +2488,7 @@ function ewww_image_optimizer_cloud_based_media() {
2462
  return true;
2463
  }
2464
  }
2465
- if ( class_exists( 'S3_Uploads' ) && function_exists( 's3_uploads_enabled' ) && s3_uploads_enabled() ) {
2466
- return true;
2467
- }
2468
- if ( class_exists( 'S3_Uploads\Plugin' ) && function_exists( 'S3_Uploads\enabled' ) && \S3_Uploads\enabled() ) {
2469
  return true;
2470
  }
2471
  if ( class_exists( 'wpCloud\StatelessMedia\EWWW' ) && function_exists( 'ud_get_stateless_media' ) ) {
@@ -2488,7 +2511,7 @@ function ewww_image_optimizer_cloud_based_media() {
2488
  */
2489
  function ewww_image_optimizer_load_editor( $editors ) {
2490
  ewwwio_debug_message( '<b>' . __FUNCTION__ . '()</b>' );
2491
- if ( class_exists( 'S3_Uploads\Image_Editor_Imagick' ) ) {
2492
  return $editors;
2493
  }
2494
  if ( ! class_exists( 'EWWWIO_GD_Editor' ) && ! class_exists( 'EWWWIO_Imagick_Editor' ) ) {
@@ -4430,7 +4453,7 @@ function ewww_image_optimizer_cloud_restore_from_meta_data( $id, $gallery = 'med
4430
  }
4431
  remove_filter( 'wp_update_attachment_metadata', 'ewww_image_optimizer_update_filesize_metadata', 9 );
4432
  $meta = ewww_image_optimizer_update_filesize_metadata( $meta, $id );
4433
- if ( class_exists( 'S3_Uploads' ) || class_exists( 'S3_uploads\Plugin' ) ) {
4434
  ewww_image_optimizer_remote_push( $meta, $id );
4435
  ewwwio_debug_message( 're-uploading to S3(_Uploads)' );
4436
  }
@@ -4616,7 +4639,7 @@ function ewww_image_optimizer_delete( $id ) {
4616
  }
4617
  $s3_path = false;
4618
  $s3_dir = false;
4619
- if ( ( class_exists( 'S3_Uploads' ) || class_exists( 'S3_Uploads\Plugin' ) ) && ewww_image_optimizer_get_option( 'ewww_image_optimizer_webp' ) ) {
4620
  $s3_path = get_attached_file( $id );
4621
  if ( 0 === strpos( $s3_path, 's3://' ) ) {
4622
  ewwwio_debug_message( 'removing: ' . $s3_path . '.webp' );
@@ -7056,7 +7079,7 @@ function ewww_image_optimizer_stream_wrapped( $filename ) {
7056
  */
7057
  function ewww_image_optimizer_remote_push( $meta, $id ) {
7058
  ewwwio_debug_message( '<b>' . __FUNCTION__ . '()</b>' );
7059
- if ( ( class_exists( 'S3_Uploads' ) || class_exists( 'S3_Uploads\Plugin' ) ) && ! empty( $meta['file'] ) ) {
7060
  $s3_upload_dir = wp_get_upload_dir();
7061
  $s3_upload_dir = trailingslashit( $s3_upload_dir['basedir'] );
7062
  $s3_path = get_attached_file( $id );
@@ -7148,7 +7171,7 @@ function ewww_image_optimizer_remote_fetch( $id, $meta ) {
7148
  require_once( ABSPATH . '/wp-admin/includes/file.php' );
7149
  }
7150
  $filename = false;
7151
- if ( ( class_exists( 'S3_Uploads' ) || class_exists( 'S3_Uploads\Plugin' ) ) && ! empty( $meta['file'] ) ) {
7152
  $s3_upload_dir = wp_get_upload_dir();
7153
  $s3_upload_dir = trailingslashit( $s3_upload_dir['basedir'] );
7154
  $s3_path = get_attached_file( $id );
@@ -8942,7 +8965,7 @@ function ewww_image_optimizer_resize_from_meta_data( $meta, $id = null, $log = t
8942
  ewwwio_debug_message( 'uploading to Amazon S3' );
8943
  }
8944
  }
8945
- if ( class_exists( 'S3_Uploads' ) || class_exists( 'S3_Uploads\Plugin' ) ) {
8946
  ewww_image_optimizer_remote_push( $meta, $id );
8947
  ewwwio_debug_message( 're-uploading to S3(_Uploads)' );
8948
  }
@@ -9867,11 +9890,7 @@ function ewww_image_optimizer_custom_column( $column_name, $id, $meta = null ) {
9867
  echo '<div>' . esc_html__( 'Offloaded Media', 'ewww-image-optimizer' ) . '</div>';
9868
  $ewww_cdn = true;
9869
  }
9870
- if ( is_array( $meta ) && class_exists( 'S3_Uploads' ) && preg_match( '/^(http|s3|gs)\w*:/', get_attached_file( $id ) ) ) {
9871
- echo '<div>' . esc_html__( 'Amazon S3 image', 'ewww-image-optimizer' ) . '</div>';
9872
- $ewww_cdn = true;
9873
- }
9874
- if ( is_array( $meta ) && class_exists( 'S3_Uploads\Plugin' ) && preg_match( '/^(http|s3|gs)\w*:/', get_attached_file( $id ) ) ) {
9875
  echo '<div>' . esc_html__( 'Amazon S3 image', 'ewww-image-optimizer' ) . '</div>';
9876
  $ewww_cdn = true;
9877
  }
@@ -10033,7 +10052,7 @@ function ewww_image_optimizer_custom_column( $column_name, $id, $meta = null ) {
10033
  $backup_available = false;
10034
  $file_parts = pathinfo( $file_path );
10035
  $basename = $file_parts['filename'];
10036
- $action_id = ewww_image_optimizer_get_primary_wpml_id( $id );
10037
  // If necessary, use get_post_meta( $post_id, '_wp_attachment_backup_sizes', true ); to only use basename for edited attachments, but that requires extra queries, so kiss for now.
10038
  if ( $ewww_cdn ) {
10039
  if ( ewww_image_optimizer_image_is_pending( $action_id, 'media-async' ) ) {
@@ -10050,7 +10069,7 @@ function ewww_image_optimizer_custom_column( $column_name, $id, $meta = null ) {
10050
  $optimized_images = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM $wpdb->ewwwio_images WHERE attachment_id = %d AND gallery = 'media' AND image_size <> 0 ORDER BY orig_size DESC", $id ), ARRAY_A );
10051
  }
10052
  if ( ! $optimized_images ) {
10053
- list( $possible_action_id, $optimized_images ) = ewww_image_optimizer_get_wpml_results( $id );
10054
  if ( $optimized_images ) {
10055
  $action_id = $possible_action_id;
10056
  }
@@ -10128,7 +10147,7 @@ function ewww_image_optimizer_custom_column( $column_name, $id, $meta = null ) {
10128
  $optimized_images = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM $wpdb->ewwwio_images WHERE attachment_id = %d AND gallery = 'media' AND image_size <> 0 ORDER BY orig_size DESC", $id ), ARRAY_A );
10129
  }
10130
  if ( ! $optimized_images ) {
10131
- list( $possible_action_id, $optimized_images ) = ewww_image_optimizer_get_wpml_results( $id );
10132
  if ( $optimized_images ) {
10133
  $action_id = $possible_action_id;
10134
  }
@@ -10429,16 +10448,16 @@ function ewww_image_optimizer_custom_column_results( $id, $optimized_images ) {
10429
  }
10430
 
10431
  /**
10432
- * If attachment is translated by WPML, get the primary ID number.
 
 
 
10433
  *
10434
- * @param int $id The attachment ID number to search for in the WPML tables.
10435
  * @return int The primary/original ID number.
10436
  */
10437
- function ewww_image_optimizer_get_primary_wpml_id( $id ) {
10438
- if ( ! defined( 'ICL_SITEPRESS_VERSION' ) ) {
10439
- return $id;
10440
- }
10441
- if ( get_post_meta( $id, 'wpml_media_processed', true ) ) {
10442
  $trid = apply_filters( 'wpml_element_trid', null, $id, 'post_attachment' );
10443
  if ( ! empty( $trid ) ) {
10444
  $translations = apply_filters( 'wpml_get_element_translations', null, $trid, 'post_attachment' );
@@ -10456,40 +10475,45 @@ function ewww_image_optimizer_get_primary_wpml_id( $id ) {
10456
  }
10457
  }
10458
  }
10459
- return $id;
10460
  }
 
10461
  /**
10462
- * Gets results for WPML replicates.
10463
  *
10464
- * @param int $id The attachment ID number to search for in the WPML tables.
10465
  * @return array The resultant attachment ID, and a list of image optimization results.
10466
  */
10467
- function ewww_image_optimizer_get_wpml_results( $id ) {
10468
- if ( ! defined( 'ICL_SITEPRESS_VERSION' ) ) {
10469
- return array( $id, array() );
10470
- }
10471
  ewwwio_debug_message( '<b>' . __FUNCTION__ . '()</b>' );
10472
- $trid = apply_filters( 'wpml_element_trid', null, $id, 'post_attachment' );
10473
- if ( empty( $trid ) ) {
10474
- return array( $id, array() );
10475
- }
10476
- $translations = apply_filters( 'wpml_get_element_translations', null, $trid, 'post_attachment' );
10477
- if ( empty( $translations ) ) {
10478
- return array( $id, array() );
10479
- }
10480
- global $wpdb;
10481
- foreach ( $translations as $translation ) {
10482
- if ( empty( $translation->element_id ) ) {
10483
- continue;
10484
  }
10485
- ewwwio_debug_message( "checking {$translation->element_id} for results with WPML" );
10486
- $optimized_images = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM $wpdb->ewwwio_images WHERE attachment_id = %d AND gallery = 'media' AND image_size <> 0 ORDER BY orig_size DESC", $translation->element_id ), ARRAY_A );
10487
- if ( ! empty( $optimized_images ) ) {
10488
- return array( (int) $translation->element_id, $optimized_images );
 
 
 
 
 
 
 
 
 
 
 
 
 
10489
  }
10490
  }
10491
  return array( $id, array() );
10492
  }
 
10493
  /**
10494
  * Removes optimization from metadata, because we store it all in the images table now.
10495
  *
@@ -13453,6 +13477,7 @@ function ewww_image_optimizer_options( $network = 'singlesite' ) {
13453
  <textarea id='ewww_image_optimizer_ll_all_things' name='ewww_image_optimizer_ll_all_things' rows='3' cols='60'><?php echo esc_html( ewww_image_optimizer_get_option( 'ewww_image_optimizer_ll_all_things' ) ); ?></textarea>
13454
  <p class='description'>
13455
  <?php esc_html_e( 'Specify class/id values of elements with CSS background images (comma-separated).', 'ewww-image-optimizer' ); ?>
 
13456
  <br>*<?php esc_html_e( 'Background images directly attached via inline style attributes will be lazy loaded by default.', 'ewww-image-optimizer' ); ?>
13457
  </p>
13458
  </td>
1
  <?php
2
  /**
3
+ * Common functions for Standard plugin
4
  *
5
+ * This file contains functions that are shared by both EWWW IO plugin(s), back when we had a
6
  * Cloud version. Functions that differed between the two are stored in unique.php.
7
  *
8
  * @link https://ewww.io
13
  exit;
14
  }
15
 
16
+ define( 'EWWW_IMAGE_OPTIMIZER_VERSION', 690 );
17
 
18
  // Initialize a couple globals.
19
  $eio_debug = '';
555
  }
556
  }
557
 
558
+ if ( ! function_exists( 'str_ends_with' ) ) {
559
+ /**
560
+ * Polyfill for `str_ends_with()` function added in WP 5.9 or PHP 8.0.
561
+ *
562
+ * Performs a case-sensitive check indicating if
563
+ * the haystack ends with needle.
564
+ *
565
+ * @since 6.8.1
566
+ *
567
+ * @param string $haystack The string to search in.
568
+ * @param string $needle The substring to search for in the `$haystack`.
569
+ * @return bool True if `$haystack` ends with `$needle`, otherwise false.
570
+ */
571
+ function str_ends_with( $haystack, $needle ) {
572
+ if ( '' === $haystack && '' !== $needle ) {
573
+ return false;
574
+ }
575
+
576
+ $len = strlen( $needle );
577
+
578
+ return 0 === substr_compare( $haystack, $needle, -$len, $len );
579
+ }
580
+ }
581
+
582
  /**
583
  * Wrapper around json_encode to handle non-utf8 characters.
584
  *
844
  if ( ! empty( $_GET['uncomplete_wizard'] ) && ! empty( $_REQUEST['_wpnonce'] ) && wp_verify_nonce( sanitize_key( $_REQUEST['_wpnonce'] ), 'ewww_image_optimizer_options-options' ) ) {
845
  update_option( 'ewww_image_optimizer_wizard_complete', false, false );
846
  }
847
+ if ( ewww_image_optimizer_s3_uploads_enabled() ) {
848
  ewwwio_debug_message( 's3-uploads detected, deferring resize_upload' );
849
  add_filter( 'ewww_image_optimizer_defer_resizing', '__return_true' );
850
  }
1508
  } // End if().
1509
  }
1510
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1511
  /**
1512
  * Checks to see if this is a REST API request, and whether the WP_Image_Editor hooks should be undone.
1513
  *
2459
  }
2460
  }
2461
 
2462
+ /**
2463
+ * Checks if the S3 Uploads plugin is installed and active.
2464
+ *
2465
+ * @return bool True if it is fully active and rewriting/offloding media, false otherwise.
2466
+ */
2467
+ function ewww_image_optimizer_s3_uploads_enabled() {
2468
+ // For version 3.x.
2469
+ if ( class_exists( 'S3_Uploads\Plugin', false ) && function_exists( 'S3_Uploads\enabled' ) && \S3_Uploads\enabled() ) {
2470
+ return true;
2471
+ }
2472
+ // Pre version 3.
2473
+ if ( class_exists( 'S3_Uploads', false ) && function_exists( 's3_uploads_enabled' ) && s3_uploads_enabled() ) {
2474
+ return true;
2475
+ }
2476
+ return false;
2477
+ }
2478
+
2479
  /**
2480
  * Checks if a plugin is offloading media to cloud storage and removing local copies.
2481
  *
2482
+ * @return bool True if a plugin is removing local files, false otherwise.
2483
  */
2484
  function ewww_image_optimizer_cloud_based_media() {
2485
  if ( class_exists( 'Amazon_S3_And_CloudFront' ) ) {
2488
  return true;
2489
  }
2490
  }
2491
+ if ( ewww_image_optimizer_s3_uploads_enabled() ) {
 
 
 
2492
  return true;
2493
  }
2494
  if ( class_exists( 'wpCloud\StatelessMedia\EWWW' ) && function_exists( 'ud_get_stateless_media' ) ) {
2511
  */
2512
  function ewww_image_optimizer_load_editor( $editors ) {
2513
  ewwwio_debug_message( '<b>' . __FUNCTION__ . '()</b>' );
2514
+ if ( class_exists( 'S3_Uploads\Image_Editor_Imagick', false ) ) {
2515
  return $editors;
2516
  }
2517
  if ( ! class_exists( 'EWWWIO_GD_Editor' ) && ! class_exists( 'EWWWIO_Imagick_Editor' ) ) {
4453
  }
4454
  remove_filter( 'wp_update_attachment_metadata', 'ewww_image_optimizer_update_filesize_metadata', 9 );
4455
  $meta = ewww_image_optimizer_update_filesize_metadata( $meta, $id );
4456
+ if ( ewww_image_optimizer_s3_uploads_enabled() ) {
4457
  ewww_image_optimizer_remote_push( $meta, $id );
4458
  ewwwio_debug_message( 're-uploading to S3(_Uploads)' );
4459
  }
4639
  }
4640
  $s3_path = false;
4641
  $s3_dir = false;
4642
+ if ( ewww_image_optimizer_s3_uploads_enabled() && ewww_image_optimizer_get_option( 'ewww_image_optimizer_webp' ) ) {
4643
  $s3_path = get_attached_file( $id );
4644
  if ( 0 === strpos( $s3_path, 's3://' ) ) {
4645
  ewwwio_debug_message( 'removing: ' . $s3_path . '.webp' );
7079
  */
7080
  function ewww_image_optimizer_remote_push( $meta, $id ) {
7081
  ewwwio_debug_message( '<b>' . __FUNCTION__ . '()</b>' );
7082
+ if ( ewww_image_optimizer_s3_uploads_enabled() && ! empty( $meta['file'] ) ) {
7083
  $s3_upload_dir = wp_get_upload_dir();
7084
  $s3_upload_dir = trailingslashit( $s3_upload_dir['basedir'] );
7085
  $s3_path = get_attached_file( $id );
7171
  require_once( ABSPATH . '/wp-admin/includes/file.php' );
7172
  }
7173
  $filename = false;
7174
+ if ( ewww_image_optimizer_s3_uploads_enabled() && ! empty( $meta['file'] ) ) {
7175
  $s3_upload_dir = wp_get_upload_dir();
7176
  $s3_upload_dir = trailingslashit( $s3_upload_dir['basedir'] );
7177
  $s3_path = get_attached_file( $id );
8965
  ewwwio_debug_message( 'uploading to Amazon S3' );
8966
  }
8967
  }
8968
+ if ( ewww_image_optimizer_s3_uploads_enabled() ) {
8969
  ewww_image_optimizer_remote_push( $meta, $id );
8970
  ewwwio_debug_message( 're-uploading to S3(_Uploads)' );
8971
  }
9890
  echo '<div>' . esc_html__( 'Offloaded Media', 'ewww-image-optimizer' ) . '</div>';
9891
  $ewww_cdn = true;
9892
  }
9893
+ if ( is_array( $meta ) && ewww_image_optimizer_s3_uploads_enabled() && preg_match( '/^(http|s3|gs)\w*:/', get_attached_file( $id ) ) ) {
 
 
 
 
9894
  echo '<div>' . esc_html__( 'Amazon S3 image', 'ewww-image-optimizer' ) . '</div>';
9895
  $ewww_cdn = true;
9896
  }
10052
  $backup_available = false;
10053
  $file_parts = pathinfo( $file_path );
10054
  $basename = $file_parts['filename'];
10055
+ $action_id = ewww_image_optimizer_get_primary_translated_media_id( $id );
10056
  // If necessary, use get_post_meta( $post_id, '_wp_attachment_backup_sizes', true ); to only use basename for edited attachments, but that requires extra queries, so kiss for now.
10057
  if ( $ewww_cdn ) {
10058
  if ( ewww_image_optimizer_image_is_pending( $action_id, 'media-async' ) ) {
10069
  $optimized_images = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM $wpdb->ewwwio_images WHERE attachment_id = %d AND gallery = 'media' AND image_size <> 0 ORDER BY orig_size DESC", $id ), ARRAY_A );
10070
  }
10071
  if ( ! $optimized_images ) {
10072
+ list( $possible_action_id, $optimized_images ) = ewww_image_optimizer_get_translated_media_results( $id );
10073
  if ( $optimized_images ) {
10074
  $action_id = $possible_action_id;
10075
  }
10147
  $optimized_images = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM $wpdb->ewwwio_images WHERE attachment_id = %d AND gallery = 'media' AND image_size <> 0 ORDER BY orig_size DESC", $id ), ARRAY_A );
10148
  }
10149
  if ( ! $optimized_images ) {
10150
+ list( $possible_action_id, $optimized_images ) = ewww_image_optimizer_get_translated_media_results( $id );
10151
  if ( $optimized_images ) {
10152
  $action_id = $possible_action_id;
10153
  }
10448
  }
10449
 
10450
  /**
10451
+ * If attachment is translated (and duplicated), get the primary ID number.
10452
+ *
10453
+ * Primarily for WPML, but if others duplicate media, the primary_translated_media_id
10454
+ * filter may be used, or a pull request may be submitted to contribute the lookup code.
10455
  *
10456
+ * @param int $id The attachment ID number to search for in the translation plugin table(s).
10457
  * @return int The primary/original ID number.
10458
  */
10459
+ function ewww_image_optimizer_get_primary_translated_media_id( $id ) {
10460
+ if ( defined( 'ICL_SITEPRESS_VERSION' ) && get_post_meta( $id, 'wpml_media_processed', true ) ) {
 
 
 
10461
  $trid = apply_filters( 'wpml_element_trid', null, $id, 'post_attachment' );
10462
  if ( ! empty( $trid ) ) {
10463
  $translations = apply_filters( 'wpml_get_element_translations', null, $trid, 'post_attachment' );
10475
  }
10476
  }
10477
  }
10478
+ return apply_filters( 'ewwwio_primary_translated_media_id', $id );
10479
  }
10480
+
10481
  /**
10482
+ * Gets results for translation (WPML) replicates.
10483
  *
10484
+ * @param int $id The attachment ID number to search for in the translation tables/data.
10485
  * @return array The resultant attachment ID, and a list of image optimization results.
10486
  */
10487
+ function ewww_image_optimizer_get_translated_media_results( $id ) {
 
 
 
10488
  ewwwio_debug_message( '<b>' . __FUNCTION__ . '()</b>' );
10489
+ $translations = array();
10490
+ if ( defined( 'ICL_SITEPRESS_VERSION' ) ) {
10491
+ $trid = apply_filters( 'wpml_element_trid', null, $id, 'post_attachment' );
10492
+ if ( empty( $trid ) ) {
10493
+ return array( $id, array() );
 
 
 
 
 
 
 
10494
  }
10495
+ $translations = apply_filters( 'wpml_get_element_translations', null, $trid, 'post_attachment' );
10496
+ if ( empty( $translations ) ) {
10497
+ return array( $id, array() );
10498
+ }
10499
+ }
10500
+ apply_filters( 'ewwwio_translated_media_ids', $translations, $id );
10501
+ if ( ewww_image_optimizer_iterable( $translations ) ) {
10502
+ global $wpdb;
10503
+ foreach ( $translations as $translation ) {
10504
+ if ( empty( $translation->element_id ) ) {
10505
+ continue;
10506
+ }
10507
+ ewwwio_debug_message( "checking {$translation->element_id} for results with WPML (or another translation plugin)" );
10508
+ $optimized_images = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM $wpdb->ewwwio_images WHERE attachment_id = %d AND gallery = 'media' AND image_size <> 0 ORDER BY orig_size DESC", $translation->element_id ), ARRAY_A );
10509
+ if ( ! empty( $optimized_images ) ) {
10510
+ return array( (int) $translation->element_id, $optimized_images );
10511
+ }
10512
  }
10513
  }
10514
  return array( $id, array() );
10515
  }
10516
+
10517
  /**
10518
  * Removes optimization from metadata, because we store it all in the images table now.
10519
  *
13477
  <textarea id='ewww_image_optimizer_ll_all_things' name='ewww_image_optimizer_ll_all_things' rows='3' cols='60'><?php echo esc_html( ewww_image_optimizer_get_option( 'ewww_image_optimizer_ll_all_things' ) ); ?></textarea>
13478
  <p class='description'>
13479
  <?php esc_html_e( 'Specify class/id values of elements with CSS background images (comma-separated).', 'ewww-image-optimizer' ); ?>
13480
+ <?php esc_html_e( 'Can match any text within the target element, like elementor-widget-container or et_pb_column.', 'ewww-image-optimizer' ); ?>
13481
  <br>*<?php esc_html_e( 'Background images directly attached via inline style attributes will be lazy loaded by default.', 'ewww-image-optimizer' ); ?>
13482
  </p>
13483
  </td>
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.8.0
17
  Requires at least: 5.8
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.9.0
17
  Requires at least: 5.8
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(/\.svg(\?.+)?$/.exec(s))return 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"img-w"===i?s.replace(o,"w="+t):"img-h"===i?s.replace(o,"h="+a):s.replace(o,"resize="+t+","+a);o=r.exec(e);if(o&&t<=o[1]){if("img-h"===i)return s.replace(r,"h="+a);if("bg-cover"!==i&&"img-crop"!==i)return e.replace(r,"w="+t);var c=o[1]-t;return 20<c||a<1080?e.replace(r,"resize="+t+","+a):e}c=n.exec(s);if(c&&t<c[1]){if("bg-cover"!==i&&"img-crop"!==i)return"img-w"===i?s.replace(n,"w="+t):"img-h"===i?s.replace(n,"h="+a):s.replace(n,"fit="+t+","+a);s=c[1]-t,n=c[2]-a;return 20<s||20<n?e.replace(r,"resize="+t+","+a):e}if(!o&&!c&&!l)return"img"===i?e+"&fit="+t+","+a:"bg-cover"===i||"img-crop"===i?e+"&resize="+t+","+a:"img-h"===i||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:"img-h"===i||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")?constrainSrc(i,a,r,"img-crop"):window.lazySizes.hC(o,"object-cover")&&(window.lazySizes.hC(o,"object-top")||window.lazySizes.hC(o,"object-bottom"))?constrainSrc(i,a,r,"img-w"):window.lazySizes.hC(o,"object-cover")&&(window.lazySizes.hC(o,"object-left")||window.lazySizes.hC(o,"object-right"))?constrainSrc(i,a,r,"img-h"):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 d(e,t){A(e,t)||e.setAttribute("class",(e[y]("class")||"").trim()+" "+t)}function u(e,t){(t=A(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,c="addEventListener",y="getAttribute",e=i[c].bind(i),p=i.setTimeout,v=i.requestAnimationFrame||p,w=i.requestIdleCallback,b=/^picture$/i,_=["load","error","lazyincluded","_lazyloaded"],C={},S=Array.prototype.forEach,A=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?c:"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 j(a,e){return e?function(){W(a)}:function(){var e=this,t=arguments;W(function(){a.apply(e,t)})}}function H(e){function t(){var e=n.now()-i;e<99?p(t,99-e):(w||r)(r)}var a,i,r=function(){a=null,e()};return function(){i=n.now(),a=a||p(t,99)}}var I,O,R,B,T,F,P,D,J,$,q,U,G,K,Q,V,X,Y,Z,ee,te,ae,ie,re,ne,oe,se,le,ce,de,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=w&&49<X?function(){w(ze,{timeout:X}),X!==h.ricTimeout&&(X=h.ricTimeout)}:j(function(){p(ze)},!0),se=j(me),le=function(e){se({target:e.target})},ce=j(function(t,e,a,i,r){var n,o,s,l,c;(s=x(t,"lazybeforeunveil",e)).defaultPrevented||(i&&(a?d(t,h.autosizesClass):t.setAttribute("sizes",i)),n=t[y](h.srcsetAttr),a=t[y](h.srcAttr),r&&(o=(c=t.parentNode)&&b.test(c.nodeName||"")),l=e.firesLoad||"src"in t&&(n||a||o),s={target:t},d(t,h.loadingClass),l&&(clearTimeout(R),R=p(ge,2500),E(t,le,!0)),o&&S.call(c.getElementsByTagName("source"),ye),n?t.setAttribute("srcset",n):a&&!o&&(ee.test(t.nodeName)?(i=a,0==(c=(e=t).getAttribute("data-load-mode")||h.iframeLoadMode)?e.contentWindow.location.replace(i):1==c&&(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&&d(t,h.fastLoadedClass),me(s),t._lazyCache=!0,p(function(){"_lazyCache"in t&&delete t._lazyCache},9)),"lazy"==t.loading&&ie--},!0)}),ue=H(function(){h.loadMode=3,oe()}),{_:function(){T=n.now(),g.elements=f.getElementsByClassName(h.lazyClass),I=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&&de(e)})})}),i.MutationObserver?new MutationObserver(oe).observe(m,{childList:!0,subtree:!0,attributes:!0}):(m[c]("DOMNodeInserted",oe,!0),m[c]("DOMAttrModified",oe,!0),setInterval(oe,999)),e("hashchange",oe,!0),["focus","mouseover","click","load","transitionend","animationend"].forEach(function(e){f[c](e,oe,!0)}),/d$|^c/.test(f.readyState)?ve():(e("load",ve),f[c]("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:de=function(e){var t,a,i,r;e._lazyRace||(!(r="auto"==(i=(a=Z.test(e.nodeName))&&(e[y](h.sizesAttr)||e[y]("sizes"))))&&O||!a||!e[y]("src")&&!e.srcset||e.complete||A(e,h.errorClass)||!A(e,h.lazyClass))&&(t=x(e,"lazyunveilread").detail,r&&Ce.updateElem(e,!0,e.offsetWidth),e._lazyRace=!0,ie++,ce(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,c,d,u=g.elements;if((B=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]))de(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,c=(g._defEx=l)*h.expFactor,d=h.hFac,U=null,ae<c&&ie<1&&2<re&&2<B&&!f.hidden?(ae=c,re=0):ae=1<B&&1<re&&ie<6?l:0),s!==r&&(F=innerWidth+r*d,P=innerHeight+r,n=-1*r,s=r),c=u[t].getBoundingClientRect(),(q=c.bottom)>=n&&(D=c.top)<=P&&($=c.right)>=n*d&&(J=c.left)<=F&&(q||$||J||D)&&(h.loadHidden||ne(u[t]))&&(O&&ie<3&&!o&&(B<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(de(u[t]),i=!0,9<ie)break}else!i&&O&&!a&&ie<4&&re<4&&2<B&&(I[0]||h.preloadAfterLoad)&&(I[0]||!o&&(q||$||J||D||"auto"!=u[t][y](h.sizesAttr)))&&(a=I[0]||u[t]);a&&!i&&de(a)}}function ze(){K=!1,Q=n.now(),G()}function me(e){var t=e.target;t._lazyCache?delete t._lazyCache:(ge(e),d(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(){O||(n.now()-T<999?p(ve,999):(O=!0,h.loadMode=3,oe(),e("scroll",pe,!0)))}var we,be,_e,Ce=(be=j(function(e,t,a,i){var r,n,o;if(e._lazysizesWidth=i,e.setAttribute("sizes",i+="px"),b.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(){we=f.getElementsByClassName(h.autosizesClass),e("resize",_e)},checkElems:_e=H(function(){var e,t=we.length;if(t)for(e=0;e<t;e++)Se(we[e])}),updateElem:Se});function Se(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&&be(e,i,t,a))}function Ae(){!Ae.i&&f.getElementsByClassName&&(Ae.i=!0,Ce._(),fe._())}return p(function(){h.init&&Ae()}),g={cfg:h,autoSizer:Ce,loader:fe,init:Ae,uP:z,aC:d,rC:u,hC:A,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(/\.svg(\?.+)?$/.exec(s))return 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"img-w"===i?s.replace(o,"w="+t):"img-h"===i?s.replace(o,"h="+a):s.replace(o,"resize="+t+","+a);o=r.exec(e);if(o&&t<=o[1]){if("img-h"===i)return s.replace(r,"h="+a);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"img-w"===i?s.replace(n,"w="+t):"img-h"===i?s.replace(n,"h="+a):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:"img-h"===i||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:"img-h"===i||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")):"function"==typeof define&&define.amd?define(["lazysizes"],t):e.lazySizes?a():e.addEventListener("lazyunveilread",a,!0)}(window,function(e,n,o){"use strict";var s,l,d={};function c(e,t,a){var i,r;d[e]||(i=n.createElement(t?"link":"script"),r=n.getElementsByTagName("script")[0],t?(i.rel="stylesheet",i.href=e):(i.onload=function(){i.onerror=null,i.onload=null,a()},i.onerror=i.onload,i.src=e),d[e]=!0,d[i.src||i.href]=!0,r.parentNode.insertBefore(i,r))}n.addEventListener&&(l=/\(|\)|\s|'/,s=function(e,t){var a=n.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==o&&!e.defaultPrevented){var r=e.target;if("none"==r.preload&&(r.preload=r.getAttribute("data-preload")||"auto"),null!=r.getAttribute("data-autoplay"))if(r.getAttribute("data-expand")&&!r.autoplay)try{r.play()}catch(e){}else requestAnimationFrame(function(){r.setAttribute("data-expand","-10"),o.aC(r,o.cfg.lazyClass)});(t=r.getAttribute("data-link"))&&c(t,!0),(t=r.getAttribute("data-script"))&&(e.detail.firesLoad=!0,c(t,null,function(){e.detail.firesLoad=!1,o.fire(r,"_lazyloaded",{},!0,!0)})),(t=r.getAttribute("data-require"))&&(o.cfg.requireJs?o.cfg.requireJs([t]):c(t)),(a=r.getAttribute("data-bg"))&&(e.detail.firesLoad=!0,s(a,function(){r.style.backgroundImage="url("+(l.test(a)?JSON.stringify(a):a)+")",e.detail.firesLoad=!1,o.fire(r,"_lazyloaded",{},!0,!0)})),(i=r.getAttribute("data-poster"))&&(e.detail.firesLoad=!0,s(i,function(){r.poster=i,e.detail.firesLoad=!1,o.fire(r,"_lazyloaded",{},!0,!0)}))}},!1))}),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")):"function"==typeof define&&define.amd?define(["lazysizes"],t):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-back"))&&(ewww_webp_supported&&(r=e.target.getAttribute("data-back-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")?constrainSrc(i,a,r,"img-crop"):window.lazySizes.hC(o,"object-cover")&&(window.lazySizes.hC(o,"object-top")||window.lazySizes.hC(o,"object-bottom"))?constrainSrc(i,a,r,"img-w"):window.lazySizes.hC(o,"object-cover")&&(window.lazySizes.hC(o,"object-left")||window.lazySizes.hC(o,"object-right"))?constrainSrc(i,a,r,"img-h"):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,z;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 z=i.lazySizesConfig||i.lazysizesConfig||{},t)e in z||(z[e]=t[e])}(),!f||!f.getElementsByClassName)return{init:function(){},cfg:z,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 h(e,t){var a;!l&&(a=i.picturefill||z.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},L=function(e,t){return(getComputedStyle(e,null)||{})[t]},N=function(e,t,a){for(a=a||e.offsetWidth;a<z.minSize&&t&&!e._lazysizesWidth;)a=t.offsetWidth,t=t.parentNode;return a},M=(o=[],s=t=[],k._lsFlush=W,k);function W(){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)(W)))}function j(a,e){return e?function(){M(a)}:function(){var e=this,t=arguments;M(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 H,O,B,R,T,q,F,J,P,D,$,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"==L(f.body,"visibility"):U)||!("hidden"==L(e.parentNode,"visibility")&&"hidden"==L(e,"visibility"))},G=ze,Q=ie=ae=0,V=z.throttleDelay,X=z.ricTimeout,Y=b&&49<X?function(){b(he,{timeout:X}),X!==z.ricTimeout&&(X=z.ricTimeout)}:j(function(){p(he)},!0),se=j(me),le=function(e){se({target:e.target})},de=j(function(t,e,a,i,r){var n,o,s,l,d;(s=x(t,"lazybeforeunveil",e)).defaultPrevented||(i&&(a?c(t,z.autosizesClass):t.setAttribute("sizes",i)),n=t[y](z.srcsetAttr),a=t[y](z.srcAttr),r&&(o=(d=t.parentNode)&&w.test(d.nodeName||"")),l=e.firesLoad||"src"in t&&(n||a||o),s={target:t},c(t,z.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")||z.iframeLoadMode)?e.contentWindow.location.replace(i):1==d&&(e.src=i)):t.src=a),r&&(n||o)&&h(t,{src:a})),t._lazyRace&&delete t._lazyRace,u(t,z.lazyClass),M(function(){var e=t.complete&&1<t.naturalWidth;l&&!e||(e&&c(t,z.fastLoadedClass),me(s),t._lazyCache=!0,p(function(){"_lazyCache"in t&&delete t._lazyCache},9)),"lazy"==t.loading&&ie--},!0)}),ue=I(function(){z.loadMode=3,oe()}),{_:function(){T=n.now(),g.elements=f.getElementsByClassName(z.lazyClass),H=f.getElementsByClassName(z.lazyClass+" "+z.preloadClass),e("scroll",oe,!0),e("resize",oe,!0),e("pageshow",function(e){var t;!e.persisted||(t=f.querySelectorAll("."+z.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?(ze(),M._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](z.sizesAttr)||e[y]("sizes"))))&&O||!a||!e[y]("src")&&!e.srcset||e.complete||S(e,z.errorClass)||!S(e,z.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 ze(){var e,t,a,i,r,n,o,s,l,d,c,u=g.elements;if((R=z.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=!z.expand||z.expand<1?500<m.clientHeight&&500<m.clientWidth?500:370:z.expand,d=(g._defEx=l)*z.expFactor,c=z.hFac,U=null,ae<d&&ie<1&&2<re&&2<R&&!f.hidden?(ae=d,re=0):ae=1<R&&1<re&&ie<6?l:0),s!==r&&(q=innerWidth+r*c,F=innerHeight+r,n=-1*r,s=r),d=u[t].getBoundingClientRect(),($=d.bottom)>=n&&(J=d.top)<=F&&(D=d.right)>=n*c&&(P=d.left)<=q&&($||D||P||J)&&(z.loadHidden||ne(u[t]))&&(O&&ie<3&&!o&&(R<3||re<4)||function(e,t){var a,i=e,r=ne(e);for(J-=t,$+=t,P-=t,D+=t;r&&(i=i.offsetParent)&&i!=f.body&&i!=m;)(r=0<(L(i,"opacity")||1))&&"visible"!=L(i,"overflow")&&(a=i.getBoundingClientRect(),r=D>a.left&&P<a.right&&$>a.top-1&&J<a.bottom+1);return r}(u[t],r))){if(ce(u[t]),i=!0,9<ie)break}else!i&&O&&!a&&ie<4&&re<4&&2<R&&(H[0]||z.preloadAfterLoad)&&(H[0]||!o&&($||D||P||J||"auto"!=u[t][y](z.sizesAttr)))&&(a=H[0]||u[t]);a&&!i&&ce(a)}}function he(){K=!1,Q=n.now(),G()}function me(e){var t=e.target;t._lazyCache?delete t._lazyCache:(ge(e),c(t,z.loadedClass),u(t,z.loadingClass),E(t,le),x(t,"lazyloaded"))}function ye(e){var t,a=e[y](z.srcsetAttr);(t=z.customMedia[e[y]("data-media")||e[y]("media")])&&e.setAttribute("media",t),a&&e.setAttribute("srcset",a)}function pe(){3==z.loadMode&&(z.loadMode=2),ue()}function ve(){O||(n.now()-T<999?p(ve,999):(O=!0,z.loadMode=3,oe(),e("scroll",pe,!0)))}var be,we,_e,Ce=(we=j(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||h(e,a.detail)}),{_:function(){be=f.getElementsByClassName(z.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=N(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(){z.init&&Se()}),g={cfg:z,autoSizer:Ce,loader:fe,init:Se,uP:h,aC:c,rC:u,hC:S,fire:x,gW:N,rAF:M}});
includes/ls.unveilhooks-addon.js ADDED
@@ -0,0 +1,118 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ (function(window, factory) {
2
+ var globalInstall = function(){
3
+ factory(window.lazySizes);
4
+ window.removeEventListener('lazyunveilread', globalInstall, true);
5
+ };
6
+
7
+ factory = factory.bind(null, window, window.document);
8
+
9
+ if(typeof module == 'object' && module.exports){
10
+ factory(require('lazysizes'));
11
+ } else if (typeof define == 'function' && define.amd) {
12
+ define(['lazysizes'], factory);
13
+ } else if(window.lazySizes) {
14
+ globalInstall();
15
+ } else {
16
+ window.addEventListener('lazyunveilread', globalInstall, true);
17
+ }
18
+ }(window, function(window, document, lazySizes) {
19
+ /*jshint eqnull:true */
20
+ 'use strict';
21
+ var regBgUrlEscape;
22
+
23
+ if(document.addEventListener){
24
+ regBgUrlEscape = /\(|\)|\s|'/;
25
+
26
+ addEventListener('lazybeforeunveil', function(e){
27
+ if(e.detail.instance != lazySizes){return;}
28
+
29
+ var bg, bgWebP;
30
+ if(!e.defaultPrevented) {
31
+
32
+ if(e.target.preload == 'none'){
33
+ e.target.preload = 'auto';
34
+ }
35
+
36
+ // handle data-back (so as not to conflict with the stock data-bg)
37
+ bg = e.target.getAttribute('data-back');
38
+ if (bg) {
39
+ if(ewww_webp_supported) {
40
+ console.log('checking for data-back-webp');
41
+ bgWebP = e.target.getAttribute('data-back-webp');
42
+ if (bgWebP) {
43
+ console.log('replacing data-back with data-back-webp');
44
+ bg = bgWebP;
45
+ }
46
+ }
47
+ var dPR = (window.devicePixelRatio || 1);
48
+ var targetWidth = Math.round(e.target.offsetWidth * dPR);
49
+ var targetHeight = Math.round(e.target.offsetHeight * dPR);
50
+ if ( 0 === bg.search(/\[/) ) {
51
+ } else if (!shouldAutoScale(e.target)||!shouldAutoScale(e.target.parentNode)){
52
+ } else if (window.lazySizes.hC(e.target,'wp-block-cover')) {
53
+ console.log('found wp-block-cover with data-back');
54
+ if (window.lazySizes.hC(e.target,'has-parallax')) {
55
+ console.log('also has-parallax with data-back');
56
+ targetWidth = Math.round(window.screen.width * dPR);
57
+ targetHeight = Math.round(window.screen.height * dPR);
58
+ } else if (targetHeight<300) {
59
+ targetHeight = 430;
60
+ }
61
+ bg = constrainSrc(bg,targetWidth,targetHeight,'bg-cover');
62
+ } else if (window.lazySizes.hC(e.target,'cover-image')){
63
+ console.log('found .cover-image with data-back');
64
+ bg = constrainSrc(bg,targetWidth,targetHeight,'bg-cover');
65
+ } else if (window.lazySizes.hC(e.target,'elementor-bg')){
66
+ console.log('found elementor-bg with data-back');
67
+ bg = constrainSrc(bg,targetWidth,targetHeight,'bg-cover');
68
+ } else if (window.lazySizes.hC(e.target,'et_parallax_bg')){
69
+ console.log('found et_parallax_bg with data-back');
70
+ bg = constrainSrc(bg,targetWidth,targetHeight,'bg-cover');
71
+ } else if (window.lazySizes.hC(e.target,'bg-image-crop')){
72
+ console.log('found bg-image-crop with data-back');
73
+ bg = constrainSrc(bg,targetWidth,targetHeight,'bg-cover');
74
+ } else {
75
+ console.log('found other data-back');
76
+ bg = constrainSrc(bg,targetWidth,targetHeight,'bg');
77
+ }
78
+ if ( e.target.style.backgroundImage && -1 === e.target.style.backgroundImage.search(/^initial/) ) {
79
+ // Convert JSON for multiple URLs.
80
+ if ( 0 === bg.search(/\[/) ) {
81
+ console.log('multiple URLs to append');
82
+ bg = JSON.parse(bg);
83
+ bg.forEach(
84
+ function(bg_url){
85
+ bg_url = (regBgUrlEscape.test(bg_url) ? JSON.stringify(bg_url) : bg_url );
86
+ }
87
+ );
88
+ bg = 'url("' + bg.join('"), url("') + '"';
89
+ var new_bg = e.target.style.backgroundImage + ', ' + bg;
90
+ console.log('setting .backgroundImage: ' + new_bg );
91
+ e.target.style.backgroundImage = new_bg;
92
+ } else {
93
+ console.log( 'appending bg url: ' + e.target.style.backgroundImage + ', url(' + (regBgUrlEscape.test(bg) ? JSON.stringify(bg) : bg ) + ')' );
94
+ e.target.style.backgroundImage = e.target.style.backgroundImage + ', url("' + (regBgUrlEscape.test(bg) ? JSON.stringify(bg) : bg ) + '")';
95
+ }
96
+ } else {
97
+ // Convert JSON for multiple URLs.
98
+ if ( 0 === bg.search(/\[/) ) {
99
+ console.log('multiple URLs to insert');
100
+ bg = JSON.parse(bg);
101
+ bg.forEach(
102
+ function(bg_url){
103
+ bg_url = (regBgUrlEscape.test(bg_url) ? JSON.stringify(bg_url) : bg_url );
104
+ }
105
+ );
106
+ bg = 'url("' + bg.join('"), url("') + '"';
107
+ console.log('setting .backgroundImage: ' + bg );
108
+ e.target.style.backgroundImage = bg;
109
+ } else {
110
+ console.log('setting .backgroundImage: ' + 'url(' + (regBgUrlEscape.test(bg) ? JSON.stringify(bg) : bg ) + ')');
111
+ e.target.style.backgroundImage = 'url(' + (regBgUrlEscape.test(bg) ? JSON.stringify(bg) : bg ) + ')';
112
+ }
113
+ }
114
+ }
115
+ }
116
+ }, false);
117
+ }
118
+ }));
includes/ls.unveilhooks.js CHANGED
@@ -1,3 +1,37 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  (function(window, factory) {
2
  var globalInstall = function(){
3
  factory(window.lazySizes);
@@ -8,6 +42,8 @@
8
 
9
  if(typeof module == 'object' && module.exports){
10
  factory(require('lazysizes'));
 
 
11
  } else if(window.lazySizes) {
12
  globalInstall();
13
  } else {
@@ -22,96 +58,127 @@
22
  if(document.addEventListener){
23
  regBgUrlEscape = /\(|\)|\s|'/;
24
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
25
  addEventListener('lazybeforeunveil', function(e){
26
  if(e.detail.instance != lazySizes){return;}
27
 
28
- var load, bg, bgWebP, poster;
29
  if(!e.defaultPrevented) {
30
 
31
- if(e.target.preload == 'none'){
32
- e.target.preload = 'auto';
 
 
33
  }
34
 
35
- // handle data-bg
36
- bg = e.target.getAttribute('data-bg');
37
- if (bg) {
38
- if(ewww_webp_supported) {
39
- console.log('checking for data-bg-webp');
40
- bgWebP = e.target.getAttribute('data-bg-webp');
41
- if (bgWebP) {
42
- console.log('replacing data-bg with data-bg-webp');
43
- bg = bgWebP;
44
- }
45
- }
46
- var dPR = (window.devicePixelRatio || 1);
47
- var targetWidth = Math.round(e.target.offsetWidth * dPR);
48
- var targetHeight = Math.round(e.target.offsetHeight * dPR);
49
- if ( 0 === bg.search(/\[/) ) {
50
- } else if (!shouldAutoScale(e.target)||!shouldAutoScale(e.target.parentNode)){
51
- } else if (window.lazySizes.hC(e.target,'wp-block-cover')) {
52
- console.log('found wp-block-cover with data-bg');
53
- if (window.lazySizes.hC(e.target,'has-parallax')) {
54
- console.log('also has-parallax with data-bg');
55
- targetWidth = Math.round(window.screen.width * dPR);
56
- targetHeight = Math.round(window.screen.height * dPR);
57
- } else if (targetHeight<300) {
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');
67
- } else if (window.lazySizes.hC(e.target,'et_parallax_bg')){
68
- console.log('found et_parallax_bg with data-bg');
69
- bg = constrainSrc(bg,targetWidth,targetHeight,'bg-cover');
70
- } else if (window.lazySizes.hC(e.target,'bg-image-crop')){
71
- console.log('found bg-image-crop with data-bg');
72
- bg = constrainSrc(bg,targetWidth,targetHeight,'bg-cover');
73
  } else {
74
- console.log('found other data-bg');
75
- bg = constrainSrc(bg,targetWidth,targetHeight,'bg');
 
 
76
  }
77
- if ( e.target.style.backgroundImage && -1 === e.target.style.backgroundImage.search(/^initial/) ) {
78
- // Convert JSON for multiple URLs.
79
- if ( 0 === bg.search(/\[/) ) {
80
- console.log('multiple URLs to append');
81
- bg = JSON.parse(bg);
82
- bg.forEach(
83
- function(bg_url){
84
- bg_url = (regBgUrlEscape.test(bg_url) ? JSON.stringify(bg_url) : bg_url );
85
- }
86
- );
87
- bg = 'url("' + bg.join('"), url("') + '"';
88
- var new_bg = e.target.style.backgroundImage + ', ' + bg;
89
- console.log('setting .backgroundImage: ' + new_bg );
90
- e.target.style.backgroundImage = new_bg;
91
- } else {
92
- console.log( 'appending bg url: ' + e.target.style.backgroundImage + ', url(' + (regBgUrlEscape.test(bg) ? JSON.stringify(bg) : bg ) + ')' );
93
- e.target.style.backgroundImage = e.target.style.backgroundImage + ', url("' + (regBgUrlEscape.test(bg) ? JSON.stringify(bg) : bg ) + '")';
94
- }
 
 
 
 
 
95
  } else {
96
- // Convert JSON for multiple URLs.
97
- if ( 0 === bg.search(/\[/) ) {
98
- console.log('multiple URLs to insert');
99
- bg = JSON.parse(bg);
100
- bg.forEach(
101
- function(bg_url){
102
- bg_url = (regBgUrlEscape.test(bg_url) ? JSON.stringify(bg_url) : bg_url );
103
- }
104
- );
105
- bg = 'url("' + bg.join('"), url("') + '"';
106
- console.log('setting .backgroundImage: ' + bg );
107
- e.target.style.backgroundImage = bg;
108
- } else {
109
- console.log('setting .backgroundImage: ' + 'url(' + (regBgUrlEscape.test(bg) ? JSON.stringify(bg) : bg ) + ')');
110
- e.target.style.backgroundImage = 'url(' + (regBgUrlEscape.test(bg) ? JSON.stringify(bg) : bg ) + ')';
111
- }
112
  }
113
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
114
  }
115
  }, false);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
116
  }
117
  }));
1
+ /*
2
+ This plugin extends lazySizes to lazyLoad:
3
+ background images, videos/posters and scripts
4
+
5
+ Background-Image:
6
+ For background images, use data-bg attribute:
7
+ <div class="lazyload" data-bg="bg-img.jpg"></div>
8
+
9
+ Video:
10
+ For video/audio use data-poster and preload="none":
11
+ <video class="lazyload" preload="none" data-poster="poster.jpg" src="src.mp4">
12
+ <!-- sources -->
13
+ </video>
14
+
15
+ For video that plays automatically if in view:
16
+ <video
17
+ class="lazyload"
18
+ preload="none"
19
+ muted=""
20
+ data-autoplay=""
21
+ data-poster="poster.jpg"
22
+ src="src.mp4">
23
+ </video>
24
+
25
+ Scripts:
26
+ For scripts use data-script:
27
+ <div class="lazyload" data-script="module-name.js"></div>
28
+
29
+
30
+ Script modules using require:
31
+ For modules using require use data-require:
32
+ <div class="lazyload" data-require="module-name"></div>
33
+ */
34
+
35
  (function(window, factory) {
36
  var globalInstall = function(){
37
  factory(window.lazySizes);
42
 
43
  if(typeof module == 'object' && module.exports){
44
  factory(require('lazysizes'));
45
+ } else if (typeof define == 'function' && define.amd) {
46
+ define(['lazysizes'], factory);
47
  } else if(window.lazySizes) {
48
  globalInstall();
49
  } else {
58
  if(document.addEventListener){
59
  regBgUrlEscape = /\(|\)|\s|'/;
60
 
61
+ bgLoad = function (url, cb){
62
+ var img = document.createElement('img');
63
+ img.onload = function(){
64
+ img.onload = null;
65
+ img.onerror = null;
66
+ img = null;
67
+ cb();
68
+ };
69
+ img.onerror = img.onload;
70
+
71
+ img.src = url;
72
+
73
+ if(img && img.complete && img.onload){
74
+ img.onload();
75
+ }
76
+ };
77
+
78
  addEventListener('lazybeforeunveil', function(e){
79
  if(e.detail.instance != lazySizes){return;}
80
 
81
+ var tmp, load, bg, poster;
82
  if(!e.defaultPrevented) {
83
 
84
+ var target = e.target;
85
+
86
+ if(target.preload == 'none'){
87
+ target.preload = target.getAttribute('data-preload') || 'auto';
88
  }
89
 
90
+ if (target.getAttribute('data-autoplay') != null) {
91
+ if (target.getAttribute('data-expand') && !target.autoplay) {
92
+ try {
93
+ target.play();
94
+ } catch (er) {}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
95
  } else {
96
+ requestAnimationFrame(function () {
97
+ target.setAttribute('data-expand', '-10');
98
+ lazySizes.aC(target, lazySizes.cfg.lazyClass);
99
+ });
100
  }
101
+ }
102
+
103
+ tmp = target.getAttribute('data-link');
104
+ if(tmp){
105
+ addStyleScript(tmp, true);
106
+ }
107
+
108
+ // handle data-script
109
+ tmp = target.getAttribute('data-script');
110
+ if(tmp){
111
+ e.detail.firesLoad = true;
112
+ load = function(){
113
+ e.detail.firesLoad = false;
114
+ lazySizes.fire(target, '_lazyloaded', {}, true, true);
115
+ };
116
+ addStyleScript(tmp, null, load);
117
+ }
118
+
119
+ // handle data-require
120
+ tmp = target.getAttribute('data-require');
121
+ if(tmp){
122
+ if(lazySizes.cfg.requireJs){
123
+ lazySizes.cfg.requireJs([tmp]);
124
  } else {
125
+ addStyleScript(tmp);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
126
  }
127
  }
128
+
129
+ // handle data-bg
130
+ bg = target.getAttribute('data-bg');
131
+ if (bg) {
132
+ e.detail.firesLoad = true;
133
+ load = function(){
134
+ target.style.backgroundImage = 'url(' + (regBgUrlEscape.test(bg) ? JSON.stringify(bg) : bg ) + ')';
135
+ e.detail.firesLoad = false;
136
+ lazySizes.fire(target, '_lazyloaded', {}, true, true);
137
+ };
138
+
139
+ bgLoad(bg, load);
140
+ }
141
+
142
+ // handle data-poster
143
+ poster = target.getAttribute('data-poster');
144
+ if(poster){
145
+ e.detail.firesLoad = true;
146
+ load = function(){
147
+ target.poster = poster;
148
+ e.detail.firesLoad = false;
149
+ lazySizes.fire(target, '_lazyloaded', {}, true, true);
150
+ };
151
+
152
+ bgLoad(poster, load);
153
+
154
+ }
155
  }
156
  }, false);
157
+
158
+ }
159
+
160
+ function addStyleScript(src, style, cb){
161
+ if(uniqueUrls[src]){
162
+ return;
163
+ }
164
+ var elem = document.createElement(style ? 'link' : 'script');
165
+ var insertElem = document.getElementsByTagName('script')[0];
166
+
167
+ if(style){
168
+ elem.rel = 'stylesheet';
169
+ elem.href = src;
170
+ } else {
171
+ elem.onload = function(){
172
+ elem.onerror = null;
173
+ elem.onload = null;
174
+ cb();
175
+ };
176
+ elem.onerror = elem.onload;
177
+
178
+ elem.src = src;
179
+ }
180
+ uniqueUrls[src] = true;
181
+ uniqueUrls[elem.src || elem.href] = true;
182
+ insertElem.parentNode.insertBefore(elem, insertElem);
183
  }
184
  }));
readme.txt CHANGED
@@ -3,9 +3,9 @@ Contributors: nosilver4u
3
  Donate link: https://ewww.io/donate/
4
  Tags: optimize, image, convert, webp, resize, compress, lazy load, optimization, lossless, lossy, seo, scale
5
  Requires at least: 5.8
6
- Tested up to: 6.0
7
  Requires PHP: 7.2
8
- Stable tag: 6.8.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,6 +137,15 @@ 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.8.0 =
141
  * added: ability to store image backups on local storage
142
  * added: tool to bulk restore images under Tools menu and WP-CLI
@@ -160,38 +169,6 @@ That's not a question, but since I made it up, I'll answer it. See this resource
160
  * updated: Gifsicle to version 1.93 and Pngquant to 2.17
161
  * removed: free binaries for SunOS, may use free cloud-based JPG compression instead
162
 
163
- = 6.6.0 =
164
- * added: AVIF support via Easy IO, enable on site management at ewww.io
165
- * added: sharpening setting to improve WP resizing via ImageMagick and WebP conversion
166
- * added: AVIF quality setting on Advanced tab
167
- * added: ability for Easy IO to get full-size path when using offloaded media
168
- * changed: JPG quality and WebP quality moved to Advanced tab
169
- * changed: allow .htaccess rules on Cloudways with notice about WebP Redirection toggle
170
- * fixed: front-end HTML parsers running within Bricks editor
171
- * fixed: Easy IO not finding scaled full-size for dynamic size generation
172
- * fixed: cover images not cropped properly by Easy IO
173
- * fixed: Easy IO URLs leaking into post editor with WP 6.0
174
-
175
- = 6.5.2 =
176
- * added: automatic optimization for Crop Thumbnails plugin
177
- * added: filters to adjust sharpening parameters for core WP (ImageMagick) image resizing
178
- * changed: Easy IO WebP quality can be defined separately from the JPG quality used for resizing operations
179
- * fixed: Picture WebP rewriting disabled on embeds
180
- * fixed: Lazy Load integration with WooCommerce Product Recommendations handling AJAX output incorrectly
181
- * fixed: PHP notice when checking for presence of mod_rewrite/mod_headers
182
-
183
- = 6.5.1 =
184
- * fixed: LQIP option not available on sub-domain multisite install unless Easy IO is active on site 1
185
- * fixed: API quota function doesn't handle expired status correctly
186
-
187
- = 6.5.0 =
188
- * added: Lazy Load and Easy IO support for multiple background images and mixing with gradients
189
- * changed: all Easy IO settings available to all plan levels
190
- * changed: Easy IO CDN image links constrained to 2560px, use EIO_PRESERVE_LINKED_IMAGES to override
191
- * fixed: database upgrade fails on MySQL 5.6
192
- * fixed: LQIP and SVG placeholder options not auto-loaded correctly
193
- * fixed: regression in legacy translation loader
194
-
195
  = Earlier versions =
196
  Please refer to the separate changelog.txt file.
197
 
3
  Donate link: https://ewww.io/donate/
4
  Tags: optimize, image, convert, webp, resize, compress, lazy load, optimization, lossless, lossy, seo, scale
5
  Requires at least: 5.8
6
+ Tested up to: 6.1
7
  Requires PHP: 7.2
8
+ Stable tag: 6.9.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.9.0 =
141
+ * added: allow translation plugins to filter attachment IDs for retrieving Media Library results via ewwwio_primary_translated_media_id/ewwwio_translated_media_ids
142
+ * changed: include upstream lazysizes unveilhooks for use by developers, props @saas786
143
+ * fixed: Easy IO compatibility with S3 Uploads 3.x
144
+ * fixed: better compatibility with S3 Uploads when using autoload
145
+ * fixed: PHP notices when removing images and backups are disabled
146
+ * fixed: trailing comma after parameters in WP-CLI remove_originals function
147
+ * fixed: Easy IO srcset URL construction not accounting for object versioning with S3 (or other cloud storage)
148
+
149
  = 6.8.0 =
150
  * added: ability to store image backups on local storage
151
  * added: tool to bulk restore images under Tools menu and WP-CLI
169
  * updated: Gifsicle to version 1.93 and Pngquant to 2.17
170
  * removed: free binaries for SunOS, may use free cloud-based JPG compression instead
171
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
172
  = Earlier versions =
173
  Please refer to the separate changelog.txt file.
174