Version Description
- added: PHP-based WebP Conversion via GD/Imagick in free mode when exec() is disabled
- added: enable -sharp_yuv option for WebP conversion with the EIO_WEBP_SHARP_YUV override
- added: WebP Conversion for CMYK images
- added: webp-supported conditional class added to body tag when JS WebP is active
- added: WP-CLI command can be run with --webp-only option
- added: Lazy Load for iframes, add 'iframe' in exclusions to disable
- added: compatibility with S3 Uploads 3.x
- added: preserve metadata and apply lossless compression to linked versions of images via Easy IO with EIO_PRESERVE_LINKED_IMAGES constant
- added: Easy IO rewrites URLs in existing picture elements
- changed: JS WebP scripts moved to beginning of page footer
- changed: native lazy loading is now enabled for right-sized PNG placeholders, override with EIO_DISABLE_NATIVE_LAZY constant
- changed: add resume ability to Delete Originals tool
- changed: move Easy IO check-in to wp_cron
- fixed: empty .webp images sometimes produced when cwebp encounters an error
- fixed: Bulk Optimizer for NextGEN loading incorrect script
- fixed: Bulk Optimizer for NextGEN fails to verify nonce for selective optimization
- fixed: Last Optimized times for Optimized Images table were incorrect
- fixed: Add Missing Dimensions overwrites smaller width/height attribute if only one is set
- fixed: replacing an existing attribute (like width) with a numeric value is broken
Download this release
Release Info
Developer | nosilver4u |
Plugin | EWWW Image Optimizer |
Version | 6.2.0 |
Comparing to | |
See all releases |
Code changes from version 6.1.9 to 6.2.0
- aux-optimize.php +17 -13
- bulk.php +20 -9
- changelog.txt +21 -0
- classes/class-eio-base.php +14 -0
- classes/class-eio-js-webp.php +959 -0
- classes/class-eio-lazy-load.php +89 -29
- classes/class-eio-page-parser.php +4 -3
- classes/class-ewww-flag.php +1 -1
- classes/class-ewww-nextcellent.php +1 -1
- classes/class-ewww-nextgen.php +23 -6
- classes/class-ewwwio-cli.php +16 -3
- classes/class-ewwwio-gd-editor.php +2 -2
- classes/class-ewwwio-gmagick-editor.php +0 -1
- classes/class-ewwwio-imagick-editor.php +0 -1
- classes/class-exactdn.php +189 -10
- common.php +347 -78
- ewww-image-optimizer.php +1 -1
- includes/check-webp.js +26 -0
- includes/check-webp.min.js +1 -0
- includes/eio-tools.js +38 -0
- includes/lazysizes-post.js +1 -1
- includes/lazysizes-pre.js +2 -2
- includes/lazysizes.min.js +1 -1
- includes/load-webp.js +704 -0
- includes/load-webp.min.js +1 -0
- mwebp.php +0 -1
- readme.txt +23 -2
- tests/test-agr.php +1 -1
- unique.php +38 -20
- vendor/icc/sRGB2014.icc +0 -0
aux-optimize.php
CHANGED
@@ -205,7 +205,7 @@ function ewww_image_optimizer_aux_images_table() {
|
|
205 |
}
|
206 |
$output['table'] .= '</td>';
|
207 |
$output['table'] .= "<td>$type</td>";
|
208 |
-
$output['table'] .= "<td>$last_updated
|
209 |
$output['table'] .= "<td>$savings<br>$size_string<br>" .
|
210 |
'<a class="ewww-remove-image" data-id="' . (int) $optimized_image['id'] . '">' . esc_html__( 'Remove from history', 'ewww-image-optimizer' ) . '</a>' .
|
211 |
( $optimized_image['backup'] ? '<br><a class="ewww-restore-image" data-id="' . (int) $optimized_image['id'] . '">' . esc_html__( 'Restore original', 'ewww-image-optimizer' ) . '</a>' : '' ) .
|
@@ -244,7 +244,6 @@ function ewww_image_optimizer_aux_images_table() {
|
|
244 |
$output['table'] .= '</td>';
|
245 |
$output['table'] .= "<td>$type</td>";
|
246 |
$output['table'] .= "<td>$last_updated</td>";
|
247 |
-
$output['table'] .= "<td>$last_updated ({$optimized_image['updated']})</td>";
|
248 |
// Determine filepath for webp.
|
249 |
$webpfile = $file . '.webp';
|
250 |
$webp_size = ewww_image_optimizer_filesize( $webpfile );
|
@@ -298,7 +297,6 @@ function ewww_image_optimizer_aux_images_table() {
|
|
298 |
$output['table'] .= '</td>';
|
299 |
$output['table'] .= "<td>$type</td>";
|
300 |
$output['table'] .= "<td>$last_updated</td>";
|
301 |
-
$output['table'] .= "<td>$last_updated ({$optimized_image['updated']})</td>";
|
302 |
$output['table'] .= "<td>$savings<br>$size_string<br>" .
|
303 |
'<a class="ewww-remove-image" data-id="' . (int) $optimized_image['id'] . '">' . esc_html__( 'Remove from history', 'ewww-image-optimizer' ) . '</a>' .
|
304 |
'</td>';
|
@@ -566,7 +564,7 @@ function ewww_image_optimizer_delete_webp() {
|
|
566 |
}
|
567 |
$s3_path = false;
|
568 |
$s3_dir = false;
|
569 |
-
if ( class_exists( 'S3_Uploads' ) ) {
|
570 |
$s3_path = get_attached_file( $id );
|
571 |
if ( 0 === strpos( $s3_path, 's3://' ) ) {
|
572 |
ewwwio_debug_message( 'removing: ' . $s3_path . '.webp' );
|
@@ -662,6 +660,10 @@ function ewww_image_optimizer_ajax_delete_original() {
|
|
662 |
ewwwio_ob_clean();
|
663 |
die( wp_json_encode( array( 'error' => esc_html__( 'Access token has expired, please reload the page.', 'ewww-image-optimizer' ) ) ) );
|
664 |
}
|
|
|
|
|
|
|
|
|
665 |
if ( empty( $_POST['attachment_id'] ) ) {
|
666 |
die( wp_json_encode( array( 'error' => esc_html__( 'Missing attachment ID number.', 'ewww-image-optimizer' ) ) ) );
|
667 |
}
|
@@ -675,6 +677,7 @@ function ewww_image_optimizer_ajax_delete_original() {
|
|
675 |
if ( ewww_image_optimizer_iterable( $new_meta ) ) {
|
676 |
wp_update_attachment_metadata( $id, $new_meta );
|
677 |
}
|
|
|
678 |
die( wp_json_encode( array( 'completed' => 1 ) ) );
|
679 |
}
|
680 |
|
@@ -936,9 +939,18 @@ function ewww_image_optimizer_get_all_attachments() {
|
|
936 |
ewwwio_ob_clean();
|
937 |
die( wp_json_encode( array( 'error' => esc_html__( 'Access token has expired, please reload the page.', 'ewww-image-optimizer' ) ) ) );
|
938 |
}
|
|
|
939 |
global $wpdb;
|
940 |
-
$attachments = $wpdb->get_col(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
941 |
if ( empty( $attachments ) || ! is_countable( $attachments ) || 0 === count( $attachments ) ) {
|
|
|
942 |
die( wp_json_encode( array( 'error' => esc_html__( 'No media uploads found.', 'ewww-image-optimizer' ) ) ) );
|
943 |
}
|
944 |
ewwwio_debug_message( gettype( $attachments ) );
|
@@ -1136,7 +1148,6 @@ function ewww_image_optimizer_image_scan( $dir, $started = 0 ) {
|
|
1136 |
set_transient( 'ewww_image_optimizer_aux_iterator', $file_counter - 20, 300 ); // Keep track of where we left off, minus 20 to be safe.
|
1137 |
$loading_image = plugins_url( '/images/wpspin.gif', __FILE__ );
|
1138 |
ewwwio_ob_clean();
|
1139 |
-
ewww_image_optimizer_debug_log();
|
1140 |
die(
|
1141 |
wp_json_encode(
|
1142 |
array(
|
@@ -1157,7 +1168,6 @@ function ewww_image_optimizer_image_scan( $dir, $started = 0 ) {
|
|
1157 |
ewww_image_optimizer_mass_insert( $wpdb->ewwwio_images, $images, array( '%s', '%d', '%d' ) );
|
1158 |
}
|
1159 |
set_transient( 'ewww_image_optimizer_aux_iterator', $file_counter - 20, 300 ); // Keep track of where we left off, minus 20 to be safe.
|
1160 |
-
ewww_image_optimizer_debug_log();
|
1161 |
global $ewwwio_scan_async;
|
1162 |
$ewwwio_scan_async->data(
|
1163 |
array(
|
@@ -1168,7 +1178,6 @@ function ewww_image_optimizer_image_scan( $dir, $started = 0 ) {
|
|
1168 |
} elseif ( 'scheduled' === $ewww_scan && get_option( 'ewwwio_stop_scheduled_scan' ) ) {
|
1169 |
ewwwio_debug_message( 'ending current scan iteration because of stop_scan' );
|
1170 |
delete_option( 'ewwwio_stop_scheduled_scan' );
|
1171 |
-
ewww_image_optimizer_debug_log();
|
1172 |
die();
|
1173 |
}
|
1174 |
if ( $ewww_scan && 0 === $file_counter % 100 && ! ewwwio_check_memory_available( 2097000 ) ) {
|
@@ -1190,7 +1199,6 @@ function ewww_image_optimizer_image_scan( $dir, $started = 0 ) {
|
|
1190 |
set_transient( 'ewww_image_optimizer_aux_iterator', $file_counter - 20, 300 ); // Keep track of where we left off, minus 20 to be safe.
|
1191 |
$loading_image = plugins_url( '/images/wpspin.gif', __FILE__ );
|
1192 |
ewwwio_ob_clean();
|
1193 |
-
ewww_image_optimizer_debug_log();
|
1194 |
die(
|
1195 |
wp_json_encode(
|
1196 |
array(
|
@@ -1299,7 +1307,6 @@ function ewww_image_optimizer_image_scan( $dir, $started = 0 ) {
|
|
1299 |
ewwwio_memory( __FUNCTION__ );
|
1300 |
$folders_completed[] = $dir;
|
1301 |
update_option( 'ewww_image_optimizer_aux_folders_completed', $folders_completed, false );
|
1302 |
-
ewww_image_optimizer_debug_log();
|
1303 |
}
|
1304 |
|
1305 |
/**
|
@@ -1486,7 +1493,6 @@ function ewww_image_optimizer_aux_images_script( $hook = '' ) {
|
|
1486 |
update_option( 'ewww_image_optimizer_aux_folders_completed', array(), false );
|
1487 |
update_option( 'ewww_image_optimizer_aux_resume', '' );
|
1488 |
update_option( 'ewww_image_optimizer_bulk_resume', '' );
|
1489 |
-
ewww_image_optimizer_debug_log();
|
1490 |
if ( wp_doing_ajax() && 'ewww-image-optimizer-auto' !== $hook && ( ! defined( 'WP_CLI' ) || ! WP_CLI ) ) {
|
1491 |
$verify_cloud = ewww_image_optimizer_cloud_verify( ewww_image_optimizer_get_option( 'ewww_image_optimizer_cloud_key' ), false );
|
1492 |
$usage = false;
|
@@ -1534,7 +1540,6 @@ function ewww_image_optimizer_aux_images_script( $hook = '' ) {
|
|
1534 |
$ewwwio_image_background->dispatch();
|
1535 |
update_option( 'ewww_image_optimizer_aux_resume', '', false );
|
1536 |
}
|
1537 |
-
ewww_image_optimizer_debug_log();
|
1538 |
ewwwio_memory( __FUNCTION__ );
|
1539 |
return $image_count;
|
1540 |
}
|
@@ -1575,4 +1580,3 @@ add_action( 'wp_ajax_bulk_aux_images_webp_clean', 'ewww_image_optimizer_aux_imag
|
|
1575 |
add_action( 'wp_ajax_bulk_aux_images_delete_webp', 'ewww_image_optimizer_delete_webp' );
|
1576 |
add_action( 'wp_ajax_bulk_aux_images_delete_original', 'ewww_image_optimizer_ajax_delete_original' );
|
1577 |
add_action( 'wp_ajax_ewwwio_get_all_attachments', 'ewww_image_optimizer_get_all_attachments' );
|
1578 |
-
?>
|
205 |
}
|
206 |
$output['table'] .= '</td>';
|
207 |
$output['table'] .= "<td>$type</td>";
|
208 |
+
$output['table'] .= "<td>$last_updated</td>";
|
209 |
$output['table'] .= "<td>$savings<br>$size_string<br>" .
|
210 |
'<a class="ewww-remove-image" data-id="' . (int) $optimized_image['id'] . '">' . esc_html__( 'Remove from history', 'ewww-image-optimizer' ) . '</a>' .
|
211 |
( $optimized_image['backup'] ? '<br><a class="ewww-restore-image" data-id="' . (int) $optimized_image['id'] . '">' . esc_html__( 'Restore original', 'ewww-image-optimizer' ) . '</a>' : '' ) .
|
244 |
$output['table'] .= '</td>';
|
245 |
$output['table'] .= "<td>$type</td>";
|
246 |
$output['table'] .= "<td>$last_updated</td>";
|
|
|
247 |
// Determine filepath for webp.
|
248 |
$webpfile = $file . '.webp';
|
249 |
$webp_size = ewww_image_optimizer_filesize( $webpfile );
|
297 |
$output['table'] .= '</td>';
|
298 |
$output['table'] .= "<td>$type</td>";
|
299 |
$output['table'] .= "<td>$last_updated</td>";
|
|
|
300 |
$output['table'] .= "<td>$savings<br>$size_string<br>" .
|
301 |
'<a class="ewww-remove-image" data-id="' . (int) $optimized_image['id'] . '">' . esc_html__( 'Remove from history', 'ewww-image-optimizer' ) . '</a>' .
|
302 |
'</td>';
|
564 |
}
|
565 |
$s3_path = false;
|
566 |
$s3_dir = false;
|
567 |
+
if ( class_exists( 'S3_Uploads' ) || class_exists( 'S3_Uploads\Plugin' ) ) {
|
568 |
$s3_path = get_attached_file( $id );
|
569 |
if ( 0 === strpos( $s3_path, 's3://' ) ) {
|
570 |
ewwwio_debug_message( 'removing: ' . $s3_path . '.webp' );
|
660 |
ewwwio_ob_clean();
|
661 |
die( wp_json_encode( array( 'error' => esc_html__( 'Access token has expired, please reload the page.', 'ewww-image-optimizer' ) ) ) );
|
662 |
}
|
663 |
+
if ( ! empty( $_POST['delete_originals_done'] ) ) {
|
664 |
+
delete_option( 'ewww_image_optimizer_delete_originals_resume' );
|
665 |
+
die( wp_json_encode( array( 'done' => 1 ) ) );
|
666 |
+
}
|
667 |
if ( empty( $_POST['attachment_id'] ) ) {
|
668 |
die( wp_json_encode( array( 'error' => esc_html__( 'Missing attachment ID number.', 'ewww-image-optimizer' ) ) ) );
|
669 |
}
|
677 |
if ( ewww_image_optimizer_iterable( $new_meta ) ) {
|
678 |
wp_update_attachment_metadata( $id, $new_meta );
|
679 |
}
|
680 |
+
update_option( 'ewww_image_optimizer_delete_originals_resume', $id, false );
|
681 |
die( wp_json_encode( array( 'completed' => 1 ) ) );
|
682 |
}
|
683 |
|
939 |
ewwwio_ob_clean();
|
940 |
die( wp_json_encode( array( 'error' => esc_html__( 'Access token has expired, please reload the page.', 'ewww-image-optimizer' ) ) ) );
|
941 |
}
|
942 |
+
$start_id = get_option( 'ewww_image_optimizer_delete_originals_resume', 0 );
|
943 |
global $wpdb;
|
944 |
+
$attachments = $wpdb->get_col(
|
945 |
+
$wpdb->prepare(
|
946 |
+
"SELECT ID FROM $wpdb->posts WHERE ID > %d AND (post_type = 'attachment' OR post_type = 'ims_image') AND (post_mime_type LIKE %s OR post_mime_type LIKE %s) ORDER BY ID DESC",
|
947 |
+
(int) $start_id,
|
948 |
+
'%image%',
|
949 |
+
'%pdf%'
|
950 |
+
)
|
951 |
+
);
|
952 |
if ( empty( $attachments ) || ! is_countable( $attachments ) || 0 === count( $attachments ) ) {
|
953 |
+
delete_option( 'ewww_image_optimizer_delete_originals_resume' );
|
954 |
die( wp_json_encode( array( 'error' => esc_html__( 'No media uploads found.', 'ewww-image-optimizer' ) ) ) );
|
955 |
}
|
956 |
ewwwio_debug_message( gettype( $attachments ) );
|
1148 |
set_transient( 'ewww_image_optimizer_aux_iterator', $file_counter - 20, 300 ); // Keep track of where we left off, minus 20 to be safe.
|
1149 |
$loading_image = plugins_url( '/images/wpspin.gif', __FILE__ );
|
1150 |
ewwwio_ob_clean();
|
|
|
1151 |
die(
|
1152 |
wp_json_encode(
|
1153 |
array(
|
1168 |
ewww_image_optimizer_mass_insert( $wpdb->ewwwio_images, $images, array( '%s', '%d', '%d' ) );
|
1169 |
}
|
1170 |
set_transient( 'ewww_image_optimizer_aux_iterator', $file_counter - 20, 300 ); // Keep track of where we left off, minus 20 to be safe.
|
|
|
1171 |
global $ewwwio_scan_async;
|
1172 |
$ewwwio_scan_async->data(
|
1173 |
array(
|
1178 |
} elseif ( 'scheduled' === $ewww_scan && get_option( 'ewwwio_stop_scheduled_scan' ) ) {
|
1179 |
ewwwio_debug_message( 'ending current scan iteration because of stop_scan' );
|
1180 |
delete_option( 'ewwwio_stop_scheduled_scan' );
|
|
|
1181 |
die();
|
1182 |
}
|
1183 |
if ( $ewww_scan && 0 === $file_counter % 100 && ! ewwwio_check_memory_available( 2097000 ) ) {
|
1199 |
set_transient( 'ewww_image_optimizer_aux_iterator', $file_counter - 20, 300 ); // Keep track of where we left off, minus 20 to be safe.
|
1200 |
$loading_image = plugins_url( '/images/wpspin.gif', __FILE__ );
|
1201 |
ewwwio_ob_clean();
|
|
|
1202 |
die(
|
1203 |
wp_json_encode(
|
1204 |
array(
|
1307 |
ewwwio_memory( __FUNCTION__ );
|
1308 |
$folders_completed[] = $dir;
|
1309 |
update_option( 'ewww_image_optimizer_aux_folders_completed', $folders_completed, false );
|
|
|
1310 |
}
|
1311 |
|
1312 |
/**
|
1493 |
update_option( 'ewww_image_optimizer_aux_folders_completed', array(), false );
|
1494 |
update_option( 'ewww_image_optimizer_aux_resume', '' );
|
1495 |
update_option( 'ewww_image_optimizer_bulk_resume', '' );
|
|
|
1496 |
if ( wp_doing_ajax() && 'ewww-image-optimizer-auto' !== $hook && ( ! defined( 'WP_CLI' ) || ! WP_CLI ) ) {
|
1497 |
$verify_cloud = ewww_image_optimizer_cloud_verify( ewww_image_optimizer_get_option( 'ewww_image_optimizer_cloud_key' ), false );
|
1498 |
$usage = false;
|
1540 |
$ewwwio_image_background->dispatch();
|
1541 |
update_option( 'ewww_image_optimizer_aux_resume', '', false );
|
1542 |
}
|
|
|
1543 |
ewwwio_memory( __FUNCTION__ );
|
1544 |
return $image_count;
|
1545 |
}
|
1580 |
add_action( 'wp_ajax_bulk_aux_images_delete_webp', 'ewww_image_optimizer_delete_webp' );
|
1581 |
add_action( 'wp_ajax_bulk_aux_images_delete_original', 'ewww_image_optimizer_ajax_delete_original' );
|
1582 |
add_action( 'wp_ajax_ewwwio_get_all_attachments', 'ewww_image_optimizer_get_all_attachments' );
|
|
bulk.php
CHANGED
@@ -33,7 +33,7 @@ function ewww_image_optimizer_display_tools() {
|
|
33 |
update_option( 'ewwwio_stop_scheduled_scan', true, false );
|
34 |
}
|
35 |
echo "<div class='wrap'>\n";
|
36 |
-
echo "<h1>EWWW Image Optimizer</h1>\n";
|
37 |
|
38 |
// Find out if the auxiliary image table has anything in it.
|
39 |
$already_optimized = ewww_image_optimizer_aux_images_table_count();
|
@@ -125,7 +125,7 @@ function ewww_image_optimizer_display_tools() {
|
|
125 |
$as3cf_remove = true;
|
126 |
}
|
127 |
}
|
128 |
-
if ( ! class_exists( 'S3_Uploads' ) && ! function_exists( 'ud_get_stateless_media' ) && ! $as3cf_remove ) {
|
129 |
echo '<hr class="ewww-tool-divider">';
|
130 |
echo "<div>\n<p id='ewww-clean-table-info' class='ewww-tool-info'>" .
|
131 |
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>' .
|
@@ -967,13 +967,11 @@ function ewww_image_optimizer_media_scan( $hook = '' ) {
|
|
967 |
$permissions = apply_filters( 'ewww_image_optimizer_bulk_permissions', '' );
|
968 |
if ( 'ewww-image-optimizer-cli' !== $hook && empty( $_REQUEST['ewww_scan'] ) ) {
|
969 |
ewwwio_debug_message( 'bailing no cli' );
|
970 |
-
ewww_image_optimizer_debug_log();
|
971 |
ewwwio_ob_clean();
|
972 |
die( wp_json_encode( array( 'error' => esc_html__( 'Access denied.', 'ewww-image-optimizer' ) ) ) );
|
973 |
}
|
974 |
if ( ! empty( $_REQUEST['ewww_scan'] ) && ( empty( $_REQUEST['ewww_wpnonce'] ) || ! wp_verify_nonce( sanitize_key( $_REQUEST['ewww_wpnonce'] ), 'ewww-image-optimizer-bulk' ) || ! current_user_can( $permissions ) ) ) {
|
975 |
ewwwio_debug_message( 'bailing no nonce' );
|
976 |
-
ewww_image_optimizer_debug_log();
|
977 |
ewwwio_ob_clean();
|
978 |
die( wp_json_encode( array( 'error' => esc_html__( 'Access token has expired, please reload the page.', 'ewww-image-optimizer' ) ) ) );
|
979 |
}
|
@@ -1187,6 +1185,7 @@ function ewww_image_optimizer_media_scan( $hook = '' ) {
|
|
1187 |
class_exists( 'WindowsAzureStorageUtil' ) ||
|
1188 |
class_exists( 'Amazon_S3_And_CloudFront' ) ||
|
1189 |
class_exists( 'S3_Uploads' ) ||
|
|
|
1190 |
class_exists( 'wpCloud\StatelessMedia\EWWW' )
|
1191 |
)
|
1192 |
) {
|
@@ -1197,12 +1196,19 @@ function ewww_image_optimizer_media_scan( $hook = '' ) {
|
|
1197 |
$s3_uploads = S3_Uploads::get_instance();
|
1198 |
remove_filter( 'upload_dir', array( $s3_uploads, 'filter_upload_dir' ) );
|
1199 |
}
|
|
|
|
|
|
|
|
|
1200 |
if ( ewww_image_optimizer_stream_wrapped( $file_path ) || 0 === strpos( $file_path, 'http' ) ) {
|
1201 |
$file_path = get_attached_file( $selected_id, true );
|
1202 |
}
|
1203 |
if ( class_exists( 'S3_Uploads' ) && method_exists( 'S3_Uploads', 'filter_upload_dir' ) ) {
|
1204 |
add_filter( 'upload_dir', array( $s3_uploads, 'filter_upload_dir' ) );
|
1205 |
}
|
|
|
|
|
|
|
1206 |
ewwwio_debug_message( "remote file possible: $file_path" );
|
1207 |
if ( ! $file_path ) {
|
1208 |
ewwwio_debug_message( 'no file found on remote storage, bailing' );
|
@@ -1880,7 +1886,9 @@ function ewww_image_optimizer_bulk_loop( $hook = '', $delay = 0 ) {
|
|
1880 |
$ewww_force_smart = false;
|
1881 |
delete_transient( 'ewww_image_optimizer_smart_reopt' );
|
1882 |
}
|
1883 |
-
$ewww_webp_only
|
|
|
|
|
1884 |
if ( ! empty( $_REQUEST['ewww_webp_only'] ) ) {
|
1885 |
$ewww_webp_only = true;
|
1886 |
}
|
@@ -1893,7 +1901,7 @@ function ewww_image_optimizer_bulk_loop( $hook = '', $delay = 0 ) {
|
|
1893 |
$output['new_nonce'] = '';
|
1894 |
}
|
1895 |
}
|
1896 |
-
$batch_image_limit = ( empty( $_REQUEST['ewww_batch_limit'] ) && ! class_exists( 'S3_Uploads' ) ? 999 : 1 );
|
1897 |
// Get the 'bulk attachments' with a list of IDs remaining.
|
1898 |
$attachments = ewww_image_optimizer_get_queued_attachments( 'media', $batch_image_limit );
|
1899 |
if ( ! empty( $attachments ) && is_array( $attachments ) ) {
|
@@ -2011,11 +2019,14 @@ function ewww_image_optimizer_bulk_loop( $hook = '', $delay = 0 ) {
|
|
2011 |
|
2012 |
if ( defined( 'WP_CLI' ) && WP_CLI ) {
|
2013 |
WP_CLI::line( __( 'Optimized', 'ewww-image-optimizer' ) . ' ' . $image->file );
|
2014 |
-
WP_CLI::line( str_replace( ' ', '', $msg ) );
|
2015 |
}
|
2016 |
$output['results'] .= sprintf( '<p>' . esc_html__( 'Optimized', 'ewww-image-optimizer' ) . ' <strong>%s</strong><br>', esc_html( $image->file ) );
|
2017 |
if ( ! empty( $ewwwio_resize_status ) ) {
|
2018 |
$output['results'] .= esc_html( $ewwwio_resize_status ) . '<br>';
|
|
|
|
|
|
|
2019 |
}
|
2020 |
$output['results'] .= "$msg</p>";
|
2021 |
|
@@ -2038,7 +2049,7 @@ function ewww_image_optimizer_bulk_loop( $hook = '', $delay = 0 ) {
|
|
2038 |
if ( defined( 'WP_CLI' ) && WP_CLI ) {
|
2039 |
ewwwio_debug_message( 'saving attachment meta' );
|
2040 |
$meta = wp_get_attachment_metadata( $image->attachment_id );
|
2041 |
-
if ( class_exists( 'S3_Uploads' ) ) {
|
2042 |
ewwwio_debug_message( 're-uploading to S3(_Uploads)' );
|
2043 |
ewww_image_optimizer_remote_push( $meta, $image->attachment_id );
|
2044 |
}
|
@@ -2143,7 +2154,7 @@ function ewww_image_optimizer_bulk_update_meta() {
|
|
2143 |
$attachment_id = (int) $_REQUEST['attachment_id'];
|
2144 |
ewwwio_debug_message( "saving attachment meta for $attachment_id" );
|
2145 |
$meta = wp_get_attachment_metadata( $attachment_id );
|
2146 |
-
if ( class_exists( 'S3_Uploads' ) ) {
|
2147 |
ewwwio_debug_message( 're-uploading to S3(_Uploads)' );
|
2148 |
ewww_image_optimizer_remote_push( $meta, $attachment_id );
|
2149 |
}
|
33 |
update_option( 'ewwwio_stop_scheduled_scan', true, false );
|
34 |
}
|
35 |
echo "<div class='wrap'>\n";
|
36 |
+
echo "<h1 id='ewwwio-tools-header'>EWWW Image Optimizer</h1>\n";
|
37 |
|
38 |
// Find out if the auxiliary image table has anything in it.
|
39 |
$already_optimized = ewww_image_optimizer_aux_images_table_count();
|
125 |
$as3cf_remove = true;
|
126 |
}
|
127 |
}
|
128 |
+
if ( ! class_exists( 'S3_Uploads' ) && ! class_exists( 'S3_Uploads\Plugin' ) && ! function_exists( 'ud_get_stateless_media' ) && ! $as3cf_remove ) {
|
129 |
echo '<hr class="ewww-tool-divider">';
|
130 |
echo "<div>\n<p id='ewww-clean-table-info' class='ewww-tool-info'>" .
|
131 |
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>' .
|
967 |
$permissions = apply_filters( 'ewww_image_optimizer_bulk_permissions', '' );
|
968 |
if ( 'ewww-image-optimizer-cli' !== $hook && empty( $_REQUEST['ewww_scan'] ) ) {
|
969 |
ewwwio_debug_message( 'bailing no cli' );
|
|
|
970 |
ewwwio_ob_clean();
|
971 |
die( wp_json_encode( array( 'error' => esc_html__( 'Access denied.', 'ewww-image-optimizer' ) ) ) );
|
972 |
}
|
973 |
if ( ! empty( $_REQUEST['ewww_scan'] ) && ( empty( $_REQUEST['ewww_wpnonce'] ) || ! wp_verify_nonce( sanitize_key( $_REQUEST['ewww_wpnonce'] ), 'ewww-image-optimizer-bulk' ) || ! current_user_can( $permissions ) ) ) {
|
974 |
ewwwio_debug_message( 'bailing no nonce' );
|
|
|
975 |
ewwwio_ob_clean();
|
976 |
die( wp_json_encode( array( 'error' => esc_html__( 'Access token has expired, please reload the page.', 'ewww-image-optimizer' ) ) ) );
|
977 |
}
|
1185 |
class_exists( 'WindowsAzureStorageUtil' ) ||
|
1186 |
class_exists( 'Amazon_S3_And_CloudFront' ) ||
|
1187 |
class_exists( 'S3_Uploads' ) ||
|
1188 |
+
class_exists( 'S3_Uploads\Plugin' ) ||
|
1189 |
class_exists( 'wpCloud\StatelessMedia\EWWW' )
|
1190 |
)
|
1191 |
) {
|
1196 |
$s3_uploads = S3_Uploads::get_instance();
|
1197 |
remove_filter( 'upload_dir', array( $s3_uploads, 'filter_upload_dir' ) );
|
1198 |
}
|
1199 |
+
if ( class_exists( 'S3_Uploads\Plugin' ) && method_exists( 'S3_Uploads\Plugin', 'filter_upload_dir' ) ) {
|
1200 |
+
$s3_uploads = \S3_Uploads\Plugin::get_instance();
|
1201 |
+
remove_filter( 'upload_dir', array( $s3_uploads, 'filter_upload_dir' ) );
|
1202 |
+
}
|
1203 |
if ( ewww_image_optimizer_stream_wrapped( $file_path ) || 0 === strpos( $file_path, 'http' ) ) {
|
1204 |
$file_path = get_attached_file( $selected_id, true );
|
1205 |
}
|
1206 |
if ( class_exists( 'S3_Uploads' ) && method_exists( 'S3_Uploads', 'filter_upload_dir' ) ) {
|
1207 |
add_filter( 'upload_dir', array( $s3_uploads, 'filter_upload_dir' ) );
|
1208 |
}
|
1209 |
+
if ( class_exists( 'S3_Uploads\Plugin' ) && method_exists( 'S3_Uploads\Plugin', 'filter_upload_dir' ) ) {
|
1210 |
+
add_filter( 'upload_dir', array( $s3_uploads, 'filter_upload_dir' ) );
|
1211 |
+
}
|
1212 |
ewwwio_debug_message( "remote file possible: $file_path" );
|
1213 |
if ( ! $file_path ) {
|
1214 |
ewwwio_debug_message( 'no file found on remote storage, bailing' );
|
1886 |
$ewww_force_smart = false;
|
1887 |
delete_transient( 'ewww_image_optimizer_smart_reopt' );
|
1888 |
}
|
1889 |
+
if ( ! isset( $ewww_webp_only ) ) {
|
1890 |
+
$ewww_webp_only = false;
|
1891 |
+
}
|
1892 |
if ( ! empty( $_REQUEST['ewww_webp_only'] ) ) {
|
1893 |
$ewww_webp_only = true;
|
1894 |
}
|
1901 |
$output['new_nonce'] = '';
|
1902 |
}
|
1903 |
}
|
1904 |
+
$batch_image_limit = ( empty( $_REQUEST['ewww_batch_limit'] ) && ! class_exists( 'S3_Uploads' ) && ! class_exists( 'S3_Uploads\Plugin' ) ? 999 : 1 );
|
1905 |
// Get the 'bulk attachments' with a list of IDs remaining.
|
1906 |
$attachments = ewww_image_optimizer_get_queued_attachments( 'media', $batch_image_limit );
|
1907 |
if ( ! empty( $attachments ) && is_array( $attachments ) ) {
|
2019 |
|
2020 |
if ( defined( 'WP_CLI' ) && WP_CLI ) {
|
2021 |
WP_CLI::line( __( 'Optimized', 'ewww-image-optimizer' ) . ' ' . $image->file );
|
2022 |
+
WP_CLI::line( str_replace( array( ' ', '<br>' ), array( '', "\n" ), $msg ) );
|
2023 |
}
|
2024 |
$output['results'] .= sprintf( '<p>' . esc_html__( 'Optimized', 'ewww-image-optimizer' ) . ' <strong>%s</strong><br>', esc_html( $image->file ) );
|
2025 |
if ( ! empty( $ewwwio_resize_status ) ) {
|
2026 |
$output['results'] .= esc_html( $ewwwio_resize_status ) . '<br>';
|
2027 |
+
if ( defined( 'WP_CLI' ) && WP_CLI ) {
|
2028 |
+
WP_CLI::line( $ewwwio_resize_status );
|
2029 |
+
}
|
2030 |
}
|
2031 |
$output['results'] .= "$msg</p>";
|
2032 |
|
2049 |
if ( defined( 'WP_CLI' ) && WP_CLI ) {
|
2050 |
ewwwio_debug_message( 'saving attachment meta' );
|
2051 |
$meta = wp_get_attachment_metadata( $image->attachment_id );
|
2052 |
+
if ( class_exists( 'S3_Uploads' ) || class_exists( 'S3_Uploads\Plugin' ) ) {
|
2053 |
ewwwio_debug_message( 're-uploading to S3(_Uploads)' );
|
2054 |
ewww_image_optimizer_remote_push( $meta, $image->attachment_id );
|
2055 |
}
|
2154 |
$attachment_id = (int) $_REQUEST['attachment_id'];
|
2155 |
ewwwio_debug_message( "saving attachment meta for $attachment_id" );
|
2156 |
$meta = wp_get_attachment_metadata( $attachment_id );
|
2157 |
+
if ( class_exists( 'S3_Uploads' ) || class_exists( 'S3_Uploads\Plugin' ) ) {
|
2158 |
ewwwio_debug_message( 're-uploading to S3(_Uploads)' );
|
2159 |
ewww_image_optimizer_remote_push( $meta, $attachment_id );
|
2160 |
}
|
changelog.txt
CHANGED
@@ -1,3 +1,24 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
= 6.1.9 =
|
2 |
* fixed: Easy IO's Include All Resources compat with Oxygen Builder and Beaver Builder
|
3 |
* fixed: regex to detect SVG images in use elements caused excessive backtracking
|
1 |
+
= 6.2.0 =
|
2 |
+
* added: PHP-based WebP Conversion via GD/Imagick in free mode when exec() is disabled
|
3 |
+
* added: enable -sharp_yuv option for WebP conversion with the EIO_WEBP_SHARP_YUV override
|
4 |
+
* added: WebP Conversion for CMYK images
|
5 |
+
* added: webp-supported conditional class added to body tag when JS WebP is active
|
6 |
+
* added: WP-CLI command can be run with --webp-only option
|
7 |
+
* added: Lazy Load for iframes, add 'iframe' in exclusions to disable
|
8 |
+
* added: compatibility with S3 Uploads 3.x
|
9 |
+
* added: preserve metadata and apply lossless compression to linked versions of images via Easy IO with EIO_PRESERVE_LINKED_IMAGES constant
|
10 |
+
* added: Easy IO rewrites URLs in existing picture elements
|
11 |
+
* changed: JS WebP scripts moved to beginning of page footer
|
12 |
+
* changed: native lazy loading is now enabled for right-sized PNG placeholders, override with EIO_DISABLE_NATIVE_LAZY constant
|
13 |
+
* changed: add resume ability to Delete Originals tool
|
14 |
+
* changed: move Easy IO check-in to wp_cron
|
15 |
+
* fixed: empty .webp images sometimes produced when cwebp encounters an error
|
16 |
+
* fixed: Bulk Optimizer for NextGEN loading incorrect script
|
17 |
+
* fixed: Bulk Optimizer for NextGEN fails to verify nonce for selective optimization
|
18 |
+
* fixed: Last Optimized times for Optimized Images table were incorrect
|
19 |
+
* fixed: Add Missing Dimensions overwrites smaller width/height attribute if only one is set
|
20 |
+
* fixed: replacing an existing attribute (like width) with a numeric value is broken
|
21 |
+
|
22 |
= 6.1.9 =
|
23 |
* fixed: Easy IO's Include All Resources compat with Oxygen Builder and Beaver Builder
|
24 |
* fixed: regex to detect SVG images in use elements caused excessive backtracking
|
classes/class-eio-base.php
CHANGED
@@ -703,6 +703,20 @@ if ( ! class_exists( 'EIO_Base' ) ) {
|
|
703 |
$this->s3_active = $s3_domain;
|
704 |
}
|
705 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
706 |
if ( class_exists( 'wpCloud\StatelessMedia\EWWW' ) && function_exists( 'ud_get_stateless_media' ) ) {
|
707 |
$sm = ud_get_stateless_media();
|
708 |
if ( method_exists( $sm, 'get' ) && method_exists( $sm, 'get_gs_host' ) ) {
|
703 |
$this->s3_active = $s3_domain;
|
704 |
}
|
705 |
|
706 |
+
if (
|
707 |
+
class_exists( 'S3_Uploads\Plugin' ) &&
|
708 |
+
function_exists( 's3_uploads_enabled' ) && s3_uploads_enabled() &&
|
709 |
+
method_exists( 'S3_Uploads\Plugin', 'get_instance' ) && method_exists( 'S3_Uploads', 'get_s3_url\Plugin' )
|
710 |
+
) {
|
711 |
+
$s3_uploads_instance = \S3_Uploads\Plugin::get_instance();
|
712 |
+
$s3_uploads_url = $s3_uploads_instance->get_s3_url();
|
713 |
+
$this->allowed_urls[] = $s3_uploads_url;
|
714 |
+
$this->debug_message( "found S3 URL from S3_Uploads: $s3_uploads_url" );
|
715 |
+
$s3_domain = $this->parse_url( $s3_uploads_url, PHP_URL_HOST );
|
716 |
+
$s3_scheme = $this->parse_url( $s3_uploads_url, PHP_URL_SCHEME );
|
717 |
+
$this->s3_active = $s3_domain;
|
718 |
+
}
|
719 |
+
|
720 |
if ( class_exists( 'wpCloud\StatelessMedia\EWWW' ) && function_exists( 'ud_get_stateless_media' ) ) {
|
721 |
$sm = ud_get_stateless_media();
|
722 |
if ( method_exists( $sm, 'get' ) && method_exists( $sm, 'get_gs_host' ) ) {
|
classes/class-eio-js-webp.php
ADDED
@@ -0,0 +1,959 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Implements WebP rewriting using page parsing and JS functionality.
|
4 |
+
*
|
5 |
+
* @link https://ewww.io
|
6 |
+
* @package EIO
|
7 |
+
*/
|
8 |
+
|
9 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
10 |
+
exit;
|
11 |
+
}
|
12 |
+
|
13 |
+
/**
|
14 |
+
* Enables EWWW IO to filter the page content and replace img elements with WebP markup.
|
15 |
+
*/
|
16 |
+
class EIO_JS_Webp extends EIO_Page_Parser {
|
17 |
+
|
18 |
+
/**
|
19 |
+
* A list of user-defined exclusions, populated by validate_user_exclusions().
|
20 |
+
*
|
21 |
+
* @access protected
|
22 |
+
* @var array $user_exclusions
|
23 |
+
*/
|
24 |
+
protected $user_exclusions = array();
|
25 |
+
|
26 |
+
/**
|
27 |
+
* A list of user-defined (element-type) exclusions, populated by validate_user_exclusions().
|
28 |
+
*
|
29 |
+
* @access protected
|
30 |
+
* @var array $user_exclusions
|
31 |
+
*/
|
32 |
+
protected $user_element_exclusions = array();
|
33 |
+
|
34 |
+
/**
|
35 |
+
* Base64-encoded placeholder image.
|
36 |
+
*
|
37 |
+
* @access protected
|
38 |
+
* @var string $placeholder_src
|
39 |
+
*/
|
40 |
+
protected $placeholder_src = 'data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==';
|
41 |
+
|
42 |
+
/**
|
43 |
+
* The 'check webp' script contents.
|
44 |
+
*
|
45 |
+
* @access private
|
46 |
+
* @var string $check_webp_script
|
47 |
+
*/
|
48 |
+
private $check_webp_script = '';
|
49 |
+
|
50 |
+
/**
|
51 |
+
* The 'load webp' script contents.
|
52 |
+
*
|
53 |
+
* @access private
|
54 |
+
* @var string $load_webp_script
|
55 |
+
*/
|
56 |
+
private $load_webp_script = '';
|
57 |
+
|
58 |
+
/**
|
59 |
+
* Register (once) actions and filters for JS WebP.
|
60 |
+
*/
|
61 |
+
function __construct() {
|
62 |
+
global $eio_js_webp;
|
63 |
+
if ( is_object( $eio_js_webp ) ) {
|
64 |
+
return 'you are doing it wrong';
|
65 |
+
}
|
66 |
+
if ( ewww_image_optimizer_ce_webp_enabled() ) {
|
67 |
+
return false;
|
68 |
+
}
|
69 |
+
parent::__construct();
|
70 |
+
$this->debug_message( '<b>' . __METHOD__ . '()</b>' );
|
71 |
+
|
72 |
+
// Hook into the output buffer callback function.
|
73 |
+
add_filter( 'ewww_image_optimizer_filter_page_output', array( $this, 'filter_page_output' ), 20 );
|
74 |
+
// Filter for NextGEN image urls within JSON.
|
75 |
+
add_filter( 'ngg_pro_lightbox_images_queue', array( $this, 'ngg_pro_lightbox_images_queue' ), 11 );
|
76 |
+
// Filter for WooCommerce product variations JSON.
|
77 |
+
add_filter( 'woocommerce_pre_json_available_variations', array( $this, 'woocommerce_pre_json_available_variations' ) );
|
78 |
+
|
79 |
+
// Load up the minified check script.
|
80 |
+
$this->check_webp_script = file_get_contents( EWWW_IMAGE_OPTIMIZER_PLUGIN_PATH . 'includes/check-webp.min.js' );
|
81 |
+
// Load up the minified script so we can inline it.
|
82 |
+
$this->load_webp_script = file_get_contents( EWWW_IMAGE_OPTIMIZER_PLUGIN_PATH . 'includes/load-webp.min.js' );
|
83 |
+
|
84 |
+
$allowed_urls = ewww_image_optimizer_get_option( 'ewww_image_optimizer_webp_paths' );
|
85 |
+
if ( $this->is_iterable( $allowed_urls ) ) {
|
86 |
+
$this->allowed_urls = array_merge( $this->allowed_urls, $allowed_urls );
|
87 |
+
}
|
88 |
+
|
89 |
+
$this->get_allowed_domains();
|
90 |
+
|
91 |
+
$this->allowed_urls = apply_filters( 'webp_allowed_urls', $this->allowed_urls );
|
92 |
+
$this->allowed_domains = apply_filters( 'webp_allowed_domains', $this->allowed_domains );
|
93 |
+
$this->debug_message( 'checking any images matching these URLs/patterns for webp: ' . implode( ',', $this->allowed_urls ) );
|
94 |
+
$this->debug_message( 'rewriting any images matching these domains to webp: ' . implode( ',', $this->allowed_domains ) );
|
95 |
+
|
96 |
+
// Load the appropriate JS, in the footer, but as early as possible.
|
97 |
+
if ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ) {
|
98 |
+
// Load the non-minified, non-inline version of the webp rewrite script.
|
99 |
+
add_action( 'wp_enqueue_scripts', array( $this, 'debug_script' ), -99 );
|
100 |
+
} elseif ( defined( 'EWWW_IMAGE_OPTIMIZER_WEBP_EXTERNAL_SCRIPT' ) && EWWW_IMAGE_OPTIMIZER_WEBP_EXTERNAL_SCRIPT ) {
|
101 |
+
// Load the minified, non-inline version of the webp rewrite script.
|
102 |
+
add_action( 'wp_enqueue_scripts', array( $this, 'min_external_script' ), -99 );
|
103 |
+
} else {
|
104 |
+
add_action( 'wp_head', array( $this, 'inline_check_script' ), -99 );
|
105 |
+
add_action( 'wp_footer', array( $this, 'inline_load_script' ), -99 );
|
106 |
+
}
|
107 |
+
$this->validate_user_exclusions();
|
108 |
+
}
|
109 |
+
|
110 |
+
/**
|
111 |
+
* Grant read-only access to allowed WebP domains.
|
112 |
+
*
|
113 |
+
* @return array A list of WebP domains.
|
114 |
+
*/
|
115 |
+
function get_webp_domains() {
|
116 |
+
return $this->allowed_domains;
|
117 |
+
}
|
118 |
+
|
119 |
+
/**
|
120 |
+
* Starts an output buffer and registers the callback function to do WebP replacement.
|
121 |
+
*/
|
122 |
+
function buffer_start() {
|
123 |
+
ob_start( array( $this, 'filter_page_output' ) );
|
124 |
+
}
|
125 |
+
|
126 |
+
/**
|
127 |
+
* Replaces images within a srcset attribute with their .webp derivatives.
|
128 |
+
*
|
129 |
+
* @param string $srcset A valid srcset attribute from an img element.
|
130 |
+
* @return bool|string False if no changes were made, or the new srcset if any WebP images replaced the originals.
|
131 |
+
*/
|
132 |
+
function srcset_replace( $srcset ) {
|
133 |
+
$this->debug_message( '<b>' . __METHOD__ . '()</b>' );
|
134 |
+
$srcset_urls = explode( ' ', $srcset );
|
135 |
+
$found_webp = false;
|
136 |
+
if ( $this->is_iterable( $srcset_urls ) && count( $srcset_urls ) > 1 ) {
|
137 |
+
$this->debug_message( 'parsing srcset urls' );
|
138 |
+
foreach ( $srcset_urls as $srcurl ) {
|
139 |
+
if ( is_numeric( substr( $srcurl, 0, 1 ) ) ) {
|
140 |
+
continue;
|
141 |
+
}
|
142 |
+
$trailing = ' ';
|
143 |
+
if ( ',' === substr( $srcurl, -1 ) ) {
|
144 |
+
$trailing = ',';
|
145 |
+
$srcurl = rtrim( $srcurl, ',' );
|
146 |
+
}
|
147 |
+
$this->debug_message( "looking for $srcurl from srcset" );
|
148 |
+
if ( $this->validate_image_url( $srcurl ) ) {
|
149 |
+
$srcset = str_replace( $srcurl . $trailing, $this->generate_url( $srcurl ) . $trailing, $srcset );
|
150 |
+
$this->debug_message( "replaced $srcurl in srcset" );
|
151 |
+
$found_webp = true;
|
152 |
+
}
|
153 |
+
}
|
154 |
+
} elseif ( $this->validate_image_url( $srcset ) ) {
|
155 |
+
return $this->generate_url( $srcset );
|
156 |
+
}
|
157 |
+
if ( $found_webp ) {
|
158 |
+
return $srcset;
|
159 |
+
} else {
|
160 |
+
return false;
|
161 |
+
}
|
162 |
+
}
|
163 |
+
|
164 |
+
/**
|
165 |
+
* Replaces images within the Jetpack data attributes with their .webp derivatives.
|
166 |
+
*
|
167 |
+
* @param string $image The full text of the img element.
|
168 |
+
* @return string The modified noscript tag.
|
169 |
+
*/
|
170 |
+
function jetpack_replace( $image ) {
|
171 |
+
$this->debug_message( '<b>' . __METHOD__ . '()</b>' );
|
172 |
+
$data_orig_file = $this->get_attribute( $image, 'data-orig-file' );
|
173 |
+
if ( $data_orig_file ) {
|
174 |
+
$this->debug_message( "looking for data-orig-file: $data_orig_file" );
|
175 |
+
if ( $this->validate_image_url( $data_orig_file ) ) {
|
176 |
+
$this->set_attribute( $image, 'data-webp-orig-file', $this->generate_url( $data_orig_file ), true );
|
177 |
+
$this->debug_message( "replacing $data_orig_file via data-webp-orig-file" );
|
178 |
+
}
|
179 |
+
}
|
180 |
+
$data_medium_file = $this->get_attribute( $image, 'data-medium-file' );
|
181 |
+
if ( $data_medium_file ) {
|
182 |
+
$this->debug_message( "looking for data-medium-file: $data_medium_file" );
|
183 |
+
if ( $this->validate_image_url( $data_medium_file ) ) {
|
184 |
+
$this->set_attribute( $image, 'data-webp-medium-file', $this->generate_url( $data_medium_file ), true );
|
185 |
+
$this->debug_message( "replacing $data_medium_file via data-webp-medium-file" );
|
186 |
+
}
|
187 |
+
}
|
188 |
+
$data_large_file = $this->get_attribute( $image, 'data-large-file' );
|
189 |
+
if ( $data_large_file ) {
|
190 |
+
$this->debug_message( "looking for data-large-file: $data_large_file" );
|
191 |
+
if ( $this->validate_image_url( $data_large_file ) ) {
|
192 |
+
$this->set_attribute( $image, 'data-webp-large-file', $this->generate_url( $data_large_file ), true );
|
193 |
+
$this->debug_message( "replacing $data_large_file via data-webp-large-file" );
|
194 |
+
}
|
195 |
+
}
|
196 |
+
return $image;
|
197 |
+
}
|
198 |
+
|
199 |
+
/**
|
200 |
+
* Replaces images with the WooCommerce data attributes with their .webp derivatives.
|
201 |
+
*
|
202 |
+
* @param string $image The full text of the img element.
|
203 |
+
* @return string The modified noscript tag.
|
204 |
+
*/
|
205 |
+
function woocommerce_replace( $image ) {
|
206 |
+
$this->debug_message( '<b>' . __METHOD__ . '()</b>' );
|
207 |
+
$data_large_image = $this->get_attribute( $image, 'data-large_image' );
|
208 |
+
if ( $data_large_image ) {
|
209 |
+
$this->debug_message( "looking for data-large_image: $data_large_image" );
|
210 |
+
if ( $this->validate_image_url( $data_large_image ) ) {
|
211 |
+
$this->set_attribute( $image, 'data-webp-large_image', $this->generate_url( $data_large_image ), true );
|
212 |
+
$this->debug_message( "replacing $data_large_image via data-webp-large_image" );
|
213 |
+
}
|
214 |
+
}
|
215 |
+
$data_src = $this->get_attribute( $image, 'data-src' );
|
216 |
+
if ( $data_src ) {
|
217 |
+
$this->debug_message( "looking for data-src: $data_src" );
|
218 |
+
if ( $this->validate_image_url( $data_src ) ) {
|
219 |
+
$this->set_attribute( $image, 'data-webp-src', $this->generate_url( $data_src ), true );
|
220 |
+
ewwwio_debug_message( "replacing $data_src via data-webp-src" );
|
221 |
+
}
|
222 |
+
}
|
223 |
+
return $image;
|
224 |
+
}
|
225 |
+
|
226 |
+
/**
|
227 |
+
* Search for img elements and rewrite them with noscript elements for WebP replacement.
|
228 |
+
*
|
229 |
+
* Any img elements or elements that may be used in place of img elements by JS are checked to see
|
230 |
+
* if WebP derivatives exist. The element is then wrapped within a noscript element for fallback,
|
231 |
+
* and noscript element receives a copy of the attributes from the img along with webp replacement
|
232 |
+
* values for those attributes.
|
233 |
+
*
|
234 |
+
* @param string $buffer The full HTML page generated since the output buffer was started.
|
235 |
+
* @return string The altered buffer containing the full page with WebP images inserted.
|
236 |
+
*/
|
237 |
+
function filter_page_output( $buffer ) {
|
238 |
+
ewwwio_debug_message( '<b>' . __METHOD__ . '()</b>' );
|
239 |
+
// If any of this is true, don't filter the page.
|
240 |
+
$uri = add_query_arg( null, null );
|
241 |
+
$this->debug_message( "request uri is $uri" );
|
242 |
+
if (
|
243 |
+
empty( $buffer ) ||
|
244 |
+
is_admin() ||
|
245 |
+
strpos( $uri, 'cornerstone=' ) !== false ||
|
246 |
+
strpos( $uri, 'cornerstone-endpoint' ) !== false ||
|
247 |
+
did_action( 'cornerstone_boot_app' ) || did_action( 'cs_before_preview_frame' ) ||
|
248 |
+
'/print/' === substr( $uri, -7 ) ||
|
249 |
+
strpos( $uri, 'elementor-preview=' ) !== false ||
|
250 |
+
strpos( $uri, 'et_fb=' ) !== false ||
|
251 |
+
strpos( $uri, 'tatsu=' ) !== false ||
|
252 |
+
( ! empty( $_POST['action'] ) && 'tatsu_get_concepts' === sanitize_text_field( wp_unslash( $_POST['action'] ) ) ) || // phpcs:ignore WordPress.Security.NonceVerification
|
253 |
+
is_embed() ||
|
254 |
+
is_feed() ||
|
255 |
+
is_preview() ||
|
256 |
+
is_customize_preview() ||
|
257 |
+
( defined( 'REST_REQUEST' ) && REST_REQUEST ) ||
|
258 |
+
preg_match( '/^<\?xml/', $buffer ) ||
|
259 |
+
strpos( $buffer, 'amp-boilerplate' ) ||
|
260 |
+
$this->is_amp() ||
|
261 |
+
ewww_image_optimizer_ce_webp_enabled()
|
262 |
+
) {
|
263 |
+
ewwwio_debug_message( 'JS WebP disabled' );
|
264 |
+
return $buffer;
|
265 |
+
}
|
266 |
+
|
267 |
+
$body_tags = $this->get_elements_from_html( $buffer, 'body' );
|
268 |
+
if ( $this->is_iterable( $body_tags ) && ! empty( $body_tags[0] ) && false !== strpos( $body_tags[0], '<body' ) ) {
|
269 |
+
$body_webp_script = '<script>if(ewww_webp_supported){document.body.classList.add("webp-support");}</script>';
|
270 |
+
// Add the WebP script right after the opening tag.
|
271 |
+
$buffer = str_replace( $body_tags[0], $body_tags[0] . "\n" . $body_webp_script, $buffer );
|
272 |
+
}
|
273 |
+
$images = $this->get_images_from_html( preg_replace( '/<(picture|noscript).*?\/\1>/s', '', $buffer ), false );
|
274 |
+
if ( ! empty( $images[0] ) && $this->is_iterable( $images[0] ) ) {
|
275 |
+
foreach ( $images[0] as $index => $image ) {
|
276 |
+
if ( false !== strpos( $image, 'ewww_webp' ) ) {
|
277 |
+
continue;
|
278 |
+
}
|
279 |
+
// Ignore 0-size Pinterest schema images.
|
280 |
+
if ( strpos( $image, 'data-pin-description=' ) && strpos( $image, 'width="0" height="0"' ) ) {
|
281 |
+
continue;
|
282 |
+
}
|
283 |
+
if ( ! $this->validate_tag( $image ) ) {
|
284 |
+
continue;
|
285 |
+
}
|
286 |
+
$file = $images['img_url'][ $index ];
|
287 |
+
ewwwio_debug_message( "parsing an image: $file" );
|
288 |
+
if ( strpos( $image, 'jetpack-lazy-image' ) && $this->validate_image_url( $file ) ) {
|
289 |
+
$new_image = $image;
|
290 |
+
$new_image = $this->jetpack_replace( $new_image );
|
291 |
+
$real_file = $this->get_attribute( $new_image, 'data-lazy-src' );
|
292 |
+
ewwwio_debug_message( 'checking webp for Jetpack Lazy Load data-lazy-src' );
|
293 |
+
if ( $real_file && $this->validate_image_url( $real_file ) ) {
|
294 |
+
ewwwio_debug_message( "found webp for Lazy Load: $real_file" );
|
295 |
+
$this->set_attribute( $new_image, 'data-lazy-src-webp', $this->generate_url( $real_file ) );
|
296 |
+
}
|
297 |
+
$srcset = $this->get_attribute( $new_image, 'data-lazy-srcset' );
|
298 |
+
if ( $srcset ) {
|
299 |
+
$srcset_webp = $this->srcset_replace( $srcset );
|
300 |
+
if ( $srcset_webp ) {
|
301 |
+
$this->set_attribute( $new_image, 'data-lazy-srcset-webp', $srcset_webp );
|
302 |
+
}
|
303 |
+
}
|
304 |
+
if ( $new_image !== $image ) {
|
305 |
+
$this->set_attribute( $new_image, 'class', $this->get_attribute( $new_image, 'class' ) . ' ewww_webp_lazy_load', true );
|
306 |
+
$buffer = str_replace( $image, $new_image, $buffer );
|
307 |
+
}
|
308 |
+
} elseif ( $this->validate_image_url( $file ) && false === strpos( $image, 'lazyload' ) ) {
|
309 |
+
// If a CDN path match was found, or .webp image existence is confirmed, and this is not a lazy-load 'dummy' image.
|
310 |
+
$this->debug_message( 'found a webp image or forced path' );
|
311 |
+
$new_image = $image;
|
312 |
+
$this->set_attribute( $new_image, 'data-src-img', $file );
|
313 |
+
$this->set_attribute( $new_image, 'data-src-webp', $this->generate_url( $file ) );
|
314 |
+
$srcset = $this->get_attribute( $image, 'srcset' );
|
315 |
+
if ( $srcset ) {
|
316 |
+
$srcset_webp = $this->srcset_replace( $srcset );
|
317 |
+
if ( $srcset_webp ) {
|
318 |
+
$this->set_attribute( $new_image, 'data-srcset-webp', $srcset_webp );
|
319 |
+
}
|
320 |
+
$this->set_attribute( $new_image, 'data-srcset-img', $srcset );
|
321 |
+
$this->remove_attribute( $new_image, 'srcset' );
|
322 |
+
}
|
323 |
+
if ( $this->get_attribute( $image, 'data-orig-file' ) && $this->get_attribute( $image, 'data-medium-file' ) && $this->get_attribute( $image, 'data-large-file' ) ) {
|
324 |
+
$new_image = $this->jetpack_replace( $new_image );
|
325 |
+
}
|
326 |
+
if ( $this->get_attribute( $image, 'data-large_image' ) && $this->get_attribute( $image, 'data-src' ) ) {
|
327 |
+
$new_image = $this->woocommerce_replace( $new_image );
|
328 |
+
}
|
329 |
+
$this->set_attribute( $new_image, 'src', $this->placeholder_src, true );
|
330 |
+
if ( $new_image !== $image ) {
|
331 |
+
$this->set_attribute( $new_image, 'data-eio', 'j', true );
|
332 |
+
$this->set_attribute( $new_image, 'class', $this->get_attribute( $new_image, 'class' ) . ' ewww_webp', true );
|
333 |
+
$this->debug_message( "going to swap\n$image\nwith\n$new_image" );
|
334 |
+
$noscript = '<noscript>' . $image . '</noscript>';
|
335 |
+
$buffer = str_replace( $image, $new_image . $noscript, $buffer );
|
336 |
+
}
|
337 |
+
} elseif ( ! empty( $file ) && strpos( $image, ' data-lazy-src=' ) ) {
|
338 |
+
// BJ Lazy Load & WP Rocket.
|
339 |
+
$new_image = $image;
|
340 |
+
$real_file = $this->get_attribute( $new_image, 'data-lazy-src' );
|
341 |
+
ewwwio_debug_message( "checking webp for Lazy Load data-lazy-src: $real_file" );
|
342 |
+
if ( $this->validate_image_url( $real_file ) ) {
|
343 |
+
ewwwio_debug_message( "found webp for Lazy Load: $real_file" );
|
344 |
+
$this->set_attribute( $new_image, 'data-lazy-src-webp', $this->generate_url( $real_file ) );
|
345 |
+
}
|
346 |
+
$srcset = $this->get_attribute( $new_image, 'data-lazy-srcset' );
|
347 |
+
if ( $srcset ) {
|
348 |
+
$srcset_webp = $this->srcset_replace( $srcset );
|
349 |
+
if ( $srcset_webp ) {
|
350 |
+
$this->set_attribute( $new_image, 'data-lazy-srcset-webp', $srcset_webp );
|
351 |
+
}
|
352 |
+
}
|
353 |
+
if ( $new_image !== $image ) {
|
354 |
+
$this->set_attribute( $new_image, 'class', $this->get_attribute( $new_image, 'class' ) . ' ewww_webp_lazy_load', true );
|
355 |
+
$buffer = str_replace( $image, $new_image, $buffer );
|
356 |
+
}
|
357 |
+
} elseif ( ! empty( $file ) && strpos( $image, ' data-src=' ) && ( strpos( $image, ' data-lazy-type="image' ) || strpos( $image, 'lazyload' ) ) ) {
|
358 |
+
// a3 or EWWW IO Lazy Load.
|
359 |
+
$new_image = $image;
|
360 |
+
$real_file = $this->get_attribute( $new_image, 'data-src' );
|
361 |
+
ewwwio_debug_message( "checking webp for Lazy Load data-src: $real_file" );
|
362 |
+
if ( $this->validate_image_url( $real_file ) ) {
|
363 |
+
ewwwio_debug_message( 'found webp for Lazy Load' );
|
364 |
+
$this->set_attribute( $new_image, 'data-src-webp', $this->generate_url( $real_file ) );
|
365 |
+
}
|
366 |
+
$srcset = $this->get_attribute( $new_image, 'data-srcset' );
|
367 |
+
if ( $srcset ) {
|
368 |
+
$srcset_webp = $this->srcset_replace( $srcset );
|
369 |
+
if ( $srcset_webp ) {
|
370 |
+
$this->set_attribute( $new_image, 'data-srcset-webp', $srcset_webp );
|
371 |
+
}
|
372 |
+
}
|
373 |
+
if ( $new_image !== $image ) {
|
374 |
+
$this->set_attribute( $new_image, 'class', $this->get_attribute( $new_image, 'class' ) . ' ewww_webp_lazy_load', true );
|
375 |
+
$buffer = str_replace( $image, $new_image, $buffer );
|
376 |
+
}
|
377 |
+
} elseif ( ! empty( $file ) && strpos( $image, 'data-lazysrc=' ) && strpos( $image, '/essential-grid' ) ) {
|
378 |
+
// Essential Grid.
|
379 |
+
$new_image = $image;
|
380 |
+
$real_file = $this->get_attribute( $new_image, 'data-lazysrc' );
|
381 |
+
ewwwio_debug_message( "checking webp for EG Lazy Load data-lazysrc: $real_file" );
|
382 |
+
if ( $this->validate_image_url( $real_file ) ) {
|
383 |
+
ewwwio_debug_message( "found webp for Lazy Load: $real_file" );
|
384 |
+
$this->set_attribute( $new_image, 'data-lazysrc-webp', $this->generate_url( $real_file ) );
|
385 |
+
}
|
386 |
+
if ( $new_image !== $image ) {
|
387 |
+
$this->set_attribute( $new_image, 'class', $this->get_attribute( $new_image, 'class' ) . ' ewww_webp_lazy_load', true );
|
388 |
+
$buffer = str_replace( $image, $new_image, $buffer );
|
389 |
+
}
|
390 |
+
}
|
391 |
+
// Rev Slider data-lazyload attribute on image elements.
|
392 |
+
if ( $this->get_attribute( $image, 'data-lazyload' ) ) {
|
393 |
+
$new_image = $image;
|
394 |
+
$lazyload = $this->get_attribute( $new_image, 'data-lazyload' );
|
395 |
+
if ( $lazyload ) {
|
396 |
+
if ( $this->validate_image_url( $lazyload ) ) {
|
397 |
+
$this->set_attribute( $new_image, 'data-webp-lazyload', $this->generate_url( $lazyload ) );
|
398 |
+
ewwwio_debug_message( "replacing with webp for data-lazyload: $lazyload" );
|
399 |
+
$buffer = str_replace( $image, $new_image, $buffer );
|
400 |
+
}
|
401 |
+
}
|
402 |
+
}
|
403 |
+
} // End foreach().
|
404 |
+
} // End if().
|
405 |
+
// Now we will look for any lazy images that don't have a src attribute (this search returns ALL img elements though).
|
406 |
+
$images = $this->get_images_from_html( preg_replace( '/<(picture|noscript).*?\/\1>/s', '', $buffer ), false, false );
|
407 |
+
if ( ! empty( $images[0] ) && $this->is_iterable( $images[0] ) ) {
|
408 |
+
ewwwio_debug_message( 'parsing images without requiring src' );
|
409 |
+
foreach ( $images[0] as $index => $image ) {
|
410 |
+
if ( $this->get_attribute( $image, 'src' ) ) {
|
411 |
+
continue;
|
412 |
+
}
|
413 |
+
if ( ! $this->validate_tag( $image ) ) {
|
414 |
+
continue;
|
415 |
+
}
|
416 |
+
ewwwio_debug_message( 'found img without src' );
|
417 |
+
if ( strpos( $image, 'data-src=' ) && strpos( $image, 'data-srcset=' ) && strpos( $image, 'lazyload' ) ) {
|
418 |
+
// EWWW IO Lazy Load.
|
419 |
+
$new_image = $image;
|
420 |
+
$real_file = $this->get_attribute( $new_image, 'data-src' );
|
421 |
+
ewwwio_debug_message( "checking webp for Lazy Load data-src: $real_file" );
|
422 |
+
if ( $this->validate_image_url( $real_file ) ) {
|
423 |
+
ewwwio_debug_message( 'found webp for Lazy Load' );
|
424 |
+
$this->set_attribute( $new_image, 'data-src-webp', $this->generate_url( $real_file ) );
|
425 |
+
}
|
426 |
+
$srcset = $this->get_attribute( $new_image, 'data-srcset' );
|
427 |
+
if ( $srcset ) {
|
428 |
+
$srcset_webp = $this->srcset_replace( $srcset );
|
429 |
+
if ( $srcset_webp ) {
|
430 |
+
$this->set_attribute( $new_image, 'data-srcset-webp', $srcset_webp );
|
431 |
+
}
|
432 |
+
}
|
433 |
+
if ( $new_image !== $image ) {
|
434 |
+
$this->set_attribute( $new_image, 'class', $this->get_attribute( $new_image, 'class' ) . ' ewww_webp_lazy_load', true );
|
435 |
+
$buffer = str_replace( $image, $new_image, $buffer );
|
436 |
+
}
|
437 |
+
}
|
438 |
+
} // End foreach().
|
439 |
+
} // End if().
|
440 |
+
// Look for images to parse WP Retina Lazy Load.
|
441 |
+
if ( class_exists( 'Meow_WR2X_Core' ) && strpos( $buffer, ' lazyload' ) ) {
|
442 |
+
$images = $this->get_elements_from_html( $buffer, 'img' );
|
443 |
+
if ( $this->is_iterable( $images ) ) {
|
444 |
+
foreach ( $images as $index => $image ) {
|
445 |
+
if ( ! $this->validate_tag( $image ) ) {
|
446 |
+
continue;
|
447 |
+
}
|
448 |
+
$file = $this->get_attribute( $image, 'src' );
|
449 |
+
if ( ( empty( $file ) || strpos( $image, 'R0lGODlhAQABAIAAAAAAAP' ) ) && strpos( $image, ' data-srcset=' ) && strpos( $this->get_attribute( $image, 'class' ), 'lazyload' ) ) {
|
450 |
+
$new_image = $image;
|
451 |
+
$srcset = $this->get_attribute( $new_image, 'data-srcset' );
|
452 |
+
ewwwio_debug_message( 'checking webp for Retina Lazy Load data-src' );
|
453 |
+
if ( $srcset ) {
|
454 |
+
$srcset_webp = $this->srcset_replace( $srcset );
|
455 |
+
if ( $srcset_webp ) {
|
456 |
+
$this->set_attribute( $new_image, 'data-srcset-webp', $srcset_webp );
|
457 |
+
}
|
458 |
+
}
|
459 |
+
if ( $new_image !== $image ) {
|
460 |
+
$this->set_attribute( $new_image, 'class', $this->get_attribute( $new_image, 'class' ) . ' ewww_webp_lazy_load', true );
|
461 |
+
$buffer = str_replace( $image, $new_image, $buffer );
|
462 |
+
}
|
463 |
+
}
|
464 |
+
}
|
465 |
+
}
|
466 |
+
}
|
467 |
+
// Images listed as picture/source elements.
|
468 |
+
$pictures = $this->get_picture_tags_from_html( $buffer );
|
469 |
+
if ( $this->is_iterable( $pictures ) ) {
|
470 |
+
foreach ( $pictures as $index => $picture ) {
|
471 |
+
if ( strpos( $picture, 'image/webp' ) ) {
|
472 |
+
continue;
|
473 |
+
}
|
474 |
+
if ( ! $this->validate_tag( $picture ) ) {
|
475 |
+
continue;
|
476 |
+
}
|
477 |
+
$sources = $this->get_elements_from_html( $picture, 'source' );
|
478 |
+
if ( $this->is_iterable( $sources ) ) {
|
479 |
+
foreach ( $sources as $source ) {
|
480 |
+
$this->debug_message( "parsing a picture source: $source" );
|
481 |
+
$srcset_attr_name = 'srcset';
|
482 |
+
if ( false !== strpos( $source, 'base64,R0lGOD' ) && false !== strpos( $source, 'data-srcset=' ) ) {
|
483 |
+
$srcset_attr_name = 'data-srcset';
|
484 |
+
} elseif ( ! $this->get_attribute( $source, $srcset_attr_name ) && false !== strpos( $source, 'data-srcset=' ) ) {
|
485 |
+
$srcset_attr_name = 'data-srcset';
|
486 |
+
}
|
487 |
+
$srcset = $this->get_attribute( $source, $srcset_attr_name );
|
488 |
+
if ( $srcset ) {
|
489 |
+
$srcset_webp = $this->srcset_replace( $srcset );
|
490 |
+
if ( $srcset_webp ) {
|
491 |
+
$source_webp = str_replace( $srcset, $srcset_webp, $source );
|
492 |
+
$this->set_attribute( $source_webp, 'type', 'image/webp' );
|
493 |
+
$picture = str_replace( $source, $source_webp . $source, $picture );
|
494 |
+
}
|
495 |
+
}
|
496 |
+
}
|
497 |
+
if ( $picture !== $pictures[ $index ] ) {
|
498 |
+
$this->debug_message( 'found webp for picture element' );
|
499 |
+
$buffer = str_replace( $pictures[ $index ], $picture, $buffer );
|
500 |
+
}
|
501 |
+
}
|
502 |
+
}
|
503 |
+
}
|
504 |
+
// NextGEN slides listed as 'a' elements and LL 'a' background images.
|
505 |
+
$links = $this->get_elements_from_html( $buffer, 'a' );
|
506 |
+
if ( $this->is_iterable( $links ) ) {
|
507 |
+
foreach ( $links as $index => $link ) {
|
508 |
+
ewwwio_debug_message( "parsing a link $link" );
|
509 |
+
if ( ! $this->validate_tag( $link ) ) {
|
510 |
+
continue;
|
511 |
+
}
|
512 |
+
$file = $this->get_attribute( $link, 'data-src' );
|
513 |
+
$thumb = $this->get_attribute( $link, 'data-thumbnail' );
|
514 |
+
if ( $file && $thumb ) {
|
515 |
+
ewwwio_debug_message( "checking webp for ngg data-src: $file" );
|
516 |
+
if ( $this->validate_image_url( $file ) ) {
|
517 |
+
$this->set_attribute( $link, 'data-webp', $this->generate_url( $file ) );
|
518 |
+
ewwwio_debug_message( "found webp for ngg data-src: $file" );
|
519 |
+
}
|
520 |
+
ewwwio_debug_message( "checking webp for ngg data-thumbnail: $thumb" );
|
521 |
+
if ( $this->validate_image_url( $thumb ) ) {
|
522 |
+
$this->set_attribute( $link, 'data-webp-thumbnail', $this->generate_url( $thumb ) );
|
523 |
+
ewwwio_debug_message( "found webp for ngg data-thumbnail: $thumb" );
|
524 |
+
}
|
525 |
+
}
|
526 |
+
$bg_image = $this->get_attribute( $link, 'data-bg' );
|
527 |
+
$link_class = $this->get_attribute( $link, 'class' );
|
528 |
+
if ( $link_class && $bg_image && false !== strpos( $link_class, 'lazyload' ) ) {
|
529 |
+
ewwwio_debug_message( "checking a/link for LL data-bg: $bg_image" );
|
530 |
+
if ( $this->validate_image_url( $bg_image ) ) {
|
531 |
+
$this->set_attribute( $link, 'data-bg-webp', $this->generate_url( $bg_image ) );
|
532 |
+
ewwwio_debug_message( 'found webp for LL data-bg' );
|
533 |
+
}
|
534 |
+
}
|
535 |
+
if ( $link !== $links[ $index ] ) {
|
536 |
+
$buffer = str_replace( $links[ $index ], $link, $buffer );
|
537 |
+
}
|
538 |
+
}
|
539 |
+
}
|
540 |
+
// Revolution Slider 'li' elements and LL li backgrounds.
|
541 |
+
$listitems = $this->get_elements_from_html( $buffer, 'li' );
|
542 |
+
if ( $this->is_iterable( $listitems ) ) {
|
543 |
+
foreach ( $listitems as $index => $listitem ) {
|
544 |
+
ewwwio_debug_message( 'parsing a listitem' );
|
545 |
+
if ( ! $this->validate_tag( $listitem ) ) {
|
546 |
+
continue;
|
547 |
+
}
|
548 |
+
if ( $this->get_attribute( $listitem, 'data-title' ) === 'Slide' && ( $this->get_attribute( $listitem, 'data-lazyload' ) || $this->get_attribute( $listitem, 'data-thumb' ) ) ) {
|
549 |
+
$thumb = $this->get_attribute( $listitem, 'data-thumb' );
|
550 |
+
ewwwio_debug_message( "checking webp for revslider data-thumb: $thumb" );
|
551 |
+
if ( $this->validate_image_url( $thumb ) ) {
|
552 |
+
$this->set_attribute( $listitem, 'data-webp-thumb', $this->generate_url( $thumb ) );
|
553 |
+
ewwwio_debug_message( "found webp for revslider data-thumb: $thumb" );
|
554 |
+
}
|
555 |
+
$param_num = 1;
|
556 |
+
while ( $param_num < 11 ) {
|
557 |
+
$parameter = $this->get_attribute( $listitem, 'data-param' . $param_num );
|
558 |
+
if ( $parameter ) {
|
559 |
+
ewwwio_debug_message( "checking webp for revslider data-param$param_num: $parameter" );
|
560 |
+
if ( strpos( $parameter, 'http' ) === 0 ) {
|
561 |
+
ewwwio_debug_message( "looking for $parameter" );
|
562 |
+
if ( $this->validate_image_url( $parameter ) ) {
|
563 |
+
$this->set_attribute( $listitem, 'data-webp-param' . $param_num, $this->generate_url( $parameter ) );
|
564 |
+
ewwwio_debug_message( "found webp for data-param$param_num: $parameter" );
|
565 |
+
}
|
566 |
+
}
|
567 |
+
}
|
568 |
+
$param_num++;
|
569 |
+
}
|
570 |
+
if ( $listitem !== $listitems[ $index ] ) {
|
571 |
+
$buffer = str_replace( $listitems[ $index ], $listitem, $buffer );
|
572 |
+
}
|
573 |
+
}
|
574 |
+
$bg_image = $this->get_attribute( $listitem, 'data-bg' );
|
575 |
+
$li_class = $this->get_attribute( $listitem, 'class' );
|
576 |
+
if ( $li_class && $bg_image && false !== strpos( $li_class, 'lazyload' ) ) {
|
577 |
+
ewwwio_debug_message( "checking div for LL data-bg: $bg_image" );
|
578 |
+
if ( $this->validate_image_url( $bg_image ) ) {
|
579 |
+
$this->set_attribute( $listitem, 'data-bg-webp', $this->generate_url( $bg_image ) );
|
580 |
+
ewwwio_debug_message( 'found webp for LL data-bg' );
|
581 |
+
$buffer = str_replace( $listitems[ $index ], $listitem, $buffer );
|
582 |
+
}
|
583 |
+
}
|
584 |
+
} // End foreach().
|
585 |
+
} // End if().
|
586 |
+
// WooCommerce thumbs listed as 'div' elements and LL div backgrounds.
|
587 |
+
$divs = $this->get_elements_from_html( $buffer, 'div' );
|
588 |
+
if ( $this->is_iterable( $divs ) ) {
|
589 |
+
foreach ( $divs as $index => $div ) {
|
590 |
+
ewwwio_debug_message( 'parsing a div' );
|
591 |
+
if ( ! $this->validate_tag( $div ) ) {
|
592 |
+
continue;
|
593 |
+
}
|
594 |
+
$thumb = $this->get_attribute( $div, 'data-thumb' );
|
595 |
+
$div_class = $this->get_attribute( $div, 'class' );
|
596 |
+
if ( $div_class && $thumb && strpos( $div_class, 'woocommerce-product-gallery__image' ) !== false ) {
|
597 |
+
ewwwio_debug_message( "checking webp for WC data-thumb: $thumb" );
|
598 |
+
if ( $this->validate_image_url( $thumb ) ) {
|
599 |
+
$this->set_attribute( $div, 'data-webp-thumb', $this->generate_url( $thumb ) );
|
600 |
+
ewwwio_debug_message( 'found webp for WC data-thumb' );
|
601 |
+
$buffer = str_replace( $divs[ $index ], $div, $buffer );
|
602 |
+
}
|
603 |
+
}
|
604 |
+
$bg_image = $this->get_attribute( $div, 'data-bg' );
|
605 |
+
if ( $div_class && $bg_image && false !== strpos( $div_class, 'lazyload' ) ) {
|
606 |
+
ewwwio_debug_message( "checking div for LL data-bg: $bg_image" );
|
607 |
+
if ( $this->validate_image_url( $bg_image ) ) {
|
608 |
+
$this->set_attribute( $div, 'data-bg-webp', $this->generate_url( $bg_image ) );
|
609 |
+
ewwwio_debug_message( 'found webp for LL data-bg' );
|
610 |
+
$buffer = str_replace( $divs[ $index ], $div, $buffer );
|
611 |
+
}
|
612 |
+
}
|
613 |
+
}
|
614 |
+
}
|
615 |
+
// Look for LL 'section' elements.
|
616 |
+
$sections = $this->get_elements_from_html( $buffer, 'section' );
|
617 |
+
if ( $this->is_iterable( $sections ) ) {
|
618 |
+
foreach ( $sections as $index => $section ) {
|
619 |
+
ewwwio_debug_message( 'parsing a section' );
|
620 |
+
if ( ! $this->validate_tag( $section ) ) {
|
621 |
+
continue;
|
622 |
+
}
|
623 |
+
$class = $this->get_attribute( $section, 'class' );
|
624 |
+
$bg_image = $this->get_attribute( $section, 'data-bg' );
|
625 |
+
if ( $class && $bg_image && false !== strpos( $class, 'lazyload' ) ) {
|
626 |
+
ewwwio_debug_message( "checking section for LL data-bg: $bg_image" );
|
627 |
+
if ( $this->validate_image_url( $bg_image ) ) {
|
628 |
+
$this->set_attribute( $section, 'data-bg-webp', $this->generate_url( $bg_image ) );
|
629 |
+
ewwwio_debug_message( 'found webp for LL data-bg' );
|
630 |
+
$buffer = str_replace( $sections[ $index ], $section, $buffer );
|
631 |
+
}
|
632 |
+
}
|
633 |
+
}
|
634 |
+
}
|
635 |
+
// Look for LL 'span' elements.
|
636 |
+
$spans = $this->get_elements_from_html( $buffer, 'span' );
|
637 |
+
if ( $this->is_iterable( $spans ) ) {
|
638 |
+
foreach ( $spans as $index => $span ) {
|
639 |
+
ewwwio_debug_message( 'parsing a span' );
|
640 |
+
if ( ! $this->validate_tag( $span ) ) {
|
641 |
+
continue;
|
642 |
+
}
|
643 |
+
$class = $this->get_attribute( $span, 'class' );
|
644 |
+
$bg_image = $this->get_attribute( $span, 'data-bg' );
|
645 |
+
if ( $class && $bg_image && false !== strpos( $class, 'lazyload' ) ) {
|
646 |
+
ewwwio_debug_message( "checking span for LL data-bg: $bg_image" );
|
647 |
+
if ( $this->validate_image_url( $bg_image ) ) {
|
648 |
+
$this->set_attribute( $span, 'data-bg-webp', $this->generate_url( $bg_image ) );
|
649 |
+
ewwwio_debug_message( 'found webp for LL data-bg' );
|
650 |
+
$buffer = str_replace( $spans[ $index ], $span, $buffer );
|
651 |
+
}
|
652 |
+
}
|
653 |
+
}
|
654 |
+
}
|
655 |
+
// Video elements, looking for poster attributes that are images.
|
656 |
+
$videos = $this->get_elements_from_html( $buffer, 'video' );
|
657 |
+
if ( $this->is_iterable( $videos ) ) {
|
658 |
+
foreach ( $videos as $index => $video ) {
|
659 |
+
ewwwio_debug_message( 'parsing a video element' );
|
660 |
+
if ( ! $this->validate_tag( $video ) ) {
|
661 |
+
continue;
|
662 |
+
}
|
663 |
+
$file = $this->get_attribute( $video, 'poster' );
|
664 |
+
if ( $file ) {
|
665 |
+
ewwwio_debug_message( "checking webp for video poster: $file" );
|
666 |
+
if ( $this->validate_image_url( $file ) ) {
|
667 |
+
$this->set_attribute( $video, 'data-poster-webp', $this->generate_url( $file ) );
|
668 |
+
$this->set_attribute( $video, 'data-poster-image', $file );
|
669 |
+
$this->remove_attribute( $video, 'poster' );
|
670 |
+
ewwwio_debug_message( "found webp for video poster: $file" );
|
671 |
+
$buffer = str_replace( $videos[ $index ], $video, $buffer );
|
672 |
+
}
|
673 |
+
}
|
674 |
+
}
|
675 |
+
}
|
676 |
+
$this->debug_message( 'all done parsing page for JS WebP' );
|
677 |
+
return $buffer;
|
678 |
+
}
|
679 |
+
|
680 |
+
/**
|
681 |
+
* Handle image urls within the NextGEN pro lightbox displays.
|
682 |
+
*
|
683 |
+
* @param array $images An array of NextGEN images and associate attributes.
|
684 |
+
* @return array The array of images with WebP versions added.
|
685 |
+
*/
|
686 |
+
function ngg_pro_lightbox_images_queue( $images ) {
|
687 |
+
$this->debug_message( '<b>' . __METHOD__ . '()</b>' );
|
688 |
+
if ( $this->is_iterable( $images ) ) {
|
689 |
+
foreach ( $images as $index => $image ) {
|
690 |
+
if ( ! empty( $image['image'] ) && $this->validate_image_url( $image['image'] ) ) {
|
691 |
+
$images[ $index ]['image-webp'] = $this->generate_url( $image['image'] );
|
692 |
+
}
|
693 |
+
if ( ! empty( $image['thumb'] ) && $this->validate_image_url( $image['thumb'] ) ) {
|
694 |
+
$images[ $index ]['thumb-webp'] = $this->generate_url( $image['thumb'] );
|
695 |
+
}
|
696 |
+
if ( ! empty( $image['full_image'] ) && $this->validate_image_url( $image['full_image'] ) ) {
|
697 |
+
$images[ $index ]['full_image_webp'] = $this->generate_url( $image['full_image'] );
|
698 |
+
}
|
699 |
+
if ( $this->is_iterable( $image['srcsets'] ) ) {
|
700 |
+
foreach ( $image['srcsets'] as $size => $srcset ) {
|
701 |
+
if ( $this->validate_image_url( $srcset ) ) {
|
702 |
+
$images[ $index ]['srcsets'][ $size . '-webp' ] = $this->generate_url( $srcset );
|
703 |
+
}
|
704 |
+
}
|
705 |
+
}
|
706 |
+
if ( $this->is_iterable( $image['full_srcsets'] ) ) {
|
707 |
+
foreach ( $image['full_srcsets'] as $size => $srcset ) {
|
708 |
+
if ( $this->validate_image_url( $srcset ) ) {
|
709 |
+
$images[ $index ]['full_srcsets'][ $size . '-webp' ] = $this->generate_url( $srcset );
|
710 |
+
}
|
711 |
+
}
|
712 |
+
}
|
713 |
+
}
|
714 |
+
}
|
715 |
+
return $images;
|
716 |
+
}
|
717 |
+
|
718 |
+
/**
|
719 |
+
* Adds WebP URLs to the product variations data before it is JSON-encoded.
|
720 |
+
*
|
721 |
+
* @param array $variations The product variations with all the associated data.
|
722 |
+
* @return array The product variations with WebP image URLs added.
|
723 |
+
*/
|
724 |
+
function woocommerce_pre_json_available_variations( $variations ) {
|
725 |
+
$this->debug_message( '<b>' . __METHOD__ . '()</b>' );
|
726 |
+
if ( $this->is_iterable( $variations ) ) {
|
727 |
+
foreach ( $variations as $index => $variation ) {
|
728 |
+
if ( $this->is_iterable( $variation['image'] ) ) {
|
729 |
+
if ( ! empty( $variation['image']['src'] ) && $this->validate_image_url( $variation['image']['src'] ) ) {
|
730 |
+
$variations[ $index ]['image']['src_webp'] = $this->generate_url( $variation['image']['src'] );
|
731 |
+
}
|
732 |
+
if ( ! empty( $variation['image']['full_src'] ) && $this->validate_image_url( $variation['image']['full_src'] ) ) {
|
733 |
+
$variations[ $index ]['image']['full_src_webp'] = $this->generate_url( $variation['image']['full_src'] );
|
734 |
+
}
|
735 |
+
if ( ! empty( $variation['image']['gallery_thumbnail_src'] ) && $this->validate_image_url( $variation['image']['gallery_thumbnail_src'] ) ) {
|
736 |
+
$variations[ $index ]['image']['gallery_thumbnail_src_webp'] = $this->generate_url( $variation['image']['gallery_thumbnail_src'] );
|
737 |
+
}
|
738 |
+
if ( ! empty( $variation['image']['thumb_src'] ) && $this->validate_image_url( $variation['image']['thumb_src'] ) ) {
|
739 |
+
$variations[ $index ]['image']['thumb_src_webp'] = $this->generate_url( $variation['image']['thumb_src'] );
|
740 |
+
}
|
741 |
+
if ( ! empty( $variation['image']['srcset'] ) ) {
|
742 |
+
$webp_srcset = $this->srcset_replace( $variation['image']['srcset'] );
|
743 |
+
if ( $webp_srcset ) {
|
744 |
+
$variations[ $index ]['image']['srcset_webp'] = $webp_srcset;
|
745 |
+
}
|
746 |
+
}
|
747 |
+
}
|
748 |
+
}
|
749 |
+
if ( $this->function_exists( 'print_r' ) ) {
|
750 |
+
$this->debug_message( print_r( $variations, true ) );
|
751 |
+
}
|
752 |
+
}
|
753 |
+
return $variations;
|
754 |
+
}
|
755 |
+
|
756 |
+
/**
|
757 |
+
* Converts a URL to a file-system path and checks if the resulting path exists.
|
758 |
+
*
|
759 |
+
* @param string $url The URL to mangle.
|
760 |
+
* @param string $extension An optional extension to append during is_file().
|
761 |
+
* @return bool True if a local file exists correlating to the URL, false otherwise.
|
762 |
+
*/
|
763 |
+
function url_to_path_exists( $url, $extension = '' ) {
|
764 |
+
return parent::url_to_path_exists( $url, '.webp' );
|
765 |
+
}
|
766 |
+
|
767 |
+
/**
|
768 |
+
* Validate the user-defined exclusions.
|
769 |
+
*/
|
770 |
+
function validate_user_exclusions() {
|
771 |
+
$user_exclusions = $this->get_option( $this->prefix . 'webp_rewrite_exclude' );
|
772 |
+
$this->debug_message( $this->prefix . 'webp_rewrite_exclude' );
|
773 |
+
if ( ! empty( $user_exclusions ) ) {
|
774 |
+
if ( is_string( $user_exclusions ) ) {
|
775 |
+
$user_exclusions = array( $user_exclusions );
|
776 |
+
}
|
777 |
+
if ( is_array( $user_exclusions ) ) {
|
778 |
+
foreach ( $user_exclusions as $exclusion ) {
|
779 |
+
if ( ! is_string( $exclusion ) ) {
|
780 |
+
continue;
|
781 |
+
}
|
782 |
+
if (
|
783 |
+
'a' === $exclusion ||
|
784 |
+
'div' === $exclusion ||
|
785 |
+
'li' === $exclusion ||
|
786 |
+
'picture' === $exclusion ||
|
787 |
+
'section' === $exclusion ||
|
788 |
+
'span' === $exclusion ||
|
789 |
+
'video' === $exclusion
|
790 |
+
) {
|
791 |
+
$this->user_element_exclusions[] = $exclusion;
|
792 |
+
continue;
|
793 |
+
}
|
794 |
+
$this->user_exclusions[] = $exclusion;
|
795 |
+
}
|
796 |
+
}
|
797 |
+
}
|
798 |
+
}
|
799 |
+
|
800 |
+
/**
|
801 |
+
* Checks if the tag is allowed to be rewritten.
|
802 |
+
*
|
803 |
+
* @param string $image The HTML tag: img, span, etc.
|
804 |
+
* @return bool False if it flags a filter or exclusion, true otherwise.
|
805 |
+
*/
|
806 |
+
function validate_tag( $image ) {
|
807 |
+
$this->debug_message( '<b>' . __METHOD__ . '()</b>' );
|
808 |
+
// Ignore 0-size Pinterest schema images.
|
809 |
+
if ( strpos( $image, 'data-pin-description=' ) && strpos( $image, 'width="0" height="0"' ) ) {
|
810 |
+
$this->debug_message( 'data-pin-description img skipped' );
|
811 |
+
return false;
|
812 |
+
}
|
813 |
+
|
814 |
+
$test_tag = ltrim( substr( $image, 0, 10 ), '<' );
|
815 |
+
foreach ( $this->user_element_exclusions as $element_exclusion ) {
|
816 |
+
if ( 0 === strpos( $test_tag, $element_exclusion ) ) {
|
817 |
+
$this->debug_message( "$element_exclusion tag skipped" );
|
818 |
+
return;
|
819 |
+
}
|
820 |
+
}
|
821 |
+
|
822 |
+
$exclusions = apply_filters(
|
823 |
+
'ewwwio_js_webp_exclusions',
|
824 |
+
array_merge(
|
825 |
+
array(
|
826 |
+
'timthumb.php?',
|
827 |
+
'wpcf7_captcha/',
|
828 |
+
),
|
829 |
+
$this->user_exclusions
|
830 |
+
),
|
831 |
+
$image
|
832 |
+
);
|
833 |
+
foreach ( $exclusions as $exclusion ) {
|
834 |
+
if ( false !== strpos( $image, $exclusion ) ) {
|
835 |
+
$this->debug_message( "tag matched $exclusion" );
|
836 |
+
return false;
|
837 |
+
}
|
838 |
+
}
|
839 |
+
return true;
|
840 |
+
}
|
841 |
+
|
842 |
+
/**
|
843 |
+
* Checks if the path is a valid WebP image, on-disk or forced.
|
844 |
+
*
|
845 |
+
* @param string $image The image URL.
|
846 |
+
* @return bool True if the file exists or matches a forced path, false otherwise.
|
847 |
+
*/
|
848 |
+
function validate_image_url( $image ) {
|
849 |
+
$this->debug_message( "webp validation for $image" );
|
850 |
+
if (
|
851 |
+
strpos( $image, 'base64,R0lGOD' ) ||
|
852 |
+
strpos( $image, 'lazy-load/images/1x1' ) ||
|
853 |
+
strpos( $image, '/assets/images/' ) ||
|
854 |
+
strpos( $image, '/lazy/placeholder' )
|
855 |
+
) {
|
856 |
+
$this->debug_message( 'lazy load placeholder' );
|
857 |
+
return false;
|
858 |
+
}
|
859 |
+
$extension = '';
|
860 |
+
$image_path = $this->parse_url( $image, PHP_URL_PATH );
|
861 |
+
if ( ! is_null( $image_path ) && $image_path ) {
|
862 |
+
$extension = strtolower( pathinfo( $image_path, PATHINFO_EXTENSION ) );
|
863 |
+
}
|
864 |
+
if ( $extension && 'gif' === $extension && ! $this->get_option( 'ewww_image_optimizer_force_gif2webp' ) ) {
|
865 |
+
return false;
|
866 |
+
}
|
867 |
+
if ( $extension && 'svg' === $extension ) {
|
868 |
+
return false;
|
869 |
+
}
|
870 |
+
if ( $extension && 'webp' === $extension ) {
|
871 |
+
return false;
|
872 |
+
}
|
873 |
+
if ( apply_filters( 'ewww_image_optimizer_skip_webp_rewrite', false, $image ) ) {
|
874 |
+
return false;
|
875 |
+
}
|
876 |
+
if ( $this->get_option( 'ewww_image_optimizer_webp_force' ) && $this->is_iterable( $this->allowed_urls ) ) {
|
877 |
+
// Check the image for configured CDN paths.
|
878 |
+
foreach ( $this->allowed_urls as $allowed_url ) {
|
879 |
+
if ( strpos( $image, $allowed_url ) !== false ) {
|
880 |
+
$this->debug_message( 'forced cdn image' );
|
881 |
+
return true;
|
882 |
+
}
|
883 |
+
}
|
884 |
+
} elseif ( $this->allowed_urls && $this->allowed_domains ) {
|
885 |
+
if ( $this->cdn_to_local( $image ) ) {
|
886 |
+
return true;
|
887 |
+
}
|
888 |
+
}
|
889 |
+
return $this->url_to_path_exists( $image );
|
890 |
+
}
|
891 |
+
|
892 |
+
/**
|
893 |
+
* Generate a WebP url.
|
894 |
+
*
|
895 |
+
* Adds .webp to the end, or adds a webp parameter for ExactDN urls.
|
896 |
+
*
|
897 |
+
* @param string $url The image url.
|
898 |
+
* @return string The WebP version of the image url.
|
899 |
+
*/
|
900 |
+
function generate_url( $url ) {
|
901 |
+
$path_parts = explode( '?', $url );
|
902 |
+
return $path_parts[0] . '.webp' . ( ! empty( $path_parts[1] ) && 'is-pending-load=1' !== $path_parts[1] ? '?' . $path_parts[1] : '' );
|
903 |
+
}
|
904 |
+
|
905 |
+
/**
|
906 |
+
* Load full WebP script when SCRIPT_DEBUG is enabled.
|
907 |
+
*/
|
908 |
+
function debug_script() {
|
909 |
+
if ( $this->is_amp() ) {
|
910 |
+
return;
|
911 |
+
}
|
912 |
+
if ( ! ewww_image_optimizer_ce_webp_enabled() ) {
|
913 |
+
wp_enqueue_script( 'ewww-webp-load-script', plugins_url( '/includes/load-webp.js', EWWW_IMAGE_OPTIMIZER_PLUGIN_FILE ), array(), EWWW_IMAGE_OPTIMIZER_VERSION, true );
|
914 |
+
}
|
915 |
+
}
|
916 |
+
|
917 |
+
/**
|
918 |
+
* Load minified WebP script when EWWW_IMAGE_OPTIMIZER_WEBP_EXTERNAL_SCRIPT is set.
|
919 |
+
*/
|
920 |
+
function min_external_script() {
|
921 |
+
if ( $this->is_amp() ) {
|
922 |
+
return;
|
923 |
+
}
|
924 |
+
if ( ! ewww_image_optimizer_ce_webp_enabled() ) {
|
925 |
+
wp_enqueue_script( 'ewww-webp-load-script', plugins_url( '/includes/load-webp.min.js', EWWW_IMAGE_OPTIMIZER_PLUGIN_FILE ), array(), EWWW_IMAGE_OPTIMIZER_VERSION, true );
|
926 |
+
}
|
927 |
+
}
|
928 |
+
|
929 |
+
/**
|
930 |
+
* Load minified inline version of check WebP script.
|
931 |
+
*/
|
932 |
+
function inline_check_script() {
|
933 |
+
if ( defined( 'EWWW_IMAGE_OPTIMIZER_NO_JS' ) && EWWW_IMAGE_OPTIMIZER_NO_JS ) {
|
934 |
+
return;
|
935 |
+
}
|
936 |
+
if ( $this->is_amp() ) {
|
937 |
+
return;
|
938 |
+
}
|
939 |
+
$this->debug_message( 'inlining check webp script' );
|
940 |
+
echo '<script data-cfasync="false" type="text/javascript">' . $this->check_webp_script . '</script>'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
941 |
+
}
|
942 |
+
|
943 |
+
/**
|
944 |
+
* Load minified inline version of load WebP script.
|
945 |
+
*/
|
946 |
+
function inline_load_script() {
|
947 |
+
if ( defined( 'EWWW_IMAGE_OPTIMIZER_NO_JS' ) && EWWW_IMAGE_OPTIMIZER_NO_JS ) {
|
948 |
+
return;
|
949 |
+
}
|
950 |
+
if ( $this->is_amp() ) {
|
951 |
+
return;
|
952 |
+
}
|
953 |
+
$this->debug_message( 'inlining load webp script' );
|
954 |
+
echo '<script data-cfasync="false" type="text/javascript">' . $this->load_webp_script . '</script>'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
955 |
+
}
|
956 |
+
}
|
957 |
+
|
958 |
+
global $eio_js_webp;
|
959 |
+
$eio_js_webp = new EIO_JS_Webp();
|
classes/class-eio-lazy-load.php
CHANGED
@@ -285,6 +285,16 @@ if ( ! class_exists( 'EIO_Lazy_Load' ) ) {
|
|
285 |
return $buffer;
|
286 |
}
|
287 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
288 |
$above_the_fold = apply_filters( 'eio_lazy_fold', 0 );
|
289 |
$images_processed = 0;
|
290 |
|
@@ -360,8 +370,6 @@ if ( ! class_exists( 'EIO_Lazy_Load' ) ) {
|
|
360 |
$lazy_source = $source;
|
361 |
$this->set_attribute( $lazy_source, 'data-srcset', $srcset );
|
362 |
$this->remove_attribute( $lazy_source, 'srcset' );
|
363 |
-
// TODO: remove this after testing.
|
364 |
-
/* $this->set_attribute( $lazy_source, 'srcset', $this->placeholder_src, true ); */
|
365 |
$picture = str_replace( $source, $lazy_source, $picture );
|
366 |
}
|
367 |
}
|
@@ -372,21 +380,23 @@ if ( ! class_exists( 'EIO_Lazy_Load' ) ) {
|
|
372 |
}
|
373 |
}
|
374 |
}
|
375 |
-
//
|
376 |
-
|
377 |
-
|
378 |
-
|
379 |
-
|
380 |
-
|
381 |
-
|
382 |
-
|
383 |
-
|
384 |
-
|
385 |
-
|
386 |
-
|
387 |
-
|
388 |
-
|
389 |
-
|
|
|
|
|
390 |
}
|
391 |
}
|
392 |
}
|
@@ -440,19 +450,27 @@ if ( ! class_exists( 'EIO_Lazy_Load' ) ) {
|
|
440 |
$insert_dimensions = false;
|
441 |
if ( apply_filters( 'eio_add_missing_width_height_attrs', $this->get_option( $this->prefix . 'add_missing_dims' ) ) && ( empty( $width_attr ) || empty( $height_attr ) ) ) {
|
442 |
$this->debug_message( 'missing width attr or height attr' );
|
443 |
-
list( $
|
444 |
-
if ( $
|
445 |
-
$this->debug_message( "found $width_attr and $height_attr to insert" );
|
446 |
-
$
|
447 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
448 |
$insert_dimensions = true;
|
449 |
}
|
450 |
}
|
451 |
-
|
452 |
-
$
|
453 |
-
if ( defined( 'EIO_ENABLE_NATIVE_LAZY' ) && EIO_ENABLE_NATIVE_LAZY && ! $loading_attr && is_numeric( $width_attr ) && is_numeric( $height_attr ) ) {
|
454 |
-
$this->set_attribute( $image, 'loading', 'lazy' );
|
455 |
-
}
|
456 |
|
457 |
$placeholder_types = array();
|
458 |
if ( $this->parsing_exactdn && $this->allow_lqip && apply_filters( 'eio_use_lqip', $this->get_option( $this->prefix . 'use_lqip' ), $file ) ) {
|
@@ -485,6 +503,7 @@ if ( ! class_exists( 'EIO_Lazy_Load' ) ) {
|
|
485 |
$this->debug_message( 'using lqip, maybe' );
|
486 |
if ( false === strpos( $file, 'nggid' ) && ! preg_match( '#\.svg(\?|$)#', $file ) && strpos( $file, $this->exactdn_domain ) ) {
|
487 |
$placeholder_src = add_query_arg( array( 'lazy' => 1 ), $file );
|
|
|
488 |
break 2;
|
489 |
}
|
490 |
break;
|
@@ -513,9 +532,11 @@ if ( ! class_exists( 'EIO_Lazy_Load' ) ) {
|
|
513 |
|
514 |
if ( $filename_width && $filename_height ) {
|
515 |
$placeholder_src = $exactdn->generate_url( $this->content_url . 'lazy/placeholder-' . $filename_width . 'x' . $filename_height . '.png' );
|
|
|
516 |
break 2;
|
517 |
} else {
|
518 |
$placeholder_src = add_query_arg( array( 'lazy' => 2 ), $file );
|
|
|
519 |
break 2;
|
520 |
}
|
521 |
}
|
@@ -536,6 +557,7 @@ if ( ! class_exists( 'EIO_Lazy_Load' ) ) {
|
|
536 |
$png_placeholder_src = $this->create_piip( $filename_width, $filename_height );
|
537 |
if ( $png_placeholder_src ) {
|
538 |
$placeholder_src = $png_placeholder_src;
|
|
|
539 |
break 2;
|
540 |
}
|
541 |
}
|
@@ -547,6 +569,13 @@ if ( ! class_exists( 'EIO_Lazy_Load' ) ) {
|
|
547 |
$this->debug_message( "current placeholder is $placeholder_src" );
|
548 |
|
549 |
$placeholder_src = apply_filters( 'eio_lazy_placeholder', $placeholder_src, $image );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
550 |
if ( $srcset ) {
|
551 |
if ( strpos( $placeholder_src, '64,R0lGOD' ) ) {
|
552 |
$this->set_attribute( $image, 'srcset', $placeholder_src, true );
|
@@ -571,13 +600,14 @@ if ( ! class_exists( 'EIO_Lazy_Load' ) ) {
|
|
571 |
$this->set_attribute( $image, 'src', $placeholder_src, true );
|
572 |
}
|
573 |
|
574 |
-
$existing_class =
|
575 |
if ( ! empty( $existing_class ) ) {
|
576 |
-
$this->set_attribute( $image, 'class', $existing_class . ' lazyload', true );
|
577 |
} else {
|
578 |
$this->set_attribute( $image, 'class', 'lazyload', true );
|
579 |
}
|
580 |
if ( $insert_dimensions ) {
|
|
|
581 |
$this->set_attribute( $image, 'width', $width_attr, true );
|
582 |
$this->set_attribute( $image, 'height', $height_attr, true );
|
583 |
}
|
@@ -585,6 +615,8 @@ if ( ! class_exists( 'EIO_Lazy_Load' ) ) {
|
|
585 |
$this->set_attribute( $image, 'data-eio-rwidth', $physical_width, true );
|
586 |
$this->set_attribute( $image, 'data-eio-rheight', $physical_height, true );
|
587 |
}
|
|
|
|
|
588 |
return $image;
|
589 |
}
|
590 |
|
@@ -827,6 +859,34 @@ if ( ! class_exists( 'EIO_Lazy_Load' ) ) {
|
|
827 |
return true;
|
828 |
}
|
829 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
830 |
/**
|
831 |
* Build a PNG inline image placeholder.
|
832 |
*
|
285 |
return $buffer;
|
286 |
}
|
287 |
|
288 |
+
// If JS WebP isn't running, set ewww_webp_supported to false so we have something defined.
|
289 |
+
if ( ! class_exists( 'EIO_JS_Webp' ) ) {
|
290 |
+
$body_tags = $this->get_elements_from_html( $buffer, 'body' );
|
291 |
+
if ( $this->is_iterable( $body_tags ) && ! empty( $body_tags[0] ) && false !== strpos( $body_tags[0], '<body' ) ) {
|
292 |
+
$body_webp_script = '<script>var ewww_webp_supported=false;</script>';
|
293 |
+
// Add the WebP script right after the opening tag.
|
294 |
+
$buffer = str_replace( $body_tags[0], $body_tags[0] . "\n" . $body_webp_script, $buffer );
|
295 |
+
}
|
296 |
+
}
|
297 |
+
|
298 |
$above_the_fold = apply_filters( 'eio_lazy_fold', 0 );
|
299 |
$images_processed = 0;
|
300 |
|
370 |
$lazy_source = $source;
|
371 |
$this->set_attribute( $lazy_source, 'data-srcset', $srcset );
|
372 |
$this->remove_attribute( $lazy_source, 'srcset' );
|
|
|
|
|
373 |
$picture = str_replace( $source, $lazy_source, $picture );
|
374 |
}
|
375 |
}
|
380 |
}
|
381 |
}
|
382 |
}
|
383 |
+
// Iframe elements, looking for stuff like YouTube embeds.
|
384 |
+
if ( in_array( 'iframe', $this->user_element_exclusions, true ) ) {
|
385 |
+
$frames = '';
|
386 |
+
} else {
|
387 |
+
$frames = $this->get_elements_from_html( $buffer, 'iframe' );
|
388 |
+
}
|
389 |
+
if ( $this->is_iterable( $frames ) ) {
|
390 |
+
foreach ( $frames as $index => $frame ) {
|
391 |
+
$this->debug_message( 'parsing an iframe element' );
|
392 |
+
$url = $this->get_attribute( $frame, 'src' );
|
393 |
+
if ( $url && $this->validate_iframe_tag( $frame ) ) {
|
394 |
+
$this->debug_message( "lazifying iframe for: $url" );
|
395 |
+
$this->set_attribute( $frame, 'data-src', $url );
|
396 |
+
$this->remove_attribute( $frame, 'src' );
|
397 |
+
$this->set_attribute( $frame, 'class', trim( $this->get_attribute( $frame, 'class' ) . ' lazyload' ), true );
|
398 |
+
if ( $frame !== $frames[ $index ] ) {
|
399 |
+
$buffer = str_replace( $frames[ $index ], $frame, $buffer );
|
400 |
}
|
401 |
}
|
402 |
}
|
450 |
$insert_dimensions = false;
|
451 |
if ( apply_filters( 'eio_add_missing_width_height_attrs', $this->get_option( $this->prefix . 'add_missing_dims' ) ) && ( empty( $width_attr ) || empty( $height_attr ) ) ) {
|
452 |
$this->debug_message( 'missing width attr or height attr' );
|
453 |
+
list( $new_width_attr, $new_height_attr ) = $this->get_image_dimensions_by_url( $file );
|
454 |
+
if ( $new_width_attr && is_numeric( $new_width_attr ) && $new_height_attr && is_numeric( $new_height_attr ) ) {
|
455 |
+
$this->debug_message( "found $width_attr and $height_attr to insert (maybe)" );
|
456 |
+
if ( $width_attr && is_numeric( $width_attr ) && $width_attr < $new_width_attr ) { // Then $height_attr is empty...
|
457 |
+
$height_attr = round( ( $new_height_attr / $new_width_attr ) * $width_attr );
|
458 |
+
$this->debug_message( "width was set to $width_attr, height was empty, but now $height_attr" );
|
459 |
+
} elseif ( $height_attr && is_numeric( $height_attr ) && $height_attr < $new_height_attr ) { // Or $width_attr is empty...
|
460 |
+
$width_attr = round( ( $new_width_attr / $new_height_attr ) * $height_attr );
|
461 |
+
$this->debug_message( "height was set to $height_attr, width was empty, but now $width_attr" );
|
462 |
+
} else {
|
463 |
+
$width_attr = $new_width_attr;
|
464 |
+
$height_attr = $new_height_attr;
|
465 |
+
$this->debug_message( 'both width and height were empty, filling for sure' );
|
466 |
+
}
|
467 |
+
$physical_width = $new_width_attr;
|
468 |
+
$physical_height = $new_height_attr;
|
469 |
$insert_dimensions = true;
|
470 |
}
|
471 |
}
|
472 |
+
|
473 |
+
$use_native_lazy = false;
|
|
|
|
|
|
|
474 |
|
475 |
$placeholder_types = array();
|
476 |
if ( $this->parsing_exactdn && $this->allow_lqip && apply_filters( 'eio_use_lqip', $this->get_option( $this->prefix . 'use_lqip' ), $file ) ) {
|
503 |
$this->debug_message( 'using lqip, maybe' );
|
504 |
if ( false === strpos( $file, 'nggid' ) && ! preg_match( '#\.svg(\?|$)#', $file ) && strpos( $file, $this->exactdn_domain ) ) {
|
505 |
$placeholder_src = add_query_arg( array( 'lazy' => 1 ), $file );
|
506 |
+
$use_native_lazy = true;
|
507 |
break 2;
|
508 |
}
|
509 |
break;
|
532 |
|
533 |
if ( $filename_width && $filename_height ) {
|
534 |
$placeholder_src = $exactdn->generate_url( $this->content_url . 'lazy/placeholder-' . $filename_width . 'x' . $filename_height . '.png' );
|
535 |
+
$use_native_lazy = true;
|
536 |
break 2;
|
537 |
} else {
|
538 |
$placeholder_src = add_query_arg( array( 'lazy' => 2 ), $file );
|
539 |
+
$use_native_lazy = true;
|
540 |
break 2;
|
541 |
}
|
542 |
}
|
557 |
$png_placeholder_src = $this->create_piip( $filename_width, $filename_height );
|
558 |
if ( $png_placeholder_src ) {
|
559 |
$placeholder_src = $png_placeholder_src;
|
560 |
+
$use_native_lazy = true;
|
561 |
break 2;
|
562 |
}
|
563 |
}
|
569 |
$this->debug_message( "current placeholder is $placeholder_src" );
|
570 |
|
571 |
$placeholder_src = apply_filters( 'eio_lazy_placeholder', $placeholder_src, $image );
|
572 |
+
|
573 |
+
// Check for native lazy loading images.
|
574 |
+
$loading_attr = $this->get_attribute( $image, 'loading' );
|
575 |
+
if ( ( ! defined( 'EIO_DISABLE_NATIVE_LAZY' ) || ! EIO_DISABLE_NATIVE_LAZY ) && ! $loading_attr && $use_native_lazy ) {
|
576 |
+
$this->set_attribute( $image, 'loading', 'lazy' );
|
577 |
+
}
|
578 |
+
|
579 |
if ( $srcset ) {
|
580 |
if ( strpos( $placeholder_src, '64,R0lGOD' ) ) {
|
581 |
$this->set_attribute( $image, 'srcset', $placeholder_src, true );
|
600 |
$this->set_attribute( $image, 'src', $placeholder_src, true );
|
601 |
}
|
602 |
|
603 |
+
$existing_class = $this->get_attribute( $image, 'class' );
|
604 |
if ( ! empty( $existing_class ) ) {
|
605 |
+
$this->set_attribute( $image, 'class', trim( $existing_class . ' lazyload' ), true );
|
606 |
} else {
|
607 |
$this->set_attribute( $image, 'class', 'lazyload', true );
|
608 |
}
|
609 |
if ( $insert_dimensions ) {
|
610 |
+
$this->debug_message( "setting width=$width_attr and height=$height_attr" );
|
611 |
$this->set_attribute( $image, 'width', $width_attr, true );
|
612 |
$this->set_attribute( $image, 'height', $height_attr, true );
|
613 |
}
|
615 |
$this->set_attribute( $image, 'data-eio-rwidth', $physical_width, true );
|
616 |
$this->set_attribute( $image, 'data-eio-rheight', $physical_height, true );
|
617 |
}
|
618 |
+
$this->debug_message( 'lazified img element:' );
|
619 |
+
$this->debug_message( trim( $image ) );
|
620 |
return $image;
|
621 |
}
|
622 |
|
859 |
return true;
|
860 |
}
|
861 |
|
862 |
+
/**
|
863 |
+
* Checks if an iframe tag is allowed to be lazy loaded.
|
864 |
+
*
|
865 |
+
* @param string $tag The tag.
|
866 |
+
* @return bool True if the tag is allowed, false otherwise.
|
867 |
+
*/
|
868 |
+
function validate_iframe_tag( $tag ) {
|
869 |
+
$this->debug_message( '<b>' . __METHOD__ . '()</b>' );
|
870 |
+
$exclusions = apply_filters(
|
871 |
+
'eio_lazy_iframe_exclusions',
|
872 |
+
array_merge(
|
873 |
+
array(
|
874 |
+
'data-no-lazy=',
|
875 |
+
'lazyload',
|
876 |
+
'skip-lazy',
|
877 |
+
),
|
878 |
+
$this->user_exclusions
|
879 |
+
),
|
880 |
+
$tag
|
881 |
+
);
|
882 |
+
foreach ( $exclusions as $exclusion ) {
|
883 |
+
if ( false !== strpos( $tag, $exclusion ) ) {
|
884 |
+
return false;
|
885 |
+
}
|
886 |
+
}
|
887 |
+
return true;
|
888 |
+
}
|
889 |
+
|
890 |
/**
|
891 |
* Build a PNG inline image placeholder.
|
892 |
*
|
classes/class-eio-page-parser.php
CHANGED
@@ -29,6 +29,7 @@ if ( ! class_exists( 'EIO_Page_Parser' ) ) {
|
|
29 |
'jpe',
|
30 |
'png',
|
31 |
'svg',
|
|
|
32 |
);
|
33 |
|
34 |
/**
|
@@ -53,7 +54,7 @@ if ( ! class_exists( 'EIO_Page_Parser' ) ) {
|
|
53 |
if ( $hyperlinks ) {
|
54 |
$this->debug_message( 'using figure+hyperlink(a) patterns with src required' );
|
55 |
$search_pattern = '#(?:<figure[^>]*?\s+?class\s*=\s*["\'](?P<figure_class>[\w\s-]+?)["\'][^>]*?>\s*)?(?:<a[^>]*?\s+?href\s*=\s*["\'](?P<link_url>[^\s]+?)["\'][^>]*?>\s*)?(?P<img_tag><img[^>]*?\s+?src\s*=\s*("|\')(?P<img_url>(?!\4).+?)\4[^>]*?>){1}(?:\s*</a>)?#is';
|
56 |
-
$unquoted_pattern = '#(?:<figure[^>]*?\s+?class\s*=\s*(?P<figure_class>[\w-]+)[^>]*?>\s*)?(?:<a[^>]*?\s+?href\s*=\s*(?P<link_url>[^"\'
|
57 |
} elseif ( $src_required ) {
|
58 |
$this->debug_message( 'using plain img pattern, src still required' );
|
59 |
$search_pattern = '#(?P<img_tag><img[^>]*?\s+?src\s*=\s*("|\')(?P<img_url>(?!\2).+?)\2[^>]*?>)#is';
|
@@ -231,7 +232,7 @@ if ( ! class_exists( 'EIO_Page_Parser' ) ) {
|
|
231 |
$this->debug_message( '<b>' . __METHOD__ . '()</b>' );
|
232 |
$this->debug_message( "getting dimensions for $url" );
|
233 |
|
234 |
-
list( $width, $height ) = $this->get_dimensions_from_filename( $url );
|
235 |
if ( empty( $width ) || empty( $height ) ) {
|
236 |
// Couldn't get it from the URL directly, see if we can get the actual filename.
|
237 |
$file = false;
|
@@ -362,7 +363,7 @@ if ( ! class_exists( 'EIO_Page_Parser' ) ) {
|
|
362 |
$value = trim( $value );
|
363 |
if ( $replace ) {
|
364 |
// Don't forget, back references cannot be used in character classes.
|
365 |
-
$new_element = preg_replace( '#\s' . $name . '\s*=\s*("|\')(?!\1).*?\1#is',
|
366 |
if ( strpos( $new_element, "$name=" ) && $new_element !== $element ) {
|
367 |
$element = $new_element;
|
368 |
return;
|
29 |
'jpe',
|
30 |
'png',
|
31 |
'svg',
|
32 |
+
'webp',
|
33 |
);
|
34 |
|
35 |
/**
|
54 |
if ( $hyperlinks ) {
|
55 |
$this->debug_message( 'using figure+hyperlink(a) patterns with src required' );
|
56 |
$search_pattern = '#(?:<figure[^>]*?\s+?class\s*=\s*["\'](?P<figure_class>[\w\s-]+?)["\'][^>]*?>\s*)?(?:<a[^>]*?\s+?href\s*=\s*["\'](?P<link_url>[^\s]+?)["\'][^>]*?>\s*)?(?P<img_tag><img[^>]*?\s+?src\s*=\s*("|\')(?P<img_url>(?!\4).+?)\4[^>]*?>){1}(?:\s*</a>)?#is';
|
57 |
+
$unquoted_pattern = '#(?:<figure[^>]*?\s+?class\s*=\s*(?P<figure_class>[\w-]+)[^>]*?>\s*)?(?:<a[^>]*?\s+?href\s*=\s*(?P<link_url>[^"\'\\\\<>][^\s<>]+)[^>]*?>\s*)?(?P<img_tag><img[^>]*?\s+?src\s*=\s*(?P<img_url>[^"\'\\\\<>][^\s<>]+)[^>]*?>){1}(?:\s*</a>)?#is';
|
58 |
} elseif ( $src_required ) {
|
59 |
$this->debug_message( 'using plain img pattern, src still required' );
|
60 |
$search_pattern = '#(?P<img_tag><img[^>]*?\s+?src\s*=\s*("|\')(?P<img_url>(?!\2).+?)\2[^>]*?>)#is';
|
232 |
$this->debug_message( '<b>' . __METHOD__ . '()</b>' );
|
233 |
$this->debug_message( "getting dimensions for $url" );
|
234 |
|
235 |
+
list( $width, $height ) = $this->get_dimensions_from_filename( $url, ! empty( $this->parsing_exactdn ) );
|
236 |
if ( empty( $width ) || empty( $height ) ) {
|
237 |
// Couldn't get it from the URL directly, see if we can get the actual filename.
|
238 |
$file = false;
|
363 |
$value = trim( $value );
|
364 |
if ( $replace ) {
|
365 |
// Don't forget, back references cannot be used in character classes.
|
366 |
+
$new_element = preg_replace( '#\s' . $name . '\s*=\s*("|\')(?!\1).*?\1#is', ' ' . $name . '=${1}' . $value . '${1}', $element );
|
367 |
if ( strpos( $new_element, "$name=" ) && $new_element !== $element ) {
|
368 |
$element = $new_element;
|
369 |
return;
|
classes/class-ewww-flag.php
CHANGED
@@ -299,7 +299,7 @@ if ( ! class_exists( 'EWWW_Flag' ) ) {
|
|
299 |
// Store the IDs to optimize in the options table of the db.
|
300 |
update_option( 'ewww_image_optimizer_bulk_flag_attachments', $ids );
|
301 |
// Add the EWWW IO javascript.
|
302 |
-
wp_enqueue_script( 'ewwwbulkscript', plugins_url( '/includes/eio.js', EWWW_IMAGE_OPTIMIZER_PLUGIN_FILE ), array( 'jquery', 'jquery-ui-progressbar', 'jquery-ui-slider', 'postbox', 'dashboard' ), EWWW_IMAGE_OPTIMIZER_VERSION );
|
303 |
// Add the styling for the progressbar.
|
304 |
wp_enqueue_style( 'jquery-ui-progressbar', plugins_url( '/includes/jquery-ui-1.10.1.custom.css', EWWW_IMAGE_OPTIMIZER_PLUGIN_FILE ) );
|
305 |
// Prepare a few variables to be used by the javascript code.
|
299 |
// Store the IDs to optimize in the options table of the db.
|
300 |
update_option( 'ewww_image_optimizer_bulk_flag_attachments', $ids );
|
301 |
// Add the EWWW IO javascript.
|
302 |
+
wp_enqueue_script( 'ewwwbulkscript', plugins_url( '/includes/eio-bulk.js', EWWW_IMAGE_OPTIMIZER_PLUGIN_FILE ), array( 'jquery', 'jquery-ui-progressbar', 'jquery-ui-slider', 'postbox', 'dashboard' ), EWWW_IMAGE_OPTIMIZER_VERSION );
|
303 |
// Add the styling for the progressbar.
|
304 |
wp_enqueue_style( 'jquery-ui-progressbar', plugins_url( '/includes/jquery-ui-1.10.1.custom.css', EWWW_IMAGE_OPTIMIZER_PLUGIN_FILE ) );
|
305 |
// Prepare a few variables to be used by the javascript code.
|
classes/class-ewww-nextcellent.php
CHANGED
@@ -506,7 +506,7 @@ if ( ! class_exists( 'EWWW_Nextcellent' ) ) {
|
|
506 |
// Store the image IDs to process in the db.
|
507 |
update_option( 'ewww_image_optimizer_bulk_ngg_attachments', $images, false );
|
508 |
// Add the EWWW IO script.
|
509 |
-
wp_enqueue_script( 'ewwwbulkscript', plugins_url( '/includes/eio.js', EWWW_IMAGE_OPTIMIZER_PLUGIN_FILE ), array( 'jquery', 'jquery-ui-progressbar', 'jquery-ui-slider', 'postbox', 'dashboard' ), EWWW_IMAGE_OPTIMIZER_VERSION );
|
510 |
// Replacing the built-in nextgen styling rules for progressbar.
|
511 |
wp_register_style( 'ngg-jqueryui', plugins_url( '/includes/jquery-ui-1.10.1.custom.css', EWWW_IMAGE_OPTIMIZER_PLUGIN_FILE ) );
|
512 |
// Enqueue the progressbar styling.
|
506 |
// Store the image IDs to process in the db.
|
507 |
update_option( 'ewww_image_optimizer_bulk_ngg_attachments', $images, false );
|
508 |
// Add the EWWW IO script.
|
509 |
+
wp_enqueue_script( 'ewwwbulkscript', plugins_url( '/includes/eio-bulk.js', EWWW_IMAGE_OPTIMIZER_PLUGIN_FILE ), array( 'jquery', 'jquery-ui-progressbar', 'jquery-ui-slider', 'postbox', 'dashboard' ), EWWW_IMAGE_OPTIMIZER_VERSION );
|
510 |
// Replacing the built-in nextgen styling rules for progressbar.
|
511 |
wp_register_style( 'ngg-jqueryui', plugins_url( '/includes/jquery-ui-1.10.1.custom.css', EWWW_IMAGE_OPTIMIZER_PLUGIN_FILE ) );
|
512 |
// Enqueue the progressbar styling.
|
classes/class-ewww-nextgen.php
CHANGED
@@ -229,6 +229,7 @@ if ( ! class_exists( 'EWWW_Nextgen' ) ) {
|
|
229 |
* @param object $size The name of the size generated.
|
230 |
*/
|
231 |
function ewww_ngg_generated_image( $image, $size ) {
|
|
|
232 |
global $ewww_image;
|
233 |
// Creating the 'registry' object for working with nextgen.
|
234 |
$registry = C_Component_Registry::get_instance();
|
@@ -250,6 +251,7 @@ if ( ! class_exists( 'EWWW_Nextgen' ) ) {
|
|
250 |
* Manually process an image from the NextGEN Gallery.
|
251 |
*/
|
252 |
function ewww_ngg_manual() {
|
|
|
253 |
// Check permission of current user.
|
254 |
$permissions = apply_filters( 'ewww_image_optimizer_manual_permissions', '' );
|
255 |
if ( false === current_user_can( $permissions ) ) {
|
@@ -319,6 +321,7 @@ if ( ! class_exists( 'EWWW_Nextgen' ) ) {
|
|
319 |
* Restore an image from the NextGEN Gallery.
|
320 |
*/
|
321 |
function ewww_ngg_cloud_restore() {
|
|
|
322 |
// Check permission of current user.
|
323 |
$permissions = apply_filters( 'ewww_image_optimizer_manual_permissions', '' );
|
324 |
if ( false === current_user_can( $permissions ) ) {
|
@@ -629,8 +632,15 @@ if ( ! class_exists( 'EWWW_Nextgen' ) ) {
|
|
629 |
*/
|
630 |
function ewww_ngg_bulk_preview() {
|
631 |
if ( ! empty( $_REQUEST['doaction'] ) ) {
|
632 |
-
if (
|
633 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
634 |
}
|
635 |
// If there is no requested bulk action, do nothing.
|
636 |
if ( empty( $_REQUEST['bulkaction'] ) ) {
|
@@ -653,7 +663,7 @@ if ( ! class_exists( 'EWWW_Nextgen' ) ) {
|
|
653 |
<?php
|
654 |
if ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_cloud_key' ) ) {
|
655 |
ewww_image_optimizer_cloud_verify( ewww_image_optimizer_get_option( 'ewww_image_optimizer_cloud_key' ) );
|
656 |
-
echo '<
|
657 |
}
|
658 |
echo '<div id="ewww-bulk-warning" class="ewww-bulk-info notice notice-warning"><p>' . esc_html__( 'Bulk Optimization will alter your original images and cannot be undone. Please be sure you have a backup of your images before proceeding.', 'ewww-image-optimizer' ) . '</p></div>';
|
659 |
// Retrieve the value of the 'bulk resume' option and set the button text for the form to use.
|
@@ -824,7 +834,7 @@ if ( ! class_exists( 'EWWW_Nextgen' ) ) {
|
|
824 |
// Store the image IDs to process in the db.
|
825 |
update_option( 'ewww_image_optimizer_bulk_ngg_attachments', $images, false );
|
826 |
// Add the EWWW IO script.
|
827 |
-
wp_enqueue_script( 'ewwwbulkscript', plugins_url( '/includes/eio.js', EWWW_IMAGE_OPTIMIZER_PLUGIN_FILE ), array( 'jquery', 'jquery-ui-progressbar', 'jquery-ui-slider', 'postbox', 'dashboard' ), EWWW_IMAGE_OPTIMIZER_VERSION );
|
828 |
// Replacing the built-in nextgen styling rules for progressbar, partially because the bulk optimize page doesn't work without them.
|
829 |
wp_deregister_style( 'ngg-jqueryui' );
|
830 |
wp_deregister_style( 'ngg-jquery-ui' );
|
@@ -1037,7 +1047,14 @@ if ( ! class_exists( 'EWWW_Nextgen' ) ) {
|
|
1037 |
*/
|
1038 |
function ewww_ngg_bulk_action_handler() {
|
1039 |
ewwwio_debug_message( '<b>' . __METHOD__ . '()</b>' );
|
1040 |
-
if (
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1041 |
return;
|
1042 |
}
|
1043 |
// If the requested page is blank, or not a bulk_optimize, do nothing.
|
@@ -1064,7 +1081,7 @@ if ( ! class_exists( 'EWWW_Nextgen' ) ) {
|
|
1064 |
'_wpnonce' => sanitize_key( $_REQUEST['_wpnonce'] ),
|
1065 |
'bulk_type' => $type,
|
1066 |
'bulkaction' => 'bulk_optimize',
|
1067 |
-
'doaction' =>
|
1068 |
),
|
1069 |
admin_url( 'admin.php' )
|
1070 |
)
|
229 |
* @param object $size The name of the size generated.
|
230 |
*/
|
231 |
function ewww_ngg_generated_image( $image, $size ) {
|
232 |
+
ewwwio_debug_message( '<b>' . __METHOD__ . '()</b>' );
|
233 |
global $ewww_image;
|
234 |
// Creating the 'registry' object for working with nextgen.
|
235 |
$registry = C_Component_Registry::get_instance();
|
251 |
* Manually process an image from the NextGEN Gallery.
|
252 |
*/
|
253 |
function ewww_ngg_manual() {
|
254 |
+
ewwwio_debug_message( '<b>' . __METHOD__ . '()</b>' );
|
255 |
// Check permission of current user.
|
256 |
$permissions = apply_filters( 'ewww_image_optimizer_manual_permissions', '' );
|
257 |
if ( false === current_user_can( $permissions ) ) {
|
321 |
* Restore an image from the NextGEN Gallery.
|
322 |
*/
|
323 |
function ewww_ngg_cloud_restore() {
|
324 |
+
ewwwio_debug_message( '<b>' . __METHOD__ . '()</b>' );
|
325 |
// Check permission of current user.
|
326 |
$permissions = apply_filters( 'ewww_image_optimizer_manual_permissions', '' );
|
327 |
if ( false === current_user_can( $permissions ) ) {
|
632 |
*/
|
633 |
function ewww_ngg_bulk_preview() {
|
634 |
if ( ! empty( $_REQUEST['doaction'] ) ) {
|
635 |
+
if (
|
636 |
+
empty( $_REQUEST['_wpnonce'] ) ||
|
637 |
+
(
|
638 |
+
! wp_verify_nonce( sanitize_key( $_REQUEST['_wpnonce'] ), 'ngg_bulkgallery' ) &&
|
639 |
+
! wp_verify_nonce( sanitize_key( $_REQUEST['_wpnonce'] ), 'ngg_updategallery' )
|
640 |
+
)
|
641 |
+
) {
|
642 |
+
ewwwio_debug_message( 'nonce verify failed' );
|
643 |
+
return;
|
644 |
}
|
645 |
// If there is no requested bulk action, do nothing.
|
646 |
if ( empty( $_REQUEST['bulkaction'] ) ) {
|
663 |
<?php
|
664 |
if ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_cloud_key' ) ) {
|
665 |
ewww_image_optimizer_cloud_verify( ewww_image_optimizer_get_option( 'ewww_image_optimizer_cloud_key' ) );
|
666 |
+
echo '<span id="ewww-bulk-credits-available">' . esc_html__( 'Image credits available:', 'ewww-image-optimizer' ) . ' ' . wp_kses_post( ewww_image_optimizer_cloud_quota() ) . '</span>';
|
667 |
}
|
668 |
echo '<div id="ewww-bulk-warning" class="ewww-bulk-info notice notice-warning"><p>' . esc_html__( 'Bulk Optimization will alter your original images and cannot be undone. Please be sure you have a backup of your images before proceeding.', 'ewww-image-optimizer' ) . '</p></div>';
|
669 |
// Retrieve the value of the 'bulk resume' option and set the button text for the form to use.
|
834 |
// Store the image IDs to process in the db.
|
835 |
update_option( 'ewww_image_optimizer_bulk_ngg_attachments', $images, false );
|
836 |
// Add the EWWW IO script.
|
837 |
+
wp_enqueue_script( 'ewwwbulkscript', plugins_url( '/includes/eio-bulk.js', EWWW_IMAGE_OPTIMIZER_PLUGIN_FILE ), array( 'jquery', 'jquery-ui-progressbar', 'jquery-ui-slider', 'postbox', 'dashboard' ), EWWW_IMAGE_OPTIMIZER_VERSION );
|
838 |
// Replacing the built-in nextgen styling rules for progressbar, partially because the bulk optimize page doesn't work without them.
|
839 |
wp_deregister_style( 'ngg-jqueryui' );
|
840 |
wp_deregister_style( 'ngg-jquery-ui' );
|
1047 |
*/
|
1048 |
function ewww_ngg_bulk_action_handler() {
|
1049 |
ewwwio_debug_message( '<b>' . __METHOD__ . '()</b>' );
|
1050 |
+
if (
|
1051 |
+
empty( $_REQUEST['_wpnonce'] ) ||
|
1052 |
+
(
|
1053 |
+
! wp_verify_nonce( sanitize_key( $_REQUEST['_wpnonce'] ), 'ngg_bulkgallery' ) &&
|
1054 |
+
! wp_verify_nonce( sanitize_key( $_REQUEST['_wpnonce'] ), 'ngg_updategallery' )
|
1055 |
+
)
|
1056 |
+
) {
|
1057 |
+
ewwwio_debug_message( 'nonce verify failed' );
|
1058 |
return;
|
1059 |
}
|
1060 |
// If the requested page is blank, or not a bulk_optimize, do nothing.
|
1081 |
'_wpnonce' => sanitize_key( $_REQUEST['_wpnonce'] ),
|
1082 |
'bulk_type' => $type,
|
1083 |
'bulkaction' => 'bulk_optimize',
|
1084 |
+
'doaction' => array_map( 'intval', wp_unslash( $_REQUEST['doaction'] ) ), // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
|
1085 |
),
|
1086 |
admin_url( 'admin.php' )
|
1087 |
)
|
classes/class-ewwwio-cli.php
CHANGED
@@ -32,17 +32,21 @@ class EWWWIO_CLI extends WP_CLI_Command {
|
|
32 |
*
|
33 |
* <force>
|
34 |
* : optional, should the plugin re-optimize images that have already been processed.
|
35 |
-
*
|
|
|
36 |
* : optional, start the optimizer back at the beginning instead of resuming from last position
|
37 |
*
|
|
|
|
|
|
|
38 |
* <noprompt>
|
39 |
* : do not prompt, just start optimizing
|
40 |
*
|
41 |
* ## EXAMPLES
|
42 |
*
|
43 |
-
* wp-cli ewwwio optimize media 5 --force --reset --noprompt
|
44 |
*
|
45 |
-
* @synopsis <library> [<delay>] [--force] [--reset] [--noprompt]
|
46 |
*
|
47 |
* @global bool $ewww_defer Gets set to false to make sure optimization happens inline.
|
48 |
*
|
@@ -52,6 +56,8 @@ class EWWWIO_CLI extends WP_CLI_Command {
|
|
52 |
function optimize( $args, $assoc_args ) {
|
53 |
global $ewww_defer;
|
54 |
$ewww_defer = false;
|
|
|
|
|
55 |
// because NextGEN hasn't flushed it's buffers...
|
56 |
while ( @ob_end_flush() ) {
|
57 |
}
|
@@ -71,6 +77,13 @@ class EWWWIO_CLI extends WP_CLI_Command {
|
|
71 |
global $ewww_force;
|
72 |
$ewww_force = 1;
|
73 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
74 |
/* translators: 1: type of images, like media, or nextgen 2: number of seconds */
|
75 |
WP_CLI::line( sprintf( _x( 'Optimizing %1$s with a %2$d second pause between images.', 'string will be something like "media" or "nextgen"', 'ewww-image-optimizer' ), $library, $delay ) );
|
76 |
// Let's get started, shall we?
|
32 |
*
|
33 |
* <force>
|
34 |
* : optional, should the plugin re-optimize images that have already been processed.
|
35 |
+
*
|
36 |
+
* <reset>
|
37 |
* : optional, start the optimizer back at the beginning instead of resuming from last position
|
38 |
*
|
39 |
+
* <webp-only>
|
40 |
+
* : optional, only do WebP Conversion, skip all other operations
|
41 |
+
*
|
42 |
* <noprompt>
|
43 |
* : do not prompt, just start optimizing
|
44 |
*
|
45 |
* ## EXAMPLES
|
46 |
*
|
47 |
+
* wp-cli ewwwio optimize media 5 --force --reset --webp-only --noprompt
|
48 |
*
|
49 |
+
* @synopsis <library> [<delay>] [--force] [--reset] [--webp-only] [--noprompt]
|
50 |
*
|
51 |
* @global bool $ewww_defer Gets set to false to make sure optimization happens inline.
|
52 |
*
|
56 |
function optimize( $args, $assoc_args ) {
|
57 |
global $ewww_defer;
|
58 |
$ewww_defer = false;
|
59 |
+
global $ewww_webp_only;
|
60 |
+
$ewww_webp_only = false;
|
61 |
// because NextGEN hasn't flushed it's buffers...
|
62 |
while ( @ob_end_flush() ) {
|
63 |
}
|
77 |
global $ewww_force;
|
78 |
$ewww_force = 1;
|
79 |
}
|
80 |
+
if ( ! empty( $assoc_args['webp-only'] ) ) {
|
81 |
+
if ( empty( ewww_image_optimizer_get_option( 'ewww_image_optimizer_webp' ) ) ) {
|
82 |
+
WP_CLI::error( __( 'WebP Conversion is not enabled.', 'ewww-image-optimizer' ) );
|
83 |
+
}
|
84 |
+
WP_CLI::line( __( 'Running WebP conversion only.', 'ewww-image-optimizer' ) );
|
85 |
+
$ewww_webp_only = true;
|
86 |
+
}
|
87 |
/* translators: 1: type of images, like media, or nextgen 2: number of seconds */
|
88 |
WP_CLI::line( sprintf( _x( 'Optimizing %1$s with a %2$d second pause between images.', 'string will be something like "media" or "nextgen"', 'ewww-image-optimizer' ), $library, $delay ) );
|
89 |
// Let's get started, shall we?
|
classes/class-ewwwio-gd-editor.php
CHANGED
@@ -240,7 +240,7 @@ if ( class_exists( 'Bbpp_Animated_Gif' ) ) {
|
|
240 |
|
241 |
$resized = $this->_resize( $max_w, $max_h, $crop );
|
242 |
|
243 |
-
if ( is_resource( $resized ) ) {
|
244 |
imagedestroy( $this->image );
|
245 |
$this->image = $resized;
|
246 |
return true;
|
@@ -359,7 +359,7 @@ if ( class_exists( 'Bbpp_Animated_Gif' ) ) {
|
|
359 |
$duplicate = ( (int) $orig_size['width'] === (int) $size_data['width'] && (int) $orig_size['height'] === (int) $size_data['height'] );
|
360 |
|
361 |
if ( ! is_wp_error( $image ) && ! $duplicate ) {
|
362 |
-
if ( is_resource( $image ) ) {
|
363 |
$resized = $this->_save( $image );
|
364 |
imagedestroy( $image );
|
365 |
} elseif ( is_string( $image ) ) {
|
240 |
|
241 |
$resized = $this->_resize( $max_w, $max_h, $crop );
|
242 |
|
243 |
+
if ( is_resource( $resized ) || ( is_object( $resized ) && $resized instanceof GdImage ) ) {
|
244 |
imagedestroy( $this->image );
|
245 |
$this->image = $resized;
|
246 |
return true;
|
359 |
$duplicate = ( (int) $orig_size['width'] === (int) $size_data['width'] && (int) $orig_size['height'] === (int) $size_data['height'] );
|
360 |
|
361 |
if ( ! is_wp_error( $image ) && ! $duplicate ) {
|
362 |
+
if ( is_resource( $image ) || ( is_object( $image ) && $image instanceof GdImage ) ) {
|
363 |
$resized = $this->_save( $image );
|
364 |
imagedestroy( $image );
|
365 |
} elseif ( is_string( $image ) ) {
|
classes/class-ewwwio-gmagick-editor.php
CHANGED
@@ -79,7 +79,6 @@ if ( class_exists( 'WP_Image_Editor_Gmagick' ) ) {
|
|
79 |
}
|
80 |
*/
|
81 |
}
|
82 |
-
ewww_image_optimizer_debug_log();
|
83 |
}
|
84 |
ewwwio_memory( __FUNCTION__ );
|
85 |
return $saved;
|
79 |
}
|
80 |
*/
|
81 |
}
|
|
|
82 |
}
|
83 |
ewwwio_memory( __FUNCTION__ );
|
84 |
return $saved;
|
classes/class-ewwwio-imagick-editor.php
CHANGED
@@ -181,7 +181,6 @@ if ( class_exists( 'WP_Thumb_Image_Editor_Imagick' ) ) {
|
|
181 |
$image_size = ewww_image_optimizer_filesize( $filename );
|
182 |
ewwwio_debug_message( "image editor size: $image_size" );
|
183 |
}
|
184 |
-
ewww_image_optimizer_debug_log();
|
185 |
}
|
186 |
ewwwio_memory( __FUNCTION__ );
|
187 |
return $saved;
|
181 |
$image_size = ewww_image_optimizer_filesize( $filename );
|
182 |
ewwwio_debug_message( "image editor size: $image_size" );
|
183 |
}
|
|
|
184 |
}
|
185 |
ewwwio_memory( __FUNCTION__ );
|
186 |
return $saved;
|
classes/class-exactdn.php
CHANGED
@@ -162,6 +162,8 @@ if ( ! class_exists( 'ExactDN' ) ) {
|
|
162 |
if ( ! $this->setup() ) {
|
163 |
return;
|
164 |
}
|
|
|
|
|
165 |
|
166 |
// Images in post content and galleries.
|
167 |
add_filter( 'the_content', array( $this, 'filter_the_content' ), 999999 );
|
@@ -274,9 +276,11 @@ if ( ! class_exists( 'ExactDN' ) ) {
|
|
274 |
$this->debug_message( '<b>' . __METHOD__ . '()</b>' );
|
275 |
// If we don't have a domain yet, go grab one.
|
276 |
$this->plan_id = $this->get_exactdn_option( 'plan_id' );
|
|
|
277 |
if ( ! $this->get_exactdn_domain() ) {
|
278 |
$this->debug_message( 'attempting to activate exactDN' );
|
279 |
$exactdn_domain = $this->activate_site();
|
|
|
280 |
} else {
|
281 |
$this->debug_message( 'grabbing existing exactDN domain' );
|
282 |
$exactdn_domain = $this->get_exactdn_domain();
|
@@ -284,11 +288,19 @@ if ( ! class_exists( 'ExactDN' ) ) {
|
|
284 |
if ( ! $exactdn_domain ) {
|
285 |
delete_option( $this->prefix . 'exactdn' );
|
286 |
delete_site_option( $this->prefix . 'exactdn' );
|
|
|
287 |
return false;
|
288 |
}
|
|
|
289 |
// If we have a domain, verify it.
|
290 |
-
if ( $
|
291 |
-
$this->
|
|
|
|
|
|
|
|
|
|
|
|
|
292 |
$this->exactdn_domain = $exactdn_domain;
|
293 |
$this->debug_message( 'exactdn_domain: ' . $exactdn_domain );
|
294 |
$this->debug_message( 'exactdn_plan_id: ' . $this->plan_id );
|
@@ -298,9 +310,47 @@ if ( ! class_exists( 'ExactDN' ) ) {
|
|
298 |
delete_option( $this->prefix . 'exactdn_verified' );
|
299 |
delete_site_option( $this->prefix . 'exactdn_domain' );
|
300 |
delete_site_option( $this->prefix . 'exactdn_verified' );
|
|
|
301 |
return false;
|
302 |
}
|
303 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
304 |
/**
|
305 |
* Use the Site URL to get the zone domain.
|
306 |
*/
|
@@ -384,6 +434,15 @@ if ( ! class_exists( 'ExactDN' ) ) {
|
|
384 |
return false;
|
385 |
}
|
386 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
387 |
/**
|
388 |
* Verify the ExactDN domain.
|
389 |
*
|
@@ -403,7 +462,7 @@ if ( ! class_exists( 'ExactDN' ) ) {
|
|
403 |
}
|
404 |
|
405 |
$this->check_verify_method();
|
406 |
-
$this->set_exactdn_option( 'checkin', time() +
|
407 |
|
408 |
// Set a default error.
|
409 |
global $exactdn_activate_error;
|
@@ -426,8 +485,9 @@ if ( ! class_exists( 'ExactDN' ) ) {
|
|
426 |
array(
|
427 |
'timeout' => 10,
|
428 |
'body' => array(
|
429 |
-
'alias'
|
430 |
-
'url'
|
|
|
431 |
),
|
432 |
)
|
433 |
);
|
@@ -472,7 +532,8 @@ if ( ! class_exists( 'ExactDN' ) ) {
|
|
472 |
array(
|
473 |
'timeout' => 10,
|
474 |
'body' => array(
|
475 |
-
'alias'
|
|
|
476 |
),
|
477 |
)
|
478 |
);
|
@@ -1180,8 +1241,26 @@ if ( ! class_exists( 'ExactDN' ) ) {
|
|
1180 |
$new_tag = $tag;
|
1181 |
|
1182 |
// If present, replace the link href with an ExactDN URL for the full-size image.
|
1183 |
-
if ( ! empty( $images['link_url'][ $index ] ) && $this->validate_image_url( $images['link_url'][ $index ] ) ) {
|
1184 |
-
$new_tag = preg_replace(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1185 |
}
|
1186 |
|
1187 |
// Insert new image src into the srcset as well, if we have a width.
|
@@ -1334,9 +1413,13 @@ if ( ! class_exists( 'ExactDN' ) ) {
|
|
1334 |
}
|
1335 |
} // End foreach().
|
1336 |
} // End if();
|
|
|
|
|
|
|
|
|
|
|
1337 |
$element_types = apply_filters( 'eio_allowed_background_image_elements', array( 'div', 'li', 'span', 'section', 'a' ) );
|
1338 |
foreach ( $element_types as $element_type ) {
|
1339 |
-
// Process background images on HTML elements.
|
1340 |
$content = $this->filter_bg_images( $content, $element_type );
|
1341 |
}
|
1342 |
if ( $this->filtering_the_page ) {
|
@@ -1365,6 +1448,83 @@ if ( ! class_exists( 'ExactDN' ) ) {
|
|
1365 |
return $content;
|
1366 |
}
|
1367 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1368 |
/**
|
1369 |
* Parse page content looking for elements with CSS background-image properties.
|
1370 |
*
|
@@ -1627,6 +1787,10 @@ if ( ! class_exists( 'ExactDN' ) ) {
|
|
1627 |
$started = microtime( true );
|
1628 |
$this->debug_message( '<b>' . __METHOD__ . '()</b>' );
|
1629 |
|
|
|
|
|
|
|
|
|
1630 |
// Don't foul up the admin side of things, unless a plugin wants to.
|
1631 |
if ( is_admin() &&
|
1632 |
/**
|
@@ -2658,9 +2822,21 @@ if ( ! class_exists( 'ExactDN' ) ) {
|
|
2658 |
* @return boolean True to skip the page, unchanged otherwise.
|
2659 |
*/
|
2660 |
function skip_page( $skip = false, $uri = '' ) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2661 |
if ( false !== strpos( $uri, 'ct_builder=' ) ) {
|
2662 |
return true;
|
2663 |
}
|
|
|
|
|
|
|
2664 |
if ( false !== strpos( $uri, '?fl_builder' ) ) {
|
2665 |
return true;
|
2666 |
}
|
@@ -2871,6 +3047,9 @@ if ( ! class_exists( 'ExactDN' ) ) {
|
|
2871 |
if ( $this->plan_id > 1 && false === strpos( $image_url, 'quality=' ) && 75 !== (int) $webp_quality && $webp_quality < $jpg_quality ) {
|
2872 |
$more_args['quality'] = $webp_quality;
|
2873 |
}
|
|
|
|
|
|
|
2874 |
// Merge given args with the automatic (option-based) args, and also makes sure args is an array if it was previously a string.
|
2875 |
$args = wp_parse_args( $args, $more_args );
|
2876 |
|
@@ -2978,7 +3157,7 @@ if ( ! class_exists( 'ExactDN' ) ) {
|
|
2978 |
}
|
2979 |
|
2980 |
// Clear out args for some files (like videos) that might go through image_downsize.
|
2981 |
-
if ( ! empty( $extension ) && in_array( $extension, array( 'mp4', 'm4p', 'm4v', 'mov', 'wvm', 'qt', '
|
2982 |
$args = array();
|
2983 |
}
|
2984 |
|
162 |
if ( ! $this->setup() ) {
|
163 |
return;
|
164 |
}
|
165 |
+
// Enables scheduled health checks via wp-cron.
|
166 |
+
add_action( 'easyio_verification_checkin', array( $this, 'health_check' ) );
|
167 |
|
168 |
// Images in post content and galleries.
|
169 |
add_filter( 'the_content', array( $this, 'filter_the_content' ), 999999 );
|
276 |
$this->debug_message( '<b>' . __METHOD__ . '()</b>' );
|
277 |
// If we don't have a domain yet, go grab one.
|
278 |
$this->plan_id = $this->get_exactdn_option( 'plan_id' );
|
279 |
+
$new_site = false;
|
280 |
if ( ! $this->get_exactdn_domain() ) {
|
281 |
$this->debug_message( 'attempting to activate exactDN' );
|
282 |
$exactdn_domain = $this->activate_site();
|
283 |
+
$new_site = true;
|
284 |
} else {
|
285 |
$this->debug_message( 'grabbing existing exactDN domain' );
|
286 |
$exactdn_domain = $this->get_exactdn_domain();
|
288 |
if ( ! $exactdn_domain ) {
|
289 |
delete_option( $this->prefix . 'exactdn' );
|
290 |
delete_site_option( $this->prefix . 'exactdn' );
|
291 |
+
$this->cron_setup( false );
|
292 |
return false;
|
293 |
}
|
294 |
+
$verified = true;
|
295 |
// If we have a domain, verify it.
|
296 |
+
if ( $new_site ) {
|
297 |
+
$verified = $this->verify_domain( $exactdn_domain );
|
298 |
+
if ( $verified ) {
|
299 |
+
// When this is a new site that is verified, setup health check.
|
300 |
+
$this->cron_setup();
|
301 |
+
}
|
302 |
+
}
|
303 |
+
if ( $verified ) {
|
304 |
$this->exactdn_domain = $exactdn_domain;
|
305 |
$this->debug_message( 'exactdn_domain: ' . $exactdn_domain );
|
306 |
$this->debug_message( 'exactdn_plan_id: ' . $this->plan_id );
|
310 |
delete_option( $this->prefix . 'exactdn_verified' );
|
311 |
delete_site_option( $this->prefix . 'exactdn_domain' );
|
312 |
delete_site_option( $this->prefix . 'exactdn_verified' );
|
313 |
+
$this->cron_setup( false );
|
314 |
return false;
|
315 |
}
|
316 |
|
317 |
+
/**
|
318 |
+
* Setup wp_cron tasks for scheduled verification.
|
319 |
+
*
|
320 |
+
* @global object $wpdb
|
321 |
+
*
|
322 |
+
* @param bool $schedule True to add event, false to remove/unschedule it.
|
323 |
+
*/
|
324 |
+
function cron_setup( $schedule = true ) {
|
325 |
+
$this->debug_message( '<b>' . __FUNCTION__ . '()</b>' );
|
326 |
+
$event = 'easyio_verification_checkin';
|
327 |
+
// Setup scheduled optimization if the user has enabled it, and it isn't already scheduled.
|
328 |
+
if ( $schedule && ! wp_next_scheduled( $event ) ) {
|
329 |
+
$this->debug_message( "scheduling $event" );
|
330 |
+
wp_schedule_event( time() + DAY_IN_SECONDS, apply_filters( 'easyio_verification_schedule', 'daily', $event ), $event );
|
331 |
+
} elseif ( $schedule ) {
|
332 |
+
$this->debug_message( "$event already scheduled: " . wp_next_scheduled( $event ) );
|
333 |
+
} elseif ( wp_next_scheduled( $event ) ) {
|
334 |
+
$this->debug_message( "un-scheduling $event" );
|
335 |
+
wp_clear_scheduled_hook( $event );
|
336 |
+
if ( ! function_exists( 'is_plugin_active_for_network' ) && is_multisite() ) {
|
337 |
+
// Need to include the plugin library for the is_plugin_active function.
|
338 |
+
require_once( ABSPATH . 'wp-admin/includes/plugin.php' );
|
339 |
+
}
|
340 |
+
if ( is_multisite() && is_plugin_active_for_network( constant( strtoupper( $this->prefix ) . 'PLUGIN_FILE_REL' ) ) ) {
|
341 |
+
global $wpdb;
|
342 |
+
$blogs = $wpdb->get_results( $wpdb->prepare( "SELECT blog_id FROM $wpdb->blogs WHERE site_id = %d", $wpdb->siteid ), ARRAY_A );
|
343 |
+
if ( ewww_image_optimizer_iterable( $blogs ) ) {
|
344 |
+
foreach ( $blogs as $blog ) {
|
345 |
+
switch_to_blog( $blog['blog_id'] );
|
346 |
+
wp_clear_scheduled_hook( $event );
|
347 |
+
restore_current_blog();
|
348 |
+
}
|
349 |
+
}
|
350 |
+
}
|
351 |
+
}
|
352 |
+
}
|
353 |
+
|
354 |
/**
|
355 |
* Use the Site URL to get the zone domain.
|
356 |
*/
|
434 |
return false;
|
435 |
}
|
436 |
|
437 |
+
/**
|
438 |
+
* Do a health check to verify the Easy IO domain is still good.
|
439 |
+
*/
|
440 |
+
function health_check() {
|
441 |
+
$this->debug_message( '<b>' . __METHOD__ . '()</b>' );
|
442 |
+
$this->verify_domain( $this->exactdn_domain );
|
443 |
+
$this->set_exactdn_option( 'checkin', time() - 60 );
|
444 |
+
}
|
445 |
+
|
446 |
/**
|
447 |
* Verify the ExactDN domain.
|
448 |
*
|
462 |
}
|
463 |
|
464 |
$this->check_verify_method();
|
465 |
+
$this->set_exactdn_option( 'checkin', time() + HOUR_IN_SECONDS );
|
466 |
|
467 |
// Set a default error.
|
468 |
global $exactdn_activate_error;
|
485 |
array(
|
486 |
'timeout' => 10,
|
487 |
'body' => array(
|
488 |
+
'alias' => $domain,
|
489 |
+
'url' => $test_url,
|
490 |
+
'origin' => $this->content_url(),
|
491 |
),
|
492 |
)
|
493 |
);
|
532 |
array(
|
533 |
'timeout' => 10,
|
534 |
'body' => array(
|
535 |
+
'alias' => $domain,
|
536 |
+
'origin' => $this->content_url(),
|
537 |
),
|
538 |
)
|
539 |
);
|
1241 |
$new_tag = $tag;
|
1242 |
|
1243 |
// If present, replace the link href with an ExactDN URL for the full-size image.
|
1244 |
+
if ( defined( 'EIO_PRESERVE_LINKED_IMAGES' ) && EIO_PRESERVE_LINKED_IMAGES && ! empty( $images['link_url'][ $index ] ) && $this->validate_image_url( $images['link_url'][ $index ] ) ) {
|
1245 |
+
$new_tag = preg_replace(
|
1246 |
+
'#(href=["|\'])' . $images['link_url'][ $index ] . '(["|\'])#i',
|
1247 |
+
'\1' . $this->generate_url(
|
1248 |
+
$images['link_url'][ $index ],
|
1249 |
+
array(
|
1250 |
+
'lossy' => 0,
|
1251 |
+
'strip' => 'none',
|
1252 |
+
)
|
1253 |
+
) . '\2',
|
1254 |
+
$new_tag,
|
1255 |
+
1
|
1256 |
+
);
|
1257 |
+
} elseif ( ! empty( $images['link_url'][ $index ] ) && $this->validate_image_url( $images['link_url'][ $index ] ) ) {
|
1258 |
+
$new_tag = preg_replace(
|
1259 |
+
'#(href=["|\'])' . $images['link_url'][ $index ] . '(["|\'])#i',
|
1260 |
+
'\1' . $this->generate_url( $images['link_url'][ $index ] ) . '\2',
|
1261 |
+
$new_tag,
|
1262 |
+
1
|
1263 |
+
);
|
1264 |
}
|
1265 |
|
1266 |
// Insert new image src into the srcset as well, if we have a width.
|
1413 |
}
|
1414 |
} // End foreach().
|
1415 |
} // End if();
|
1416 |
+
|
1417 |
+
// Process <picture> elements in the page.
|
1418 |
+
$content = $this->filter_picture_images( $content );
|
1419 |
+
|
1420 |
+
// Process background images on HTML elements.
|
1421 |
$element_types = apply_filters( 'eio_allowed_background_image_elements', array( 'div', 'li', 'span', 'section', 'a' ) );
|
1422 |
foreach ( $element_types as $element_type ) {
|
|
|
1423 |
$content = $this->filter_bg_images( $content, $element_type );
|
1424 |
}
|
1425 |
if ( $this->filtering_the_page ) {
|
1448 |
return $content;
|
1449 |
}
|
1450 |
|
1451 |
+
/**
|
1452 |
+
* Parse page content for picture elements to rewrite.
|
1453 |
+
*
|
1454 |
+
* @param string $content The HTML content to parse.
|
1455 |
+
* @return string The filtered HTML content.
|
1456 |
+
*/
|
1457 |
+
function filter_picture_images( $content ) {
|
1458 |
+
$this->debug_message( '<b>' . __METHOD__ . '()</b>' );
|
1459 |
+
if ( false === strpos( $content, '<picture' ) ) {
|
1460 |
+
$this->debug_message( 'no picture elements, done' );
|
1461 |
+
return $content;
|
1462 |
+
}
|
1463 |
+
// Images listed as picture/source elements.
|
1464 |
+
$pictures = $this->get_picture_tags_from_html( $content );
|
1465 |
+
if ( $this->is_iterable( $pictures ) ) {
|
1466 |
+
foreach ( $pictures as $index => $picture ) {
|
1467 |
+
$sources = $this->get_elements_from_html( $picture, 'source' );
|
1468 |
+
if ( $this->is_iterable( $sources ) ) {
|
1469 |
+
foreach ( $sources as $source ) {
|
1470 |
+
$this->debug_message( "parsing a picture source: $source" );
|
1471 |
+
$srcset = $this->get_attribute( $source, 'srcset' );
|
1472 |
+
if ( $srcset ) {
|
1473 |
+
$new_srcset = $this->srcset_replace( $srcset );
|
1474 |
+
if ( $new_srcset ) {
|
1475 |
+
$new_source = str_replace( $srcset, $new_srcset, $source );
|
1476 |
+
$picture = str_replace( $source, $new_source, $picture );
|
1477 |
+
}
|
1478 |
+
}
|
1479 |
+
}
|
1480 |
+
if ( $picture !== $pictures[ $index ] ) {
|
1481 |
+
$this->debug_message( 'rewrote source for picture element' );
|
1482 |
+
$content = str_replace( $pictures[ $index ], $picture, $content );
|
1483 |
+
}
|
1484 |
+
}
|
1485 |
+
}
|
1486 |
+
}
|
1487 |
+
return $content;
|
1488 |
+
}
|
1489 |
+
|
1490 |
+
/**
|
1491 |
+
* Replaces images within a srcset attribute with their ExactDN derivatives.
|
1492 |
+
*
|
1493 |
+
* @param string $srcset A valid srcset attribute from an img element.
|
1494 |
+
* @return bool|string False if no changes were made, or the new srcset if any ExactDN images replaced the originals.
|
1495 |
+
*/
|
1496 |
+
function srcset_replace( $srcset ) {
|
1497 |
+
$this->debug_message( '<b>' . __METHOD__ . '()</b>' );
|
1498 |
+
$srcset_urls = explode( ' ', $srcset );
|
1499 |
+
$modified = false;
|
1500 |
+
if ( $this->is_iterable( $srcset_urls ) && count( $srcset_urls ) > 1 ) {
|
1501 |
+
$this->debug_message( 'parsing srcset urls' );
|
1502 |
+
foreach ( $srcset_urls as $srcurl ) {
|
1503 |
+
if ( is_numeric( substr( $srcurl, 0, 1 ) ) ) {
|
1504 |
+
continue;
|
1505 |
+
}
|
1506 |
+
$trailing = ' ';
|
1507 |
+
if ( ',' === substr( $srcurl, -1 ) ) {
|
1508 |
+
$trailing = ',';
|
1509 |
+
$srcurl = rtrim( $srcurl, ',' );
|
1510 |
+
}
|
1511 |
+
$this->debug_message( "looking for $srcurl from srcset" );
|
1512 |
+
if ( $this->validate_image_url( $srcurl ) ) {
|
1513 |
+
$srcset = str_replace( $srcurl . $trailing, $this->generate_url( $srcurl ) . $trailing, $srcset );
|
1514 |
+
$this->debug_message( "replaced $srcurl in srcset" );
|
1515 |
+
$modified = true;
|
1516 |
+
}
|
1517 |
+
}
|
1518 |
+
} elseif ( $this->validate_image_url( $srcset ) ) {
|
1519 |
+
return $this->generate_url( $srcset );
|
1520 |
+
}
|
1521 |
+
if ( $modified ) {
|
1522 |
+
return $srcset;
|
1523 |
+
} else {
|
1524 |
+
return false;
|
1525 |
+
}
|
1526 |
+
}
|
1527 |
+
|
1528 |
/**
|
1529 |
* Parse page content looking for elements with CSS background-image properties.
|
1530 |
*
|
1787 |
$started = microtime( true );
|
1788 |
$this->debug_message( '<b>' . __METHOD__ . '()</b>' );
|
1789 |
|
1790 |
+
if ( is_array( $attachment_id ) || is_object( $attachment_id ) ) {
|
1791 |
+
return $image;
|
1792 |
+
}
|
1793 |
+
|
1794 |
// Don't foul up the admin side of things, unless a plugin wants to.
|
1795 |
if ( is_admin() &&
|
1796 |
/**
|
2822 |
* @return boolean True to skip the page, unchanged otherwise.
|
2823 |
*/
|
2824 |
function skip_page( $skip = false, $uri = '' ) {
|
2825 |
+
if ( false !== strpos( $uri, 'cornerstone=' ) || false !== strpos( $uri, 'cornerstone-endpoint' ) ) {
|
2826 |
+
return true;
|
2827 |
+
}
|
2828 |
+
if ( false !== strpos( $uri, 'et_fb=' ) ) {
|
2829 |
+
return true;
|
2830 |
+
}
|
2831 |
+
if ( false !== strpos( $uri, 'tatsu=' ) ) {
|
2832 |
+
return true;
|
2833 |
+
}
|
2834 |
if ( false !== strpos( $uri, 'ct_builder=' ) ) {
|
2835 |
return true;
|
2836 |
}
|
2837 |
+
if ( false !== strpos( $uri, 'ct_render_shortcode=' ) || false !== strpos( $uri, 'action=oxy_render' ) ) {
|
2838 |
+
return true;
|
2839 |
+
}
|
2840 |
if ( false !== strpos( $uri, '?fl_builder' ) ) {
|
2841 |
return true;
|
2842 |
}
|
3047 |
if ( $this->plan_id > 1 && false === strpos( $image_url, 'quality=' ) && 75 !== (int) $webp_quality && $webp_quality < $jpg_quality ) {
|
3048 |
$more_args['quality'] = $webp_quality;
|
3049 |
}
|
3050 |
+
if ( defined( 'EIO_WEBP_SHARP_YUV' ) && EIO_WEBP_SHARP_YUV ) {
|
3051 |
+
$more_args['sharp'] = 1;
|
3052 |
+
}
|
3053 |
// Merge given args with the automatic (option-based) args, and also makes sure args is an array if it was previously a string.
|
3054 |
$args = wp_parse_args( $args, $more_args );
|
3055 |
|
3157 |
}
|
3158 |
|
3159 |
// Clear out args for some files (like videos) that might go through image_downsize.
|
3160 |
+
if ( ! empty( $extension ) && in_array( $extension, array( 'mp4', 'm4p', 'm4v', 'mov', 'wvm', 'qt', 'ogv', 'mpg', 'mpeg', 'mpv' ), true ) ) {
|
3161 |
$args = array();
|
3162 |
}
|
3163 |
|
common.php
CHANGED
@@ -14,7 +14,7 @@ if ( ! defined( 'ABSPATH' ) ) {
|
|
14 |
exit;
|
15 |
}
|
16 |
|
17 |
-
define( 'EWWW_IMAGE_OPTIMIZER_VERSION', '
|
18 |
|
19 |
// Initialize a couple globals.
|
20 |
$eio_debug = '';
|
@@ -50,7 +50,7 @@ use lsolesen\pel\PelTag;
|
|
50 |
add_action( 'plugins_loaded', 'ewww_image_optimizer_preinit' );
|
51 |
// Runs any checks that need to run everywhere and early.
|
52 |
add_action( 'init', 'ewww_image_optimizer_init', 9 );
|
53 |
-
// Load our front-end parsers for ExactDN and
|
54 |
add_action( 'init', 'ewww_image_optimizer_parser_init', 99 );
|
55 |
// Initializes the plugin for admin interactions, like saving network settings and scheduling cron jobs.
|
56 |
add_action( 'admin_init', 'ewww_image_optimizer_admin_init' );
|
@@ -212,7 +212,9 @@ if ( defined( 'WP_CLI' ) && WP_CLI ) {
|
|
212 |
if ( 'done' !== get_option( 'ewww_image_optimizer_relative_migration_status' ) ) {
|
213 |
require_once( EWWW_IMAGE_OPTIMIZER_PLUGIN_PATH . 'classes/class-ewwwio-relative-migration.php' );
|
214 |
}
|
215 |
-
|
|
|
|
|
216 |
|
217 |
/**
|
218 |
* Setup page parsing classes after theme functions.php is loaded and plugins have run init routines.
|
@@ -257,17 +259,24 @@ function ewww_image_optimizer_parser_init() {
|
|
257 |
global $eio_lazy_load;
|
258 |
$eio_lazy_load = new EIO_Lazy_Load();
|
259 |
}
|
260 |
-
// If
|
261 |
if ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_webp_for_cdn' ) && ! ewww_image_optimizer_get_option( 'ewww_image_optimizer_exactdn' ) ) {
|
262 |
$buffer_start = true;
|
263 |
/**
|
264 |
* Page Parsing class for working with HTML content.
|
265 |
*/
|
266 |
require_once( EWWW_IMAGE_OPTIMIZER_PLUGIN_PATH . 'classes/class-eio-page-parser.php' );
|
267 |
-
|
268 |
-
|
269 |
-
|
270 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
271 |
}
|
272 |
if ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_picture_webp' ) && ! ewww_image_optimizer_get_option( 'ewww_image_optimizer_exactdn' ) ) {
|
273 |
$buffer_start = true;
|
@@ -408,6 +417,39 @@ function ewww_image_optimizer_ce_webp_enabled() {
|
|
408 |
return false;
|
409 |
}
|
410 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
411 |
/**
|
412 |
* Checks to see if the WebP rules from WPFC are enabled.
|
413 |
*
|
@@ -765,7 +807,7 @@ function ewww_image_optimizer_init() {
|
|
765 |
}
|
766 |
// Resizes and auto-rotates images.
|
767 |
add_filter( 'wp_handle_upload', 'ewww_image_optimizer_handle_upload' );
|
768 |
-
if ( class_exists( 'S3_Uploads' ) ) {
|
769 |
ewwwio_debug_message( 's3-uploads detected, deferring resize_upload' );
|
770 |
add_filter( 'ewww_image_optimizer_defer_resizing', '__return_true' );
|
771 |
}
|
@@ -1299,7 +1341,9 @@ function ewww_image_optimizer_current_screen( $screen ) {
|
|
1299 |
global $eio_debug;
|
1300 |
if ( false === strpos( $screen->id, 'settings_page_ewww-image-optimizer' ) && false === strpos( $screen->id, 'settings_page_easy-image-optimizer' ) ) {
|
1301 |
$ewwwio_temp_debug = false;
|
1302 |
-
|
|
|
|
|
1303 |
}
|
1304 |
}
|
1305 |
|
@@ -1598,6 +1642,7 @@ function ewww_image_optimizer_install_table() {
|
|
1598 |
}
|
1599 |
// Make sure there are valid dates in updated column.
|
1600 |
$wpdb->query( "UPDATE $wpdb->ewwwio_images SET updated = '1971-01-01 00:00:00' WHERE updated < '1001-01-01 00:00:01'" );
|
|
|
1601 |
// Check the current collation and adjust it if necessary.
|
1602 |
$column_collate = $wpdb->get_col_charset( $wpdb->ewwwio_images, 'path' );
|
1603 |
if ( ! empty( $column_collate ) && ! is_wp_error( $column_collate ) && 'utf8mb4' !== $column_collate ) {
|
@@ -1676,7 +1721,7 @@ function ewww_image_optimizer_install_table() {
|
|
1676 |
level int unsigned,
|
1677 |
pending tinyint NOT NULL DEFAULT 0,
|
1678 |
updates int unsigned,
|
1679 |
-
updated timestamp DEFAULT
|
1680 |
trace blob,
|
1681 |
$primary_key_definition
|
1682 |
KEY path (path($path_index_size)),
|
@@ -1870,6 +1915,9 @@ function ewww_image_optimizer_cloud_based_media() {
|
|
1870 |
if ( class_exists( 'S3_Uploads' ) && function_exists( 's3_uploads_enabled' ) && s3_uploads_enabled() ) {
|
1871 |
return true;
|
1872 |
}
|
|
|
|
|
|
|
1873 |
if ( class_exists( 'wpCloud\StatelessMedia\EWWW' ) && function_exists( 'ud_get_stateless_media' ) ) {
|
1874 |
$sm = ud_get_stateless_media();
|
1875 |
if ( method_exists( $sm, 'get' ) ) {
|
@@ -2246,7 +2294,7 @@ function ewww_image_optimizer_notice_reoptimization() {
|
|
2246 |
*/
|
2247 |
function ewww_image_optimizer_load_editor( $editors ) {
|
2248 |
ewwwio_debug_message( '<b>' . __FUNCTION__ . '()</b>' );
|
2249 |
-
if ( class_exists( '
|
2250 |
return $editors;
|
2251 |
}
|
2252 |
if ( ! class_exists( 'EWWWIO_GD_Editor' ) && ! class_exists( 'EWWWIO_Imagick_Editor' ) ) {
|
@@ -2684,7 +2732,6 @@ function ewww_image_optimizer_auto() {
|
|
2684 |
ewwwio_debug_message( '<b>' . __FUNCTION__ . '()</b>' );
|
2685 |
if ( get_transient( 'ewww_image_optimizer_no_scheduled_optimization' ) ) {
|
2686 |
ewwwio_debug_message( 'detected bulk operation in progress, bailing' );
|
2687 |
-
ewww_image_optimizer_debug_log();
|
2688 |
return;
|
2689 |
}
|
2690 |
if ( ! class_exists( 'WP_Background_Process' ) ) {
|
@@ -3001,7 +3048,7 @@ function ewww_image_optimizer_settings_link( $links ) {
|
|
3001 |
/**
|
3002 |
* Check for GD support of both PNG and JPG.
|
3003 |
*
|
3004 |
-
* @return
|
3005 |
*/
|
3006 |
function ewww_image_optimizer_gd_support() {
|
3007 |
ewwwio_debug_message( '<b>' . __FUNCTION__ . '()</b>' );
|
@@ -3014,13 +3061,86 @@ function ewww_image_optimizer_gd_support() {
|
|
3014 |
}
|
3015 |
ewwwio_memory( __FUNCTION__ );
|
3016 |
if ( ( ! empty( $gd_support['JPEG Support'] ) || ! empty( $gd_support['JPG Support'] ) ) && ! empty( $gd_support['PNG Support'] ) ) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3017 |
return true;
|
3018 |
}
|
3019 |
}
|
3020 |
}
|
|
|
3021 |
return false;
|
3022 |
}
|
3023 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3024 |
/**
|
3025 |
* Check for IMagick support of both PNG and JPG.
|
3026 |
*
|
@@ -3040,6 +3160,110 @@ function ewww_image_optimizer_imagick_support() {
|
|
3040 |
return false;
|
3041 |
}
|
3042 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3043 |
/**
|
3044 |
* Check for GMagick support of both PNG and JPG.
|
3045 |
*
|
@@ -3849,7 +4073,7 @@ function ewww_image_optimizer_cloud_restore_from_meta_data( $id, $gallery = 'med
|
|
3849 |
}
|
3850 |
}
|
3851 |
}
|
3852 |
-
if ( class_exists( 'S3_Uploads' ) ) {
|
3853 |
ewww_image_optimizer_remote_push( $meta, $id );
|
3854 |
ewwwio_debug_message( 're-uploading to S3(_Uploads)' );
|
3855 |
}
|
@@ -4024,7 +4248,7 @@ function ewww_image_optimizer_delete( $id ) {
|
|
4024 |
}
|
4025 |
$s3_path = false;
|
4026 |
$s3_dir = false;
|
4027 |
-
if ( class_exists( 'S3_Uploads' ) && ewww_image_optimizer_get_option( 'ewww_image_optimizer_webp' ) ) {
|
4028 |
$s3_path = get_attached_file( $id );
|
4029 |
if ( 0 === strpos( $s3_path, 's3://' ) ) {
|
4030 |
ewwwio_debug_message( 'removing: ' . $s3_path . '.webp' );
|
@@ -4464,7 +4688,7 @@ function ewww_image_optimizer_cloud_key_verify_ajax() {
|
|
4464 |
wp_json_encode(
|
4465 |
array(
|
4466 |
'error' => sprintf(
|
4467 |
-
/* translators: %s: an error message
|
4468 |
esc_html__( 'Could not validate API key, HTTP error: %s', 'ewww-image-optimizer' ),
|
4469 |
$error_message
|
4470 |
),
|
@@ -4777,7 +5001,6 @@ function ewww_image_optimizer_cloud_optimizer( $file, $type, $convert = false, $
|
|
4777 |
add_filter( 'image_memory_limit', 'ewww_image_optimizer_raise_memory_limit' );
|
4778 |
wp_raise_memory_limit( 'image' );
|
4779 |
}
|
4780 |
-
ewww_image_optimizer_debug_log();
|
4781 |
}
|
4782 |
$api_key = ewww_image_optimizer_get_option( 'ewww_image_optimizer_cloud_key' );
|
4783 |
if ( 'exceeded' === get_transient( 'ewww_image_optimizer_cloud_status' ) ) {
|
@@ -4837,6 +5060,7 @@ function ewww_image_optimizer_cloud_optimizer( $file, $type, $convert = false, $
|
|
4837 |
$lossy = 0;
|
4838 |
$lossy_fast = 0;
|
4839 |
}
|
|
|
4840 |
if ( 'image/webp' === $newtype ) {
|
4841 |
$webp = 1;
|
4842 |
$jpg_quality = apply_filters( 'webp_quality', 75, 'image/webp' );
|
@@ -4891,6 +5115,7 @@ function ewww_image_optimizer_cloud_optimizer( $file, $type, $convert = false, $
|
|
4891 |
ewwwio_debug_message( "newfile: $newfile" );
|
4892 |
ewwwio_debug_message( "newtype: $newtype" );
|
4893 |
ewwwio_debug_message( "webp: $webp" );
|
|
|
4894 |
ewwwio_debug_message( "jpg fill: $jpg_fill" );
|
4895 |
ewwwio_debug_message( "jpg quality: $jpg_quality" );
|
4896 |
$free_exec = EWWW_IMAGE_OPTIMIZER_NOEXEC && 'image/jpeg' === $type;
|
@@ -4930,6 +5155,7 @@ function ewww_image_optimizer_cloud_optimizer( $file, $type, $convert = false, $
|
|
4930 |
'lossy' => $lossy,
|
4931 |
'lossy_fast' => $lossy_fast,
|
4932 |
'webp' => $webp,
|
|
|
4933 |
'backup' => $hash,
|
4934 |
'domain' => $domain,
|
4935 |
);
|
@@ -5034,7 +5260,6 @@ function ewww_image_optimizer_cloud_autorotate( $file, $type ) {
|
|
5034 |
add_filter( 'image_memory_limit', 'ewww_image_optimizer_raise_memory_limit' );
|
5035 |
wp_raise_memory_limit( 'image' );
|
5036 |
}
|
5037 |
-
ewww_image_optimizer_debug_log();
|
5038 |
}
|
5039 |
$api_key = ewww_image_optimizer_get_option( 'ewww_image_optimizer_cloud_key' );
|
5040 |
if ( empty( $api_key ) ) {
|
@@ -5161,7 +5386,6 @@ function ewww_image_optimizer_cloud_backup( $file ) {
|
|
5161 |
add_filter( 'image_memory_limit', 'ewww_image_optimizer_raise_memory_limit' );
|
5162 |
wp_raise_memory_limit( 'image' );
|
5163 |
}
|
5164 |
-
ewww_image_optimizer_debug_log();
|
5165 |
}
|
5166 |
if ( ! ewww_image_optimizer_cloud_verify( $api_key ) ) {
|
5167 |
ewwwio_debug_message( 'cloud verify failed, image not backed up' );
|
@@ -5275,7 +5499,6 @@ function ewww_image_optimizer_cloud_resize( $file, $type, $dst_x, $dst_y, $src_x
|
|
5275 |
add_filter( 'image_memory_limit', 'ewww_image_optimizer_raise_memory_limit' );
|
5276 |
wp_raise_memory_limit( 'image' );
|
5277 |
}
|
5278 |
-
ewww_image_optimizer_debug_log();
|
5279 |
}
|
5280 |
$api_key = ewww_image_optimizer_get_option( 'ewww_image_optimizer_cloud_key' );
|
5281 |
if ( empty( $api_key ) ) {
|
@@ -5779,7 +6002,7 @@ function ewww_image_optimizer_update_table( $attachment, $opt_size, $orig_size,
|
|
5779 |
$updates['level'] = $ewww_image->level;
|
5780 |
}
|
5781 |
$updates['orig_size'] = $orig_size;
|
5782 |
-
$updates['updated'] = gmdate( 'Y-m-d H:i:s' );
|
5783 |
$ewwwdb->insert( $ewwwdb->ewwwio_images, $updates );
|
5784 |
} else {
|
5785 |
if ( is_array( $already_optimized ) && empty( $already_optimized['orig_size'] ) ) {
|
@@ -6111,7 +6334,7 @@ function ewww_image_optimizer_stream_wrapped( $filename ) {
|
|
6111 |
*/
|
6112 |
function ewww_image_optimizer_remote_push( $meta, $id ) {
|
6113 |
ewwwio_debug_message( '<b>' . __FUNCTION__ . '()</b>' );
|
6114 |
-
if ( class_exists( 'S3_Uploads' ) && ! empty( $meta['file'] ) ) {
|
6115 |
$s3_upload_dir = wp_get_upload_dir();
|
6116 |
$s3_upload_dir = trailingslashit( $s3_upload_dir['basedir'] );
|
6117 |
$s3_path = get_attached_file( $id );
|
@@ -6202,7 +6425,8 @@ function ewww_image_optimizer_remote_fetch( $id, $meta ) {
|
|
6202 |
if ( ! function_exists( 'download_url' ) ) {
|
6203 |
require_once( ABSPATH . '/wp-admin/includes/file.php' );
|
6204 |
}
|
6205 |
-
|
|
|
6206 |
$s3_upload_dir = wp_get_upload_dir();
|
6207 |
$s3_upload_dir = trailingslashit( $s3_upload_dir['basedir'] );
|
6208 |
$s3_path = get_attached_file( $id );
|
@@ -6523,10 +6747,10 @@ function ewww_image_optimizer_remote_fetch( $id, $meta ) {
|
|
6523 |
if ( ! empty( $filename ) && ewwwio_is_file( $filename ) ) {
|
6524 |
ewwwio_debug_message( "$filename found, success!" );
|
6525 |
return $filename;
|
6526 |
-
}
|
6527 |
ewwwio_debug_message( "$filename not found, boo..." );
|
6528 |
-
return false;
|
6529 |
}
|
|
|
6530 |
}
|
6531 |
|
6532 |
/**
|
@@ -6959,7 +7183,6 @@ function ewww_image_optimizer_resize_upload( $file ) {
|
|
6959 |
add_filter( 'image_memory_limit', 'ewww_image_optimizer_raise_memory_limit' );
|
6960 |
wp_raise_memory_limit( 'image' );
|
6961 |
}
|
6962 |
-
ewww_image_optimizer_debug_log();
|
6963 |
}
|
6964 |
if ( ! function_exists( 'wp_get_image_editor' ) ) {
|
6965 |
ewwwio_debug_message( 'no image editor function' );
|
@@ -8003,7 +8226,7 @@ function ewww_image_optimizer_resize_from_meta_data( $meta, $id = null, $log = t
|
|
8003 |
ewwwio_debug_message( 'uploading to Amazon S3' );
|
8004 |
}
|
8005 |
}
|
8006 |
-
if ( class_exists( 'S3_Uploads' ) ) {
|
8007 |
ewww_image_optimizer_remote_push( $meta, $id );
|
8008 |
ewwwio_debug_message( 're-uploading to S3(_Uploads)' );
|
8009 |
}
|
@@ -8323,8 +8546,6 @@ function ewww_image_optimizer_update_attachment( $meta, $id ) {
|
|
8323 |
'post_mime_type' => $mime,
|
8324 |
)
|
8325 |
);
|
8326 |
-
ewww_image_optimizer_debug_log();
|
8327 |
-
ewwwio_memory( __FUNCTION__ );
|
8328 |
return $meta;
|
8329 |
}
|
8330 |
|
@@ -8699,6 +8920,34 @@ function ewww_image_optimizer_is_animated_png( $filename ) {
|
|
8699 |
return $apng;
|
8700 |
}
|
8701 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
8702 |
/**
|
8703 |
* Count how many sizes are in the metadata, accounting for those with duplicate dimensions.
|
8704 |
*
|
@@ -8809,6 +9058,10 @@ function ewww_image_optimizer_custom_column( $column_name, $id, $meta = null ) {
|
|
8809 |
echo '<div>' . esc_html__( 'Amazon S3 image', 'ewww-image-optimizer' ) . '</div>';
|
8810 |
$ewww_cdn = true;
|
8811 |
}
|
|
|
|
|
|
|
|
|
8812 |
if ( is_array( $meta ) & class_exists( 'wpCloud\StatelessMedia\EWWW' ) && ! empty( $meta['gs_link'] ) ) {
|
8813 |
echo '<div>' . esc_html__( 'WP Stateless image', 'ewww-image-optimizer' ) . '</div>';
|
8814 |
$ewww_cdn = true;
|
@@ -8933,6 +9186,15 @@ function ewww_image_optimizer_custom_column( $column_name, $id, $meta = null ) {
|
|
8933 |
) . '</div>';
|
8934 |
}
|
8935 |
break;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
8936 |
default:
|
8937 |
// Not a supported mimetype.
|
8938 |
$msg = '<div>' . esc_html__( 'Unsupported file type', 'ewww-image-optimizer' ) . '</div>';
|
@@ -9181,8 +9443,6 @@ function ewww_image_optimizer_custom_column( $column_name, $id, $meta = null ) {
|
|
9181 |
} // End if().
|
9182 |
echo '</div>';
|
9183 |
} // End if().
|
9184 |
-
ewwwio_memory( __FUNCTION__ );
|
9185 |
-
ewww_image_optimizer_debug_log();
|
9186 |
}
|
9187 |
|
9188 |
/**
|
@@ -9253,7 +9513,6 @@ function ewww_image_optimizer_count_unoptimized_sizes( $sizes ) {
|
|
9253 |
$processed = array();
|
9254 |
foreach ( $sizes as $size => $data ) {
|
9255 |
ewwwio_debug_message( "checking for size: $size" );
|
9256 |
-
ewww_image_optimizer_debug_log();
|
9257 |
if ( strpos( $size, 'webp' ) === 0 ) {
|
9258 |
continue;
|
9259 |
}
|
@@ -10599,7 +10858,7 @@ function ewwwio_debug_info() {
|
|
10599 |
ewwwio_debug_message( 'png2jpg fill:' );
|
10600 |
ewww_image_optimizer_jpg_background();
|
10601 |
ewwwio_debug_message( 'webp conversion: ' . ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_webp' ) ? 'on' : 'off' ) );
|
10602 |
-
ewwwio_debug_message( '
|
10603 |
ewwwio_debug_message( 'picture webp rewriting: ' . ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_picture_webp' ) ? 'on' : 'off' ) );
|
10604 |
ewwwio_debug_message( 'WebP Rewrite exclusions:' );
|
10605 |
$webp_exclude_paths = ewww_image_optimizer_get_option( 'ewww_image_optimizer_webp_rewrite_exclude' ) ? esc_html( implode( "\n", ewww_image_optimizer_get_option( 'ewww_image_optimizer_webp_rewrite_exclude' ) ) ) : '';
|
@@ -10622,6 +10881,7 @@ function ewwwio_debug_info() {
|
|
10622 |
! ewww_image_optimizer_get_option( 'ewww_image_optimizer_webp_for_cdn' ) &&
|
10623 |
! ewww_image_optimizer_get_option( 'ewww_image_optimizer_picture_webp' ) &&
|
10624 |
! ewww_image_optimizer_ce_webp_enabled() &&
|
|
|
10625 |
! ewww_image_optimizer_easy_active()
|
10626 |
) {
|
10627 |
if ( defined( 'PHP_SAPI' ) ) {
|
@@ -10664,7 +10924,7 @@ function ewww_image_optimizer_intro_wizard() {
|
|
10664 |
$eio_base = new EIO_Base();
|
10665 |
$easyio_site_url = $eio_base->content_url();
|
10666 |
$no_tracking = false;
|
10667 |
-
$webp_available =
|
10668 |
$bulk_available = false;
|
10669 |
$tools_available = true;
|
10670 |
if ( ! defined( 'EWWW_IMAGE_OPTIMIZER_NOEXEC' ) ) {
|
@@ -10714,12 +10974,6 @@ function ewww_image_optimizer_intro_wizard() {
|
|
10714 |
// Expand the missing utilities list for use in the error message.
|
10715 |
$tools_missing_message = implode( ', ', $tools_missing );
|
10716 |
}
|
10717 |
-
if (
|
10718 |
-
defined( 'EWWW_IMAGE_OPTIMIZER_NOEXEC' ) && EWWW_IMAGE_OPTIMIZER_NOEXEC &&
|
10719 |
-
! ewww_image_optimizer_get_option( 'ewww_image_optimizer_cloud_key' )
|
10720 |
-
) {
|
10721 |
-
$webp_available = false;
|
10722 |
-
}
|
10723 |
if (
|
10724 |
! ewww_image_optimizer_get_option( 'ewww_image_optimizer_exactdn' ) ||
|
10725 |
ewww_image_optimizer_get_option( 'ewww_image_optimizer_cloud_key' ) ||
|
@@ -10761,7 +11015,6 @@ function ewww_image_optimizer_intro_wizard() {
|
|
10761 |
}
|
10762 |
if ( $tools_missing_notice && ! $tools_available ) {
|
10763 |
ewww_image_optimizer_enable_free_exec();
|
10764 |
-
$webp_available = false;
|
10765 |
}
|
10766 |
}
|
10767 |
if ( 3 === $wizard_step ) {
|
@@ -10841,7 +11094,9 @@ function ewww_image_optimizer_intro_wizard() {
|
|
10841 |
);
|
10842 |
?>
|
10843 |
</span>
|
10844 |
-
<?php if (
|
|
|
|
|
10845 |
<br><br>
|
10846 |
<a href="<?php echo esc_url( add_query_arg( 'site_url', trim( $easyio_site_url ), 'https://ewww.io/manage-sites/' ) ); ?>" target="_blank">
|
10847 |
<?php esc_html_e( 'First, add your Site URL to your account:', 'easy-image-optimizer' ); ?>
|
@@ -10852,7 +11107,7 @@ function ewww_image_optimizer_intro_wizard() {
|
|
10852 |
<a id='ewwwio-easy-activate' href='#' class='button-secondary'><?php esc_html_e( 'Activate', 'ewww-image-optimizer' ); ?></a>
|
10853 |
<span id='ewwwio-easy-activation-processing'><img src='<?php echo esc_url( $loading_image_url ); ?>' alt='loading'/></span>
|
10854 |
<?php elseif ( class_exists( 'ExactDN' ) && ewww_image_optimizer_get_option( 'ewww_image_optimizer_exactdn' ) && $exactdn->get_exactdn_domain() && $exactdn->verify_domain( $exactdn->get_exactdn_domain() ) ) : ?>
|
10855 |
-
<span style="color: #3eadc9; font-weight: bolder"><?php esc_html_e( 'Verified', 'ewww-image-optimizer' ); ?></span>
|
10856 |
<span class="dashicons dashicons-yes"></span>
|
10857 |
<?php endif; ?>
|
10858 |
</p>
|
@@ -11616,7 +11871,7 @@ function ewww_image_optimizer_options( $network = 'singlesite' ) {
|
|
11616 |
sprintf(
|
11617 |
/* translators: %s: S3 Image Optimizer (link) */
|
11618 |
esc_html__( 'Optimize unlimited Amazon S3 buckets with our %s.' ),
|
11619 |
-
'<a href="https://
|
11620 |
) : '' );
|
11621 |
?>
|
11622 |
</p>
|
@@ -11740,6 +11995,7 @@ function ewww_image_optimizer_options( $network = 'singlesite' ) {
|
|
11740 |
if ( ewww_image_optimizer_easy_active() || $cf_host ) {
|
11741 |
ewww_image_optimizer_webp_rewrite_verify();
|
11742 |
}
|
|
|
11743 |
$test_webp_image = plugins_url( '/images/test.png.webp', __FILE__ );
|
11744 |
$test_png_image = plugins_url( '/images/test.png', __FILE__ );
|
11745 |
?>
|
@@ -11829,9 +12085,6 @@ function ewww_image_optimizer_options( $network = 'singlesite' ) {
|
|
11829 |
</tr>
|
11830 |
</table>
|
11831 |
<input type='hidden' id='ewww_image_optimizer_allow_multisite_override_active' name='ewww_image_optimizer_allow_multisite_override_active' value='0'>
|
11832 |
-
<?php if ( get_site_option( 'ewww_image_optimizer_cloud_key' ) ) : ?>
|
11833 |
-
<input type='hidden' id='ewww_image_optimizer_cloud_key' name='ewww_image_optimizer_cloud_key' value='<?php echo esc_attr( get_site_option( 'ewww_image_optimizer_cloud_key' ) ); ?>' />
|
11834 |
-
<?php endif; ?>
|
11835 |
</div><!-- end container general settings -->
|
11836 |
<p class='submit'><input type='submit' class='button-primary' value='<?php esc_attr_e( 'Save Changes', 'ewww-image-optimizer' ); ?>' /></p>
|
11837 |
</form>
|
@@ -11854,7 +12107,6 @@ function ewww_image_optimizer_options( $network = 'singlesite' ) {
|
|
11854 |
<a class='button-secondary' href='<?php echo esc_url( admin_url( 'admin.php?action=ewww_image_optimizer_remove_cloud_key' ) ); ?>'>
|
11855 |
<?php esc_html_e( 'Remove API key', 'ewww-image-optimizer' ); ?>
|
11856 |
</a>
|
11857 |
-
<input type='hidden' id='ewww_image_optimizer_cloud_key' name='ewww_image_optimizer_cloud_key' value='<?php echo esc_attr( ewww_image_optimizer_get_option( 'ewww_image_optimizer_cloud_key' ) ); ?>' />
|
11858 |
<p>
|
11859 |
<?php if ( false !== strpos( $verify_cloud, 'great' ) ) : ?>
|
11860 |
<span style="color: #3eadc9; font-weight: bolder"><?php esc_html_e( 'Verified,', 'ewww-image-optimizer' ); ?> </span><?php echo wp_kses_post( ewww_image_optimizer_cloud_quota() ); ?>
|
@@ -11921,6 +12173,8 @@ function ewww_image_optimizer_options( $network = 'singlesite' ) {
|
|
11921 |
?>
|
11922 |
<?php if ( class_exists( 'Jetpack' ) && Jetpack::is_module_active( 'photon' ) && ewww_image_optimizer_get_option( 'ewww_image_optimizer_exactdn' ) ) : ?>
|
11923 |
<p style='color: red'><?php esc_html_e( 'Inactive, please disable the Image Accelerator option on the Jetpack Dashboard.', 'ewww-image-optimizer' ); ?></p>
|
|
|
|
|
11924 |
<?php elseif ( ! $exactdn_enabled ) : ?>
|
11925 |
<p>
|
11926 |
<strong><a href="https://ewww.io/plans/" target="_blank">
|
@@ -12172,7 +12426,7 @@ function ewww_image_optimizer_options( $network = 'singlesite' ) {
|
|
12172 |
</tr>
|
12173 |
<?php endif; ?>
|
12174 |
<?php endif; ?>
|
12175 |
-
<?php if ( $
|
12176 |
<tr id='ewww_image_optimizer_webp_container'>
|
12177 |
<th scope='row'>
|
12178 |
<label for='ewww_image_optimizer_webp'><?php esc_html_e( 'WebP Conversion', 'ewww-image-optimizer' ); ?></label>
|
@@ -12219,7 +12473,42 @@ function ewww_image_optimizer_options( $network = 'singlesite' ) {
|
|
12219 |
</tr>
|
12220 |
<tr>
|
12221 |
<?php endif; ?>
|
12222 |
-
<?php if (
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
12223 |
<tr class='ewww_image_optimizer_webp_setting_container' <?php echo ewww_image_optimizer_get_option( 'ewww_image_optimizer_webp' ) ? '' : ' style="display:none"'; ?>>
|
12224 |
<th scope='row'>
|
12225 |
<?php esc_html_e( 'WebP Delivery Method', 'ewww-image-optimizer' ); ?>
|
@@ -12437,32 +12726,6 @@ AddType image/webp .webp</pre>
|
|
12437 |
</td>
|
12438 |
</tr>
|
12439 |
<?php endif; ?>
|
12440 |
-
<tr id='ewww_image_optimizer_webp_easyio_container' style='display:none;'>
|
12441 |
-
<th scope='row'>
|
12442 |
-
<label for='ewww_image_optimizer_webp'><?php esc_html_e( 'WebP Conversion', 'ewww-image-optimizer' ); ?></label>
|
12443 |
-
</th>
|
12444 |
-
<td>
|
12445 |
-
<p class='description'><?php esc_html_e( 'WebP images are served automatically by Easy IO.', 'ewww-image-optimizer' ); ?></p>
|
12446 |
-
</td>
|
12447 |
-
</tr>
|
12448 |
-
<?php elseif ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_exactdn' ) ) : ?>
|
12449 |
-
<tr id='ewww_image_optimizer_webp_easyio_container'>
|
12450 |
-
<th scope='row'>
|
12451 |
-
<label for='ewww_image_optimizer_webp'><?php esc_html_e( 'WebP Conversion', 'ewww-image-optimizer' ); ?></label>
|
12452 |
-
</th>
|
12453 |
-
<td>
|
12454 |
-
<p class='description'><?php esc_html_e( 'WebP images are served automatically by Easy IO.', 'ewww-image-optimizer' ); ?></p>
|
12455 |
-
</td>
|
12456 |
-
</tr>
|
12457 |
-
<?php elseif ( get_option( 'easyio_exactdn' ) ) : ?>
|
12458 |
-
<tr>
|
12459 |
-
<th scope='row'>
|
12460 |
-
<label for='ewww_image_optimizer_webp'><?php esc_html_e( 'WebP Conversion', 'ewww-image-optimizer' ); ?></label>
|
12461 |
-
</th>
|
12462 |
-
<td>
|
12463 |
-
<p class='description'><?php esc_html_e( 'WebP images are served automatically by Easy Image Optimizer.', 'ewww-image-optimizer' ); ?></p>
|
12464 |
-
</td>
|
12465 |
-
</tr>
|
12466 |
<?php endif; ?>
|
12467 |
|
12468 |
<?php if ( class_exists( 'Cloudinary' ) && Cloudinary::config_get( 'api_secret' ) ) : ?>
|
@@ -13062,6 +13325,7 @@ AddType image/webp .webp</pre>
|
|
13062 |
<p class='submit'><input type='submit' class='button-primary' value='<?php esc_attr_e( 'Save Changes', 'ewww-image-optimizer' ); ?>' /></p>
|
13063 |
</form>
|
13064 |
|
|
|
13065 |
<hr style='clear:both;'>
|
13066 |
<h2><?php esc_html_e( "Shane's Recommendations", 'ewww-image-optimizer' ); ?></h2>
|
13067 |
<p><?php esc_html_e( 'These are products I have personally used. An * indicates an affiliate link so you can support future development of EWWW IO.', 'ewww-image-optimizer' ); ?></p>
|
@@ -13090,6 +13354,7 @@ AddType image/webp .webp</pre>
|
|
13090 |
<a href="https://nodeping.com?rid=201407082225W862K">NodePing</a>* -
|
13091 |
<?php esc_html_e( 'Monitor all the things, and make sure they stay online. They have a fantastic array of monitors and notifications that you can setup, they are cheap, simple, and have great support.', 'ewww-image-optimizer' ); ?>
|
13092 |
</p>
|
|
|
13093 |
</div><!-- end container wrap -->
|
13094 |
<?php
|
13095 |
if ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_enable_help' ) ) {
|
@@ -13228,6 +13493,8 @@ function ewww_image_optimizer_remove_easyio() {
|
|
13228 |
delete_site_option( 'ewww_image_optimizer_exactdn_verified' );
|
13229 |
delete_site_option( 'ewww_image_optimizer_exactdn_validation' );
|
13230 |
delete_site_option( 'ewww_image_optimizer_exactdn_suspended' );
|
|
|
|
|
13231 |
$sendback = wp_get_referer();
|
13232 |
wp_safe_redirect( $sendback );
|
13233 |
exit;
|
@@ -13398,8 +13665,10 @@ function ewww_image_optimizer_debug_log() {
|
|
13398 |
$eio_debug = str_replace( '<br>', "\n", $eio_debug );
|
13399 |
file_put_contents( $debug_log, $timestamp . $eio_debug, FILE_APPEND );
|
13400 |
}
|
|
|
|
|
|
|
13401 |
}
|
13402 |
-
$eio_debug = '';
|
13403 |
ewwwio_memory( __FUNCTION__ );
|
13404 |
}
|
13405 |
|
14 |
exit;
|
15 |
}
|
16 |
|
17 |
+
define( 'EWWW_IMAGE_OPTIMIZER_VERSION', '620' );
|
18 |
|
19 |
// Initialize a couple globals.
|
20 |
$eio_debug = '';
|
50 |
add_action( 'plugins_loaded', 'ewww_image_optimizer_preinit' );
|
51 |
// Runs any checks that need to run everywhere and early.
|
52 |
add_action( 'init', 'ewww_image_optimizer_init', 9 );
|
53 |
+
// Load our front-end parsers for ExactDN, Lazy Load and WebP.
|
54 |
add_action( 'init', 'ewww_image_optimizer_parser_init', 99 );
|
55 |
// Initializes the plugin for admin interactions, like saving network settings and scheduling cron jobs.
|
56 |
add_action( 'admin_init', 'ewww_image_optimizer_admin_init' );
|
212 |
if ( 'done' !== get_option( 'ewww_image_optimizer_relative_migration_status' ) ) {
|
213 |
require_once( EWWW_IMAGE_OPTIMIZER_PLUGIN_PATH . 'classes/class-ewwwio-relative-migration.php' );
|
214 |
}
|
215 |
+
if ( defined( 'EWWW_IMAGE_OPTIMIZER_ALT_WEBP' ) && EWWW_IMAGE_OPTIMIZER_ALT_WEBP ) {
|
216 |
+
require_once( EWWW_IMAGE_OPTIMIZER_PLUGIN_PATH . 'classes/class-eio-alt-webp-weglot-alt.php' );
|
217 |
+
}
|
218 |
|
219 |
/**
|
220 |
* Setup page parsing classes after theme functions.php is loaded and plugins have run init routines.
|
259 |
global $eio_lazy_load;
|
260 |
$eio_lazy_load = new EIO_Lazy_Load();
|
261 |
}
|
262 |
+
// If JS WebP Rewriting is enabled.
|
263 |
if ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_webp_for_cdn' ) && ! ewww_image_optimizer_get_option( 'ewww_image_optimizer_exactdn' ) ) {
|
264 |
$buffer_start = true;
|
265 |
/**
|
266 |
* Page Parsing class for working with HTML content.
|
267 |
*/
|
268 |
require_once( EWWW_IMAGE_OPTIMIZER_PLUGIN_PATH . 'classes/class-eio-page-parser.php' );
|
269 |
+
if ( defined( 'EWWW_IMAGE_OPTIMIZER_ALT_WEBP' ) && EWWW_IMAGE_OPTIMIZER_ALT_WEBP ) {
|
270 |
+
/**
|
271 |
+
* Alt WebP class for parsing image urls and rewriting them for WebP support.
|
272 |
+
*/
|
273 |
+
require_once( EWWW_IMAGE_OPTIMIZER_PLUGIN_PATH . 'classes/class-eio-alt-webp.php' );
|
274 |
+
} else {
|
275 |
+
/**
|
276 |
+
* JS WebP class for parsing image urls and rewriting them for WebP support.
|
277 |
+
*/
|
278 |
+
require_once( EWWW_IMAGE_OPTIMIZER_PLUGIN_PATH . 'classes/class-eio-js-webp.php' );
|
279 |
+
}
|
280 |
}
|
281 |
if ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_picture_webp' ) && ! ewww_image_optimizer_get_option( 'ewww_image_optimizer_exactdn' ) ) {
|
282 |
$buffer_start = true;
|
417 |
return false;
|
418 |
}
|
419 |
|
420 |
+
/**
|
421 |
+
* Checks to see if the WebP option from the SWIS Performance plugin is enabled.
|
422 |
+
*
|
423 |
+
* @return bool True if the WebP option for SWIS is enabled.
|
424 |
+
*/
|
425 |
+
function ewww_image_optimizer_swis_webp_enabled() {
|
426 |
+
if ( function_exists( 'swis' ) && class_exists( '\SWIS\Cache' ) ) {
|
427 |
+
$cache_settings = swis()->cache->get_settings();
|
428 |
+
if ( swis()->settings->get_option( 'cache' ) && ! empty( $cache_settings['webp'] ) ) {
|
429 |
+
ewwwio_debug_message( 'SWIS WebP option enabled' );
|
430 |
+
return true;
|
431 |
+
}
|
432 |
+
}
|
433 |
+
return false;
|
434 |
+
}
|
435 |
+
|
436 |
+
/**
|
437 |
+
* Checks to see if there is a method available for WebP conversion.
|
438 |
+
*
|
439 |
+
* @return bool True if a WebP Convertor is available.
|
440 |
+
*/
|
441 |
+
function ewww_image_optimizer_webp_available() {
|
442 |
+
if (
|
443 |
+
defined( 'EWWW_IMAGE_OPTIMIZER_NOEXEC' ) && EWWW_IMAGE_OPTIMIZER_NOEXEC &&
|
444 |
+
! ewww_image_optimizer_get_option( 'ewww_image_optimizer_cloud_key' ) &&
|
445 |
+
! ewww_image_optimizer_imagick_supports_webp() &&
|
446 |
+
! ewww_image_optimizer_gd_supports_webp()
|
447 |
+
) {
|
448 |
+
return true;
|
449 |
+
}
|
450 |
+
return true;
|
451 |
+
}
|
452 |
+
|
453 |
/**
|
454 |
* Checks to see if the WebP rules from WPFC are enabled.
|
455 |
*
|
807 |
}
|
808 |
// Resizes and auto-rotates images.
|
809 |
add_filter( 'wp_handle_upload', 'ewww_image_optimizer_handle_upload' );
|
810 |
+
if ( class_exists( 'S3_Uploads' ) || class_exists( 'S3_Uploads\Plugin' ) ) {
|
811 |
ewwwio_debug_message( 's3-uploads detected, deferring resize_upload' );
|
812 |
add_filter( 'ewww_image_optimizer_defer_resizing', '__return_true' );
|
813 |
}
|
1341 |
global $eio_debug;
|
1342 |
if ( false === strpos( $screen->id, 'settings_page_ewww-image-optimizer' ) && false === strpos( $screen->id, 'settings_page_easy-image-optimizer' ) ) {
|
1343 |
$ewwwio_temp_debug = false;
|
1344 |
+
if ( ! ewww_image_optimizer_get_option( 'ewww_image_optimizer_debug' ) ) {
|
1345 |
+
$eio_debug = '';
|
1346 |
+
}
|
1347 |
}
|
1348 |
}
|
1349 |
|
1642 |
}
|
1643 |
// Make sure there are valid dates in updated column.
|
1644 |
$wpdb->query( "UPDATE $wpdb->ewwwio_images SET updated = '1971-01-01 00:00:00' WHERE updated < '1001-01-01 00:00:01'" );
|
1645 |
+
$wpdb->query( "ALTER TABLE $wpdb->ewwwio_images ALTER updated SET DEFAULT CURRENT_TIMESTAMP" );
|
1646 |
// Check the current collation and adjust it if necessary.
|
1647 |
$column_collate = $wpdb->get_col_charset( $wpdb->ewwwio_images, 'path' );
|
1648 |
if ( ! empty( $column_collate ) && ! is_wp_error( $column_collate ) && 'utf8mb4' !== $column_collate ) {
|
1721 |
level int unsigned,
|
1722 |
pending tinyint NOT NULL DEFAULT 0,
|
1723 |
updates int unsigned,
|
1724 |
+
updated timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
1725 |
trace blob,
|
1726 |
$primary_key_definition
|
1727 |
KEY path (path($path_index_size)),
|
1915 |
if ( class_exists( 'S3_Uploads' ) && function_exists( 's3_uploads_enabled' ) && s3_uploads_enabled() ) {
|
1916 |
return true;
|
1917 |
}
|
1918 |
+
if ( class_exists( 'S3_Uploads\Plugin' ) && function_exists( 'S3_Uploads\enabled' ) && \S3_Uploads\enabled() ) {
|
1919 |
+
return true;
|
1920 |
+
}
|
1921 |
if ( class_exists( 'wpCloud\StatelessMedia\EWWW' ) && function_exists( 'ud_get_stateless_media' ) ) {
|
1922 |
$sm = ud_get_stateless_media();
|
1923 |
if ( method_exists( $sm, 'get' ) ) {
|
2294 |
*/
|
2295 |
function ewww_image_optimizer_load_editor( $editors ) {
|
2296 |
ewwwio_debug_message( '<b>' . __FUNCTION__ . '()</b>' );
|
2297 |
+
if ( class_exists( 'S3_Uploads\Image_Editor_Imagick' ) ) {
|
2298 |
return $editors;
|
2299 |
}
|
2300 |
if ( ! class_exists( 'EWWWIO_GD_Editor' ) && ! class_exists( 'EWWWIO_Imagick_Editor' ) ) {
|
2732 |
ewwwio_debug_message( '<b>' . __FUNCTION__ . '()</b>' );
|
2733 |
if ( get_transient( 'ewww_image_optimizer_no_scheduled_optimization' ) ) {
|
2734 |
ewwwio_debug_message( 'detected bulk operation in progress, bailing' );
|
|
|
2735 |
return;
|
2736 |
}
|
2737 |
if ( ! class_exists( 'WP_Background_Process' ) ) {
|
3048 |
/**
|
3049 |
* Check for GD support of both PNG and JPG.
|
3050 |
*
|
3051 |
+
* @return string The version of GD if full support is detected.
|
3052 |
*/
|
3053 |
function ewww_image_optimizer_gd_support() {
|
3054 |
ewwwio_debug_message( '<b>' . __FUNCTION__ . '()</b>' );
|
3061 |
}
|
3062 |
ewwwio_memory( __FUNCTION__ );
|
3063 |
if ( ( ! empty( $gd_support['JPEG Support'] ) || ! empty( $gd_support['JPG Support'] ) ) && ! empty( $gd_support['PNG Support'] ) ) {
|
3064 |
+
return ! empty( $gd_support['GD Version'] ) ? $gd_support['GD Version'] : '1';
|
3065 |
+
}
|
3066 |
+
}
|
3067 |
+
}
|
3068 |
+
return false;
|
3069 |
+
}
|
3070 |
+
|
3071 |
+
/**
|
3072 |
+
* Check for GD support of WebP format.
|
3073 |
+
*
|
3074 |
+
* @return bool True if proper WebP support is detected.
|
3075 |
+
*/
|
3076 |
+
function ewww_image_optimizer_gd_supports_webp() {
|
3077 |
+
ewwwio_debug_message( '<b>' . __FUNCTION__ . '()</b>' );
|
3078 |
+
$gd_version = ewww_image_optimizer_gd_support();
|
3079 |
+
if ( $gd_version ) {
|
3080 |
+
if (
|
3081 |
+
function_exists( 'imagewebp' ) &&
|
3082 |
+
function_exists( 'imagepalettetotruecolor' ) &&
|
3083 |
+
function_exists( 'imageistruecolor' ) &&
|
3084 |
+
function_exists( 'imagealphablending' ) &&
|
3085 |
+
function_exists( 'imagesavealpha' )
|
3086 |
+
) {
|
3087 |
+
if ( version_compare( $gd_version, '2.2.5', '>=' ) ) {
|
3088 |
+
ewwwio_debug_message( 'yes it does' );
|
3089 |
return true;
|
3090 |
}
|
3091 |
}
|
3092 |
}
|
3093 |
+
ewwwio_debug_message( 'sorry nope' );
|
3094 |
return false;
|
3095 |
}
|
3096 |
|
3097 |
+
/**
|
3098 |
+
* Use GD to convert an image to WebP.
|
3099 |
+
*
|
3100 |
+
* @param string $file The original source image path.
|
3101 |
+
* @param string $type The mime-type of the original image.
|
3102 |
+
* @param string $webpfile The location to store the new WebP image.
|
3103 |
+
*/
|
3104 |
+
function ewww_image_optimizer_gd_create_webp( $file, $type, $webpfile ) {
|
3105 |
+
ewwwio_debug_message( '<b>' . __FUNCTION__ . '()</b>' );
|
3106 |
+
$quality = (int) apply_filters( 'webp_quality', 75, 'image/webp' );
|
3107 |
+
if ( $quality < 50 || $quality > 100 ) {
|
3108 |
+
$quality = 75;
|
3109 |
+
}
|
3110 |
+
switch ( $type ) {
|
3111 |
+
case 'image/jpeg':
|
3112 |
+
$image = imagecreatefromjpeg( $file );
|
3113 |
+
if ( false === $image ) {
|
3114 |
+
return;
|
3115 |
+
}
|
3116 |
+
break;
|
3117 |
+
case 'image/png':
|
3118 |
+
$image = imagecreatefrompng( $file );
|
3119 |
+
if ( false === $image ) {
|
3120 |
+
return;
|
3121 |
+
}
|
3122 |
+
if ( ! imageistruecolor( $image ) ) {
|
3123 |
+
ewwwio_debug_message( 'converting to true color' );
|
3124 |
+
imagepalettetotruecolor( $image );
|
3125 |
+
}
|
3126 |
+
if ( ewww_image_optimizer_png_alpha( $file ) ) {
|
3127 |
+
ewwwio_debug_message( 'saving alpha and disabling alpha blending' );
|
3128 |
+
imagealphablending( $image, false );
|
3129 |
+
imagesavealpha( $image, true );
|
3130 |
+
}
|
3131 |
+
if ( ! defined( 'EWWW_IMAGE_OPTIMIZER_LOSSY_PNG2WEBP' ) || ! EWWW_IMAGE_OPTIMIZER_LOSSY_PNG2WEBP ) {
|
3132 |
+
$quality = 100;
|
3133 |
+
}
|
3134 |
+
break;
|
3135 |
+
default:
|
3136 |
+
return;
|
3137 |
+
}
|
3138 |
+
ewwwio_debug_message( "creating $webpfile with quality $quality" );
|
3139 |
+
$result = imagewebp( $image, $webpfile, $quality );
|
3140 |
+
// Make sure to cleanup--if $webpfile is borked, that will be handled elsewhere.
|
3141 |
+
imagedestroy( $image );
|
3142 |
+
}
|
3143 |
+
|
3144 |
/**
|
3145 |
* Check for IMagick support of both PNG and JPG.
|
3146 |
*
|
3160 |
return false;
|
3161 |
}
|
3162 |
|
3163 |
+
/**
|
3164 |
+
* Check for IMagick support of WebP.
|
3165 |
+
*
|
3166 |
+
* @return bool True if WebP support is detected.
|
3167 |
+
*/
|
3168 |
+
function ewww_image_optimizer_imagick_supports_webp() {
|
3169 |
+
ewwwio_debug_message( '<b>' . __FUNCTION__ . '()</b>' );
|
3170 |
+
if ( ewww_image_optimizer_imagick_support() ) {
|
3171 |
+
$imagick = new Imagick();
|
3172 |
+
$formats = $imagick->queryFormats();
|
3173 |
+
if ( in_array( 'WEBP', $formats, true ) ) {
|
3174 |
+
ewwwio_debug_message( 'yes it does' );
|
3175 |
+
return true;
|
3176 |
+
}
|
3177 |
+
}
|
3178 |
+
ewwwio_debug_message( 'sorry nope' );
|
3179 |
+
return false;
|
3180 |
+
}
|
3181 |
+
|
3182 |
+
/**
|
3183 |
+
* Use IMagick to convert an image to WebP.
|
3184 |
+
*
|
3185 |
+
* @param string $file The original source image path.
|
3186 |
+
* @param string $type The mime-type of the original image.
|
3187 |
+
* @param string $webpfile The location to store the new WebP image.
|
3188 |
+
*/
|
3189 |
+
function ewww_image_optimizer_imagick_create_webp( $file, $type, $webpfile ) {
|
3190 |
+
ewwwio_debug_message( '<b>' . __FUNCTION__ . '()</b>' );
|
3191 |
+
$sharp_yuv = defined( 'EIO_WEBP_SHARP_YUV' ) && EIO_WEBP_SHARP_YUV ? true : false;
|
3192 |
+
$quality = (int) apply_filters( 'webp_quality', 75, 'image/webp' );
|
3193 |
+
if ( $quality < 50 || $quality > 100 ) {
|
3194 |
+
$quality = 75;
|
3195 |
+
}
|
3196 |
+
$profiles = array();
|
3197 |
+
switch ( $type ) {
|
3198 |
+
case 'image/jpeg':
|
3199 |
+
$image = new Imagick( $file );
|
3200 |
+
if ( false === $image ) {
|
3201 |
+
return;
|
3202 |
+
}
|
3203 |
+
if ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_metadata_remove' ) ) {
|
3204 |
+
// Getting possible color profiles.
|
3205 |
+
$profiles = $image->getImageProfiles( 'icc', true );
|
3206 |
+
}
|
3207 |
+
$color = $image->getImageColorspace();
|
3208 |
+
ewwwio_debug_message( "color space is $color" );
|
3209 |
+
if ( Imagick::COLORSPACE_CMYK === $color ) {
|
3210 |
+
ewwwio_debug_message( 'found CMYK image' );
|
3211 |
+
if ( ewwwio_is_file( EWWW_IMAGE_OPTIMIZER_PLUGIN_PATH . 'vendor/icc/sRGB2014.icc' ) ) {
|
3212 |
+
ewwwio_debug_message( 'adding icc profile' );
|
3213 |
+
$icc_profile = file_get_contents( EWWW_IMAGE_OPTIMIZER_PLUGIN_PATH . 'vendor/icc/sRGB2014.icc' );
|
3214 |
+
$image->profileImage( 'icc', $icc_profile );
|
3215 |
+
}
|
3216 |
+
ewwwio_debug_message( 'attempting SRGB transform' );
|
3217 |
+
$image->transformImageColorspace( Imagick::COLORSPACE_SRGB );
|
3218 |
+
ewwwio_debug_message( 'removing icc profile' );
|
3219 |
+
$image->setImageProfile( 'icc', null );
|
3220 |
+
$profiles = array();
|
3221 |
+
}
|
3222 |
+
$image->setImageFormat( 'WEBP' );
|
3223 |
+
if ( $sharp_yuv ) {
|
3224 |
+
ewwwio_debug_message( 'enabling sharp_yuv' );
|
3225 |
+
$image->setOption( 'webp:use-sharp-yuv', 'true' );
|
3226 |
+
}
|
3227 |
+
ewwwio_debug_message( "setting quality to $quality" );
|
3228 |
+
$image->setImageCompressionQuality( $quality );
|
3229 |
+
break;
|
3230 |
+
case 'image/png':
|
3231 |
+
$image = new Imagick( $file );
|
3232 |
+
if ( false === $image ) {
|
3233 |
+
return;
|
3234 |
+
}
|
3235 |
+
$image->setImageFormat( 'WEBP' );
|
3236 |
+
if ( defined( 'EWWW_IMAGE_OPTIMIZER_LOSSY_PNG2WEBP' ) && EWWW_IMAGE_OPTIMIZER_LOSSY_PNG2WEBP ) {
|
3237 |
+
ewwwio_debug_message( 'doing lossy conversion' );
|
3238 |
+
if ( $sharp_yuv ) {
|
3239 |
+
ewwwio_debug_message( 'enabling sharp_yuv' );
|
3240 |
+
$image->setOption( 'webp:use-sharp-yuv', 'true' );
|
3241 |
+
}
|
3242 |
+
ewwwio_debug_message( "setting quality to $quality" );
|
3243 |
+
$image->setImageCompressionQuality( $quality );
|
3244 |
+
} else {
|
3245 |
+
ewwwio_debug_message( 'sticking to lossless' );
|
3246 |
+
$image->setOption( 'webp:lossless', true );
|
3247 |
+
$image->setOption( 'webp:alpha-quality', 100 );
|
3248 |
+
}
|
3249 |
+
break;
|
3250 |
+
default:
|
3251 |
+
return;
|
3252 |
+
}
|
3253 |
+
if ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_metadata_remove' ) ) {
|
3254 |
+
ewwwio_debug_message( 'removing meta' );
|
3255 |
+
$image->stripImage();
|
3256 |
+
if ( ! empty( $profiles ) ) {
|
3257 |
+
ewwwio_debug_message( 'adding color profile to WebP' );
|
3258 |
+
$image->profileImage( 'icc', $profiles['icc'] );
|
3259 |
+
}
|
3260 |
+
}
|
3261 |
+
ewwwio_debug_message( 'getting blob' );
|
3262 |
+
$image_blob = $image->getImageBlob();
|
3263 |
+
ewwwio_debug_message( 'writing file' );
|
3264 |
+
file_put_contents( $webpfile, $image_blob );
|
3265 |
+
}
|
3266 |
+
|
3267 |
/**
|
3268 |
* Check for GMagick support of both PNG and JPG.
|
3269 |
*
|
4073 |
}
|
4074 |
}
|
4075 |
}
|
4076 |
+
if ( class_exists( 'S3_Uploads' ) || class_exists( 'S3_uploads\Plugin' ) ) {
|
4077 |
ewww_image_optimizer_remote_push( $meta, $id );
|
4078 |
ewwwio_debug_message( 're-uploading to S3(_Uploads)' );
|
4079 |
}
|
4248 |
}
|
4249 |
$s3_path = false;
|
4250 |
$s3_dir = false;
|
4251 |
+
if ( ( class_exists( 'S3_Uploads' ) || class_exists( 'S3_Uploads\Plugin' ) ) && ewww_image_optimizer_get_option( 'ewww_image_optimizer_webp' ) ) {
|
4252 |
$s3_path = get_attached_file( $id );
|
4253 |
if ( 0 === strpos( $s3_path, 's3://' ) ) {
|
4254 |
ewwwio_debug_message( 'removing: ' . $s3_path . '.webp' );
|
4688 |
wp_json_encode(
|
4689 |
array(
|
4690 |
'error' => sprintf(
|
4691 |
+
/* translators: %s: an HTTP error message */
|
4692 |
esc_html__( 'Could not validate API key, HTTP error: %s', 'ewww-image-optimizer' ),
|
4693 |
$error_message
|
4694 |
),
|
5001 |
add_filter( 'image_memory_limit', 'ewww_image_optimizer_raise_memory_limit' );
|
5002 |
wp_raise_memory_limit( 'image' );
|
5003 |
}
|
|
|
5004 |
}
|
5005 |
$api_key = ewww_image_optimizer_get_option( 'ewww_image_optimizer_cloud_key' );
|
5006 |
if ( 'exceeded' === get_transient( 'ewww_image_optimizer_cloud_status' ) ) {
|
5060 |
$lossy = 0;
|
5061 |
$lossy_fast = 0;
|
5062 |
}
|
5063 |
+
$sharp_yuv = defined( 'EIO_WEBP_SHARP_YUV' ) && EIO_WEBP_SHARP_YUV ? 1 : 0;
|
5064 |
if ( 'image/webp' === $newtype ) {
|
5065 |
$webp = 1;
|
5066 |
$jpg_quality = apply_filters( 'webp_quality', 75, 'image/webp' );
|
5115 |
ewwwio_debug_message( "newfile: $newfile" );
|
5116 |
ewwwio_debug_message( "newtype: $newtype" );
|
5117 |
ewwwio_debug_message( "webp: $webp" );
|
5118 |
+
ewwwio_debug_message( "sharp_yuv: $sharp_yuv" );
|
5119 |
ewwwio_debug_message( "jpg fill: $jpg_fill" );
|
5120 |
ewwwio_debug_message( "jpg quality: $jpg_quality" );
|
5121 |
$free_exec = EWWW_IMAGE_OPTIMIZER_NOEXEC && 'image/jpeg' === $type;
|
5155 |
'lossy' => $lossy,
|
5156 |
'lossy_fast' => $lossy_fast,
|
5157 |
'webp' => $webp,
|
5158 |
+
'sharp_yuv' => $sharp_yuv,
|
5159 |
'backup' => $hash,
|
5160 |
'domain' => $domain,
|
5161 |
);
|
5260 |
add_filter( 'image_memory_limit', 'ewww_image_optimizer_raise_memory_limit' );
|
5261 |
wp_raise_memory_limit( 'image' );
|
5262 |
}
|
|
|
5263 |
}
|
5264 |
$api_key = ewww_image_optimizer_get_option( 'ewww_image_optimizer_cloud_key' );
|
5265 |
if ( empty( $api_key ) ) {
|
5386 |
add_filter( 'image_memory_limit', 'ewww_image_optimizer_raise_memory_limit' );
|
5387 |
wp_raise_memory_limit( 'image' );
|
5388 |
}
|
|
|
5389 |
}
|
5390 |
if ( ! ewww_image_optimizer_cloud_verify( $api_key ) ) {
|
5391 |
ewwwio_debug_message( 'cloud verify failed, image not backed up' );
|
5499 |
add_filter( 'image_memory_limit', 'ewww_image_optimizer_raise_memory_limit' );
|
5500 |
wp_raise_memory_limit( 'image' );
|
5501 |
}
|
|
|
5502 |
}
|
5503 |
$api_key = ewww_image_optimizer_get_option( 'ewww_image_optimizer_cloud_key' );
|
5504 |
if ( empty( $api_key ) ) {
|
6002 |
$updates['level'] = $ewww_image->level;
|
6003 |
}
|
6004 |
$updates['orig_size'] = $orig_size;
|
6005 |
+
/* $updates['updated'] = gmdate( 'Y-m-d H:i:s' ); */
|
6006 |
$ewwwdb->insert( $ewwwdb->ewwwio_images, $updates );
|
6007 |
} else {
|
6008 |
if ( is_array( $already_optimized ) && empty( $already_optimized['orig_size'] ) ) {
|
6334 |
*/
|
6335 |
function ewww_image_optimizer_remote_push( $meta, $id ) {
|
6336 |
ewwwio_debug_message( '<b>' . __FUNCTION__ . '()</b>' );
|
6337 |
+
if ( ( class_exists( 'S3_Uploads' ) || class_exists( 'S3_Uploads\Plugin' ) ) && ! empty( $meta['file'] ) ) {
|
6338 |
$s3_upload_dir = wp_get_upload_dir();
|
6339 |
$s3_upload_dir = trailingslashit( $s3_upload_dir['basedir'] );
|
6340 |
$s3_path = get_attached_file( $id );
|
6425 |
if ( ! function_exists( 'download_url' ) ) {
|
6426 |
require_once( ABSPATH . '/wp-admin/includes/file.php' );
|
6427 |
}
|
6428 |
+
$filename = false;
|
6429 |
+
if ( ( class_exists( 'S3_Uploads' ) || class_exists( 'S3_Uploads\Plugin' ) ) && ! empty( $meta['file'] ) ) {
|
6430 |
$s3_upload_dir = wp_get_upload_dir();
|
6431 |
$s3_upload_dir = trailingslashit( $s3_upload_dir['basedir'] );
|
6432 |
$s3_path = get_attached_file( $id );
|
6747 |
if ( ! empty( $filename ) && ewwwio_is_file( $filename ) ) {
|
6748 |
ewwwio_debug_message( "$filename found, success!" );
|
6749 |
return $filename;
|
6750 |
+
} elseif ( ! empty( $filename ) ) {
|
6751 |
ewwwio_debug_message( "$filename not found, boo..." );
|
|
|
6752 |
}
|
6753 |
+
return false;
|
6754 |
}
|
6755 |
|
6756 |
/**
|
7183 |
add_filter( 'image_memory_limit', 'ewww_image_optimizer_raise_memory_limit' );
|
7184 |
wp_raise_memory_limit( 'image' );
|
7185 |
}
|
|
|
7186 |
}
|
7187 |
if ( ! function_exists( 'wp_get_image_editor' ) ) {
|
7188 |
ewwwio_debug_message( 'no image editor function' );
|
8226 |
ewwwio_debug_message( 'uploading to Amazon S3' );
|
8227 |
}
|
8228 |
}
|
8229 |
+
if ( class_exists( 'S3_Uploads' ) || class_exists( 'S3_Uploads\Plugin' ) ) {
|
8230 |
ewww_image_optimizer_remote_push( $meta, $id );
|
8231 |
ewwwio_debug_message( 're-uploading to S3(_Uploads)' );
|
8232 |
}
|
8546 |
'post_mime_type' => $mime,
|
8547 |
)
|
8548 |
);
|
|
|
|
|
8549 |
return $meta;
|
8550 |
}
|
8551 |
|
8920 |
return $apng;
|
8921 |
}
|
8922 |
|
8923 |
+
/**
|
8924 |
+
* Check a JPG to see if it uses the CMYK color space.
|
8925 |
+
*
|
8926 |
+
* @param string $filename Name of the JPG to test.
|
8927 |
+
* @return bool True if CMYK, false otherwise.
|
8928 |
+
*/
|
8929 |
+
function ewww_image_optimizer_is_cmyk( $filename ) {
|
8930 |
+
ewwwio_debug_message( '<b>' . __FUNCTION__ . '()</b>' );
|
8931 |
+
if ( ewww_image_optimizer_imagick_support() ) {
|
8932 |
+
$image = new Imagick( $filename );
|
8933 |
+
$color = $image->getImageColorspace();
|
8934 |
+
ewwwio_debug_message( "color space is $color" );
|
8935 |
+
$image->destroy();
|
8936 |
+
if ( Imagick::COLORSPACE_CMYK === $color ) {
|
8937 |
+
return true;
|
8938 |
+
}
|
8939 |
+
} elseif ( ewww_image_optimizer_gd_support() ) {
|
8940 |
+
$info = getimagesize( $filename );
|
8941 |
+
if ( ! empty( $info['channels'] ) ) {
|
8942 |
+
ewwwio_debug_message( "channel count is {$info['channels']}" );
|
8943 |
+
if ( 4 === (int) $info['channels'] ) {
|
8944 |
+
return true;
|
8945 |
+
}
|
8946 |
+
}
|
8947 |
+
}
|
8948 |
+
return false;
|
8949 |
+
}
|
8950 |
+
|
8951 |
/**
|
8952 |
* Count how many sizes are in the metadata, accounting for those with duplicate dimensions.
|
8953 |
*
|
9058 |
echo '<div>' . esc_html__( 'Amazon S3 image', 'ewww-image-optimizer' ) . '</div>';
|
9059 |
$ewww_cdn = true;
|
9060 |
}
|
9061 |
+
if ( is_array( $meta ) && class_exists( 'S3_Uploads\Plugin' ) && preg_match( '/^(http|s3|gs)\w*:/', get_attached_file( $id ) ) ) {
|
9062 |
+
echo '<div>' . esc_html__( 'Amazon S3 image', 'ewww-image-optimizer' ) . '</div>';
|
9063 |
+
$ewww_cdn = true;
|
9064 |
+
}
|
9065 |
if ( is_array( $meta ) & class_exists( 'wpCloud\StatelessMedia\EWWW' ) && ! empty( $meta['gs_link'] ) ) {
|
9066 |
echo '<div>' . esc_html__( 'WP Stateless image', 'ewww-image-optimizer' ) . '</div>';
|
9067 |
$ewww_cdn = true;
|
9186 |
) . '</div>';
|
9187 |
}
|
9188 |
break;
|
9189 |
+
case 'image/webp':
|
9190 |
+
if ( ! $ewww_cdn && ewwwio_is_file( $file_path ) ) {
|
9191 |
+
$webp_size = ewww_image_optimizer_filesize( $file_path );
|
9192 |
+
// Get a human readable filesize.
|
9193 |
+
$webp_size = ewww_image_optimizer_size_format( $webp_size );
|
9194 |
+
echo '<div>WebP: ' . esc_html( $webp_size ) . '</div>';
|
9195 |
+
}
|
9196 |
+
return;
|
9197 |
+
break;
|
9198 |
default:
|
9199 |
// Not a supported mimetype.
|
9200 |
$msg = '<div>' . esc_html__( 'Unsupported file type', 'ewww-image-optimizer' ) . '</div>';
|
9443 |
} // End if().
|
9444 |
echo '</div>';
|
9445 |
} // End if().
|
|
|
|
|
9446 |
}
|
9447 |
|
9448 |
/**
|
9513 |
$processed = array();
|
9514 |
foreach ( $sizes as $size => $data ) {
|
9515 |
ewwwio_debug_message( "checking for size: $size" );
|
|
|
9516 |
if ( strpos( $size, 'webp' ) === 0 ) {
|
9517 |
continue;
|
9518 |
}
|
10858 |
ewwwio_debug_message( 'png2jpg fill:' );
|
10859 |
ewww_image_optimizer_jpg_background();
|
10860 |
ewwwio_debug_message( 'webp conversion: ' . ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_webp' ) ? 'on' : 'off' ) );
|
10861 |
+
ewwwio_debug_message( 'js webp rewriting: ' . ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_webp_for_cdn' ) ? 'on' : 'off' ) );
|
10862 |
ewwwio_debug_message( 'picture webp rewriting: ' . ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_picture_webp' ) ? 'on' : 'off' ) );
|
10863 |
ewwwio_debug_message( 'WebP Rewrite exclusions:' );
|
10864 |
$webp_exclude_paths = ewww_image_optimizer_get_option( 'ewww_image_optimizer_webp_rewrite_exclude' ) ? esc_html( implode( "\n", ewww_image_optimizer_get_option( 'ewww_image_optimizer_webp_rewrite_exclude' ) ) ) : '';
|
10881 |
! ewww_image_optimizer_get_option( 'ewww_image_optimizer_webp_for_cdn' ) &&
|
10882 |
! ewww_image_optimizer_get_option( 'ewww_image_optimizer_picture_webp' ) &&
|
10883 |
! ewww_image_optimizer_ce_webp_enabled() &&
|
10884 |
+
! ewww_image_optimizer_swis_webp_enabled() &&
|
10885 |
! ewww_image_optimizer_easy_active()
|
10886 |
) {
|
10887 |
if ( defined( 'PHP_SAPI' ) ) {
|
10924 |
$eio_base = new EIO_Base();
|
10925 |
$easyio_site_url = $eio_base->content_url();
|
10926 |
$no_tracking = false;
|
10927 |
+
$webp_available = ewww_image_optimizer_webp_available();
|
10928 |
$bulk_available = false;
|
10929 |
$tools_available = true;
|
10930 |
if ( ! defined( 'EWWW_IMAGE_OPTIMIZER_NOEXEC' ) ) {
|
10974 |
// Expand the missing utilities list for use in the error message.
|
10975 |
$tools_missing_message = implode( ', ', $tools_missing );
|
10976 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
10977 |
if (
|
10978 |
! ewww_image_optimizer_get_option( 'ewww_image_optimizer_exactdn' ) ||
|
10979 |
ewww_image_optimizer_get_option( 'ewww_image_optimizer_cloud_key' ) ||
|
11015 |
}
|
11016 |
if ( $tools_missing_notice && ! $tools_available ) {
|
11017 |
ewww_image_optimizer_enable_free_exec();
|
|
|
11018 |
}
|
11019 |
}
|
11020 |
if ( 3 === $wizard_step ) {
|
11094 |
);
|
11095 |
?>
|
11096 |
</span>
|
11097 |
+
<?php if ( false !== strpos( $easyio_site_url, 'localhost' ) ) : ?>
|
11098 |
+
<br><span class="description" style="font-weight: bolder"><?php esc_html_e( 'Easy IO cannot be activated on localhost installs.', 'ewww-image-optimizer' ); ?></span>
|
11099 |
+
<?php elseif ( empty( ewww_image_optimizer_get_option( 'ewww_image_optimizer_exactdn' ) ) ) : ?>
|
11100 |
<br><br>
|
11101 |
<a href="<?php echo esc_url( add_query_arg( 'site_url', trim( $easyio_site_url ), 'https://ewww.io/manage-sites/' ) ); ?>" target="_blank">
|
11102 |
<?php esc_html_e( 'First, add your Site URL to your account:', 'easy-image-optimizer' ); ?>
|
11107 |
<a id='ewwwio-easy-activate' href='#' class='button-secondary'><?php esc_html_e( 'Activate', 'ewww-image-optimizer' ); ?></a>
|
11108 |
<span id='ewwwio-easy-activation-processing'><img src='<?php echo esc_url( $loading_image_url ); ?>' alt='loading'/></span>
|
11109 |
<?php elseif ( class_exists( 'ExactDN' ) && ewww_image_optimizer_get_option( 'ewww_image_optimizer_exactdn' ) && $exactdn->get_exactdn_domain() && $exactdn->verify_domain( $exactdn->get_exactdn_domain() ) ) : ?>
|
11110 |
+
<br><span style="color: #3eadc9; font-weight: bolder"><?php esc_html_e( 'Verified', 'ewww-image-optimizer' ); ?></span>
|
11111 |
<span class="dashicons dashicons-yes"></span>
|
11112 |
<?php endif; ?>
|
11113 |
</p>
|
11871 |
sprintf(
|
11872 |
/* translators: %s: S3 Image Optimizer (link) */
|
11873 |
esc_html__( 'Optimize unlimited Amazon S3 buckets with our %s.' ),
|
11874 |
+
'<a href="https://wordpress.org/plugins/s3-image-optimizer/">' . esc_html__( 'S3 Image Optimizer', 'ewww-image-optimizer' ) . '</a>'
|
11875 |
) : '' );
|
11876 |
?>
|
11877 |
</p>
|
11995 |
if ( ewww_image_optimizer_easy_active() || $cf_host ) {
|
11996 |
ewww_image_optimizer_webp_rewrite_verify();
|
11997 |
}
|
11998 |
+
$webp_available = ewww_image_optimizer_webp_available();
|
11999 |
$test_webp_image = plugins_url( '/images/test.png.webp', __FILE__ );
|
12000 |
$test_png_image = plugins_url( '/images/test.png', __FILE__ );
|
12001 |
?>
|
12085 |
</tr>
|
12086 |
</table>
|
12087 |
<input type='hidden' id='ewww_image_optimizer_allow_multisite_override_active' name='ewww_image_optimizer_allow_multisite_override_active' value='0'>
|
|
|
|
|
|
|
12088 |
</div><!-- end container general settings -->
|
12089 |
<p class='submit'><input type='submit' class='button-primary' value='<?php esc_attr_e( 'Save Changes', 'ewww-image-optimizer' ); ?>' /></p>
|
12090 |
</form>
|
12107 |
<a class='button-secondary' href='<?php echo esc_url( admin_url( 'admin.php?action=ewww_image_optimizer_remove_cloud_key' ) ); ?>'>
|
12108 |
<?php esc_html_e( 'Remove API key', 'ewww-image-optimizer' ); ?>
|
12109 |
</a>
|
|
|
12110 |
<p>
|
12111 |
<?php if ( false !== strpos( $verify_cloud, 'great' ) ) : ?>
|
12112 |
<span style="color: #3eadc9; font-weight: bolder"><?php esc_html_e( 'Verified,', 'ewww-image-optimizer' ); ?> </span><?php echo wp_kses_post( ewww_image_optimizer_cloud_quota() ); ?>
|
12173 |
?>
|
12174 |
<?php if ( class_exists( 'Jetpack' ) && Jetpack::is_module_active( 'photon' ) && ewww_image_optimizer_get_option( 'ewww_image_optimizer_exactdn' ) ) : ?>
|
12175 |
<p style='color: red'><?php esc_html_e( 'Inactive, please disable the Image Accelerator option on the Jetpack Dashboard.', 'ewww-image-optimizer' ); ?></p>
|
12176 |
+
<?php elseif ( false !== strpos( $easyio_site_url, 'localhost' ) ) : ?>
|
12177 |
+
<p class="description" style="font-weight: bolder"><?php esc_html_e( 'Easy IO cannot be activated on localhost installs.', 'ewww-image-optimizer' ); ?></p>
|
12178 |
<?php elseif ( ! $exactdn_enabled ) : ?>
|
12179 |
<p>
|
12180 |
<strong><a href="https://ewww.io/plans/" target="_blank">
|
12426 |
</tr>
|
12427 |
<?php endif; ?>
|
12428 |
<?php endif; ?>
|
12429 |
+
<?php if ( ! $webp_available ) : ?>
|
12430 |
<tr id='ewww_image_optimizer_webp_container'>
|
12431 |
<th scope='row'>
|
12432 |
<label for='ewww_image_optimizer_webp'><?php esc_html_e( 'WebP Conversion', 'ewww-image-optimizer' ); ?></label>
|
12473 |
</tr>
|
12474 |
<tr>
|
12475 |
<?php endif; ?>
|
12476 |
+
<?php if ( ewww_image_optimizer_easy_active() ) : ?>
|
12477 |
+
<tr id='ewww_image_optimizer_webp_easyio_container'>
|
12478 |
+
<th scope='row'>
|
12479 |
+
<label for='ewww_image_optimizer_webp'><?php esc_html_e( 'WebP Conversion', 'ewww-image-optimizer' ); ?></label>
|
12480 |
+
</th>
|
12481 |
+
<td>
|
12482 |
+
<p class='description'><?php esc_html_e( 'WebP images are served automatically by Easy IO.', 'ewww-image-optimizer' ); ?></p>
|
12483 |
+
</td>
|
12484 |
+
</tr>
|
12485 |
+
<?php elseif ( ewww_image_optimizer_ce_webp_enabled() ) : ?>
|
12486 |
+
<tr id='ewww_image_optimizer_webp_setting_container'>
|
12487 |
+
<th scope='row'>
|
12488 |
+
<?php esc_html_e( 'WebP Delivery Method', 'ewww-image-optimizer' ); ?>
|
12489 |
+
</th>
|
12490 |
+
<td>
|
12491 |
+
<p class='description'><?php esc_html_e( 'WebP images are delivered by Cache Enabler.', 'ewww-image-optimizer' ); ?></p>
|
12492 |
+
</td>
|
12493 |
+
</tr>
|
12494 |
+
<?php elseif ( ewww_image_optimizer_swis_webp_enabled() ) : ?>
|
12495 |
+
<tr id='ewww_image_optimizer_webp_setting_container'>
|
12496 |
+
<th scope='row'>
|
12497 |
+
<?php esc_html_e( 'WebP Delivery Method', 'ewww-image-optimizer' ); ?>
|
12498 |
+
</th>
|
12499 |
+
<td>
|
12500 |
+
<p class='description'><?php esc_html_e( 'WebP images are delivered by SWIS Performance.', 'ewww-image-optimizer' ); ?></p>
|
12501 |
+
</td>
|
12502 |
+
</tr>
|
12503 |
+
<?php elseif ( $webp_available ) : ?>
|
12504 |
+
<tr id='ewww_image_optimizer_webp_easyio_container' style='display:none;'>
|
12505 |
+
<th scope='row'>
|
12506 |
+
<label for='ewww_image_optimizer_webp'><?php esc_html_e( 'WebP Conversion', 'ewww-image-optimizer' ); ?></label>
|
12507 |
+
</th>
|
12508 |
+
<td>
|
12509 |
+
<p class='description'><?php esc_html_e( 'WebP images are served automatically by Easy IO.', 'ewww-image-optimizer' ); ?></p>
|
12510 |
+
</td>
|
12511 |
+
</tr>
|
12512 |
<tr class='ewww_image_optimizer_webp_setting_container' <?php echo ewww_image_optimizer_get_option( 'ewww_image_optimizer_webp' ) ? '' : ' style="display:none"'; ?>>
|
12513 |
<th scope='row'>
|
12514 |
<?php esc_html_e( 'WebP Delivery Method', 'ewww-image-optimizer' ); ?>
|
12726 |
</td>
|
12727 |
</tr>
|
12728 |
<?php endif; ?>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
12729 |
<?php endif; ?>
|
12730 |
|
12731 |
<?php if ( class_exists( 'Cloudinary' ) && Cloudinary::config_get( 'api_secret' ) ) : ?>
|
13325 |
<p class='submit'><input type='submit' class='button-primary' value='<?php esc_attr_e( 'Save Changes', 'ewww-image-optimizer' ); ?>' /></p>
|
13326 |
</form>
|
13327 |
|
13328 |
+
<?php if ( ! ewww_image_optimizer_easy_active() && ! ewww_image_optimizer_get_option( 'ewww_image_optimizer_cloud_key' ) ) : ?>
|
13329 |
<hr style='clear:both;'>
|
13330 |
<h2><?php esc_html_e( "Shane's Recommendations", 'ewww-image-optimizer' ); ?></h2>
|
13331 |
<p><?php esc_html_e( 'These are products I have personally used. An * indicates an affiliate link so you can support future development of EWWW IO.', 'ewww-image-optimizer' ); ?></p>
|
13354 |
<a href="https://nodeping.com?rid=201407082225W862K">NodePing</a>* -
|
13355 |
<?php esc_html_e( 'Monitor all the things, and make sure they stay online. They have a fantastic array of monitors and notifications that you can setup, they are cheap, simple, and have great support.', 'ewww-image-optimizer' ); ?>
|
13356 |
</p>
|
13357 |
+
<?php endif; ?>
|
13358 |
</div><!-- end container wrap -->
|
13359 |
<?php
|
13360 |
if ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_enable_help' ) ) {
|
13493 |
delete_site_option( 'ewww_image_optimizer_exactdn_verified' );
|
13494 |
delete_site_option( 'ewww_image_optimizer_exactdn_validation' );
|
13495 |
delete_site_option( 'ewww_image_optimizer_exactdn_suspended' );
|
13496 |
+
global $exactdn;
|
13497 |
+
$exactdn->cron_setup( false );
|
13498 |
$sendback = wp_get_referer();
|
13499 |
wp_safe_redirect( $sendback );
|
13500 |
exit;
|
13665 |
$eio_debug = str_replace( '<br>', "\n", $eio_debug );
|
13666 |
file_put_contents( $debug_log, $timestamp . $eio_debug, FILE_APPEND );
|
13667 |
}
|
13668 |
+
$eio_debug = '';
|
13669 |
+
} elseif ( ! is_dir( dirname( $debug_log ) ) || ! is_writable( dirname( $debug_log ) ) ) {
|
13670 |
+
$eio_debug = '';
|
13671 |
}
|
|
|
13672 |
ewwwio_memory( __FUNCTION__ );
|
13673 |
}
|
13674 |
|
ewww-image-optimizer.php
CHANGED
@@ -13,7 +13,7 @@ Plugin Name: EWWW Image Optimizer
|
|
13 |
Plugin URI: https://wordpress.org/plugins/ewww-image-optimizer/
|
14 |
Description: Reduce file sizes for images within WordPress including NextGEN Gallery and GRAND FlAGallery. Uses jpegtran, optipng/pngout, and gifsicle.
|
15 |
Author: Exactly WWW
|
16 |
-
Version: 6.
|
17 |
Author URI: https://ewww.io/
|
18 |
License: GPLv3
|
19 |
*/
|
13 |
Plugin URI: https://wordpress.org/plugins/ewww-image-optimizer/
|
14 |
Description: Reduce file sizes for images within WordPress including NextGEN Gallery and GRAND FlAGallery. Uses jpegtran, optipng/pngout, and gifsicle.
|
15 |
Author: Exactly WWW
|
16 |
+
Version: 6.2.0
|
17 |
Author URI: https://ewww.io/
|
18 |
License: GPLv3
|
19 |
*/
|
includes/check-webp.js
ADDED
@@ -0,0 +1,26 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
var ewww_webp_supported = false;
|
2 |
+
// webp detection adapted from https://developers.google.com/speed/webp/faq#how_can_i_detect_browser_support_using_javascript
|
3 |
+
function check_webp_feature(feature, callback) {
|
4 |
+
callback = (typeof callback !== 'undefined') ? callback : function(){};
|
5 |
+
if (ewww_webp_supported) {
|
6 |
+
callback(ewww_webp_supported);
|
7 |
+
return;
|
8 |
+
}
|
9 |
+
var kTestImages = {
|
10 |
+
alpha: "UklGRkoAAABXRUJQVlA4WAoAAAAQAAAAAAAAAAAAQUxQSAwAAAARBxAR/Q9ERP8DAABWUDggGAAAABQBAJ0BKgEAAQAAAP4AAA3AAP7mtQAAAA==",
|
11 |
+
};
|
12 |
+
var img = new Image();
|
13 |
+
img.onload = function () {
|
14 |
+
ewww_webp_supported = (img.width > 0) && (img.height > 0);
|
15 |
+
if (callback) {
|
16 |
+
callback(ewww_webp_supported);
|
17 |
+
}
|
18 |
+
};
|
19 |
+
img.onerror = function () {
|
20 |
+
if (callback) {
|
21 |
+
callback(false);
|
22 |
+
}
|
23 |
+
};
|
24 |
+
img.src = "data:image/webp;base64," + kTestImages[feature];
|
25 |
+
}
|
26 |
+
check_webp_feature('alpha');
|
includes/check-webp.min.js
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
var ewww_webp_supported=!1;function check_webp_feature(A,e){if(e=void 0!==e?e:function(){},ewww_webp_supported)e(ewww_webp_supported);else{var w=new Image;w.onload=function(){ewww_webp_supported=0<w.width&&0<w.height,e&&e(ewww_webp_supported)},w.onerror=function(){e&&e(!1)},w.src="data:image/webp;base64,"+{alpha:"UklGRkoAAABXRUJQVlA4WAoAAAAQAAAAAAAAAAAAQUxQSAwAAAARBxAR/Q9ERP8DAABWUDggGAAAABQBAJ0BKgEAAQAAAP4AAA3AAP7mtQAAAA=="}[A]}}check_webp_feature("alpha");
|
includes/eio-tools.js
CHANGED
@@ -271,6 +271,10 @@ jQuery(document).ready(function($) {
|
|
271 |
if (!confirm(ewww_vars.tool_warning)) {
|
272 |
return false;
|
273 |
}
|
|
|
|
|
|
|
|
|
274 |
var ewww_originals_data = {
|
275 |
action: 'ewwwio_get_all_attachments',
|
276 |
ewww_wpnonce: ewww_vars._wpnonce,
|
@@ -279,11 +283,23 @@ jQuery(document).ready(function($) {
|
|
279 |
try {
|
280 |
ewww_original_attachments = JSON.parse(response);
|
281 |
} catch (err) {
|
|
|
|
|
|
|
282 |
$('#ewww-clean-originals-progress').html('<span style="color: red"><b>' + ewww_vars.invalid_response + '</b></span>');
|
|
|
283 |
console.log(err);
|
284 |
console.log(response);
|
285 |
return false;
|
286 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
287 |
ewww_total_originals = ewww_original_attachments.length;
|
288 |
$('.ewww-tool-info').hide();
|
289 |
$('.ewww-tool-form').hide();
|
@@ -319,6 +335,12 @@ jQuery(document).ready(function($) {
|
|
319 |
return false;
|
320 |
}
|
321 |
if(!ewww_original_attachments.length) {
|
|
|
|
|
|
|
|
|
|
|
|
|
322 |
$('#ewww-clean-originals-progress').html(ewww_vars.finished);
|
323 |
return false;
|
324 |
}
|
@@ -334,6 +356,10 @@ jQuery(document).ready(function($) {
|
|
334 |
action: 'bulk_aux_images_count_converted',
|
335 |
ewww_wpnonce: ewww_vars._wpnonce,
|
336 |
};
|
|
|
|
|
|
|
|
|
337 |
$.post(ajaxurl, ewww_converted_data, function(response) {
|
338 |
try {
|
339 |
var ewww_response = JSON.parse(response);
|
@@ -391,6 +417,10 @@ jQuery(document).ready(function($) {
|
|
391 |
action: 'ewwwio_get_all_attachments',
|
392 |
ewww_wpnonce: ewww_vars._wpnonce,
|
393 |
};
|
|
|
|
|
|
|
|
|
394 |
$.post(ajaxurl, ewww_webp_data, function(response) {
|
395 |
try {
|
396 |
ewww_webp_attachments = JSON.parse(response);
|
@@ -481,6 +511,10 @@ jQuery(document).ready(function($) {
|
|
481 |
});
|
482 |
}
|
483 |
$('#ewww-clean-table').on( 'submit', function() {
|
|
|
|
|
|
|
|
|
484 |
ewww_total_pages = Math.ceil(ewww_vars.image_count / 500);
|
485 |
$('.ewww-tool-info').hide();
|
486 |
$('.ewww-tool-form').hide();
|
@@ -525,6 +559,10 @@ jQuery(document).ready(function($) {
|
|
525 |
});
|
526 |
}
|
527 |
$('#ewww-clean-meta').on( 'submit', function() {
|
|
|
|
|
|
|
|
|
528 |
$('.ewww-tool-info').hide();
|
529 |
$('.ewww-tool-form').hide();
|
530 |
$('.ewww-tool-divider').hide();
|
271 |
if (!confirm(ewww_vars.tool_warning)) {
|
272 |
return false;
|
273 |
}
|
274 |
+
var header_label = $(this).find('input[type="submit"]').val();
|
275 |
+
if (header_label) {
|
276 |
+
$('#ewwwio-tools-header').html(header_label);
|
277 |
+
}
|
278 |
var ewww_originals_data = {
|
279 |
action: 'ewwwio_get_all_attachments',
|
280 |
ewww_wpnonce: ewww_vars._wpnonce,
|
283 |
try {
|
284 |
ewww_original_attachments = JSON.parse(response);
|
285 |
} catch (err) {
|
286 |
+
$('.ewww-tool-info').hide();
|
287 |
+
$('.ewww-tool-form').hide();
|
288 |
+
$('.ewww-tool-divider').hide();
|
289 |
$('#ewww-clean-originals-progress').html('<span style="color: red"><b>' + ewww_vars.invalid_response + '</b></span>');
|
290 |
+
$('#ewww-clean-originals-progress').show();
|
291 |
console.log(err);
|
292 |
console.log(response);
|
293 |
return false;
|
294 |
}
|
295 |
+
if ( ewww_original_attachments.error ) {
|
296 |
+
$('.ewww-tool-info').hide();
|
297 |
+
$('.ewww-tool-form').hide();
|
298 |
+
$('.ewww-tool-divider').hide();
|
299 |
+
$('#ewww-clean-originals-progress').html(ewww_original_attachments.error);
|
300 |
+
$('#ewww-clean-originals-progress').show();
|
301 |
+
return false;
|
302 |
+
}
|
303 |
ewww_total_originals = ewww_original_attachments.length;
|
304 |
$('.ewww-tool-info').hide();
|
305 |
$('.ewww-tool-form').hide();
|
335 |
return false;
|
336 |
}
|
337 |
if(!ewww_original_attachments.length) {
|
338 |
+
var ewww_originals_data = {
|
339 |
+
action: 'bulk_aux_images_delete_original',
|
340 |
+
ewww_wpnonce: ewww_vars._wpnonce,
|
341 |
+
delete_originals_done: 1,
|
342 |
+
};
|
343 |
+
$.post(ajaxurl, ewww_originals_data);
|
344 |
$('#ewww-clean-originals-progress').html(ewww_vars.finished);
|
345 |
return false;
|
346 |
}
|
356 |
action: 'bulk_aux_images_count_converted',
|
357 |
ewww_wpnonce: ewww_vars._wpnonce,
|
358 |
};
|
359 |
+
var header_label = $(this).find('input[type="submit"]').val();
|
360 |
+
if (header_label) {
|
361 |
+
$('#ewwwio-tools-header').html(header_label);
|
362 |
+
}
|
363 |
$.post(ajaxurl, ewww_converted_data, function(response) {
|
364 |
try {
|
365 |
var ewww_response = JSON.parse(response);
|
417 |
action: 'ewwwio_get_all_attachments',
|
418 |
ewww_wpnonce: ewww_vars._wpnonce,
|
419 |
};
|
420 |
+
var header_label = $(this).find('input[type="submit"]').val();
|
421 |
+
if (header_label) {
|
422 |
+
$('#ewwwio-tools-header').html(header_label);
|
423 |
+
}
|
424 |
$.post(ajaxurl, ewww_webp_data, function(response) {
|
425 |
try {
|
426 |
ewww_webp_attachments = JSON.parse(response);
|
511 |
});
|
512 |
}
|
513 |
$('#ewww-clean-table').on( 'submit', function() {
|
514 |
+
var header_label = $(this).find('input[type="submit"]').val();
|
515 |
+
if (header_label) {
|
516 |
+
$('#ewwwio-tools-header').html(header_label);
|
517 |
+
}
|
518 |
ewww_total_pages = Math.ceil(ewww_vars.image_count / 500);
|
519 |
$('.ewww-tool-info').hide();
|
520 |
$('.ewww-tool-form').hide();
|
559 |
});
|
560 |
}
|
561 |
$('#ewww-clean-meta').on( 'submit', function() {
|
562 |
+
var header_label = $(this).find('input[type="submit"]').val();
|
563 |
+
if (header_label) {
|
564 |
+
$('#ewwwio-tools-header').html(header_label);
|
565 |
+
}
|
566 |
$('.ewww-tool-info').hide();
|
567 |
$('.ewww-tool-form').hide();
|
568 |
$('.ewww-tool-divider').hide();
|
includes/lazysizes-post.js
CHANGED
@@ -1,4 +1,4 @@
|
|
1 |
-
|
2 |
function shouldAutoScale(target){
|
3 |
if (eio_lazy_vars.skip_autoscale == 1) {
|
4 |
console.log('autoscale disabled globally');
|
1 |
+
lazySizes.init();
|
2 |
function shouldAutoScale(target){
|
3 |
if (eio_lazy_vars.skip_autoscale == 1) {
|
4 |
console.log('autoscale disabled globally');
|
includes/lazysizes-pre.js
CHANGED
@@ -1,4 +1,4 @@
|
|
1 |
-
var ewww_webp_supported = false;
|
2 |
function lazysizesWebP(feature, callback) {
|
3 |
var kTestImages = {
|
4 |
alpha: "UklGRkoAAABXRUJQVlA4WAoAAAAQAAAAAAAAAAAAQUxQSAwAAAARBxAR/Q9ERP8DAABWUDggGAAAABQBAJ0BKgEAAQAAAP4AAA3AAP7mtQAAAA==",
|
@@ -13,7 +13,7 @@ function lazysizesWebP(feature, callback) {
|
|
13 |
callback();
|
14 |
};
|
15 |
img.src = "data:image/webp;base64," + kTestImages[feature];
|
16 |
-
}
|
17 |
window.lazySizesConfig = window.lazySizesConfig || {};
|
18 |
window.lazySizesConfig.init = false;
|
19 |
window.lazySizesConfig.expand = document.documentElement.clientHeight > 500 && document.documentElement.clientWidth > 500 ? 1000 : 740;
|
1 |
+
/*var ewww_webp_supported = false;
|
2 |
function lazysizesWebP(feature, callback) {
|
3 |
var kTestImages = {
|
4 |
alpha: "UklGRkoAAABXRUJQVlA4WAoAAAAQAAAAAAAAAAAAQUxQSAwAAAARBxAR/Q9ERP8DAABWUDggGAAAABQBAJ0BKgEAAQAAAP4AAA3AAP7mtQAAAA==",
|
13 |
callback();
|
14 |
};
|
15 |
img.src = "data:image/webp;base64," + kTestImages[feature];
|
16 |
+
}*/
|
17 |
window.lazySizesConfig = window.lazySizesConfig || {};
|
18 |
window.lazySizesConfig.init = false;
|
19 |
window.lazySizesConfig.expand = document.documentElement.clientHeight > 500 && document.documentElement.clientWidth > 500 ? 1000 : 740;
|
includes/lazysizes.min.js
CHANGED
@@ -1 +1 @@
|
|
1 |
-
var ewww_webp_supported=!1;function lazysizesWebP(e,t){var a=new Image;a.onload=function(){ewww_webp_supported=0<a.width&&0<a.height,t()},a.onerror=function(){t()},a.src="data:image/webp;base64,"+{alpha:"UklGRkoAAABXRUJQVlA4WAoAAAAQAAAAAAAAAAAAQUxQSAwAAAARBxAR/Q9ERP8DAABWUDggGAAAABQBAJ0BKgEAAQAAAP4AAA3AAP7mtQAAAA==",animation:"UklGRlIAAABXRUJQVlA4WAoAAAASAAAAAAAAAAAAQU5JTQYAAAD/////AABBTk1GJgAAAAAAAAAAAAAAAAAAAGQAAABWUDhMDQAAAC8AAAAQBxAREYiI/gcA"}[e]}function shouldAutoScale(e){if(1==eio_lazy_vars.skip_autoscale)return!1;if(e.hasAttributes())for(var t=e.attributes,a=/skip-autoscale/,i=t.length-1;0<=i;i--){if(a.test(t[i].name))return!1;if(a.test(t[i].value))return!1}return!0}function constrainSrc(e,t,a,i){if(null===e)return e;var r=/w=(\d+)/,n=/fit=(\d+),(\d+)/,o=/resize=(\d+),(\d+)/,s=decodeURIComponent(e);if("undefined"==typeof eio_lazy_vars&&(eio_lazy_vars={exactdn_domain:".exactdn.com"}),0<e.search("\\?")&&0<e.search(eio_lazy_vars.exactdn_domain)){var l=o.exec(s);if(l&&t<l[1])return s.replace(o,"resize="+t+","+a);var d=r.exec(e);if(d&&t<=d[1]){if("bg-cover"!==i&&"img-crop"!==i)return e.replace(r,"w="+t);var c=d[1]-t;return 20<c||a<1080?e.replace(r,"resize="+t+","+a):e}var u=n.exec(s);if(u&&t<u[1]){if("bg-cover"!==i&&"img-crop"!==i)return s.replace(n,"fit="+t+","+a);var f=u[1]-t,A=u[2]-a;return 20<f||20<A?e.replace(r,"resize="+t+","+a):e}if(!d&&!u&&!l)return"img"===i?e+"&fit="+t+","+a:"bg-cover"===i||"img-crop"===i?e+"&resize="+t+","+a:t<a?e+"&h="+a:e+"&w="+t}return-1==e.search("\\?")&&0<e.search(eio_lazy_vars.exactdn_domain)?"img"===i?e+"?fit="+t+","+a:"bg-cover"===i||"img-crop"===i?e+"?resize="+t+","+a:t<a?e+"?h="+a:e+"?w="+t:e}window.lazySizesConfig=window.lazySizesConfig||{},window.lazySizesConfig.init=!1,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){var a=function(i,A,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])}(),!A||!A.getElementsByClassName)return{init:function(){},cfg:h,noSupport:!0};var z=A.documentElement,r=i.HTMLPictureElement,o="addEventListener",m="getAttribute",e=i[o].bind(i),v=i.setTimeout,a=i.requestAnimationFrame||v,s=i.requestIdleCallback,p=/^picture$/i,l=["load","error","lazyincluded","_lazyloaded"],d={},y=Array.prototype.forEach,c=function(e,t){return d[t]||(d[t]=new RegExp("(\\s|^)"+t+"(\\s|$)")),d[t].test(e[m]("class")||"")&&d[t]},b=function(e,t){c(e,t)||e.setAttribute("class",(e[m]("class")||"").trim()+" "+t)},w=function(e,t){var a;(a=c(e,t))&&e.setAttribute("class",(e[m]("class")||"").replace(a," "))},_=function(t,a,e){var i=e?o:"removeEventListener";e&&_(t,a),l.forEach(function(e){t[i](e,a)})},C=function(e,t,a,i,r){var n=A.createEvent("Event");return a||(a={}),a.instance=g,n.initEvent(t,!i,!r),n.detail=a,e.dispatchEvent(n),n},S=function(e,t){var a;!r&&(a=i.picturefill||h.pf)?(t&&t.src&&!e[m]("srcset")&&e.setAttribute("srcset",t.src),a({reevaluate:!0,elements:[e]})):t&&t.src&&(e.src=t.src)},u=function(e,t){return(getComputedStyle(e,null)||{})[t]},f=function(e,t,a){for(a=a||e.offsetWidth;a<h.minSize&&t&&!e._lazysizesWidth;)a=t.offsetWidth,t=t.parentNode;return a},E=(we=[],_e=[],Ce=we,Se=function(){var e=Ce;for(Ce=we.length?_e:we,be=!(ye=!0);e.length;)e.shift()();ye=!1},Ee=function(e,t){ye&&!t?e.apply(this,arguments):(Ce.push(e),be||(be=!0,(A.hidden?v:a)(Se)))},Ee._lsFlush=Se,Ee),t=function(a,e){return e?function(){E(a)}:function(){var e=this,t=arguments;E(function(){a.apply(e,t)})}},W=function(e){var t,a,i=function(){t=null,e()},r=function(){var e=n.now()-a;e<99?v(r,99-e):(s||i)(i)};return function(){a=n.now(),t||(t=v(r,99))}},x=(ee=/^img$/i,te=/^iframe$/i,ae="onscroll"in i&&!/(gle|ing)bot/.test(navigator.userAgent),ie=0,re=0,ne=-1,oe=function(e){re--,(!e||re<0||!e.target)&&(re=0)},se=function(e){return null==$&&($="hidden"==u(A.body,"visibility")),$||!("hidden"==u(e.parentNode,"visibility")&&"hidden"==u(e,"visibility"))},le=function(e,t){var a,i=e,r=se(e);for(I-=t,G+=t,J-=t,O+=t;r&&(i=i.offsetParent)&&i!=A.body&&i!=z;)(r=0<(u(i,"opacity")||1))&&"visible"!=u(i,"overflow")&&(a=i.getBoundingClientRect(),r=O>a.left&&J<a.right&&G>a.top-1&&I<a.bottom+1);return r},de=function(){var e,t,a,i,r,n,o,s,l,d,c,u,f=g.elements;if((D=h.loadMode)&&re<8&&(e=f.length)){for(t=0,ne++;t<e;t++)if(f[t]&&!f[t]._lazyRace)if(!ae||g.prematureUnveil&&g.prematureUnveil(f[t]))ze(f[t]);else if((s=f[t][m]("data-expand"))&&(n=1*s)||(n=ie),d||(d=!h.expand||h.expand<1?500<z.clientHeight&&500<z.clientWidth?500:370:h.expand,g._defEx=d,c=d*h.expFactor,u=h.hFac,$=null,ie<c&&re<1&&2<ne&&2<D&&!A.hidden?(ie=c,ne=0):ie=1<D&&1<ne&&re<6?d:0),l!==n&&(U=innerWidth+n*u,F=innerHeight+n,o=-1*n,l=n),a=f[t].getBoundingClientRect(),(G=a.bottom)>=o&&(I=a.top)<=F&&(O=a.right)>=o*u&&(J=a.left)<=U&&(G||O||J||I)&&(h.loadHidden||se(f[t]))&&(P&&re<3&&!s&&(D<3||ne<4)||le(f[t],n))){if(ze(f[t]),r=!0,9<re)break}else!r&&P&&!i&&re<4&&ne<4&&2<D&&(k[0]||h.preloadAfterLoad)&&(k[0]||!s&&(G||O||J||I||"auto"!=f[t][m](h.sizesAttr)))&&(i=k[0]||f[t]);i&&!r&&ze(i)}},q=de,V=0,X=h.throttleDelay,Y=h.ricTimeout,K=function(){j=!1,V=n.now(),q()},Z=s&&49<Y?function(){s(K,{timeout:Y}),Y!==h.ricTimeout&&(Y=h.ricTimeout)}:t(function(){v(K)},!0),ce=function(e){var t;(e=!0===e)&&(Y=33),j||(j=!0,(t=X-(n.now()-V))<0&&(t=0),e||t<9?Z():v(Z,t))},ue=function(e){var t=e.target;t._lazyCache?delete t._lazyCache:(oe(e),b(t,h.loadedClass),w(t,h.loadingClass),_(t,Ae),C(t,"lazyloaded"))},fe=t(ue),Ae=function(e){fe({target:e.target})},ge=function(e){var t,a=e[m](h.srcsetAttr);(t=h.customMedia[e[m]("data-media")||e[m]("media")])&&e.setAttribute("media",t),a&&e.setAttribute("srcset",a)},he=t(function(t,e,a,i,r){var n,o,s,l,d,c,u,f,A;(d=C(t,"lazybeforeunveil",e)).defaultPrevented||(i&&(a?b(t,h.autosizesClass):t.setAttribute("sizes",i)),o=t[m](h.srcsetAttr),n=t[m](h.srcAttr),r&&(s=t.parentNode,l=s&&p.test(s.nodeName||"")),c=e.firesLoad||"src"in t&&(o||n||l),d={target:t},b(t,h.loadingClass),c&&(clearTimeout(H),H=v(oe,2500),_(t,Ae,!0)),l&&y.call(s.getElementsByTagName("source"),ge),o?t.setAttribute("srcset",o):n&&!l&&(te.test(t.nodeName)?(f=n,0==(A=(u=t).getAttribute("data-load-mode")||h.iframeLoadMode)?u.contentWindow.location.replace(f):1==A&&(u.src=f)):t.src=n),r&&(o||l)&&S(t,{src:n})),t._lazyRace&&delete t._lazyRace,w(t,h.lazyClass),E(function(){var e=t.complete&&1<t.naturalWidth;c&&!e||(e&&b(t,h.fastLoadedClass),ue(d),t._lazyCache=!0,v(function(){"_lazyCache"in t&&delete t._lazyCache},9)),"lazy"==t.loading&&re--},!0)}),ze=function(e){if(!e._lazyRace){var t,a=ee.test(e.nodeName),i=a&&(e[m](h.sizesAttr)||e[m]("sizes")),r="auto"==i;(!r&&P||!a||!e[m]("src")&&!e.srcset||e.complete||c(e,h.errorClass)||!c(e,h.lazyClass))&&(t=C(e,"lazyunveilread").detail,r&&M.updateElem(e,!0,e.offsetWidth),e._lazyRace=!0,re++,he(e,t,r,i,a))}},me=W(function(){h.loadMode=3,ce()}),ve=function(){3==h.loadMode&&(h.loadMode=2),me()},pe=function(){P||(n.now()-T<999?v(pe,999):(P=!0,h.loadMode=3,ce(),e("scroll",ve,!0)))},{_:function(){T=n.now(),g.elements=A.getElementsByClassName(h.lazyClass),k=A.getElementsByClassName(h.lazyClass+" "+h.preloadClass),e("scroll",ce,!0),e("resize",ce,!0),e("pageshow",function(e){if(e.persisted){var t=A.querySelectorAll("."+h.loadingClass);t.length&&t.forEach&&a(function(){t.forEach(function(e){e.complete&&ze(e)})})}}),i.MutationObserver?new MutationObserver(ce).observe(z,{childList:!0,subtree:!0,attributes:!0}):(z[o]("DOMNodeInserted",ce,!0),z[o]("DOMAttrModified",ce,!0),setInterval(ce,999)),e("hashchange",ce,!0),["focus","mouseover","click","load","transitionend","animationend"].forEach(function(e){A[o](e,ce,!0)}),/d$|^c/.test(A.readyState)?pe():(e("load",pe),A[o]("DOMContentLoaded",ce),v(pe,2e4)),g.elements.length?(de(),E._lsFlush()):ce()},checkElems:ce,unveil:ze,_aLSL:ve}),M=(N=t(function(e,t,a,i){var r,n,o;if(e._lazysizesWidth=i,i+="px",e.setAttribute("sizes",i),p.test(t.nodeName||""))for(r=t.getElementsByTagName("source"),n=0,o=r.length;n<o;n++)r[n].setAttribute("sizes",i);a.detail.dataAttr||S(e,a.detail)}),R=function(e,t,a){var i,r=e.parentNode;r&&(a=f(e,r,a),(i=C(e,"lazybeforesizes",{width:a,dataAttr:!!t})).defaultPrevented||(a=i.detail.width)&&a!==e._lazysizesWidth&&N(e,r,i,a))},Q=W(function(){var e,t=L.length;if(t)for(e=0;e<t;e++)R(L[e])}),{_:function(){L=A.getElementsByClassName(h.autosizesClass),e("resize",Q)},checkElems:Q,updateElem:R}),B=function(){!B.i&&A.getElementsByClassName&&(B.i=!0,M._(),x._())};var L,N,R,Q;var k,P,H,D,T,U,F,I,J,O,G,$,q,j,V,X,Y,K,Z,ee,te,ae,ie,re,ne,oe,se,le,de,ce,ue,fe,Ae,ge,he,ze,me,ve,pe;var ye,be,we,_e,Ce,Se,Ee;return v(function(){h.init&&B()}),g={cfg:h,autoSizer:M,loader:x,init:B,uP:S,aC:b,rC:w,hC:c,fire:C,gW:f,rAF:E}}(e,e.document,Date);e.lazySizes=a,"object"==typeof module&&module.exports&&(module.exports=a)}("undefined"!=typeof window?window:{}),lazysizesWebP("alpha",lazySizes.init),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=e.target,a=t.getAttribute("data-srcset");if(t.naturalWidth&&!a&&1<t.naturalWidth&&1<t.naturalHeight){var i=window.devicePixelRatio||1,r=t.naturalWidth,n=t.naturalHeight,o=t.getAttribute("data-eio-rwidth"),s=t.getAttribute("data-eio-rheight");o&&r<o&&(r=o,n=s);var l=t.clientWidth&&1.25*t.clientWidth<r,d=t.clientHeight&&1.25*t.clientHeight<n;if(l||d){var c=Math.round(t.offsetWidth*i),u=Math.round(t.offsetHeight*i),f=t.getAttribute("data-src"),A=t.getAttribute("data-src-webp");if(ewww_webp_supported&&A&&-1==f.search("webp=1")&&(f=A),shouldAutoScale(t)&&shouldAutoScale(t.parentNode))if(window.lazySizes.hC(t,"et_pb_jt_filterable_grid_item_image")||window.lazySizes.hC(t,"ss-foreground-image")||window.lazySizes.hC(t,"img-crop"))g=constrainSrc(f,c,u,"img-crop");else g=constrainSrc(f,c,u,"img");else var g=!1;g&&f!=g&&t.setAttribute("data-src",g)}}if(ewww_webp_supported){if(a){var h=t.getAttribute("data-srcset-webp");h&&t.setAttribute("data-srcset",h)}if(!(A=t.getAttribute("data-src-webp")))return;t.setAttribute("data-src",A)}}),function(e,t){var a=function(){t(e.lazySizes),e.removeEventListener("lazyunveilread",a,!0)};t=t.bind(null,e,e.document),"object"==typeof module&&module.exports?t(require("lazysizes")):e.lazySizes?a():e.addEventListener("lazyunveilread",a,!0)}(window,function(o,e,s){"use strict";var l;e.addEventListener&&(l=/\(|\)|\s|'/,addEventListener("lazybeforeunveil",function(e){var t,a;if(e.detail.instance==s&&(!e.defaultPrevented&&("none"==e.target.preload&&(e.target.preload="auto"),t=e.target.getAttribute("data-bg")))){ewww_webp_supported&&(a=e.target.getAttribute("data-bg-webp"))&&(t=a);var i=o.devicePixelRatio||1,r=Math.round(e.target.offsetWidth*i),n=Math.round(e.target.offsetHeight*i);shouldAutoScale(e.target)&&shouldAutoScale(e.target.parentNode)&&(t=o.lazySizes.hC(e.target,"wp-block-cover")?(o.lazySizes.hC(e.target,"has-parallax")&&(r=Math.round(o.screen.width*i),n=Math.round(o.screen.height*i)),constrainSrc(t,r,n,"bg-cover")):o.lazySizes.hC(e.target,"elementor-bg")?constrainSrc(t,r,n,"bg-cover"):constrainSrc(t,r,n,"bg")),e.target.style.backgroundImage="url("+(l.test(t)?JSON.stringify(t):t)+")"}},!1))});
|
1 |
+
function shouldAutoScale(e){if(1==eio_lazy_vars.skip_autoscale)return!1;if(e.hasAttributes())for(var t=e.attributes,a=/skip-autoscale/,i=t.length-1;0<=i;i--){if(a.test(t[i].name))return!1;if(a.test(t[i].value))return!1}return!0}function constrainSrc(e,t,a,i){if(null===e)return e;var r=/w=(\d+)/,n=/fit=(\d+),(\d+)/,o=/resize=(\d+),(\d+)/,s=decodeURIComponent(e);if("undefined"==typeof eio_lazy_vars&&(eio_lazy_vars={exactdn_domain:".exactdn.com"}),0<e.search("\\?")&&0<e.search(eio_lazy_vars.exactdn_domain)){var l=o.exec(s);if(l&&t<l[1])return s.replace(o,"resize="+t+","+a);var d=r.exec(e);if(d&&t<=d[1]){if("bg-cover"!==i&&"img-crop"!==i)return e.replace(r,"w="+t);var c=d[1]-t;return 20<c||a<1080?e.replace(r,"resize="+t+","+a):e}var u=n.exec(s);if(u&&t<u[1]){if("bg-cover"!==i&&"img-crop"!==i)return s.replace(n,"fit="+t+","+a);var f=u[1]-t,g=u[2]-a;return 20<f||20<g?e.replace(r,"resize="+t+","+a):e}if(!d&&!u&&!l)return"img"===i?e+"&fit="+t+","+a:"bg-cover"===i||"img-crop"===i?e+"&resize="+t+","+a:t<a?e+"&h="+a:e+"&w="+t}return-1==e.search("\\?")&&0<e.search(eio_lazy_vars.exactdn_domain)?"img"===i?e+"?fit="+t+","+a:"bg-cover"===i||"img-crop"===i?e+"?resize="+t+","+a:t<a?e+"?h="+a:e+"?w="+t:e}window.lazySizesConfig=window.lazySizesConfig||{},window.lazySizesConfig.init=!1,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){var a=function(i,g,n){"use strict";var h,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])}(),!g||!g.getElementsByClassName)return{init:function(){},cfg:z,noSupport:!0};var v=g.documentElement,r=i.HTMLPictureElement,o="addEventListener",m="getAttribute",e=i[o].bind(i),y=i.setTimeout,a=i.requestAnimationFrame||y,s=i.requestIdleCallback,p=/^picture$/i,l=["load","error","lazyincluded","_lazyloaded"],d={},b=Array.prototype.forEach,c=function(e,t){return d[t]||(d[t]=new RegExp("(\\s|^)"+t+"(\\s|$)")),d[t].test(e[m]("class")||"")&&d[t]},w=function(e,t){c(e,t)||e.setAttribute("class",(e[m]("class")||"").trim()+" "+t)},_=function(e,t){var a;(a=c(e,t))&&e.setAttribute("class",(e[m]("class")||"").replace(a," "))},C=function(t,a,e){var i=e?o:"removeEventListener";e&&C(t,a),l.forEach(function(e){t[i](e,a)})},A=function(e,t,a,i,r){var n=g.createEvent("Event");return a||(a={}),a.instance=h,n.initEvent(t,!i,!r),n.detail=a,e.dispatchEvent(n),n},S=function(e,t){var a;!r&&(a=i.picturefill||z.pf)?(t&&t.src&&!e[m]("srcset")&&e.setAttribute("srcset",t.src),a({reevaluate:!0,elements:[e]})):t&&t.src&&(e.src=t.src)},u=function(e,t){return(getComputedStyle(e,null)||{})[t]},f=function(e,t,a){for(a=a||e.offsetWidth;a<z.minSize&&t&&!e._lazysizesWidth;)a=t.offsetWidth,t=t.parentNode;return a},E=(_e=[],Ce=[],Ae=_e,Se=function(){var e=Ae;for(Ae=_e.length?Ce:_e,we=!(be=!0);e.length;)e.shift()();be=!1},Ee=function(e,t){be&&!t?e.apply(this,arguments):(Ae.push(e),we||(we=!0,(g.hidden?y:a)(Se)))},Ee._lsFlush=Se,Ee),t=function(a,e){return e?function(){E(a)}:function(){var e=this,t=arguments;E(function(){a.apply(e,t)})}},x=function(e){var t,a,i=function(){t=null,e()},r=function(){var e=n.now()-a;e<99?y(r,99-e):(s||i)(i)};return function(){a=n.now(),t||(t=y(r,99))}},M=(ee=/^img$/i,te=/^iframe$/i,ae="onscroll"in i&&!/(gle|ing)bot/.test(navigator.userAgent),ie=0,re=0,ne=-1,oe=function(e){re--,(!e||re<0||!e.target)&&(re=0)},se=function(e){return null==J&&(J="hidden"==u(g.body,"visibility")),J||!("hidden"==u(e.parentNode,"visibility")&&"hidden"==u(e,"visibility"))},le=function(e,t){var a,i=e,r=se(e);for($-=t,U+=t,q-=t,j+=t;r&&(i=i.offsetParent)&&i!=g.body&&i!=v;)(r=0<(u(i,"opacity")||1))&&"visible"!=u(i,"overflow")&&(a=i.getBoundingClientRect(),r=j>a.left&&q<a.right&&U>a.top-1&&$<a.bottom+1);return r},de=function(){var e,t,a,i,r,n,o,s,l,d,c,u,f=h.elements;if((P=z.loadMode)&&re<8&&(e=f.length)){for(t=0,ne++;t<e;t++)if(f[t]&&!f[t]._lazyRace)if(!ae||h.prematureUnveil&&h.prematureUnveil(f[t]))ve(f[t]);else if((s=f[t][m]("data-expand"))&&(n=1*s)||(n=ie),d||(d=!z.expand||z.expand<1?500<v.clientHeight&&500<v.clientWidth?500:370:z.expand,h._defEx=d,c=d*z.expFactor,u=z.hFac,J=null,ie<c&&re<1&&2<ne&&2<P&&!g.hidden?(ie=c,ne=0):ie=1<P&&1<ne&&re<6?d:0),l!==n&&(O=innerWidth+n*u,I=innerHeight+n,o=-1*n,l=n),a=f[t].getBoundingClientRect(),(U=a.bottom)>=o&&($=a.top)<=I&&(j=a.right)>=o*u&&(q=a.left)<=O&&(U||j||q||$)&&(z.loadHidden||se(f[t]))&&(T&&re<3&&!s&&(P<3||ne<4)||le(f[t],n))){if(ve(f[t]),r=!0,9<re)break}else!r&&T&&!i&&re<4&&ne<4&&2<P&&(B[0]||z.preloadAfterLoad)&&(B[0]||!s&&(U||j||q||$||"auto"!=f[t][m](z.sizesAttr)))&&(i=B[0]||f[t]);i&&!r&&ve(i)}},G=de,Q=0,V=z.throttleDelay,X=z.ricTimeout,Y=function(){K=!1,Q=n.now(),G()},Z=s&&49<X?function(){s(Y,{timeout:X}),X!==z.ricTimeout&&(X=z.ricTimeout)}:t(function(){y(Y)},!0),ce=function(e){var t;(e=!0===e)&&(X=33),K||(K=!0,(t=V-(n.now()-Q))<0&&(t=0),e||t<9?Z():y(Z,t))},ue=function(e){var t=e.target;t._lazyCache?delete t._lazyCache:(oe(e),w(t,z.loadedClass),_(t,z.loadingClass),C(t,ge),A(t,"lazyloaded"))},fe=t(ue),ge=function(e){fe({target:e.target})},he=function(e){var t,a=e[m](z.srcsetAttr);(t=z.customMedia[e[m]("data-media")||e[m]("media")])&&e.setAttribute("media",t),a&&e.setAttribute("srcset",a)},ze=t(function(t,e,a,i,r){var n,o,s,l,d,c,u,f,g;(d=A(t,"lazybeforeunveil",e)).defaultPrevented||(i&&(a?w(t,z.autosizesClass):t.setAttribute("sizes",i)),o=t[m](z.srcsetAttr),n=t[m](z.srcAttr),r&&(s=t.parentNode,l=s&&p.test(s.nodeName||"")),c=e.firesLoad||"src"in t&&(o||n||l),d={target:t},w(t,z.loadingClass),c&&(clearTimeout(F),F=y(oe,2500),C(t,ge,!0)),l&&b.call(s.getElementsByTagName("source"),he),o?t.setAttribute("srcset",o):n&&!l&&(te.test(t.nodeName)?(f=n,0==(g=(u=t).getAttribute("data-load-mode")||z.iframeLoadMode)?u.contentWindow.location.replace(f):1==g&&(u.src=f)):t.src=n),r&&(o||l)&&S(t,{src:n})),t._lazyRace&&delete t._lazyRace,_(t,z.lazyClass),E(function(){var e=t.complete&&1<t.naturalWidth;c&&!e||(e&&w(t,z.fastLoadedClass),ue(d),t._lazyCache=!0,y(function(){"_lazyCache"in t&&delete t._lazyCache},9)),"lazy"==t.loading&&re--},!0)}),ve=function(e){if(!e._lazyRace){var t,a=ee.test(e.nodeName),i=a&&(e[m](z.sizesAttr)||e[m]("sizes")),r="auto"==i;(!r&&T||!a||!e[m]("src")&&!e.srcset||e.complete||c(e,z.errorClass)||!c(e,z.lazyClass))&&(t=A(e,"lazyunveilread").detail,r&&W.updateElem(e,!0,e.offsetWidth),e._lazyRace=!0,re++,ze(e,t,r,i,a))}},me=x(function(){z.loadMode=3,ce()}),ye=function(){3==z.loadMode&&(z.loadMode=2),me()},pe=function(){T||(n.now()-D<999?y(pe,999):(T=!0,z.loadMode=3,ce(),e("scroll",ye,!0)))},{_:function(){D=n.now(),h.elements=g.getElementsByClassName(z.lazyClass),B=g.getElementsByClassName(z.lazyClass+" "+z.preloadClass),e("scroll",ce,!0),e("resize",ce,!0),e("pageshow",function(e){if(e.persisted){var t=g.querySelectorAll("."+z.loadingClass);t.length&&t.forEach&&a(function(){t.forEach(function(e){e.complete&&ve(e)})})}}),i.MutationObserver?new MutationObserver(ce).observe(v,{childList:!0,subtree:!0,attributes:!0}):(v[o]("DOMNodeInserted",ce,!0),v[o]("DOMAttrModified",ce,!0),setInterval(ce,999)),e("hashchange",ce,!0),["focus","mouseover","click","load","transitionend","animationend"].forEach(function(e){g[o](e,ce,!0)}),/d$|^c/.test(g.readyState)?pe():(e("load",pe),g[o]("DOMContentLoaded",ce),y(pe,2e4)),h.elements.length?(de(),E._lsFlush()):ce()},checkElems:ce,unveil:ve,_aLSL:ye}),W=(H=t(function(e,t,a,i){var r,n,o;if(e._lazysizesWidth=i,i+="px",e.setAttribute("sizes",i),p.test(t.nodeName||""))for(r=t.getElementsByTagName("source"),n=0,o=r.length;n<o;n++)r[n].setAttribute("sizes",i);a.detail.dataAttr||S(e,a.detail)}),R=function(e,t,a){var i,r=e.parentNode;r&&(a=f(e,r,a),(i=A(e,"lazybeforesizes",{width:a,dataAttr:!!t})).defaultPrevented||(a=i.detail.width)&&a!==e._lazysizesWidth&&H(e,r,i,a))},k=x(function(){var e,t=N.length;if(t)for(e=0;e<t;e++)R(N[e])}),{_:function(){N=g.getElementsByClassName(z.autosizesClass),e("resize",k)},checkElems:k,updateElem:R}),L=function(){!L.i&&g.getElementsByClassName&&(L.i=!0,W._(),M._())};var N,H,R,k;var B,T,F,P,D,O,I,$,q,j,U,J,G,K,Q,V,X,Y,Z,ee,te,ae,ie,re,ne,oe,se,le,de,ce,ue,fe,ge,he,ze,ve,me,ye,pe;var be,we,_e,Ce,Ae,Se,Ee;return y(function(){z.init&&L()}),h={cfg:z,autoSizer:W,loader:M,init:L,uP:S,aC:w,rC:_,hC:c,fire:A,gW:f,rAF:E}}(e,e.document,Date);e.lazySizes=a,"object"==typeof module&&module.exports&&(module.exports=a)}("undefined"!=typeof window?window:{}),lazySizes.init(),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=e.target,a=t.getAttribute("data-srcset");if(t.naturalWidth&&!a&&1<t.naturalWidth&&1<t.naturalHeight){var i=window.devicePixelRatio||1,r=t.naturalWidth,n=t.naturalHeight,o=t.getAttribute("data-eio-rwidth"),s=t.getAttribute("data-eio-rheight");o&&r<o&&(r=o,n=s);var l=t.clientWidth&&1.25*t.clientWidth<r,d=t.clientHeight&&1.25*t.clientHeight<n;if(l||d){var c=Math.round(t.offsetWidth*i),u=Math.round(t.offsetHeight*i),f=t.getAttribute("data-src"),g=t.getAttribute("data-src-webp");if(ewww_webp_supported&&g&&-1==f.search("webp=1")&&(f=g),shouldAutoScale(t)&&shouldAutoScale(t.parentNode))if(window.lazySizes.hC(t,"et_pb_jt_filterable_grid_item_image")||window.lazySizes.hC(t,"ss-foreground-image")||window.lazySizes.hC(t,"img-crop"))h=constrainSrc(f,c,u,"img-crop");else h=constrainSrc(f,c,u,"img");else var h=!1;h&&f!=h&&t.setAttribute("data-src",h)}}if(ewww_webp_supported){if(a){var z=t.getAttribute("data-srcset-webp");z&&t.setAttribute("data-srcset",z)}if(!(g=t.getAttribute("data-src-webp")))return;t.setAttribute("data-src",g)}}),function(e,t){var a=function(){t(e.lazySizes),e.removeEventListener("lazyunveilread",a,!0)};t=t.bind(null,e,e.document),"object"==typeof module&&module.exports?t(require("lazysizes")):e.lazySizes?a():e.addEventListener("lazyunveilread",a,!0)}(window,function(o,e,s){"use strict";var l;e.addEventListener&&(l=/\(|\)|\s|'/,addEventListener("lazybeforeunveil",function(e){var t,a;if(e.detail.instance==s&&(!e.defaultPrevented&&("none"==e.target.preload&&(e.target.preload="auto"),t=e.target.getAttribute("data-bg")))){ewww_webp_supported&&(a=e.target.getAttribute("data-bg-webp"))&&(t=a);var i=o.devicePixelRatio||1,r=Math.round(e.target.offsetWidth*i),n=Math.round(e.target.offsetHeight*i);shouldAutoScale(e.target)&&shouldAutoScale(e.target.parentNode)&&(t=o.lazySizes.hC(e.target,"wp-block-cover")?(o.lazySizes.hC(e.target,"has-parallax")&&(r=Math.round(o.screen.width*i),n=Math.round(o.screen.height*i)),constrainSrc(t,r,n,"bg-cover")):o.lazySizes.hC(e.target,"elementor-bg")?constrainSrc(t,r,n,"bg-cover"):constrainSrc(t,r,n,"bg")),e.target.style.backgroundImage="url("+(l.test(t)?JSON.stringify(t):t)+")"}},!1))});
|
includes/load-webp.js
ADDED
@@ -0,0 +1,704 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/*globals jQuery,Window,HTMLElement,HTMLDocument,HTMLCollection,NodeList,MutationObserver */
|
2 |
+
/*exported Arrive*/
|
3 |
+
/*jshint latedef:false */
|
4 |
+
|
5 |
+
/*
|
6 |
+
* arrive.js
|
7 |
+
* v2.4.1
|
8 |
+
* https://github.com/uzairfarooq/arrive
|
9 |
+
* MIT licensed
|
10 |
+
*
|
11 |
+
* Copyright (c) 2014-2017 Uzair Farooq
|
12 |
+
*/
|
13 |
+
var Arrive = (function(window, $, undefined) {
|
14 |
+
|
15 |
+
"use strict";
|
16 |
+
|
17 |
+
if(!window.MutationObserver || typeof HTMLElement === 'undefined'){
|
18 |
+
return; //for unsupported browsers
|
19 |
+
}
|
20 |
+
|
21 |
+
var arriveUniqueId = 0;
|
22 |
+
|
23 |
+
var utils = (function() {
|
24 |
+
var matches = HTMLElement.prototype.matches || HTMLElement.prototype.webkitMatchesSelector || HTMLElement.prototype.mozMatchesSelector
|
25 |
+
|| HTMLElement.prototype.msMatchesSelector;
|
26 |
+
|
27 |
+
return {
|
28 |
+
matchesSelector: function(elem, selector) {
|
29 |
+
return elem instanceof HTMLElement && matches.call(elem, selector);
|
30 |
+
},
|
31 |
+
// to enable function overloading - By John Resig (MIT Licensed)
|
32 |
+
addMethod: function (object, name, fn) {
|
33 |
+
var old = object[ name ];
|
34 |
+
object[ name ] = function(){
|
35 |
+
if ( fn.length == arguments.length ) {
|
36 |
+
return fn.apply( this, arguments );
|
37 |
+
}
|
38 |
+
else if ( typeof old == 'function' ) {
|
39 |
+
return old.apply( this, arguments );
|
40 |
+
}
|
41 |
+
};
|
42 |
+
},
|
43 |
+
callCallbacks: function(callbacksToBeCalled, registrationData) {
|
44 |
+
if (registrationData && registrationData.options.onceOnly && registrationData.firedElems.length == 1) {
|
45 |
+
// as onlyOnce param is true, make sure we fire the event for only one item
|
46 |
+
callbacksToBeCalled = [callbacksToBeCalled[0]];
|
47 |
+
}
|
48 |
+
|
49 |
+
for (var i = 0, cb; (cb = callbacksToBeCalled[i]); i++) {
|
50 |
+
if (cb && cb.callback) {
|
51 |
+
cb.callback.call(cb.elem, cb.elem);
|
52 |
+
}
|
53 |
+
}
|
54 |
+
|
55 |
+
if (registrationData && registrationData.options.onceOnly && registrationData.firedElems.length == 1) {
|
56 |
+
// unbind event after first callback as onceOnly is true.
|
57 |
+
registrationData.me.unbindEventWithSelectorAndCallback.call(
|
58 |
+
registrationData.target, registrationData.selector, registrationData.callback
|
59 |
+
);
|
60 |
+
}
|
61 |
+
},
|
62 |
+
// traverse through all descendants of a node to check if event should be fired for any descendant
|
63 |
+
checkChildNodesRecursively: function(nodes, registrationData, matchFunc, callbacksToBeCalled) {
|
64 |
+
// check each new node if it matches the selector
|
65 |
+
for (var i=0, node; (node = nodes[i]); i++) {
|
66 |
+
if (matchFunc(node, registrationData, callbacksToBeCalled)) {
|
67 |
+
callbacksToBeCalled.push({ callback: registrationData.callback, elem: node });
|
68 |
+
}
|
69 |
+
|
70 |
+
if (node.childNodes.length > 0) {
|
71 |
+
utils.checkChildNodesRecursively(node.childNodes, registrationData, matchFunc, callbacksToBeCalled);
|
72 |
+
}
|
73 |
+
}
|
74 |
+
},
|
75 |
+
mergeArrays: function(firstArr, secondArr){
|
76 |
+
// Overwrites default options with user-defined options.
|
77 |
+
var options = {},
|
78 |
+
attrName;
|
79 |
+
for (attrName in firstArr) {
|
80 |
+
if (firstArr.hasOwnProperty(attrName)) {
|
81 |
+
options[attrName] = firstArr[attrName];
|
82 |
+
}
|
83 |
+
}
|
84 |
+
for (attrName in secondArr) {
|
85 |
+
if (secondArr.hasOwnProperty(attrName)) {
|
86 |
+
options[attrName] = secondArr[attrName];
|
87 |
+
}
|
88 |
+
}
|
89 |
+
return options;
|
90 |
+
},
|
91 |
+
toElementsArray: function (elements) {
|
92 |
+
// check if object is an array (or array like object)
|
93 |
+
// Note: window object has .length property but it's not array of elements so don't consider it an array
|
94 |
+
if (typeof elements !== "undefined" && (typeof elements.length !== "number" || elements === window)) {
|
95 |
+
elements = [elements];
|
96 |
+
}
|
97 |
+
return elements;
|
98 |
+
}
|
99 |
+
};
|
100 |
+
})();
|
101 |
+
|
102 |
+
|
103 |
+
// Class to maintain state of all registered events of a single type
|
104 |
+
var EventsBucket = (function() {
|
105 |
+
var EventsBucket = function() {
|
106 |
+
// holds all the events
|
107 |
+
|
108 |
+
this._eventsBucket = [];
|
109 |
+
// function to be called while adding an event, the function should do the event initialization/registration
|
110 |
+
this._beforeAdding = null;
|
111 |
+
// function to be called while removing an event, the function should do the event destruction
|
112 |
+
this._beforeRemoving = null;
|
113 |
+
};
|
114 |
+
|
115 |
+
EventsBucket.prototype.addEvent = function(target, selector, options, callback) {
|
116 |
+
var newEvent = {
|
117 |
+
target: target,
|
118 |
+
selector: selector,
|
119 |
+
options: options,
|
120 |
+
callback: callback,
|
121 |
+
firedElems: []
|
122 |
+
};
|
123 |
+
|
124 |
+
if (this._beforeAdding) {
|
125 |
+
this._beforeAdding(newEvent);
|
126 |
+
}
|
127 |
+
|
128 |
+
this._eventsBucket.push(newEvent);
|
129 |
+
return newEvent;
|
130 |
+
};
|
131 |
+
|
132 |
+
EventsBucket.prototype.removeEvent = function(compareFunction) {
|
133 |
+
for (var i=this._eventsBucket.length - 1, registeredEvent; (registeredEvent = this._eventsBucket[i]); i--) {
|
134 |
+
if (compareFunction(registeredEvent)) {
|
135 |
+
if (this._beforeRemoving) {
|
136 |
+
this._beforeRemoving(registeredEvent);
|
137 |
+
}
|
138 |
+
|
139 |
+
// mark callback as null so that even if an event mutation was already triggered it does not call callback
|
140 |
+
var removedEvents = this._eventsBucket.splice(i, 1);
|
141 |
+
if (removedEvents && removedEvents.length) {
|
142 |
+
removedEvents[0].callback = null;
|
143 |
+
}
|
144 |
+
}
|
145 |
+
}
|
146 |
+
};
|
147 |
+
|
148 |
+
EventsBucket.prototype.beforeAdding = function(beforeAdding) {
|
149 |
+
this._beforeAdding = beforeAdding;
|
150 |
+
};
|
151 |
+
|
152 |
+
EventsBucket.prototype.beforeRemoving = function(beforeRemoving) {
|
153 |
+
this._beforeRemoving = beforeRemoving;
|
154 |
+
};
|
155 |
+
|
156 |
+
return EventsBucket;
|
157 |
+
})();
|
158 |
+
|
159 |
+
|
160 |
+
/**
|
161 |
+
* @constructor
|
162 |
+
* General class for binding/unbinding arrive and leave events
|
163 |
+
*/
|
164 |
+
var MutationEvents = function(getObserverConfig, onMutation) {
|
165 |
+
var eventsBucket = new EventsBucket(),
|
166 |
+
me = this;
|
167 |
+
|
168 |
+
var defaultOptions = {
|
169 |
+
fireOnAttributesModification: false
|
170 |
+
};
|
171 |
+
|
172 |
+
// actual event registration before adding it to bucket
|
173 |
+
eventsBucket.beforeAdding(function(registrationData) {
|
174 |
+
var
|
175 |
+
target = registrationData.target,
|
176 |
+
observer;
|
177 |
+
|
178 |
+
// mutation observer does not work on window or document
|
179 |
+
if (target === window.document || target === window) {
|
180 |
+
target = document.getElementsByTagName("html")[0];
|
181 |
+
}
|
182 |
+
|
183 |
+
// Create an observer instance
|
184 |
+
observer = new MutationObserver(function(e) {
|
185 |
+
onMutation.call(this, e, registrationData);
|
186 |
+
});
|
187 |
+
|
188 |
+
var config = getObserverConfig(registrationData.options);
|
189 |
+
|
190 |
+
observer.observe(target, config);
|
191 |
+
|
192 |
+
registrationData.observer = observer;
|
193 |
+
registrationData.me = me;
|
194 |
+
});
|
195 |
+
|
196 |
+
// cleanup/unregister before removing an event
|
197 |
+
eventsBucket.beforeRemoving(function (eventData) {
|
198 |
+
eventData.observer.disconnect();
|
199 |
+
});
|
200 |
+
|
201 |
+
this.bindEvent = function(selector, options, callback) {
|
202 |
+
options = utils.mergeArrays(defaultOptions, options);
|
203 |
+
|
204 |
+
var elements = utils.toElementsArray(this);
|
205 |
+
|
206 |
+
for (var i = 0; i < elements.length; i++) {
|
207 |
+
eventsBucket.addEvent(elements[i], selector, options, callback);
|
208 |
+
}
|
209 |
+
};
|
210 |
+
|
211 |
+
this.unbindEvent = function() {
|
212 |
+
var elements = utils.toElementsArray(this);
|
213 |
+
eventsBucket.removeEvent(function(eventObj) {
|
214 |
+
for (var i = 0; i < elements.length; i++) {
|
215 |
+
if (this === undefined || eventObj.target === elements[i]) {
|
216 |
+
return true;
|
217 |
+
}
|
218 |
+
}
|
219 |
+
return false;
|
220 |
+
});
|
221 |
+
};
|
222 |
+
|
223 |
+
this.unbindEventWithSelectorOrCallback = function(selector) {
|
224 |
+
var elements = utils.toElementsArray(this),
|
225 |
+
callback = selector,
|
226 |
+
compareFunction;
|
227 |
+
|
228 |
+
if (typeof selector === "function") {
|
229 |
+
compareFunction = function(eventObj) {
|
230 |
+
for (var i = 0; i < elements.length; i++) {
|
231 |
+
if ((this === undefined || eventObj.target === elements[i]) && eventObj.callback === callback) {
|
232 |
+
return true;
|
233 |
+
}
|
234 |
+
}
|
235 |
+
return false;
|
236 |
+
};
|
237 |
+
}
|
238 |
+
else {
|
239 |
+
compareFunction = function(eventObj) {
|
240 |
+
for (var i = 0; i < elements.length; i++) {
|
241 |
+
if ((this === undefined || eventObj.target === elements[i]) && eventObj.selector === selector) {
|
242 |
+
return true;
|
243 |
+
}
|
244 |
+
}
|
245 |
+
return false;
|
246 |
+
};
|
247 |
+
}
|
248 |
+
eventsBucket.removeEvent(compareFunction);
|
249 |
+
};
|
250 |
+
|
251 |
+
this.unbindEventWithSelectorAndCallback = function(selector, callback) {
|
252 |
+
var elements = utils.toElementsArray(this);
|
253 |
+
eventsBucket.removeEvent(function(eventObj) {
|
254 |
+
for (var i = 0; i < elements.length; i++) {
|
255 |
+
if ((this === undefined || eventObj.target === elements[i]) && eventObj.selector === selector && eventObj.callback === callback) {
|
256 |
+
return true;
|
257 |
+
}
|
258 |
+
}
|
259 |
+
return false;
|
260 |
+
});
|
261 |
+
};
|
262 |
+
|
263 |
+
return this;
|
264 |
+
};
|
265 |
+
|
266 |
+
|
267 |
+
/**
|
268 |
+
* @constructor
|
269 |
+
* Processes 'arrive' events
|
270 |
+
*/
|
271 |
+
var ArriveEvents = function() {
|
272 |
+
// Default options for 'arrive' event
|
273 |
+
var arriveDefaultOptions = {
|
274 |
+
fireOnAttributesModification: false,
|
275 |
+
onceOnly: false,
|
276 |
+
existing: false
|
277 |
+
};
|
278 |
+
|
279 |
+
function getArriveObserverConfig(options) {
|
280 |
+
var config = {
|
281 |
+
attributes: false,
|
282 |
+
childList: true,
|
283 |
+
subtree: true
|
284 |
+
};
|
285 |
+
|
286 |
+
if (options.fireOnAttributesModification) {
|
287 |
+
config.attributes = true;
|
288 |
+
}
|
289 |
+
|
290 |
+
return config;
|
291 |
+
}
|
292 |
+
|
293 |
+
function onArriveMutation(mutations, registrationData) {
|
294 |
+
mutations.forEach(function( mutation ) {
|
295 |
+
var newNodes = mutation.addedNodes,
|
296 |
+
targetNode = mutation.target,
|
297 |
+
callbacksToBeCalled = [],
|
298 |
+
node;
|
299 |
+
|
300 |
+
// If new nodes are added
|
301 |
+
if( newNodes !== null && newNodes.length > 0 ) {
|
302 |
+
utils.checkChildNodesRecursively(newNodes, registrationData, nodeMatchFunc, callbacksToBeCalled);
|
303 |
+
}
|
304 |
+
else if (mutation.type === "attributes") {
|
305 |
+
if (nodeMatchFunc(targetNode, registrationData, callbacksToBeCalled)) {
|
306 |
+
callbacksToBeCalled.push({ callback: registrationData.callback, elem: targetNode });
|
307 |
+
}
|
308 |
+
}
|
309 |
+
|
310 |
+
utils.callCallbacks(callbacksToBeCalled, registrationData);
|
311 |
+
});
|
312 |
+
}
|
313 |
+
|
314 |
+
function nodeMatchFunc(node, registrationData, callbacksToBeCalled) {
|
315 |
+
// check a single node to see if it matches the selector
|
316 |
+
if (utils.matchesSelector(node, registrationData.selector)) {
|
317 |
+
if(node._id === undefined) {
|
318 |
+
node._id = arriveUniqueId++;
|
319 |
+
}
|
320 |
+
// make sure the arrive event is not already fired for the element
|
321 |
+
if (registrationData.firedElems.indexOf(node._id) == -1) {
|
322 |
+
registrationData.firedElems.push(node._id);
|
323 |
+
|
324 |
+
return true;
|
325 |
+
}
|
326 |
+
}
|
327 |
+
|
328 |
+
return false;
|
329 |
+
}
|
330 |
+
|
331 |
+
arriveEvents = new MutationEvents(getArriveObserverConfig, onArriveMutation);
|
332 |
+
|
333 |
+
var mutationBindEvent = arriveEvents.bindEvent;
|
334 |
+
|
335 |
+
// override bindEvent function
|
336 |
+
arriveEvents.bindEvent = function(selector, options, callback) {
|
337 |
+
|
338 |
+
if (typeof callback === "undefined") {
|
339 |
+
callback = options;
|
340 |
+
options = arriveDefaultOptions;
|
341 |
+
} else {
|
342 |
+
options = utils.mergeArrays(arriveDefaultOptions, options);
|
343 |
+
}
|
344 |
+
|
345 |
+
var elements = utils.toElementsArray(this);
|
346 |
+
|
347 |
+
if (options.existing) {
|
348 |
+
var existing = [];
|
349 |
+
|
350 |
+
for (var i = 0; i < elements.length; i++) {
|
351 |
+
var nodes = elements[i].querySelectorAll(selector);
|
352 |
+
for (var j = 0; j < nodes.length; j++) {
|
353 |
+
existing.push({ callback: callback, elem: nodes[j] });
|
354 |
+
}
|
355 |
+
}
|
356 |
+
|
357 |
+
// no need to bind event if the callback has to be fired only once and we have already found the element
|
358 |
+
if (options.onceOnly && existing.length) {
|
359 |
+
return callback.call(existing[0].elem, existing[0].elem);
|
360 |
+
}
|
361 |
+
|
362 |
+
setTimeout(utils.callCallbacks, 1, existing);
|
363 |
+
}
|
364 |
+
|
365 |
+
mutationBindEvent.call(this, selector, options, callback);
|
366 |
+
};
|
367 |
+
|
368 |
+
return arriveEvents;
|
369 |
+
};
|
370 |
+
|
371 |
+
|
372 |
+
/**
|
373 |
+
* @constructor
|
374 |
+
* Processes 'leave' events
|
375 |
+
*/
|
376 |
+
var LeaveEvents = function() {
|
377 |
+
// Default options for 'leave' event
|
378 |
+
var leaveDefaultOptions = {};
|
379 |
+
|
380 |
+
function getLeaveObserverConfig() {
|
381 |
+
var config = {
|
382 |
+
childList: true,
|
383 |
+
subtree: true
|
384 |
+
};
|
385 |
+
|
386 |
+
return config;
|
387 |
+
}
|
388 |
+
|
389 |
+
function onLeaveMutation(mutations, registrationData) {
|
390 |
+
mutations.forEach(function( mutation ) {
|
391 |
+
var removedNodes = mutation.removedNodes,
|
392 |
+
callbacksToBeCalled = [];
|
393 |
+
|
394 |
+
if( removedNodes !== null && removedNodes.length > 0 ) {
|
395 |
+
utils.checkChildNodesRecursively(removedNodes, registrationData, nodeMatchFunc, callbacksToBeCalled);
|
396 |
+
}
|
397 |
+
|
398 |
+
utils.callCallbacks(callbacksToBeCalled, registrationData);
|
399 |
+
});
|
400 |
+
}
|
401 |
+
|
402 |
+
function nodeMatchFunc(node, registrationData) {
|
403 |
+
return utils.matchesSelector(node, registrationData.selector);
|
404 |
+
}
|
405 |
+
|
406 |
+
leaveEvents = new MutationEvents(getLeaveObserverConfig, onLeaveMutation);
|
407 |
+
|
408 |
+
var mutationBindEvent = leaveEvents.bindEvent;
|
409 |
+
|
410 |
+
// override bindEvent function
|
411 |
+
leaveEvents.bindEvent = function(selector, options, callback) {
|
412 |
+
|
413 |
+
if (typeof callback === "undefined") {
|
414 |
+
callback = options;
|
415 |
+
options = leaveDefaultOptions;
|
416 |
+
} else {
|
417 |
+
options = utils.mergeArrays(leaveDefaultOptions, options);
|
418 |
+
}
|
419 |
+
|
420 |
+
mutationBindEvent.call(this, selector, options, callback);
|
421 |
+
};
|
422 |
+
|
423 |
+
return leaveEvents;
|
424 |
+
};
|
425 |
+
|
426 |
+
|
427 |
+
var arriveEvents = new ArriveEvents(),
|
428 |
+
leaveEvents = new LeaveEvents();
|
429 |
+
|
430 |
+
function exposeUnbindApi(eventObj, exposeTo, funcName) {
|
431 |
+
// expose unbind function with function overriding
|
432 |
+
utils.addMethod(exposeTo, funcName, eventObj.unbindEvent);
|
433 |
+
utils.addMethod(exposeTo, funcName, eventObj.unbindEventWithSelectorOrCallback);
|
434 |
+
utils.addMethod(exposeTo, funcName, eventObj.unbindEventWithSelectorAndCallback);
|
435 |
+
}
|
436 |
+
|
437 |
+
/*** expose APIs ***/
|
438 |
+
function exposeApi(exposeTo) {
|
439 |
+
exposeTo.arrive = arriveEvents.bindEvent;
|
440 |
+
exposeUnbindApi(arriveEvents, exposeTo, "unbindArrive");
|
441 |
+
|
442 |
+
exposeTo.leave = leaveEvents.bindEvent;
|
443 |
+
exposeUnbindApi(leaveEvents, exposeTo, "unbindLeave");
|
444 |
+
}
|
445 |
+
|
446 |
+
if ($) {
|
447 |
+
exposeApi($.fn);
|
448 |
+
}
|
449 |
+
exposeApi(HTMLElement.prototype);
|
450 |
+
exposeApi(NodeList.prototype);
|
451 |
+
exposeApi(HTMLCollection.prototype);
|
452 |
+
exposeApi(HTMLDocument.prototype);
|
453 |
+
exposeApi(Window.prototype);
|
454 |
+
|
455 |
+
var Arrive = {};
|
456 |
+
// expose functions to unbind all arrive/leave events
|
457 |
+
exposeUnbindApi(arriveEvents, Arrive, "unbindAllArrive");
|
458 |
+
exposeUnbindApi(leaveEvents, Arrive, "unbindAllLeave");
|
459 |
+
|
460 |
+
return Arrive;
|
461 |
+
|
462 |
+
})(window, typeof jQuery === 'undefined' ? null : jQuery, undefined);
|
463 |
+
|
464 |
+
var ewww_webp_supported = false;
|
465 |
+
// webp detection adapted from https://developers.google.com/speed/webp/faq#how_can_i_detect_browser_support_using_javascript
|
466 |
+
function check_webp_feature(feature, callback) {
|
467 |
+
if (ewww_webp_supported) {
|
468 |
+
callback(ewww_webp_supported);
|
469 |
+
return;
|
470 |
+
}
|
471 |
+
var kTestImages = {
|
472 |
+
alpha: "UklGRkoAAABXRUJQVlA4WAoAAAAQAAAAAAAAAAAAQUxQSAwAAAARBxAR/Q9ERP8DAABWUDggGAAAABQBAJ0BKgEAAQAAAP4AAA3AAP7mtQAAAA==",
|
473 |
+
animation: "UklGRlIAAABXRUJQVlA4WAoAAAASAAAAAAAAAAAAQU5JTQYAAAD/////AABBTk1GJgAAAAAAAAAAAAAAAAAAAGQAAABWUDhMDQAAAC8AAAAQBxAREYiI/gcA"
|
474 |
+
};
|
475 |
+
var img = new Image();
|
476 |
+
img.onload = function () {
|
477 |
+
ewww_webp_supported = (img.width > 0) && (img.height > 0);
|
478 |
+
callback(ewww_webp_supported);
|
479 |
+
};
|
480 |
+
img.onerror = function () {
|
481 |
+
callback(false);
|
482 |
+
};
|
483 |
+
img.src = "data:image/webp;base64," + kTestImages[feature];
|
484 |
+
}
|
485 |
+
function ewwwLoadImages(ewww_webp_supported) {
|
486 |
+
if (ewww_webp_supported) {
|
487 |
+
var nggImages = document.querySelectorAll('.batch-image img, .image-wrapper a, .ngg-pro-masonry-item a, .ngg-galleria-offscreen-seo-wrapper a');
|
488 |
+
for (var i = 0, len = nggImages.length; i < len; i++){
|
489 |
+
ewwwAttr(nggImages[i], 'data-src', nggImages[i].getAttribute('data-webp'));
|
490 |
+
ewwwAttr(nggImages[i], 'data-thumbnail', nggImages[i].getAttribute('data-webp-thumbnail'));
|
491 |
+
}
|
492 |
+
var revImages = document.querySelectorAll('.rev_slider ul li');
|
493 |
+
for (var i = 0, len = revImages.length; i < len; i++){
|
494 |
+
ewwwAttr(revImages[i], 'data-thumb', revImages[i].getAttribute('data-webp-thumb'));
|
495 |
+
var param_num = 1;
|
496 |
+
while ( param_num < 11 ) {
|
497 |
+
ewwwAttr(revImages[i], 'data-param' + param_num, revImages[i].getAttribute('data-webp-param' + param_num));
|
498 |
+
param_num++;
|
499 |
+
}
|
500 |
+
}
|
501 |
+
var revImages = document.querySelectorAll('.rev_slider img');
|
502 |
+
for (var i = 0, len = revImages.length; i < len; i++){
|
503 |
+
ewwwAttr(revImages[i], 'data-lazyload', revImages[i].getAttribute('data-webp-lazyload'));
|
504 |
+
}
|
505 |
+
var wooImages = document.querySelectorAll('div.woocommerce-product-gallery__image');
|
506 |
+
for (var i = 0, len = wooImages.length; i < len; i++){
|
507 |
+
ewwwAttr(wooImages[i], 'data-thumb', wooImages[i].getAttribute('data-webp-thumb'));
|
508 |
+
}
|
509 |
+
}
|
510 |
+
var videos = document.querySelectorAll('video');
|
511 |
+
for (var i = 0, len = videos.length; i < len; i++){
|
512 |
+
if (ewww_webp_supported) {
|
513 |
+
ewwwAttr(videos[i], 'poster', videos[i].getAttribute('data-poster-webp'));
|
514 |
+
} else {
|
515 |
+
ewwwAttr(videos[i], 'poster', videos[i].getAttribute('data-poster-image'));
|
516 |
+
}
|
517 |
+
}
|
518 |
+
var lazies = document.querySelectorAll('img.ewww_webp_lazy_load');
|
519 |
+
for (var i = 0, len = lazies.length; i < len; i++){
|
520 |
+
console.log('parsing an image: ' + lazies[i].getAttribute('data-src'));
|
521 |
+
if (ewww_webp_supported) {
|
522 |
+
console.log('webp good');
|
523 |
+
ewwwAttr(lazies[i], 'data-lazy-srcset', lazies[i].getAttribute('data-lazy-srcset-webp'));
|
524 |
+
ewwwAttr(lazies[i], 'data-srcset', lazies[i].getAttribute('data-srcset-webp'));
|
525 |
+
ewwwAttr(lazies[i], 'data-lazy-src', lazies[i].getAttribute('data-lazy-src-webp'));
|
526 |
+
ewwwAttr(lazies[i], 'data-src', lazies[i].getAttribute('data-src-webp'));
|
527 |
+
ewwwAttr(lazies[i], 'data-orig-file', lazies[i].getAttribute('data-webp-orig-file'));
|
528 |
+
ewwwAttr(lazies[i], 'data-medium-file', lazies[i].getAttribute('data-webp-medium-file'));
|
529 |
+
ewwwAttr(lazies[i], 'data-large-file', lazies[i].getAttribute('data-webp-large-file'));
|
530 |
+
var jpsrcset = lazies[i].getAttribute('srcset');
|
531 |
+
if (jpsrcset != null && jpsrcset !== false && jpsrcset.includes('R0lGOD')) {
|
532 |
+
ewwwAttr(lazies[i], 'src', lazies[i].getAttribute('data-lazy-src-webp'));
|
533 |
+
}
|
534 |
+
}
|
535 |
+
lazies[i].className = lazies[i].className.replace(/\bewww_webp_lazy_load\b/, '');
|
536 |
+
}
|
537 |
+
var elems = document.querySelectorAll('.ewww_webp');
|
538 |
+
for (var i = 0, len = elems.length; i < len; i++){
|
539 |
+
console.log('parsing an image: ' + elems[i].getAttribute('data-src'));
|
540 |
+
if (ewww_webp_supported) {
|
541 |
+
ewwwAttr(elems[i], 'srcset', elems[i].getAttribute('data-srcset-webp'));
|
542 |
+
ewwwAttr(elems[i], 'src', elems[i].getAttribute('data-src-webp'));
|
543 |
+
ewwwAttr(elems[i], 'data-orig-file', elems[i].getAttribute('data-webp-orig-file'));
|
544 |
+
ewwwAttr(elems[i], 'data-medium-file', elems[i].getAttribute('data-webp-medium-file'));
|
545 |
+
ewwwAttr(elems[i], 'data-large-file', elems[i].getAttribute('data-webp-large-file'));
|
546 |
+
ewwwAttr(elems[i], 'data-large_image', elems[i].getAttribute('data-webp-large_image'));
|
547 |
+
ewwwAttr(elems[i], 'data-src', elems[i].getAttribute('data-webp-src'));
|
548 |
+
} else {
|
549 |
+
ewwwAttr(elems[i], 'srcset', elems[i].getAttribute('data-srcset-img'));
|
550 |
+
ewwwAttr(elems[i], 'src', elems[i].getAttribute('data-src-img'));
|
551 |
+
}
|
552 |
+
elems[i].className = elems[i].className.replace(/\bewww_webp\b/, 'ewww_webp_loaded');
|
553 |
+
}
|
554 |
+
if (window.jQuery && jQuery.fn.isotope && jQuery.fn.imagesLoaded) {
|
555 |
+
jQuery('.fusion-posts-container-infinite').imagesLoaded( function() {
|
556 |
+
if ( jQuery( '.fusion-posts-container-infinite' ).hasClass( 'isotope' ) ) {
|
557 |
+
jQuery( '.fusion-posts-container-infinite' ).isotope();
|
558 |
+
}
|
559 |
+
});
|
560 |
+
jQuery('.fusion-portfolio:not(.fusion-recent-works) .fusion-portfolio-wrapper').imagesLoaded( function() {
|
561 |
+
jQuery( '.fusion-portfolio:not(.fusion-recent-works) .fusion-portfolio-wrapper' ).isotope();
|
562 |
+
});
|
563 |
+
}
|
564 |
+
}
|
565 |
+
check_webp_feature('alpha', ewwwWebPInit);
|
566 |
+
function ewwwWebPInit(ewww_webp_supported) {
|
567 |
+
ewwwLoadImages(ewww_webp_supported);
|
568 |
+
ewwwNggLoadGalleries(ewww_webp_supported);
|
569 |
+
document.arrive('.ewww_webp', function() {
|
570 |
+
ewwwLoadImages(ewww_webp_supported);
|
571 |
+
});
|
572 |
+
document.arrive('.ewww_webp_lazy_load', function() {
|
573 |
+
ewwwLoadImages(ewww_webp_supported);
|
574 |
+
});
|
575 |
+
document.arrive('videos', function() {
|
576 |
+
ewwwLoadImages(ewww_webp_supported);
|
577 |
+
});
|
578 |
+
if (document.readyState == 'loading') {
|
579 |
+
console.log('deferring ewwwJSONParserInit until DOMContentLoaded')
|
580 |
+
document.addEventListener('DOMContentLoaded', ewwwJSONParserInit);
|
581 |
+
} else {
|
582 |
+
console.log(document.readyState);
|
583 |
+
console.log('running JSON parsers post haste')
|
584 |
+
if ( typeof galleries !== 'undefined' ) {
|
585 |
+
console.log('galleries found, parsing')
|
586 |
+
ewwwNggParseGalleries(ewww_webp_supported);
|
587 |
+
}
|
588 |
+
ewwwWooParseVariations(ewww_webp_supported);
|
589 |
+
}
|
590 |
+
}
|
591 |
+
function ewwwAttr(elem, attr, value) {
|
592 |
+
if (value != null && value !== false) {
|
593 |
+
elem.setAttribute(attr, value);
|
594 |
+
}
|
595 |
+
}
|
596 |
+
function ewwwJSONParserInit() {
|
597 |
+
if ( typeof galleries !== 'undefined' ) {
|
598 |
+
check_webp_feature('alpha', ewwwNggParseGalleries);
|
599 |
+
}
|
600 |
+
check_webp_feature('alpha', ewwwWooParseVariations);
|
601 |
+
}
|
602 |
+
function ewwwWooParseVariations(ewww_webp_supported) {
|
603 |
+
if (!ewww_webp_supported) {
|
604 |
+
return;
|
605 |
+
}
|
606 |
+
var elems = document.querySelectorAll('form.variations_form');
|
607 |
+
for (var i = 0, len = elems.length; i < len; i++){
|
608 |
+
var variations = elems[i].getAttribute('data-product_variations');
|
609 |
+
var variations_changed = false;
|
610 |
+
try {
|
611 |
+
variations = JSON.parse(variations);
|
612 |
+
//console.log(variations);
|
613 |
+
console.log('parsing WC variations');
|
614 |
+
for ( var num in variations ) {
|
615 |
+
if (variations[ num ] !== undefined && variations[ num ].image !== undefined) {
|
616 |
+
console.log(variations[num].image);
|
617 |
+
if (variations[num].image.src_webp !== undefined) {
|
618 |
+
variations[num].image.src = variations[num].image.src_webp;
|
619 |
+
variations_changed = true;
|
620 |
+
}
|
621 |
+
if (variations[num].image.srcset_webp !== undefined) {
|
622 |
+
variations[num].image.srcset = variations[num].image.srcset_webp;
|
623 |
+
variations_changed = true;
|
624 |
+
}
|
625 |
+
if (variations[num].image.full_src_webp !== undefined) {
|
626 |
+
variations[num].image.full_src = variations[num].image.full_src_webp;
|
627 |
+
variations_changed = true;
|
628 |
+
}
|
629 |
+
if (variations[num].image.gallery_thumbnail_src_webp !== undefined) {
|
630 |
+
variations[num].image.gallery_thumbnail_src = variations[num].image.gallery_thumbnail_src_webp;
|
631 |
+
variations_changed = true;
|
632 |
+
}
|
633 |
+
if (variations[num].image.thumb_src_webp !== undefined) {
|
634 |
+
variations[num].image.thumb_src = variations[num].image.thumb_src_webp;
|
635 |
+
variations_changed = true;
|
636 |
+
}
|
637 |
+
}
|
638 |
+
}
|
639 |
+
if (variations_changed) {
|
640 |
+
ewwwAttr(elems[i], 'data-product_variations', JSON.stringify(variations));
|
641 |
+
}
|
642 |
+
} catch (err) {
|
643 |
+
console.log(err);
|
644 |
+
console.log(response);
|
645 |
+
}
|
646 |
+
}
|
647 |
+
}
|
648 |
+
function ewwwNggParseGalleries(ewww_webp_supported) {
|
649 |
+
if (ewww_webp_supported) {
|
650 |
+
for(var galleryIndex in galleries) {
|
651 |
+
var gallery = galleries[galleryIndex];
|
652 |
+
galleries[galleryIndex].images_list = ewwwNggParseImageList(gallery.images_list);
|
653 |
+
}
|
654 |
+
}
|
655 |
+
}
|
656 |
+
function ewwwNggLoadGalleries(ewww_webp_supported) {
|
657 |
+
if (ewww_webp_supported) {
|
658 |
+
document.addEventListener('ngg.galleria.themeadded', function(event, themename){
|
659 |
+
window.ngg_galleria._create_backup = window.ngg_galleria.create;
|
660 |
+
window.ngg_galleria.create = function(gallery_parent, themename) {
|
661 |
+
var gallery_id = $(gallery_parent).data('id');
|
662 |
+
galleries['gallery_' + gallery_id].images_list = ewwwNggParseImageList(galleries['gallery_' + gallery_id].images_list);
|
663 |
+
return window.ngg_galleria._create_backup(gallery_parent, themename);
|
664 |
+
};
|
665 |
+
});
|
666 |
+
}
|
667 |
+
}
|
668 |
+
function ewwwNggParseImageList(images_list) {
|
669 |
+
console.log('parsing gallery images');
|
670 |
+
for(var nggIndex in images_list) {
|
671 |
+
var nggImage = images_list[nggIndex];
|
672 |
+
if (typeof nggImage['image-webp'] !== typeof undefined) {
|
673 |
+
images_list[nggIndex]['image'] = nggImage['image-webp'];
|
674 |
+
delete images_list[nggIndex]['image-webp'];
|
675 |
+
}
|
676 |
+
if (typeof nggImage['thumb-webp'] !== typeof undefined) {
|
677 |
+
images_list[nggIndex]['thumb'] = nggImage['thumb-webp'];
|
678 |
+
delete images_list[nggIndex]['thumb-webp'];
|
679 |
+
}
|
680 |
+
if (typeof nggImage['full_image_webp'] !== typeof undefined) {
|
681 |
+
images_list[nggIndex]['full_image'] = nggImage['full_image_webp'];
|
682 |
+
delete images_list[nggIndex]['full_image_webp'];
|
683 |
+
}
|
684 |
+
if (typeof nggImage['srcsets'] !== typeof undefined) {
|
685 |
+
for(var nggSrcsetIndex in nggImage['srcsets']) {
|
686 |
+
nggSrcset = nggImage['srcsets'][nggSrcsetIndex];
|
687 |
+
if (typeof nggImage['srcsets'][nggSrcsetIndex + '-webp'] !== typeof undefined) {
|
688 |
+
images_list[nggIndex]['srcsets'][nggSrcsetIndex] = nggImage['srcsets'][nggSrcsetIndex + '-webp'];
|
689 |
+
delete images_list[nggIndex]['srcsets'][nggSrcsetIndex + '-webp'];
|
690 |
+
}
|
691 |
+
}
|
692 |
+
}
|
693 |
+
if (typeof nggImage['full_srcsets'] !== typeof undefined) {
|
694 |
+
for(var nggFSrcsetIndex in nggImage['full_srcsets']) {
|
695 |
+
nggFSrcset = nggImage['full_srcsets'][nggFSrcsetIndex];
|
696 |
+
if (typeof nggImage['full_srcsets'][nggFSrcsetIndex + '-webp'] !== typeof undefined) {
|
697 |
+
images_list[nggIndex]['full_srcsets'][nggFSrcsetIndex] = nggImage['full_srcsets'][nggFSrcsetIndex + '-webp'];
|
698 |
+
delete images_list[nggIndex]['full_srcsets'][nggFSrcsetIndex + '-webp'];
|
699 |
+
}
|
700 |
+
}
|
701 |
+
}
|
702 |
+
}
|
703 |
+
return images_list;
|
704 |
+
}
|
includes/load-webp.min.js
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
var Arrive=function(c,e,w){"use strict";if(c.MutationObserver&&"undefined"!=typeof HTMLElement){var r,t,a=0,u=(r=HTMLElement.prototype.matches||HTMLElement.prototype.webkitMatchesSelector||HTMLElement.prototype.mozMatchesSelector||HTMLElement.prototype.msMatchesSelector,{matchesSelector:function(e,t){return e instanceof HTMLElement&&r.call(e,t)},addMethod:function(e,t,r){var a=e[t];e[t]=function(){return r.length==arguments.length?r.apply(this,arguments):"function"==typeof a?a.apply(this,arguments):void 0}},callCallbacks:function(e,t){t&&t.options.onceOnly&&1==t.firedElems.length&&(e=[e[0]]);for(var r,a=0;r=e[a];a++)r&&r.callback&&r.callback.call(r.elem,r.elem);t&&t.options.onceOnly&&1==t.firedElems.length&&t.me.unbindEventWithSelectorAndCallback.call(t.target,t.selector,t.callback)},checkChildNodesRecursively:function(e,t,r,a){for(var i,n=0;i=e[n];n++)r(i,t,a)&&a.push({callback:t.callback,elem:i}),0<i.childNodes.length&&u.checkChildNodesRecursively(i.childNodes,t,r,a)},mergeArrays:function(e,t){var r,a={};for(r in e)e.hasOwnProperty(r)&&(a[r]=e[r]);for(r in t)t.hasOwnProperty(r)&&(a[r]=t[r]);return a},toElementsArray:function(e){return void 0===e||"number"==typeof e.length&&e!==c||(e=[e]),e}}),d=((t=function(){this._eventsBucket=[],this._beforeAdding=null,this._beforeRemoving=null}).prototype.addEvent=function(e,t,r,a){var i={target:e,selector:t,options:r,callback:a,firedElems:[]};return this._beforeAdding&&this._beforeAdding(i),this._eventsBucket.push(i),i},t.prototype.removeEvent=function(e){for(var t,r=this._eventsBucket.length-1;t=this._eventsBucket[r];r--)if(e(t)){this._beforeRemoving&&this._beforeRemoving(t);var a=this._eventsBucket.splice(r,1);a&&a.length&&(a[0].callback=null)}},t.prototype.beforeAdding=function(e){this._beforeAdding=e},t.prototype.beforeRemoving=function(e){this._beforeRemoving=e},t),o=function(i,n){var o=new d,l=this,s={fireOnAttributesModification:!1};return o.beforeAdding(function(t){var e,r=t.target;r!==c.document&&r!==c||(r=document.getElementsByTagName("html")[0]),e=new MutationObserver(function(e){n.call(this,e,t)});var a=i(t.options);e.observe(r,a),t.observer=e,t.me=l}),o.beforeRemoving(function(e){e.observer.disconnect()}),this.bindEvent=function(e,t,r){t=u.mergeArrays(s,t);for(var a=u.toElementsArray(this),i=0;i<a.length;i++)o.addEvent(a[i],e,t,r)},this.unbindEvent=function(){var r=u.toElementsArray(this);o.removeEvent(function(e){for(var t=0;t<r.length;t++)if(this===w||e.target===r[t])return!0;return!1})},this.unbindEventWithSelectorOrCallback=function(r){var e,a=u.toElementsArray(this),i=r;e="function"==typeof r?function(e){for(var t=0;t<a.length;t++)if((this===w||e.target===a[t])&&e.callback===i)return!0;return!1}:function(e){for(var t=0;t<a.length;t++)if((this===w||e.target===a[t])&&e.selector===r)return!0;return!1},o.removeEvent(e)},this.unbindEventWithSelectorAndCallback=function(r,a){var i=u.toElementsArray(this);o.removeEvent(function(e){for(var t=0;t<i.length;t++)if((this===w||e.target===i[t])&&e.selector===r&&e.callback===a)return!0;return!1})},this},i=new function(){var s={fireOnAttributesModification:!1,onceOnly:!1,existing:!1};function n(e,t,r){return!(!u.matchesSelector(e,t.selector)||(e._id===w&&(e._id=a++),-1!=t.firedElems.indexOf(e._id))||(t.firedElems.push(e._id),0))}var c=(i=new o(function(e){var t={attributes:!1,childList:!0,subtree:!0};return e.fireOnAttributesModification&&(t.attributes=!0),t},function(e,i){e.forEach(function(e){var t=e.addedNodes,r=e.target,a=[];null!==t&&0<t.length?u.checkChildNodesRecursively(t,i,n,a):"attributes"===e.type&&n(r,i)&&a.push({callback:i.callback,elem:r}),u.callCallbacks(a,i)})})).bindEvent;return i.bindEvent=function(e,t,r){t=void 0===r?(r=t,s):u.mergeArrays(s,t);var a=u.toElementsArray(this);if(t.existing){for(var i=[],n=0;n<a.length;n++)for(var o=a[n].querySelectorAll(e),l=0;l<o.length;l++)i.push({callback:r,elem:o[l]});if(t.onceOnly&&i.length)return r.call(i[0].elem,i[0].elem);setTimeout(u.callCallbacks,1,i)}c.call(this,e,t,r)},i},l=new function(){var a={};function i(e,t){return u.matchesSelector(e,t.selector)}var n=(l=new o(function(){return{childList:!0,subtree:!0}},function(e,a){e.forEach(function(e){var t=e.removedNodes,r=[];null!==t&&0<t.length&&u.checkChildNodesRecursively(t,a,i,r),u.callCallbacks(r,a)})})).bindEvent;return l.bindEvent=function(e,t,r){t=void 0===r?(r=t,a):u.mergeArrays(a,t),n.call(this,e,t,r)},l};e&&g(e.fn),g(HTMLElement.prototype),g(NodeList.prototype),g(HTMLCollection.prototype),g(HTMLDocument.prototype),g(Window.prototype);var n={};return s(i,n,"unbindAllArrive"),s(l,n,"unbindAllLeave"),n}function s(e,t,r){u.addMethod(t,r,e.unbindEvent),u.addMethod(t,r,e.unbindEventWithSelectorOrCallback),u.addMethod(t,r,e.unbindEventWithSelectorAndCallback)}function g(e){e.arrive=i.bindEvent,s(i,e,"unbindArrive"),e.leave=l.bindEvent,s(l,e,"unbindLeave")}}(window,"undefined"==typeof jQuery?null:jQuery,void 0),ewww_webp_supported=!1;function check_webp_feature(e,t){if(ewww_webp_supported)t(ewww_webp_supported);else{var r=new Image;r.onload=function(){ewww_webp_supported=0<r.width&&0<r.height,t(ewww_webp_supported)},r.onerror=function(){t(!1)},r.src="data:image/webp;base64,"+{alpha:"UklGRkoAAABXRUJQVlA4WAoAAAAQAAAAAAAAAAAAQUxQSAwAAAARBxAR/Q9ERP8DAABWUDggGAAAABQBAJ0BKgEAAQAAAP4AAA3AAP7mtQAAAA==",animation:"UklGRlIAAABXRUJQVlA4WAoAAAASAAAAAAAAAAAAQU5JTQYAAAD/////AABBTk1GJgAAAAAAAAAAAAAAAAAAAGQAAABWUDhMDQAAAC8AAAAQBxAREYiI/gcA"}[e]}}function ewwwLoadImages(e){if(e){for(var t=document.querySelectorAll(".batch-image img, .image-wrapper a, .ngg-pro-masonry-item a, .ngg-galleria-offscreen-seo-wrapper a"),r=0,a=t.length;r<a;r++)ewwwAttr(t[r],"data-src",t[r].getAttribute("data-webp")),ewwwAttr(t[r],"data-thumbnail",t[r].getAttribute("data-webp-thumbnail"));for(r=0,a=(n=document.querySelectorAll(".rev_slider ul li")).length;r<a;r++){ewwwAttr(n[r],"data-thumb",n[r].getAttribute("data-webp-thumb"));for(var i=1;i<11;)ewwwAttr(n[r],"data-param"+i,n[r].getAttribute("data-webp-param"+i)),i++}var n;for(r=0,a=(n=document.querySelectorAll(".rev_slider img")).length;r<a;r++)ewwwAttr(n[r],"data-lazyload",n[r].getAttribute("data-webp-lazyload"));var o=document.querySelectorAll("div.woocommerce-product-gallery__image");for(r=0,a=o.length;r<a;r++)ewwwAttr(o[r],"data-thumb",o[r].getAttribute("data-webp-thumb"))}var l=document.querySelectorAll("video");for(r=0,a=l.length;r<a;r++)ewwwAttr(l[r],"poster",e?l[r].getAttribute("data-poster-webp"):l[r].getAttribute("data-poster-image"));var s=document.querySelectorAll("img.ewww_webp_lazy_load");for(r=0,a=s.length;r<a;r++){if(e){ewwwAttr(s[r],"data-lazy-srcset",s[r].getAttribute("data-lazy-srcset-webp")),ewwwAttr(s[r],"data-srcset",s[r].getAttribute("data-srcset-webp")),ewwwAttr(s[r],"data-lazy-src",s[r].getAttribute("data-lazy-src-webp")),ewwwAttr(s[r],"data-src",s[r].getAttribute("data-src-webp")),ewwwAttr(s[r],"data-orig-file",s[r].getAttribute("data-webp-orig-file")),ewwwAttr(s[r],"data-medium-file",s[r].getAttribute("data-webp-medium-file")),ewwwAttr(s[r],"data-large-file",s[r].getAttribute("data-webp-large-file"));var c=s[r].getAttribute("srcset");null!=c&&!1!==c&&c.includes("R0lGOD")&&ewwwAttr(s[r],"src",s[r].getAttribute("data-lazy-src-webp"))}s[r].className=s[r].className.replace(/\bewww_webp_lazy_load\b/,"")}var w=document.querySelectorAll(".ewww_webp");for(r=0,a=w.length;r<a;r++)e?(ewwwAttr(w[r],"srcset",w[r].getAttribute("data-srcset-webp")),ewwwAttr(w[r],"src",w[r].getAttribute("data-src-webp")),ewwwAttr(w[r],"data-orig-file",w[r].getAttribute("data-webp-orig-file")),ewwwAttr(w[r],"data-medium-file",w[r].getAttribute("data-webp-medium-file")),ewwwAttr(w[r],"data-large-file",w[r].getAttribute("data-webp-large-file")),ewwwAttr(w[r],"data-large_image",w[r].getAttribute("data-webp-large_image")),ewwwAttr(w[r],"data-src",w[r].getAttribute("data-webp-src"))):(ewwwAttr(w[r],"srcset",w[r].getAttribute("data-srcset-img")),ewwwAttr(w[r],"src",w[r].getAttribute("data-src-img"))),w[r].className=w[r].className.replace(/\bewww_webp\b/,"ewww_webp_loaded");window.jQuery&&jQuery.fn.isotope&&jQuery.fn.imagesLoaded&&(jQuery(".fusion-posts-container-infinite").imagesLoaded(function(){jQuery(".fusion-posts-container-infinite").hasClass("isotope")&&jQuery(".fusion-posts-container-infinite").isotope()}),jQuery(".fusion-portfolio:not(.fusion-recent-works) .fusion-portfolio-wrapper").imagesLoaded(function(){jQuery(".fusion-portfolio:not(.fusion-recent-works) .fusion-portfolio-wrapper").isotope()}))}function ewwwWebPInit(e){ewwwLoadImages(e),ewwwNggLoadGalleries(e),document.arrive(".ewww_webp",function(){ewwwLoadImages(e)}),document.arrive(".ewww_webp_lazy_load",function(){ewwwLoadImages(e)}),document.arrive("videos",function(){ewwwLoadImages(e)}),"loading"==document.readyState?document.addEventListener("DOMContentLoaded",ewwwJSONParserInit):("undefined"!=typeof galleries&&ewwwNggParseGalleries(e),ewwwWooParseVariations(e))}function ewwwAttr(e,t,r){null!=r&&!1!==r&&e.setAttribute(t,r)}function ewwwJSONParserInit(){"undefined"!=typeof galleries&&check_webp_feature("alpha",ewwwNggParseGalleries),check_webp_feature("alpha",ewwwWooParseVariations)}function ewwwWooParseVariations(e){if(e)for(var t=document.querySelectorAll("form.variations_form"),r=0,a=t.length;r<a;r++){var i=t[r].getAttribute("data-product_variations"),n=!1;try{for(var o in i=JSON.parse(i))void 0!==i[o]&&void 0!==i[o].image&&(void 0!==i[o].image.src_webp&&(i[o].image.src=i[o].image.src_webp,n=!0),void 0!==i[o].image.srcset_webp&&(i[o].image.srcset=i[o].image.srcset_webp,n=!0),void 0!==i[o].image.full_src_webp&&(i[o].image.full_src=i[o].image.full_src_webp,n=!0),void 0!==i[o].image.gallery_thumbnail_src_webp&&(i[o].image.gallery_thumbnail_src=i[o].image.gallery_thumbnail_src_webp,n=!0),void 0!==i[o].image.thumb_src_webp&&(i[o].image.thumb_src=i[o].image.thumb_src_webp,n=!0));n&&ewwwAttr(t[r],"data-product_variations",JSON.stringify(i))}catch(e){}}}function ewwwNggParseGalleries(e){if(e)for(var t in galleries){var r=galleries[t];galleries[t].images_list=ewwwNggParseImageList(r.images_list)}}function ewwwNggLoadGalleries(e){e&&document.addEventListener("ngg.galleria.themeadded",function(e,t){window.ngg_galleria._create_backup=window.ngg_galleria.create,window.ngg_galleria.create=function(e,t){var r=$(e).data("id");return galleries["gallery_"+r].images_list=ewwwNggParseImageList(galleries["gallery_"+r].images_list),window.ngg_galleria._create_backup(e,t)}})}function ewwwNggParseImageList(e){for(var t in e){var r=e[t];if(void 0!==r["image-webp"]&&(e[t].image=r["image-webp"],delete e[t]["image-webp"]),void 0!==r["thumb-webp"]&&(e[t].thumb=r["thumb-webp"],delete e[t]["thumb-webp"]),void 0!==r.full_image_webp&&(e[t].full_image=r.full_image_webp,delete e[t].full_image_webp),void 0!==r.srcsets)for(var a in r.srcsets)nggSrcset=r.srcsets[a],void 0!==r.srcsets[a+"-webp"]&&(e[t].srcsets[a]=r.srcsets[a+"-webp"],delete e[t].srcsets[a+"-webp"]);if(void 0!==r.full_srcsets)for(var i in r.full_srcsets)nggFSrcset=r.full_srcsets[i],void 0!==r.full_srcsets[i+"-webp"]&&(e[t].full_srcsets[i]=r.full_srcsets[i+"-webp"],delete e[t].full_srcsets[i+"-webp"])}return e}check_webp_feature("alpha",ewwwWebPInit);
|
mwebp.php
CHANGED
@@ -214,7 +214,6 @@ function ewww_image_optimizer_webp_loop() {
|
|
214 |
ewwwio_debug_message( "took $elapsed seconds this time around" );
|
215 |
// Store the updated list of images back in the database.
|
216 |
update_option( 'ewww_image_optimizer_webp_images', $images );
|
217 |
-
ewww_image_optimizer_debug_log();
|
218 |
die();
|
219 |
}
|
220 |
|
214 |
ewwwio_debug_message( "took $elapsed seconds this time around" );
|
215 |
// Store the updated list of images back in the database.
|
216 |
update_option( 'ewww_image_optimizer_webp_images', $images );
|
|
|
217 |
die();
|
218 |
}
|
219 |
|
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.4
|
6 |
-
Tested up to: 5.
|
7 |
Requires PHP: 7.1
|
8 |
-
Stable tag: 6.
|
9 |
License: GPLv3
|
10 |
|
11 |
Smaller Images, Faster Sites, Happier Visitors. Comprehensive image optimization that doesn't require a degree in rocket science.
|
@@ -132,6 +132,27 @@ That's not a question, but since I made it up, I'll answer it. See this resource
|
|
132 |
* Feature requests can be viewed and submitted on our [feedback portal](https://feedback.ewww.io/b/features)
|
133 |
* 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/)
|
134 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
135 |
= 6.1.9 =
|
136 |
* fixed: Easy IO's Include All Resources compat with Oxygen Builder and Beaver Builder
|
137 |
* fixed: regex to detect SVG images in use elements caused excessive backtracking
|
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.4
|
6 |
+
Tested up to: 5.8
|
7 |
Requires PHP: 7.1
|
8 |
+
Stable tag: 6.2.0
|
9 |
License: GPLv3
|
10 |
|
11 |
Smaller Images, Faster Sites, Happier Visitors. Comprehensive image optimization that doesn't require a degree in rocket science.
|
132 |
* Feature requests can be viewed and submitted on our [feedback portal](https://feedback.ewww.io/b/features)
|
133 |
* 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/)
|
134 |
|
135 |
+
= 6.2.0 =
|
136 |
+
* added: PHP-based WebP Conversion via GD/Imagick in free mode when exec() is disabled
|
137 |
+
* added: enable -sharp_yuv option for WebP conversion with the EIO_WEBP_SHARP_YUV override
|
138 |
+
* added: WebP Conversion for CMYK images
|
139 |
+
* added: webp-supported conditional class added to body tag when JS WebP is active
|
140 |
+
* added: WP-CLI command can be run with --webp-only option
|
141 |
+
* added: Lazy Load for iframes, add 'iframe' in exclusions to disable
|
142 |
+
* added: compatibility with S3 Uploads 3.x
|
143 |
+
* added: preserve metadata and apply lossless compression to linked versions of images via Easy IO with EIO_PRESERVE_LINKED_IMAGES constant
|
144 |
+
* added: Easy IO rewrites URLs in existing picture elements
|
145 |
+
* changed: JS WebP scripts moved to beginning of page footer
|
146 |
+
* changed: native lazy loading is now enabled for right-sized PNG placeholders, override with EIO_DISABLE_NATIVE_LAZY constant
|
147 |
+
* changed: add resume ability to Delete Originals tool
|
148 |
+
* changed: move Easy IO check-in to wp_cron
|
149 |
+
* fixed: empty .webp images sometimes produced when cwebp encounters an error
|
150 |
+
* fixed: Bulk Optimizer for NextGEN loading incorrect script
|
151 |
+
* fixed: Bulk Optimizer for NextGEN fails to verify nonce for selective optimization
|
152 |
+
* fixed: Last Optimized times for Optimized Images table were incorrect
|
153 |
+
* fixed: Add Missing Dimensions overwrites smaller width/height attribute if only one is set
|
154 |
+
* fixed: replacing an existing attribute (like width) with a numeric value is broken
|
155 |
+
|
156 |
= 6.1.9 =
|
157 |
* fixed: Easy IO's Include All Resources compat with Oxygen Builder and Beaver Builder
|
158 |
* fixed: regex to detect SVG images in use elements caused excessive backtracking
|
tests/test-agr.php
CHANGED
@@ -43,7 +43,7 @@ class EWWWIO_AGR_Tests extends WP_UnitTestCase {
|
|
43 |
* Test that GD is active and Imagick is not -- otherwise our tests are bogus.
|
44 |
*/
|
45 |
function test_gd_active() {
|
46 |
-
$this->
|
47 |
$this->assertFalse( ewww_image_optimizer_imagick_support() );
|
48 |
}
|
49 |
|
43 |
* Test that GD is active and Imagick is not -- otherwise our tests are bogus.
|
44 |
*/
|
45 |
function test_gd_active() {
|
46 |
+
$this->assertNotEmpty( ewww_image_optimizer_gd_support() );
|
47 |
$this->assertFalse( ewww_image_optimizer_imagick_support() );
|
48 |
}
|
49 |
|
unique.php
CHANGED
@@ -222,7 +222,7 @@ function ewww_image_optimizer_notice_hosting_requires_api() {
|
|
222 |
}
|
223 |
echo "<div id='ewww-image-optimizer-warning-exec' class='notice notice-warning is-dismissible'><p>" .
|
224 |
/* translators: %s: Name of a web host, like WordPress.com or Pantheon. */
|
225 |
-
sprintf( esc_html__( '%s sites require cloud-based optimization, because server-based optimization is disallowed. Those who upgrade to our premium service receive much higher compression, PNG/GIF/PDF compression,
|
226 |
'<br><strong>' .
|
227 |
/* translators: %s: link to 'start your free trial' */
|
228 |
sprintf( esc_html__( 'Dismiss this notice to continue with free cloud-based JPG compression or %s.', 'ewww-image-optimizer' ), "<a href='https://ewww.io/plans/'>" . esc_html__( 'start your premium trial', 'ewww-image-optimizer' ) . '</a>' );
|
@@ -616,7 +616,7 @@ function ewww_image_optimizer_notice_utils( $quiet = null ) {
|
|
616 |
ob_start();
|
617 |
// Display a warning if exec() is disabled, can't run local tools without it.
|
618 |
echo "<div id='ewww-image-optimizer-warning-exec' class='notice notice-warning is-dismissible'><p>" .
|
619 |
-
esc_html__( 'Sites where the exec() function is disabled require cloud-based optimization, because free server-based optimization will not work. Those who upgrade to our premium service receive much higher compression, PNG/GIF/PDF compression,
|
620 |
'<strong>' .
|
621 |
( ewww_image_optimizer_get_option( 'ewww_image_optimizer_exactdn' ) || get_option( 'easyio_exactdn' ) ?
|
622 |
esc_html__( 'Sites that use Easy IO already have built-in image optimization and may dismiss this notice to disable local compression.', 'ewww-image-optimizer' )
|
@@ -720,8 +720,10 @@ function ewww_image_optimizer_notice_utils( $quiet = null ) {
|
|
720 |
break;
|
721 |
case 'CWEBP':
|
722 |
if ( ! $skip['webp'] && empty( $req ) ) {
|
723 |
-
|
724 |
-
|
|
|
|
|
725 |
}
|
726 |
if ( ! defined( 'EWWW_IMAGE_OPTIMIZER_' . $key ) ) {
|
727 |
ewwwio_debug_message( "defining EWWW_IMAGE_OPTIMIZER_$key" );
|
@@ -2107,6 +2109,7 @@ function ewww_image_optimizer( $file, $gallery_type = 4, $converted = false, $ne
|
|
2107 |
// For exec-deprived servers.
|
2108 |
if ( 10 === (int) $compression_level && EWWW_IMAGE_OPTIMIZER_NOEXEC ) {
|
2109 |
list( $file, $converted, $result, $new_size, $backup_hash ) = ewww_image_optimizer_cloud_optimizer( $file, $type );
|
|
|
2110 |
break;
|
2111 |
}
|
2112 |
if ( $convert ) {
|
@@ -2401,6 +2404,11 @@ function ewww_image_optimizer( $file, $gallery_type = 4, $converted = false, $ne
|
|
2401 |
}
|
2402 |
break;
|
2403 |
}
|
|
|
|
|
|
|
|
|
|
|
2404 |
if ( $convert ) {
|
2405 |
$tools = ewww_image_optimizer_path_check(
|
2406 |
! $skip['jpegtran'],
|
@@ -3006,7 +3014,13 @@ function ewww_image_optimizer_webp_create( $file, $orig_size, $type, $tool, $rec
|
|
3006 |
return esc_html__( 'Image dimensions too large for WebP conversion.', 'ewww-image-optimizer' );
|
3007 |
}
|
3008 |
if ( empty( $tool ) || 'image/gif' === $type ) {
|
3009 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
3010 |
} else {
|
3011 |
$nice = '';
|
3012 |
if ( ! EWWW_IMAGE_OPTIMIZER_CLOUD ) {
|
@@ -3017,26 +3031,26 @@ function ewww_image_optimizer_webp_create( $file, $orig_size, $type, $tool, $rec
|
|
3017 |
}
|
3018 |
}
|
3019 |
// Check to see if we are supposed to strip metadata.
|
3020 |
-
|
3021 |
-
|
3022 |
-
|
3023 |
-
} else {
|
3024 |
-
// Copy all the metadata.
|
3025 |
-
$copy_opt = 'all';
|
3026 |
-
}
|
3027 |
-
$quality = (int) apply_filters( 'webp_quality', 75, 'image/webp' );
|
3028 |
-
if ( $quality < 50 ) {
|
3029 |
$quality = 75;
|
3030 |
}
|
|
|
|
|
3031 |
if ( defined( 'EWWW_IMAGE_OPTIMIZER_LOSSY_PNG2WEBP' ) && EWWW_IMAGE_OPTIMIZER_LOSSY_PNG2WEBP ) {
|
3032 |
-
$lossless = "-q $quality";
|
3033 |
-
} else {
|
3034 |
-
$lossless = '-lossless';
|
3035 |
}
|
3036 |
switch ( $type ) {
|
3037 |
case 'image/jpeg':
|
3038 |
-
ewwwio_debug_message( "$nice " . $tool . " -q $quality -metadata $copy_opt -quiet " . ewww_image_optimizer_escapeshellarg( $file ) . ' -o ' . ewww_image_optimizer_escapeshellarg( $webpfile ) . ' 2>&1' );
|
3039 |
-
exec( "$nice " . $tool . " -q $quality -metadata $copy_opt -quiet " . ewww_image_optimizer_escapeshellarg( $file ) . ' -o ' . ewww_image_optimizer_escapeshellarg( $webpfile ) . ' 2>&1', $cli_output );
|
|
|
|
|
|
|
|
|
|
|
|
|
3040 |
break;
|
3041 |
case 'image/png':
|
3042 |
ewwwio_debug_message( "$nice " . $tool . " $lossless -metadata $copy_opt -quiet " . ewww_image_optimizer_escapeshellarg( $file ) . ' -o ' . ewww_image_optimizer_escapeshellarg( $webpfile ) . ' 2>&1' );
|
@@ -3050,7 +3064,7 @@ function ewww_image_optimizer_webp_create( $file, $orig_size, $type, $tool, $rec
|
|
3050 |
ewwwio_debug_message( 'webp file was too big, deleting' );
|
3051 |
ewwwio_delete_file( $webpfile );
|
3052 |
return esc_html__( 'WebP image was larger than original.', 'ewww-image-optimizer' );
|
3053 |
-
} elseif ( ewwwio_is_file( $webpfile ) ) {
|
3054 |
// Set correct file permissions.
|
3055 |
$stat = stat( dirname( $webpfile ) );
|
3056 |
$perms = $stat['mode'] & 0000666; // Same permissions as parent folder, strip off the executable bits.
|
@@ -3059,6 +3073,10 @@ function ewww_image_optimizer_webp_create( $file, $orig_size, $type, $tool, $rec
|
|
3059 |
return esc_html__( 'WebP image larger than original, saved anyway with Force WebP option.', 'ewww-image-optimizer' );
|
3060 |
}
|
3061 |
return 'WebP: ' . ewww_image_optimizer_image_results( $orig_size, $webp_size );
|
|
|
|
|
|
|
|
|
3062 |
}
|
3063 |
return esc_html__( 'Image could not be converted to WebP.', 'ewww-image-optimizer' );
|
3064 |
}
|
222 |
}
|
223 |
echo "<div id='ewww-image-optimizer-warning-exec' class='notice notice-warning is-dismissible'><p>" .
|
224 |
/* translators: %s: Name of a web host, like WordPress.com or Pantheon. */
|
225 |
+
sprintf( esc_html__( '%s sites require cloud-based optimization, because server-based optimization is disallowed. Those who upgrade to our premium service receive much higher compression, PNG/GIF/PDF compression, and image backups.', 'ewww-image-optimizer' ), esc_html( $webhost ) ) .
|
226 |
'<br><strong>' .
|
227 |
/* translators: %s: link to 'start your free trial' */
|
228 |
sprintf( esc_html__( 'Dismiss this notice to continue with free cloud-based JPG compression or %s.', 'ewww-image-optimizer' ), "<a href='https://ewww.io/plans/'>" . esc_html__( 'start your premium trial', 'ewww-image-optimizer' ) . '</a>' );
|
616 |
ob_start();
|
617 |
// Display a warning if exec() is disabled, can't run local tools without it.
|
618 |
echo "<div id='ewww-image-optimizer-warning-exec' class='notice notice-warning is-dismissible'><p>" .
|
619 |
+
esc_html__( 'Sites where the exec() function is disabled require cloud-based optimization, because free server-based optimization will not work. Those who upgrade to our premium service receive much higher compression, PNG/GIF/PDF compression, and image backups.', 'ewww-image-optimizer' ) . '<br>' .
|
620 |
'<strong>' .
|
621 |
( ewww_image_optimizer_get_option( 'ewww_image_optimizer_exactdn' ) || get_option( 'easyio_exactdn' ) ?
|
622 |
esc_html__( 'Sites that use Easy IO already have built-in image optimization and may dismiss this notice to disable local compression.', 'ewww-image-optimizer' )
|
720 |
break;
|
721 |
case 'CWEBP':
|
722 |
if ( ! $skip['webp'] && empty( $req ) ) {
|
723 |
+
if ( ! ewww_image_optimizer_imagick_supports_webp() && ! ewww_image_optimizer_gd_supports_webp() ) {
|
724 |
+
$missing[] = 'webp';
|
725 |
+
}
|
726 |
+
$req = false;
|
727 |
}
|
728 |
if ( ! defined( 'EWWW_IMAGE_OPTIMIZER_' . $key ) ) {
|
729 |
ewwwio_debug_message( "defining EWWW_IMAGE_OPTIMIZER_$key" );
|
2109 |
// For exec-deprived servers.
|
2110 |
if ( 10 === (int) $compression_level && EWWW_IMAGE_OPTIMIZER_NOEXEC ) {
|
2111 |
list( $file, $converted, $result, $new_size, $backup_hash ) = ewww_image_optimizer_cloud_optimizer( $file, $type );
|
2112 |
+
$webp_result = ewww_image_optimizer_webp_create( $file, $new_size, $type, null, $orig_size !== $new_size );
|
2113 |
break;
|
2114 |
}
|
2115 |
if ( $convert ) {
|
2404 |
}
|
2405 |
break;
|
2406 |
}
|
2407 |
+
// For exec-deprived servers.
|
2408 |
+
if ( 10 >= (int) $compression_level && EWWW_IMAGE_OPTIMIZER_NOEXEC ) {
|
2409 |
+
$webp_result = ewww_image_optimizer_webp_create( $file, $orig_size, $type, null, $orig_size !== $new_size );
|
2410 |
+
break;
|
2411 |
+
}
|
2412 |
if ( $convert ) {
|
2413 |
$tools = ewww_image_optimizer_path_check(
|
2414 |
! $skip['jpegtran'],
|
3014 |
return esc_html__( 'Image dimensions too large for WebP conversion.', 'ewww-image-optimizer' );
|
3015 |
}
|
3016 |
if ( empty( $tool ) || 'image/gif' === $type ) {
|
3017 |
+
if ( ewww_image_optimizer_get_option( 'ewww_image_optimizer_cloud_key' ) ) {
|
3018 |
+
ewww_image_optimizer_cloud_optimizer( $file, $type, false, $webpfile, 'image/webp' );
|
3019 |
+
} elseif ( ewww_image_optimizer_imagick_supports_webp() ) {
|
3020 |
+
ewww_image_optimizer_imagick_create_webp( $file, $type, $webpfile );
|
3021 |
+
} elseif ( ewww_image_optimizer_gd_supports_webp() ) {
|
3022 |
+
ewww_image_optimizer_gd_create_webp( $file, $type, $webpfile );
|
3023 |
+
}
|
3024 |
} else {
|
3025 |
$nice = '';
|
3026 |
if ( ! EWWW_IMAGE_OPTIMIZER_CLOUD ) {
|
3031 |
}
|
3032 |
}
|
3033 |
// Check to see if we are supposed to strip metadata.
|
3034 |
+
$copy_opt = ewww_image_optimizer_get_option( 'ewww_image_optimizer_metadata_remove' ) ? 'icc' : 'all';
|
3035 |
+
$quality = (int) apply_filters( 'webp_quality', 75, 'image/webp' );
|
3036 |
+
if ( $quality < 50 || $quality > 100 ) {
|
|
|
|
|
|
|
|
|
|
|
|
|
3037 |
$quality = 75;
|
3038 |
}
|
3039 |
+
$sharp_yuv = defined( 'EIO_WEBP_SHARP_YUV' ) && EIO_WEBP_SHARP_YUV ? '-sharp_yuv' : '';
|
3040 |
+
$lossless = '-lossless';
|
3041 |
if ( defined( 'EWWW_IMAGE_OPTIMIZER_LOSSY_PNG2WEBP' ) && EWWW_IMAGE_OPTIMIZER_LOSSY_PNG2WEBP ) {
|
3042 |
+
$lossless = "-q $quality $sharp_yuv";
|
|
|
|
|
3043 |
}
|
3044 |
switch ( $type ) {
|
3045 |
case 'image/jpeg':
|
3046 |
+
ewwwio_debug_message( "$nice " . $tool . " -q $quality $sharp_yuv -metadata $copy_opt -quiet " . ewww_image_optimizer_escapeshellarg( $file ) . ' -o ' . ewww_image_optimizer_escapeshellarg( $webpfile ) . ' 2>&1' );
|
3047 |
+
exec( "$nice " . $tool . " -q $quality $sharp_yuv -metadata $copy_opt -quiet " . ewww_image_optimizer_escapeshellarg( $file ) . ' -o ' . ewww_image_optimizer_escapeshellarg( $webpfile ) . ' 2>&1', $cli_output );
|
3048 |
+
if ( ! ewwwio_is_file( $webpfile ) && ewww_image_optimizer_imagick_supports_webp() && ewww_image_optimizer_is_cmyk( $file ) ) {
|
3049 |
+
ewwwio_debug_message( 'cmyk image skipped, trying imagick' );
|
3050 |
+
ewww_image_optimizer_imagick_create_webp( $file, $type, $webpfile );
|
3051 |
+
} elseif ( ewwwio_is_file( $webpfile ) && 'image/webp' !== ewww_image_optimizer_mimetype( $webpfile, 'i' ) ) {
|
3052 |
+
ewwwio_debug_message( 'non-webp file produced' );
|
3053 |
+
}
|
3054 |
break;
|
3055 |
case 'image/png':
|
3056 |
ewwwio_debug_message( "$nice " . $tool . " $lossless -metadata $copy_opt -quiet " . ewww_image_optimizer_escapeshellarg( $file ) . ' -o ' . ewww_image_optimizer_escapeshellarg( $webpfile ) . ' 2>&1' );
|
3064 |
ewwwio_debug_message( 'webp file was too big, deleting' );
|
3065 |
ewwwio_delete_file( $webpfile );
|
3066 |
return esc_html__( 'WebP image was larger than original.', 'ewww-image-optimizer' );
|
3067 |
+
} elseif ( ewwwio_is_file( $webpfile ) && 'image/webp' === ewww_image_optimizer_mimetype( $webpfile, 'i' ) ) {
|
3068 |
// Set correct file permissions.
|
3069 |
$stat = stat( dirname( $webpfile ) );
|
3070 |
$perms = $stat['mode'] & 0000666; // Same permissions as parent folder, strip off the executable bits.
|
3073 |
return esc_html__( 'WebP image larger than original, saved anyway with Force WebP option.', 'ewww-image-optimizer' );
|
3074 |
}
|
3075 |
return 'WebP: ' . ewww_image_optimizer_image_results( $orig_size, $webp_size );
|
3076 |
+
} elseif ( ewwwio_is_file( $webpfile ) ) {
|
3077 |
+
ewwwio_debug_message( 'webp file mimetype did not validate, deleting' );
|
3078 |
+
ewwwio_delete_file( $webpfile );
|
3079 |
+
return esc_html__( 'WebP conversion error.', 'ewww-image-optimizer' );
|
3080 |
}
|
3081 |
return esc_html__( 'Image could not be converted to WebP.', 'ewww-image-optimizer' );
|
3082 |
}
|
vendor/icc/sRGB2014.icc
ADDED
Binary file
|