From aec9ba7518fc2c5d39cdccc10025ff220a405a59 Mon Sep 17 00:00:00 2001 From: Git I Hate You Date: Wed, 29 May 2019 00:21:51 +0200 Subject: [PATCH 01/11] Don't use a non-existing filesystem property --- classes/Webp/RewriteRules/Display.php | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/classes/Webp/RewriteRules/Display.php b/classes/Webp/RewriteRules/Display.php index 8502e55d7..5fe8ad9f0 100644 --- a/classes/Webp/RewriteRules/Display.php +++ b/classes/Webp/RewriteRules/Display.php @@ -196,12 +196,13 @@ public function deactivate() { return; } - $file_path = $conf->get_file_path(); + $file_path = $conf->get_file_path(); + $filesystem = \Imagify_Filesystem::get_instance(); - if ( ! $this->filesystem->exists( $file_path ) ) { + if ( ! $filesystem->exists( $file_path ) ) { return; } - if ( ! $this->filesystem->is_writable( $file_path ) ) { + if ( ! $filesystem->is_writable( $file_path ) ) { return; } From 519b24beb972d36f5fccf7c048f3ddcbc8e994db Mon Sep 17 00:00:00 2001 From: Git I Hate You Date: Thu, 6 Jun 2019 00:10:44 +0200 Subject: [PATCH 02/11] Prevent a php notice if the optimization data has no "full" entry --- inc/functions/admin-stats.php | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/inc/functions/admin-stats.php b/inc/functions/admin-stats.php index 1f8134101..95f1bb69d 100755 --- a/inc/functions/admin-stats.php +++ b/inc/functions/admin-stats.php @@ -350,16 +350,17 @@ function imagify_count_saving_data( $key = '' ) { continue; } - $original_data = $attachment_data['sizes']['full']; - - if ( empty( $original_data['success'] ) ) { + if ( empty( $attachment_data['sizes']['full']['success'] ) ) { /** - * Case where this attachment has multiple '_imagify_status' metas, and is fetched (in the above query) as a "success" while the '_imagify_data' says otherwise. - * Don't ask how it's possible, I don't know. + * - Case where this attachment has multiple '_imagify_status' metas, and is fetched (in the above query) as a "success" while the '_imagify_data' says otherwise. + * - Case where this meta has no "full" entry. + * Don't ask how it's possible, I don't know ¯\(°_o)/¯ */ continue; } + $original_data = $attachment_data['sizes']['full']; + ++$count; // Increment the original sizes. From fa687e3da202e4f796c39fa7405624960865220f Mon Sep 17 00:00:00 2001 From: Git I Hate You Date: Thu, 6 Jun 2019 00:26:44 +0200 Subject: [PATCH 03/11] Prevent a php notice by adding a missing $process assignation --- inc/classes/class-imagify-admin-ajax-post.php | 1 + 1 file changed, 1 insertion(+) diff --git a/inc/classes/class-imagify-admin-ajax-post.php b/inc/classes/class-imagify-admin-ajax-post.php index b62ef1c8f..eb1ced8e3 100755 --- a/inc/classes/class-imagify-admin-ajax-post.php +++ b/inc/classes/class-imagify-admin-ajax-post.php @@ -704,6 +704,7 @@ public function imagify_restore_file_callback() { wp_send_json_error( $result->get_error_message() ); } + $process = imagify_get_optimization_process( $media_id, 'custom-folders' ); $this->file_optimization_output( $process ); } From 4a24c8cc957ca9fcf1edd502bc4a0bc4c8153fd2 Mon Sep 17 00:00:00 2001 From: Git I Hate You Date: Thu, 6 Jun 2019 00:22:23 +0200 Subject: [PATCH 04/11] Use the right needle for strpos() Because of `$folders = array_flip( $folders );` earlier, the needles used in `strpos()` were integers (array numeric keys before `array_flip()`). --- inc/classes/class-imagify-files-scan.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/inc/classes/class-imagify-files-scan.php b/inc/classes/class-imagify-files-scan.php index b6c4bb389..be8487b1e 100644 --- a/inc/classes/class-imagify-files-scan.php +++ b/inc/classes/class-imagify-files-scan.php @@ -143,7 +143,7 @@ public static function is_path_forbidden( $file_path ) { } } - foreach ( $folders as $folder ) { + foreach ( $folders as $folder => $i ) { if ( strpos( $file_path, $folder ) === 0 ) { return true; } From 624d34f8689594b682f683dfe5609b6f81f051a2 Mon Sep 17 00:00:00 2001 From: Git I Hate You Date: Thu, 6 Jun 2019 00:16:35 +0200 Subject: [PATCH 05/11] Use WP_Error->get_error_message() instead of ->get_message() --- classes/Optimization/Process/AbstractProcess.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/classes/Optimization/Process/AbstractProcess.php b/classes/Optimization/Process/AbstractProcess.php index 1ae71f313..aa1ea00c2 100644 --- a/classes/Optimization/Process/AbstractProcess.php +++ b/classes/Optimization/Process/AbstractProcess.php @@ -1108,7 +1108,7 @@ public function maybe_resize( $size, $file ) { sprintf( /* translators: %s is an error message. */ __( 'Resizement failed: %s', 'imagify' ), - $resized_path->get_message() + $resized_path->get_error_message() ) ); } @@ -1123,7 +1123,7 @@ public function maybe_resize( $size, $file ) { sprintf( /* translators: %s is an error message. */ __( 'Backup failed: %s', 'imagify' ), - $backuped->get_message() + $backuped->get_error_message() ) ); } From 3faed716fbe7b9df34d042a21bb9a07fdec0c09d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9gory=20Viguier?= Date: Fri, 7 Jun 2019 16:23:56 +0200 Subject: [PATCH 06/11] Closes #370: speed optimization up (#378) * Introduced Imagifybeat core and actions classes Imagifybeat is a Heartbeat replacement (observe how creative we are to name things). The Core class contains the mechanism, while the Actions class contains the actions to perform upon each tick. * Initiate the new classes * Remove and deprecate Heartbeat-related functions * Use Imagifybeat as a dependency for JS * Introduced Imagifybeat JS API * Use Imagifybeat in our JS scripts --- assets/js/beat.js | 872 ++++++++++++++++++ assets/js/beat.min.js | 1 + assets/js/bulk.js | 96 +- assets/js/bulk.min.js | 2 +- assets/js/files-list.js | 61 +- assets/js/files-list.min.js | 2 +- assets/js/media-modal.js | 59 +- assets/js/media-modal.min.js | 2 +- assets/js/options.js | 58 +- assets/js/options.min.js | 2 +- classes/Imagifybeat/Actions.php | 438 +++++++++ classes/Imagifybeat/Core.php | 172 ++++ .../nextgen-gallery/inc/admin/heartbeat.php | 13 - .../nextgen-gallery/nextgen-gallery.php | 1 - inc/admin/heartbeat.php | 358 ------- inc/classes/class-imagify-assets.php | 69 +- inc/classes/class-imagify-plugin.php | 3 +- .../class-imagify-assets-deprecated.php | 61 ++ inc/deprecated/deprecated.php | 379 ++++++++ inc/functions/i18n.php | 31 +- 20 files changed, 2094 insertions(+), 586 deletions(-) create mode 100644 assets/js/beat.js create mode 100644 assets/js/beat.min.js create mode 100644 classes/Imagifybeat/Actions.php create mode 100644 classes/Imagifybeat/Core.php delete mode 100644 inc/3rd-party/nextgen-gallery/inc/admin/heartbeat.php delete mode 100755 inc/admin/heartbeat.php diff --git a/assets/js/beat.js b/assets/js/beat.js new file mode 100644 index 000000000..12677de1c --- /dev/null +++ b/assets/js/beat.js @@ -0,0 +1,872 @@ +/** + * Imagify beat API + * + * This is a modified version of WordPress’ Heartbeat (WP 5.2.1). + * The main difference is that it allows to prevent suspension entirely. + * It uses the var imagifybeatSettings on init. + * + * Custom jQuery events: + * - imagifybeat-send + * - imagifybeat-tick + * - imagifybeat-error + * - imagifybeat-connection-lost + * - imagifybeat-connection-restored + * - imagifybeat-nonces-expired + * + * @since 1.9.3 + */ + +window.imagify = window.imagify || {}; + +/* eslint-disable no-use-before-define */ +(function($, d, w, undefined) { // eslint-disable-line no-unused-vars, no-shadow, no-shadow-restricted-names + + /** + * Constructs the Imagifybeat API. + * + * @since 1.9.3 + * @constructor + * + * @return {Imagifybeat} An instance of the Imagifybeat class. + */ + var Imagifybeat = function() { + var $document = $( d ), + settings = { + // Suspend/resume. + suspend: false, + + // Whether suspending is enabled. + suspendEnabled: true, + + // Current screen id, defaults to the JS global 'pagenow' when present + // (in the admin) or 'front'. + screenId: '', + + // XHR request URL, defaults to the JS global 'ajaxurl' when present. + url: '', + + // Timestamp, start of the last connection request. + lastTick: 0, + + // Container for the enqueued items. + queue: {}, + + // Connect interval (in seconds). + mainInterval: 60, + + // Used when the interval is set to 5 sec. temporarily. + tempInterval: 0, + + // Used when the interval is reset. + originalInterval: 0, + + // Used to limit the number of AJAX requests. + minimalInterval: 0, + + // Used together with tempInterval. + countdown: 0, + + // Whether a connection is currently in progress. + connecting: false, + + // Whether a connection error occurred. + connectionError: false, + + // Used to track non-critical errors. + errorcount: 0, + + // Whether at least one connection has been completed successfully. + hasConnected: false, + + // Whether the current browser w is in focus and the user is active. + hasFocus: true, + + // Timestamp, last time the user was active. Checked every 30 sec. + userActivity: 0, + + // Flag whether events tracking user activity were set. + userActivityEvents: false, + + // Timer that keeps track of how long a user has focus. + checkFocusTimer: 0, + + // Timer that keeps track of how long needs to be waited before connecting to + // the server again. + beatTimer: 0 + }; + + /** + * Sets local variables and events, then starts the beat. + * + * @since 1.9.3 + * @access private + * + * @return {void} + */ + function initialize() { + var options, hidden, visibilityState, visibilitychange; + + if ( typeof w.pagenow === 'string' ) { + settings.screenId = w.pagenow; + } + + if ( typeof w.ajaxurl === 'string' ) { + settings.url = w.ajaxurl; + } + + // Pull in options passed from PHP. + if ( typeof w.imagifybeatSettings === 'object' ) { + options = w.imagifybeatSettings; + + // The XHR URL can be passed as option when w.ajaxurl is not set. + if ( ! settings.url && options.ajaxurl ) { + settings.url = options.ajaxurl; + } + + /* + * The interval can be from 15 to 120 sec. and can be set temporarily to 5 sec. + * It can be set in the initial options or changed later through JS and/or + * through PHP. + */ + if ( options.interval ) { + settings.mainInterval = options.interval; + + if ( settings.mainInterval < 15 ) { + settings.mainInterval = 15; + } else if ( settings.mainInterval > 120 ) { + settings.mainInterval = 120; + } + } + + /* + * Used to limit the number of AJAX requests. Overrides all other intervals if + * they are shorter. Needed for some hosts that cannot handle frequent requests + * and the user may exceed the allocated server CPU time, etc. The minimal + * interval can be up to 600 sec. however setting it to longer than 120 sec. + * will limit or disable some of the functionality (like post locks). Once set + * at initialization, minimalInterval cannot be changed/overridden. + */ + if ( options.minimalInterval ) { + options.minimalInterval = parseInt( options.minimalInterval, 10 ); + settings.minimalInterval = options.minimalInterval > 0 && options.minimalInterval <= 600 ? options.minimalInterval * 1000 : 0; + } + + if ( settings.minimalInterval && settings.mainInterval < settings.minimalInterval ) { + settings.mainInterval = settings.minimalInterval; + } + + // 'screenId' can be added from settings on the front end where the JS global + // 'pagenow' is not set. + if ( ! settings.screenId ) { + settings.screenId = options.screenId || 'front'; + } + + if ( 'disable' === options.suspension ) { + disableSuspend(); + } + } + + // Convert to milliseconds. + settings.mainInterval = settings.mainInterval * 1000; + settings.originalInterval = settings.mainInterval; + + /* + * Switch the interval to 120 seconds by using the Page Visibility API. + * If the browser doesn't support it (Safari < 7, Android < 4.4, IE < 10), the + * interval will be increased to 120 seconds after 5 minutes of mouse and keyboard + * inactivity. + */ + if ( typeof document.hidden !== 'undefined' ) { + hidden = 'hidden'; + visibilitychange = 'visibilitychange'; + visibilityState = 'visibilityState'; + } else if ( typeof document.msHidden !== 'undefined' ) { // IE10 + hidden = 'msHidden'; + visibilitychange = 'msvisibilitychange'; + visibilityState = 'msVisibilityState'; + } else if ( typeof document.webkitHidden !== 'undefined' ) { // Android + hidden = 'webkitHidden'; + visibilitychange = 'webkitvisibilitychange'; + visibilityState = 'webkitVisibilityState'; + } + + if ( hidden ) { + if ( document[ hidden ] ) { + settings.hasFocus = false; + } + + $document.on( visibilitychange + '.imagifybeat', function() { + if ( 'hidden' === document[ visibilityState ] ) { + blurred(); + w.clearInterval( settings.checkFocusTimer ); + } else { + focused(); + if ( document.hasFocus ) { + settings.checkFocusTimer = w.setInterval( checkFocus, 10000 ); + } + } + }); + } + + // Use document.hasFocus() if available. + if ( document.hasFocus ) { + settings.checkFocusTimer = w.setInterval( checkFocus, 10000 ); + } + + $( w ).on( 'unload.imagifybeat', function() { + // Don't connect anymore. + settings.suspend = true; + + // Abort the last request if not completed. + if ( settings.xhr && 4 !== settings.xhr.readyState ) { + settings.xhr.abort(); + } + } ); + + // Check for user activity every 30 seconds. + w.setInterval( checkUserActivity, 30000 ); + + // Start one tick after DOM ready. + $document.ready( function() { + settings.lastTick = time(); + scheduleNextTick(); + } ); + } + + /** + * Returns the current time according to the browser. + * + * @since 1.9.3 + * @access private + * + * @return {int} Returns the current time. + */ + function time() { + return (new Date()).getTime(); + } + + /** + * Checks if the iframe is from the same origin. + * + * @since 1.9.3 + * @access private + * + * @return {bool} Returns whether or not the iframe is from the same origin. + */ + function isLocalFrame( frame ) { + var origin, src = frame.src; + + /* + * Need to compare strings as WebKit doesn't throw JS errors when iframes have different origin. It throws uncatchable exceptions. + */ + if ( src && /^https?:\/\//.test( src ) ) { + origin = w.location.origin ? w.location.origin : w.location.protocol + '//' + w.location.host; + + if ( src.indexOf( origin ) !== 0 ) { + return false; + } + } + + try { + if ( frame.contentWindow.document ) { + return true; + } + } catch ( e ) {} // eslint-disable-line no-empty + + return false; + } + + /** + * Checks if the document's focus has changed. + * + * @since 1.9.3 + * @access private + * + * @return {void} + */ + function checkFocus() { + if ( settings.hasFocus && ! document.hasFocus() ) { + blurred(); + } else if ( ! settings.hasFocus && document.hasFocus() ) { + focused(); + } + } + + /** + * Sets error state and fires an event on XHR errors or timeout. + * + * @since 1.9.3 + * @access private + * + * @param {string} error The error type passed from the XHR. + * @param {int} httpStatus The HTTP status code passed from jqXHR (200, 404, 500, etc.). + * @return {void} + */ + function setErrorState( error, httpStatus ) { + var trigger; + + if ( error ) { + switch ( error ) { + case 'abort': + // Do nothing. + break; + case 'timeout': + // No response for 30 sec. + trigger = true; + break; + case 'error': + if ( 503 === httpStatus && settings.hasConnected ) { + trigger = true; + break; + } + /* falls through */ + case 'parsererror': + case 'empty': + case 'unknown': + settings.errorcount++; + + if ( settings.errorcount > 2 && settings.hasConnected ) { + trigger = true; + } + + break; + } + + if ( trigger && ! hasConnectionError() ) { + settings.connectionError = true; + $document.trigger( 'imagifybeat-connection-lost', [ error, httpStatus ] ); + + if ( w.wp.hooks ) { + w.wp.hooks.doAction( 'imagifybeat.connection-lost', error, httpStatus ); + } + } + } + } + + /** + * Clears the error state and fires an event if there is a connection error. + * + * @since 1.9.3 + * @access private + * + * @return {void} + */ + function clearErrorState() { + // Has connected successfully. + settings.hasConnected = true; + + if ( hasConnectionError() ) { + settings.errorcount = 0; + settings.connectionError = false; + $document.trigger( 'imagifybeat-connection-restored' ); + + if ( w.wp.hooks ) { + w.wp.hooks.doAction( 'imagifybeat.connection-restored' ); + } + } + } + + /** + * Gathers the data and connects to the server. + * + * @since 1.9.3 + * @access private + * + * @return {void} + */ + function connect() { + var ajaxData, imagifybeatData; + + // If the connection to the server is slower than the interval, + // imagifybeat connects as soon as the previous connection's response is received. + if ( settings.connecting || settings.suspend ) { + return; + } + + settings.lastTick = time(); + + imagifybeatData = $.extend( {}, settings.queue ); + // Clear the data queue. Anything added after this point will be sent on the next tick. + settings.queue = {}; + + $document.trigger( 'imagifybeat-send', [ imagifybeatData ] ); + + if ( w.wp.hooks ) { + w.wp.hooks.doAction( 'imagifybeat.send', imagifybeatData ); + } + + ajaxData = { + data: imagifybeatData, + interval: settings.tempInterval ? settings.tempInterval / 1000 : settings.mainInterval / 1000, + _nonce: typeof w.imagifybeatSettings === 'object' ? w.imagifybeatSettings.nonce : '', + action: 'imagifybeat', + screen_id: settings.screenId, + has_focus: settings.hasFocus + }; + + if ( 'customize' === settings.screenId ) { + ajaxData.wp_customize = 'on'; + } + + settings.connecting = true; + settings.xhr = $.ajax( { + url: settings.url, + type: 'post', + timeout: 60000, // Throw an error if not completed after 60 sec. + data: ajaxData, + dataType: 'json' + } ).always( function() { + settings.connecting = false; + scheduleNextTick(); + } ).done( function( response, textStatus, jqXHR ) { + var newInterval; + + if ( ! response ) { + setErrorState( 'empty' ); + return; + } + + clearErrorState(); + + if ( response.nonces_expired ) { + $document.trigger( 'imagifybeat-nonces-expired' ); + + if ( w.wp.hooks ) { + w.wp.hooks.doAction( 'imagifybeat.nonces-expired' ); + } + } + + // Change the interval from PHP + if ( response.imagifybeat_interval ) { + newInterval = response.imagifybeat_interval; + delete response.imagifybeat_interval; + } + + // Update the imagifybeat nonce if set. + if ( response.imagifybeat_nonce && typeof w.imagifybeatSettings === 'object' ) { + w.imagifybeatSettings.nonce = response.imagifybeat_nonce; + delete response.imagifybeat_nonce; + } + + $document.trigger( 'imagifybeat-tick', [ response, textStatus, jqXHR ] ); + + if ( w.wp.hooks ) { + w.wp.hooks.doAction( 'imagifybeat.tick', response, textStatus, jqXHR ); + } + + // Do this last. Can trigger the next XHR if connection time > 5 sec. and newInterval == 'fast'. + if ( newInterval ) { + interval( newInterval ); + } + } ).fail( function( jqXHR, textStatus, error ) { + setErrorState( textStatus || 'unknown', jqXHR.status ); + $document.trigger( 'imagifybeat-error', [ jqXHR, textStatus, error ] ); + + if ( w.wp.hooks ) { + w.wp.hooks.doAction( 'imagifybeat.error', jqXHR, textStatus, error ); + } + } ); + } + + /** + * Schedules the next connection. + * + * Fires immediately if the connection time is longer than the interval. + * + * @since 1.9.3 + * @access private + * + * @return {void} + */ + function scheduleNextTick() { + var delta = time() - settings.lastTick, + interv = settings.mainInterval; + + if ( settings.suspend ) { + return; + } + + if ( ! settings.hasFocus && settings.suspendEnabled ) { + // When no user activity or the window lost focus, increase polling interval to 120 seconds, but only if suspend is enabled. + interv = 120000; // 120 sec. + } else if ( settings.countdown > 0 && settings.tempInterval ) { + interv = settings.tempInterval; + settings.countdown--; + + if ( settings.countdown < 1 ) { + settings.tempInterval = 0; + } + } + + if ( settings.minimalInterval && interv < settings.minimalInterval ) { + interv = settings.minimalInterval; + } + + w.clearTimeout( settings.beatTimer ); + + if ( delta < interv ) { + settings.beatTimer = w.setTimeout( + function() { + connect(); + }, + interv - delta + ); + } else { + connect(); + } + } + + /** + * Sets the internal state when the browser w becomes hidden or loses focus. + * + * @since 1.9.3 + * @access private + * + * @return {void} + */ + function blurred() { + settings.hasFocus = false; + } + + /** + * Sets the internal state when the browser w becomes visible or is in focus. + * + * @since 1.9.3 + * @access private + * + * @return {void} + */ + function focused() { + settings.userActivity = time(); + + // Resume if suspended + settings.suspend = false; + + if ( ! settings.hasFocus ) { + settings.hasFocus = true; + scheduleNextTick(); + } + } + + /** + * Runs when the user becomes active after a period of inactivity. + * + * @since 1.9.3 + * @access private + * + * @return {void} + */ + function userIsActive() { + settings.userActivityEvents = false; + $document.off( '.imagifybeat-active' ); + + $( 'iframe' ).each( function( i, frame ) { + if ( isLocalFrame( frame ) ) { + $( frame.contentWindow ).off( '.imagifybeat-active' ); + } + } ); + + focused(); + } + + /** + * Checks for user activity. + * + * Runs every 30 sec. Sets 'hasFocus = true' if user is active and the w is + * in the background. Sets 'hasFocus = false' if the user has been inactive + * (no mouse or keyboard activity) for 5 min. even when the w has focus. + * + * @since 1.9.3 + * @access private + * + * @return {void} + */ + function checkUserActivity() { + var lastActive = settings.userActivity ? time() - settings.userActivity : 0; + + // Set hasFocus to false when no mouse or keyboard activity for 5 min. + if ( lastActive > 300000 && settings.hasFocus ) { + blurred(); + } + + // Suspend after 10 min. of inactivity. + if ( settings.suspendEnabled && lastActive > 600000 ) { + settings.suspend = true; + } + + if ( ! settings.userActivityEvents ) { + $document.on( 'mouseover.imagifybeat-active keyup.imagifybeat-active touchend.imagifybeat-active', function() { + userIsActive(); + } ); + + $( 'iframe' ).each( function( i, frame ) { + if ( isLocalFrame( frame ) ) { + $( frame.contentWindow ).on( 'mouseover.imagifybeat-active keyup.imagifybeat-active touchend.imagifybeat-active', function() { + userIsActive(); + } ); + } + } ); + + settings.userActivityEvents = true; + } + } + + // Public methods. + + /** + * Checks whether the w (or any local iframe in it) has focus, or the user + * is active. + * + * @since 1.9.3 + * @memberOf imagify.beat.prototype + * + * @return {bool} True if the w or the user is active. + */ + function hasFocus() { + return settings.hasFocus; + } + + /** + * Checks whether there is a connection error. + * + * @since 1.9.3 + * @memberOf imagify.beat.prototype + * + * @return {bool} True if a connection error was found. + */ + function hasConnectionError() { + return settings.connectionError; + } + + /** + * Connects as soon as possible regardless of 'hasFocus' state. + * + * Will not open two concurrent connections. If a connection is in progress, + * will connect again immediately after the current connection completes. + * + * @since 1.9.3 + * @memberOf imagify.beat.prototype + * + * @return {void} + */ + function connectNow() { + settings.lastTick = 0; + scheduleNextTick(); + } + + /** + * Disables suspending. + * + * Should be used only when Imagifybeat is performing critical tasks like + * autosave, post-locking, etc. Using this on many screens may overload the + * user's hosting account if several browser ws/tabs are left open for a + * long time. + * + * @since 1.9.3 + * @memberOf imagify.beat.prototype + * + * @return {void} + */ + function disableSuspend() { + settings.suspendEnabled = false; + } + + /** + * Enables suspending. + * + * @since 1.9.3 + * @memberOf imagify.beat.prototype + * + * @return {void} + */ + function enableSuspend() { + settings.suspendEnabled = true; + } + + /** + * Gets/Sets the interval. + * + * When setting to 'fast' or 5, the interval is 5 seconds for the next 30 ticks + * (for 2 minutes and 30 seconds) by default. In this case the number of 'ticks' + * can be passed as second argument. If the window doesn't have focus, the + * interval slows down to 2 min. + * + * @since 1.9.3 + * @memberOf imagify.beat.prototype + * + * @param {string|int} speed Interval: 'fast' or 5, 15, 30, 60, 120. Fast equals 5. + * @param {string} ticks Tells how many ticks before the interval reverts back. Used with speed = 'fast' or 5. + * @return {int} Current interval in seconds. + */ + function interval( speed, ticks ) { + var newInterval, + oldInterval = settings.tempInterval ? settings.tempInterval : settings.mainInterval; + + if ( speed ) { + switch ( speed ) { + case 'fast': + case 5: + newInterval = 5000; + break; + case 15: + newInterval = 15000; + break; + case 30: + newInterval = 30000; + break; + case 60: + newInterval = 60000; + break; + case 120: + newInterval = 120000; + break; + case 'long-polling': + // Allow long polling, (experimental) + settings.mainInterval = 0; + return 0; + default: + newInterval = settings.originalInterval; + } + + if ( settings.minimalInterval && newInterval < settings.minimalInterval ) { + newInterval = settings.minimalInterval; + } + + if ( 5000 === newInterval ) { + ticks = parseInt( ticks, 10 ) || 30; + ticks = ticks < 1 || ticks > 30 ? 30 : ticks; + + settings.countdown = ticks; + settings.tempInterval = newInterval; + } else { + settings.countdown = 0; + settings.tempInterval = 0; + settings.mainInterval = newInterval; + } + + // Change the next connection time if new interval has been set. + // Will connect immediately if the time since the last connection + // is greater than the new interval. + if ( newInterval !== oldInterval ) { + scheduleNextTick(); + } + } + + return settings.tempInterval ? settings.tempInterval / 1000 : settings.mainInterval / 1000; + } + + /** + * Resets the interval. + * + * @since 1.9.3 + * @memberOf imagify.beat.prototype + * + * @return {int} Current interval in seconds. + */ + function resetInterval() { + return interval( settings.originalInterval ); + } + + /** + * Enqueues data to send with the next XHR. + * + * As the data is send asynchronously, this function doesn't return the XHR + * response. To see the response, use the custom jQuery event 'imagifybeat-tick' + * on the document, example: + * $(document).on( 'imagifybeat-tick.myname', function( event, data, textStatus, jqXHR ) { + * // code + * }); + * If the same 'handle' is used more than once, the data is not overwritten when + * the third argument is 'true'. Use `imagify.beat.isQueued('handle')` to see if + * any data is already queued for that handle. + * + * @since 1.9.3 + * @memberOf imagify.beat.prototype + * + * @param {string} handle Unique handle for the data, used in PHP to receive the data. + * @param {mixed} data The data to send. + * @param {bool} noOverwrite Whether to overwrite existing data in the queue. + * @return {bool} True if the data was queued. + */ + function enqueue( handle, data, noOverwrite ) { + if ( handle ) { + if ( noOverwrite && this.isQueued( handle ) ) { + return false; + } + + settings.queue[handle] = data; + return true; + } + return false; + } + + /** + * Checks if data with a particular handle is queued. + * + * @since 1.9.3 + * + * @param {string} handle The handle for the data. + * @return {bool} True if the data is queued with this handle. + */ + function isQueued( handle ) { + if ( handle ) { + return settings.queue.hasOwnProperty( handle ); + } + } + + /** + * Removes data with a particular handle from the queue. + * + * @since 1.9.3 + * @memberOf imagify.beat.prototype + * + * @param {string} handle The handle for the data. + */ + function dequeue( handle ) { + if ( handle ) { + delete settings.queue[handle]; + } + } + + /** + * Gets data that was enqueued with a particular handle. + * + * @since 1.9.3 + * @memberOf imagify.beat.prototype + * + * @param {string} handle The handle for the data. + * @return {mixed} The data or undefined. + */ + function getQueuedItem( handle ) { + if ( handle ) { + return this.isQueued( handle ) ? settings.queue[ handle ] : undefined; + } + } + + initialize(); + + // Expose public methods. + return { + hasFocus: hasFocus, + connectNow: connectNow, + disableSuspend: disableSuspend, + enableSuspend: enableSuspend, + interval: interval, + resetInterval: resetInterval, + hasConnectionError: hasConnectionError, + enqueue: enqueue, + dequeue: dequeue, + isQueued: isQueued, + getQueuedItem: getQueuedItem + }; + }; + + /** + * Contains the Imagifybeat API. + * + * @namespace imagify.beat + * @type {Imagifybeat} + */ + w.imagify.beat = new Imagifybeat(); + +} )( jQuery, document, window ); diff --git a/assets/js/beat.min.js b/assets/js/beat.min.js new file mode 100644 index 000000000..91090ef23 --- /dev/null +++ b/assets/js/beat.min.js @@ -0,0 +1 @@ +window.imagify=window.imagify||{},function(a,b,c,d){var e=function(){function e(){return(new Date).getTime()}function f(a){var b,d=a.src;if(d&&/^https?:\/\//.test(d)&&(b=c.location.origin?c.location.origin:c.location.protocol+"//"+c.location.host,0!==d.indexOf(b)))return!1;try{if(a.contentWindow.document)return!0}catch(a){}return!1}function g(){B.hasFocus&&!document.hasFocus()?l():!B.hasFocus&&document.hasFocus()&&m()}function h(a,b){var d;if(a){switch(a){case"abort":break;case"timeout":d=!0;break;case"error":if(503===b&&B.hasConnected){d=!0;break}case"parsererror":case"empty":case"unknown":B.errorcount++,B.errorcount>2&&B.hasConnected&&(d=!0)}d&&!q()&&(B.connectionError=!0,A.trigger("imagifybeat-connection-lost",[a,b]),c.wp.hooks&&c.wp.hooks.doAction("imagifybeat.connection-lost",a,b))}}function i(){B.hasConnected=!0,q()&&(B.errorcount=0,B.connectionError=!1,A.trigger("imagifybeat-connection-restored"),c.wp.hooks&&c.wp.hooks.doAction("imagifybeat.connection-restored"))}function j(){var b,d;B.connecting||B.suspend||(B.lastTick=e(),d=a.extend({},B.queue),B.queue={},A.trigger("imagifybeat-send",[d]),c.wp.hooks&&c.wp.hooks.doAction("imagifybeat.send",d),b={data:d,interval:B.tempInterval?B.tempInterval/1e3:B.mainInterval/1e3,_nonce:"object"==typeof c.imagifybeatSettings?c.imagifybeatSettings.nonce:"",action:"imagifybeat",screen_id:B.screenId,has_focus:B.hasFocus},"customize"===B.screenId&&(b.wp_customize="on"),B.connecting=!0,B.xhr=a.ajax({url:B.url,type:"post",timeout:6e4,data:b,dataType:"json"}).always(function(){B.connecting=!1,k()}).done(function(a,b,d){var e;if(!a)return void h("empty");i(),a.nonces_expired&&(A.trigger("imagifybeat-nonces-expired"),c.wp.hooks&&c.wp.hooks.doAction("imagifybeat.nonces-expired")),a.imagifybeat_interval&&(e=a.imagifybeat_interval,delete a.imagifybeat_interval),a.imagifybeat_nonce&&"object"==typeof c.imagifybeatSettings&&(c.imagifybeatSettings.nonce=a.imagifybeat_nonce,delete a.imagifybeat_nonce),A.trigger("imagifybeat-tick",[a,b,d]),c.wp.hooks&&c.wp.hooks.doAction("imagifybeat.tick",a,b,d),e&&u(e)}).fail(function(a,b,d){h(b||"unknown",a.status),A.trigger("imagifybeat-error",[a,b,d]),c.wp.hooks&&c.wp.hooks.doAction("imagifybeat.error",a,b,d)}))}function k(){var a=e()-B.lastTick,b=B.mainInterval;B.suspend||(!B.hasFocus&&B.suspendEnabled?b=12e4:B.countdown>0&&B.tempInterval&&(b=B.tempInterval,--B.countdown<1&&(B.tempInterval=0)),B.minimalInterval&&b3e5&&B.hasFocus&&l(),B.suspendEnabled&&b>6e5&&(B.suspend=!0),B.userActivityEvents||(A.on("mouseover.imagifybeat-active keyup.imagifybeat-active touchend.imagifybeat-active",function(){n()}),a("iframe").each(function(b,c){f(c)&&a(c.contentWindow).on("mouseover.imagifybeat-active keyup.imagifybeat-active touchend.imagifybeat-active",function(){n()})}),B.userActivityEvents=!0)}function p(){return B.hasFocus}function q(){return B.connectionError}function r(){B.lastTick=0,k()}function s(){B.suspendEnabled=!1}function t(){B.suspendEnabled=!0}function u(a,b){var c,d=B.tempInterval?B.tempInterval:B.mainInterval;if(a){switch(a){case"fast":case 5:c=5e3;break;case 15:c=15e3;break;case 30:c=3e4;break;case 60:c=6e4;break;case 120:c=12e4;break;case"long-polling":return B.mainInterval=0,0;default:c=B.originalInterval}B.minimalInterval&&c30?30:b,B.countdown=b,B.tempInterval=c):(B.countdown=0,B.tempInterval=0,B.mainInterval=c),c!==d&&k()}return B.tempInterval?B.tempInterval/1e3:B.mainInterval/1e3}function v(){return u(B.originalInterval)}function w(a,b,c){return!!a&&((!c||!this.isQueued(a))&&(B.queue[a]=b,!0))}function x(a){if(a)return B.queue.hasOwnProperty(a)}function y(a){a&&delete B.queue[a]}function z(a){if(a)return this.isQueued(a)?B.queue[a]:d}var A=a(b),B={suspend:!1,suspendEnabled:!0,screenId:"",url:"",lastTick:0,queue:{},mainInterval:60,tempInterval:0,originalInterval:0,minimalInterval:0,countdown:0,connecting:!1,connectionError:!1,errorcount:0,hasConnected:!1,hasFocus:!0,userActivity:0,userActivityEvents:!1,checkFocusTimer:0,beatTimer:0};return function(){var b,d,f,h;"string"==typeof c.pagenow&&(B.screenId=c.pagenow),"string"==typeof c.ajaxurl&&(B.url=c.ajaxurl),"object"==typeof c.imagifybeatSettings&&(b=c.imagifybeatSettings,!B.url&&b.ajaxurl&&(B.url=b.ajaxurl),b.interval&&(B.mainInterval=b.interval,B.mainInterval<15?B.mainInterval=15:B.mainInterval>120&&(B.mainInterval=120)),b.minimalInterval&&(b.minimalInterval=parseInt(b.minimalInterval,10),B.minimalInterval=b.minimalInterval>0&&b.minimalInterval<=600?1e3*b.minimalInterval:0),B.minimalInterval&&B.mainInterval0?this.hide(b,function(){a(this).addClass("hidden").css("display",""),void 0!==c&&c()}):(this.addClass("hidden"),void 0!==c&&c()),this.attr("aria-hidden","true")},a.fn.imagifyShow=function(b,c){return void 0!==c&&c(),b&&b>0?this.show(b,function(){a(this).removeClass("hidden").css("display","")}):this.removeClass("hidden"),this.attr("aria-hidden","false")}}(jQuery),function(a,b,c,d){c.imagify.bulk={charts:{overview:{canvas:!1,donut:!1,data:{labels:[imagifyBulk.labels.overviewChartLabels.unoptimized,imagifyBulk.labels.overviewChartLabels.optimized,imagifyBulk.labels.overviewChartLabels.error],datasets:[{data:[],backgroundColor:["#10121A","#46B1CE","#C51162"],borderWidth:0}]}},files:{donuts:{}},share:{canvas:!1,donut:!1}},folderTypesQueue:[],status:{},displayedWaitMessage:!1,hasMultipleRows:!0,imagifyAction:"",processIsStopped:!1,processingMedia:[],globalGain:0,globalOriginalSize:0,globalOptimizedSize:0,folderTypesData:{},defaultThumb:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACEAAAAhBAMAAAClyt9cAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAABtQTFRFR3BMjo6Oh4eHqqqq4uLigoKC+fn5fn5+fHx8SBBv5wAAAAF0Uk5TAEDm2GYAAABWSURBVCjPY2BgEBIEAyERBhgQUoKAIAc0EXXjEDQRRTNzBzRdBokhaGoM2CQc0NQwJJegqWFgM3VAUSNsbGwugCKiqBQUpIAiAgICoyIDKyIIB0JAEQA54jRBweNV0AAAAABJRU5ErkJggg==",init:function(){var d=a(b);this.drawOverviewChart(),this.hasMultipleRows=a('.imagify-bulk-table [name="group[]"]').length>1,a(".imagify-selector-button").on("click.imagify",this.openSelectorFromButton),a(".imagify-selector-list input").on("change.imagify init.imagify",this.syncSelectorFromRadio).filter(":checked").trigger("init.imagify"),d.on("keypress.imagify click.imagify",this.closeSelectors),a('.imagify-bulk-table [name="group[]"]').on("change.imagify init.imagify",this.toggleOptimizationButton).trigger("init.imagify"),a(".imagify-show-table-details").on("click.imagify open.imagify close.imagify",this.toggleOptimizationDetails),a("#imagify-bulk-action").on("click.imagify",this.maybeLaunchAllProcesses),a(".imagify-share-networks a").on("click.imagify",this.share),a(c).on("processQueue.imagify",this.processQueue).on("optimizeFiles.imagify",this.optimizeFiles).on("queueEmpty.imagify",this.queueEmpty),imagifyBulk.ajaxActions.getStats&&a('.imagify-bulk-table [data-group-id="library"][data-context="wp"]').length&&(imagifyBulk.heartbeatIDs.stats=!1),imagifyBulk.heartbeatIDs.stats&&d.on("heartbeat-send",this.addStatsHeartbeat).on("heartbeat-tick",this.processStatsHeartbeat),d.on("heartbeat-send",this.addQueueHeartbeat).on("heartbeat-tick",this.processQueueHeartbeat),d.on("heartbeat-send",this.addRequirementsHeartbeat).on("heartbeat-tick",this.processRequirementsHeartbeat)},getAjaxUrl:function(a,b){var d=ajaxurl+c.imagify.concat+"_wpnonce="+imagifyBulk.ajaxNonce+"&action="+imagifyBulk.ajaxActions[a];return b&&b.context&&(d+="&context="+b.context),"getMediaIds"!==a&&"bulkProcess"!==a||(d+="&imagify_action="+c.imagify.bulk.imagifyAction),d},getFolderTypes:function(){return a.isEmptyObject(c.imagify.bulk.folderTypesData)?(a(".imagify-row-folder-type").each(function(){var b=a(this),d={groupID:b.data("group-id"),context:b.data("context")},e=d.groupID+"|"+d.context;c.imagify.bulk.folderTypesData[e]=d}),c.imagify.bulk.folderTypesData):c.imagify.bulk.folderTypesData},getConfirmMessage:function(){return imagifyBulk.labels.processing},closeLevelSelector:function(a,b){if(a&&a.length)return void 0!==b&&b>0?void c.setTimeout(function(){c.imagify.bulk.closeLevelSelector(a)},b):void a.attr("aria-hidden","true")},stopProcess:function(b,d){this.processIsStopped=!0,c.imagify.bulk.status[d.groupID]={isError:!0,id:b},a(c).trigger("queueEmpty.imagify")},hasBlockingError:function(b){return b=void 0!==b&&b,imagifyBulk.curlMissing?(b&&c.imagify.bulk.displayError({html:imagifyBulk.labels.curlMissing}),!0):imagifyBulk.editorMissing?(b&&c.imagify.bulk.displayError({html:imagifyBulk.labels.editorMissing}),!0):imagifyBulk.extHttpBlocked?(b&&c.imagify.bulk.displayError({html:imagifyBulk.labels.extHttpBlocked}),!0):imagifyBulk.apiDown?(b&&c.imagify.bulk.displayError({html:imagifyBulk.labels.apiDown}),!0):imagifyBulk.keyIsValid?!!imagifyBulk.isOverQuota&&(b&&c.imagify.bulk.displayError({title:imagifyBulk.labels.overQuotaTitle,html:a("#tmpl-imagify-overquota-alert").html(),type:"info",customClass:"imagify-swal-has-subtitle imagify-swal-error-header",showConfirmButton:!1}),!0):(b&&c.imagify.bulk.displayError({title:imagifyBulk.labels.invalidAPIKeyTitle,type:"info"}),!0)},displayError:function(b,c,d){var e={title:"",html:"",type:"error",customClass:"",width:620,padding:0,showCloseButton:!0,showConfirmButton:!0};a.isPlainObject(b)?d=a.extend({},e,b):(d=d||{},d=a.extend({},e,{title:b||"",html:c||""},d)),d.title=d.title||imagifyBulk.labels.error,d.customClass+=" imagify-sweet-alert",swal(d).catch(swal.noop)},displayErrorInRow:function(b,c){var d,e;return b=a(b()),d=b.find(".imagify-cell-status ~ td"),e=d.length,c=c||"",d.remove(),b.find(".imagify-cell-status").after(''+c+""),b},displayFolderRow:function(a,b){var d,e,f,g;return"resting"===a?(b.next(".imagify-row-waiting, .imagify-row-working").remove(),void b.imagifyShow()):(d=b.next(".imagify-row-waiting, .imagify-row-working"),"waiting"===a?(f="#d2d3d6",g=imagifyBulk.labels.waitingOtimizationsText):(f="#40b1d0",g=imagifyBulk.labels.imagesOptimizedText.replace("%s","0")),d.length?(d.hasClass("imagify-row-"+a)||(d.attr("class","imagify-row-"+a),d.find(".imagify-cell-checkbox svg").attr("fill",f),d.children(".imagify-cell-count-optimized").html(g)),b.imagifyHide(),void d.imagifyShow()):(d=b.clone().attr({class:"imagify-row-"+a,"aria-hidden":"false"}),e=c.imagify.template("imagify-spinner"),d.children(".imagify-cell-checkbox").html(e()).find("svg").attr("fill",f),d.children(".imagify-cell-title").html(''+d.children(".imagify-cell-title").text()+""),d.children(".imagify-cell-count-optimized").html(g),d.children(".imagify-cell-count-errors, .imagify-cell-optimized-size, .imagify-cell-original-size, .imagify-cell-level").text(""),void b.imagifyHide().after(d)))},displayShareBox:function(){var b,d,e,f,g=imagifyBulk.labels.textToShare;if(!this.globalGain||this.folderTypesQueue.length)return this.globalGain=0,this.globalOriginalSize=0,void(this.globalOptimizedSize=0);b=(100-this.globalOptimizedSize/this.globalOriginalSize*100).toFixed(2),d=c.imagify.humanSize(this.globalGain,1),e=c.imagify.humanSize(this.globalOriginalSize,1),g=g.replace("%1$s",d),g=g.replace("%2$s",e),g=encodeURIComponent(g),f=a(".imagify-row-complete"),f.find(".imagify-ac-rt-total-gain").html(d),f.find(".imagify-ac-rt-total-original").html(e),f.find(".imagify-ac-chart").attr("data-percent",b),f.find(".imagify-sn-twitter").attr("href",imagifyBulk.labels.twitterShareURL+"&text="+g),this.drawShareChart(),f.addClass("done").imagifyShow(),a("html, body").animate({scrollTop:f.offset().top},200),this.globalGain=0,this.globalOriginalSize=0,this.globalOptimizedSize=0},updateStats:function(b){var d;b&&a.isPlainObject(b)&&(c.imagify.bulk.charts.overview.donut.data&&(d=c.imagify.bulk.charts.overview.donut.data.datasets[0].data,b.unoptimized_attachments===d[0]&&b.optimized_attachments===d[1]&&b.errors_attachments===d[2])||(b.unconsumed_quota=b.unconsumed_quota.toFixed(1),a(".imagify-meteo-icon").html(b.quota_icon),a(".imagify-unconsumed-percent").html(b.unconsumed_quota+"%"),a(".imagify-unconsumed-bar").css("width",b.unconsumed_quota+"%").parent().attr("class",b.quota_class),a("#imagify-overview-chart-percent").html(b.optimized_attachments_percent+"%"),a(".imagify-total-percent").html(b.optimized_attachments_percent+"%"),c.imagify.bulk.drawOverviewChart([b.unoptimized_attachments,b.optimized_attachments,b.errors_attachments]),a("#imagify-total-optimized-attachments").html(b.already_optimized_attachments),a("#imagify-original-bar").find(".imagify-barnb").html(b.original_human),a("#imagify-optimized-bar").css("width",100-b.optimized_percent+"%").find(".imagify-barnb").html(b.optimized_human),a("#imagify-total-optimized-attachments-pct").html(b.optimized_percent+"%")))},openSelectorFromButton:function(b){var c=a("#"+a(this).attr("aria-controls"));b.stopPropagation(),a(".imagify-selector-list").not(c).attr("aria-hidden","true"),c.attr("aria-hidden","false").find(":checked").trigger("focus.imagify")},syncSelectorFromRadio:function(){var b=a(this).closest(".imagify-selector-choice");b.addClass("imagify-selector-current-value").attr("aria-current","true").siblings(".imagify-selector-choice").removeClass("imagify-selector-current-value").attr("aria-current","false"),b.closest(".imagify-selector-list").siblings(".imagify-selector-button").find(".imagify-selector-current-value-info").html(b.find("label").html())},closeSelectors:function(b){"keypress"===b.type&&27!==b.keyCode&&13!==b.keyCode||c.imagify.bulk.closeLevelSelector(a('.imagify-selector-list[aria-hidden="false"]'))},toggleOptimizationButton:function(){if(!c.imagify.bulk.hasMultipleRows&&!this.checked)return void a(this).prop("checked",!0);a('.imagify-bulk-table [name="group[]"]:checked').length?a("#imagify-bulk-action").removeAttr("disabled"):a("#imagify-bulk-action").attr("disabled","disabled")},toggleOptimizationDetails:function(b){var c,d=a(this),e=d.closest(".imagify-bulk-table").find(".imagify-bulk-table-details");c="open"===b.type||"close"!==b.type&&e.hasClass("hidden"),c?(d.html(d.data("label-hide")+''),e.imagifyShow()):(d.html(d.data("label-show")+''),e.imagifyHide())},maybeLaunchAllProcesses:function(){var b;if(!a(this).attr("disabled")&&a('.imagify-bulk-table [name="group[]"]:checked').length&&!c.imagify.bulk.hasBlockingError(!0)){if(b=a("#tmpl-imagify-bulk-infos"),!b.length)return void c.imagify.bulk.launchAllProcesses();swal({title:imagifyBulk.labels.bulkInfoTitle,html:b.html(),type:"",customClass:"imagify-sweet-alert imagify-swal-has-subtitle imagify-before-bulk-infos",showCancelButton:!0,padding:0,width:554,confirmButtonText:imagifyBulk.labels.confirmBulk,cancelButtonText:imagifySwal.labels.cancelButtonText,reverseButtons:!0}).then(function(){var d=a('.imagify-bulk-table [name="group[]"]:checked').first().closest(".imagify-row-folder-type");a.get(c.imagify.bulk.getAjaxUrl("bulkInfoSeen",{context:d.data("context")})),b.remove(),c.imagify.bulk.launchAllProcesses()}).catch(swal.noop)}},launchAllProcesses:function(){var b=a(c),d=a("#imagify-bulk-action"),e=!0;d.attr("disabled","disabled").find(".dashicons").addClass("rotate"),b.on("beforeunload",this.getConfirmMessage),a(".imagify-row-complete").imagifyHide(200,function(){a(this).removeClass("done")}),a(".imagify-show-table-details").trigger("close.imagify"),this.folderTypesQueue=[],this.status={},this.displayedWaitMessage=!1,this.processIsStopped=!1,this.imagifyAction="optimize",this.globalGain=0,this.globalOriginalSize=0,this.globalOptimizedSize=0,a('.imagify-bulk-table [name="group[]"]:checked').each(function(){var b=a(this),d=b.closest(".imagify-row-folder-type"),f=d.data("group-id"),g=d.data("context"),h=d.find('.imagify-cell-level [name="level['+f+']"]:checked').val();if(c.imagify.bulk.folderTypesQueue.push({groupID:f,context:g,level:void 0===h?-1:parseInt(h,10)}),c.imagify.bulk.status[f]={isError:!1,id:"waiting"},e)return e=!1,!0;c.imagify.bulk.displayFolderRow("waiting",d)}),b.trigger("processQueue.imagify")},processQueue:function(){var b,d;if(!c.imagify.bulk.processIsStopped){if(!c.imagify.bulk.folderTypesQueue.length)return void a(c).trigger("queueEmpty.imagify");c.imagify.bulk.displayedWaitMessage||(swal({title:imagifyBulk.labels.waitTitle,html:imagifyBulk.labels.waitText,showConfirmButton:!1,padding:0,imageUrl:imagifyBulk.waitImageUrl,customClass:"imagify-sweet-alert"}).catch(swal.noop),c.imagify.bulk.displayedWaitMessage=!0),d=c.imagify.bulk.folderTypesQueue.shift(),b=a("#cb-select-"+d.groupID).closest(".imagify-row-folder-type"),c.imagify.bulk.status[d.groupID].id="fetching",c.imagify.bulk.displayFolderRow("working",b),a.get(c.imagify.bulk.getAjaxUrl("getMediaIds",d)).done(function(e){var f;if(swal.close(),!c.imagify.bulk.processIsStopped){if(f=e.data&&e.data.message?e.data.message:imagifyBulk.ajaxErrorText,!e.success)return void c.imagify.bulk.stopProcess(f,d);if(!e.data||!a.isPlainObject(e.data)&&!a.isArray(e.data))return void c.imagify.bulk.stopProcess(f,d);if(!a.isEmptyObject(e.data))return void a(c).trigger("optimizeFiles.imagify",[d,e.data]);if(c.imagify.bulk.status[d.groupID].id="no-images",c.imagify.bulk.hasMultipleRows&&a("#cb-select-"+d.groupID).prop("checked",!1),!c.imagify.bulk.folderTypesQueue.length)return void a(c).trigger("queueEmpty.imagify");c.imagify.bulk.displayFolderRow("resting",b),a(c).trigger("processQueue.imagify")}}).fail(function(){c.imagify.bulk.stopProcess("get-unoptimized-images",d)})}},optimizeFiles:function(b,d,e){var f,g,h,i,j,k,l,m,n,o,p,q={groupID:d.groupID,mediaID:0,thumbnail:"",filename:"",status:"",icon:"",label:"",thumbnailsCount:"",originalSizeHuman:"",newSizeHuman:"",percentHuman:"",overallSavingHuman:""};c.imagify.bulk.processIsStopped||(f=a("#cb-select-"+d.groupID).closest(".imagify-row-folder-type"),g=f.next(".imagify-row-working"),i=g.find(".imagify-cell-count-errors span"),o=parseInt(i.text(),10),j=f.closest(".imagify-bulk-table"),k=j.find(".imagify-row-progress"),l=k.find(".bar"),"optimize"===c.imagify.bulk.imagifyAction&&(h=g.find(".imagify-cell-count-optimized span"),n=parseInt(h.text(),10)),c.imagify.bulk.status[d.groupID].id="optimizing",j.find(".imagify-bulk-table-details thead").html(a("#tmpl-imagify-file-header-"+d.groupID).html()),m=j.find(".imagify-bulk-table-details tbody").text(""),l.css("width","0%").find(".percent").text("0%"),k.slideDown().attr("aria-hidden","false"),p=new c.imagify.Optimizer({groupID:d.groupID,context:d.context,level:d.level,bufferSize:imagifyBulk.bufferSizes[d.context],ajaxUrl:c.imagify.bulk.getAjaxUrl("bulkProcess",d),files:e,defaultThumb:c.imagify.bulk.defaultThumb,doneEvent:"mediaProcessed.imagify"}),p.before(function(b){var e;c.imagify.bulk.processIsStopped||(e=c.imagify.template("imagify-file-row-"+d.groupID),c.imagify.bulk.processingMedia.push({context:d.context,mediaID:b.mediaID}),m.prepend(e(a.extend({},q,b,{status:"compressing",icon:"admin-generic rotate",label:imagifyBulk.labels.optimizing}))))}),p.each(function(b){var e,f;if(!c.imagify.bulk.processIsStopped){if(e=c.imagify.template("imagify-file-row-"+d.groupID),f=a("#"+d.groupID+"-"+b.mediaID),a.each(c.imagify.bulk.processingMedia,function(a,e){return e.context!==d.context||e.mediaID!==b.mediaID||(c.imagify.bulk.processingMedia.splice(a,1),!1)}),l.css("width",b.progress+"%").find(".percent").html(b.progress+"%"),b.success)return"already-optimized"!==b.status?(f.replaceWith(e(a.extend({},q,b,{status:"complete",icon:"yes",label:imagifyBulk.labels.complete}))),c.imagify.bulk.drawFileChart(a("#"+d.groupID+"-"+b.mediaID).find(".imagify-cell-percentage canvas"))):f.replaceWith(c.imagify.bulk.displayErrorInRow(e(a.extend({},q,b,{status:"complete",icon:"yes",label:imagifyBulk.labels.alreadyOptimized})),b.error)),void("optimize"===c.imagify.bulk.imagifyAction&&(n+=1,h.text(n)));f.replaceWith(c.imagify.bulk.displayErrorInRow(e(a.extend({},q,b,{status:"error",icon:"dismiss",label:imagifyBulk.labels.error})),b.error||b)),i.length?(o+=1,i.text(o)):(o=1,i=g.find(".imagify-cell-count-errors").html(imagifyBulk.labels.imagesErrorText.replace("%s","1")).find("span")),"over-quota"===b.status&&(p.stopProcess(),c.imagify.bulk.stopProcess(b.status,d))}}),p.done(function(b){c.imagify.bulk.hasMultipleRows&&a("#cb-select-"+d.groupID).prop("checked",!1),b.globalOriginalSize&&(c.imagify.bulk.globalGain+=parseInt(b.globalGain,10),c.imagify.bulk.globalOriginalSize+=parseInt(b.globalOriginalSize,10),c.imagify.bulk.globalOptimizedSize+=parseInt(b.globalOptimizedSize,10)),c.imagify.bulk.processIsStopped||(a.isEmptyObject(c.imagify.bulk.status)||c.imagify.bulk.status[d.groupID].isError||(c.imagify.bulk.status[d.groupID].id="done"),f.addClass("updating"),a.get(c.imagify.bulk.getAjaxUrl("getFolderData",d)).done(function(b){c.imagify.bulk.processIsStopped||(b.success&&a.each(b.data,function(a,b){f.children(".imagify-cell-"+a).html(b)}),c.imagify.bulk.displayFolderRow("resting",f))}).always(function(){c.imagify.bulk.processIsStopped||(f.removeClass("updating"),c.imagify.bulk.folderTypesQueue.length?a(c).trigger("processQueue.imagify"):a(c).trigger("queueEmpty.imagify"))}))}),p.run())},queueEmpty:function(){var b=a(".imagify-bulk-table"),d={},e=!1,f=!0,g="";c.imagify.bulk.displayShareBox(),c.imagify.bulk.folderTypesQueue=[],imagifyBulk.heartbeatIDs.stats||a.get(c.imagify.bulk.getAjaxUrl("getStats"),{types:c.imagify.bulk.getFolderTypes()}).done(function(a){a.success&&c.imagify.bulk.updateStats(a.data)}),a.isEmptyObject(c.imagify.bulk.status)||(a.each(c.imagify.bulk.status,function(a,b){return b.isError?(e=b.id,f=!1,!1):"no-images"!==b.id?(f=!1,!1):void 0}),e?("invalid-api-key"===e?d={title:imagifyBulk.labels.invalidAPIKeyTitle,type:"info"}:"over-quota"===e?d={title:imagifyBulk.labels.overQuotaTitle,html:a("#tmpl-imagify-overquota-alert").html(),type:"info",customClass:"imagify-swal-has-subtitle imagify-swal-error-header",showConfirmButton:!1}:"get-unoptimized-images"!==e&&"consumed-all-data"!==e||(d={title:imagifyBulk.labels.getUnoptimizedImagesErrorTitle,html:imagifyBulk.labels.getUnoptimizedImagesErrorText,type:"info"}),c.imagify.bulk.displayError(d)):f&&(g=imagifyBulk.labels.nothingToDoText.hasOwnProperty(c.imagify.bulk.imagifyAction)?imagifyBulk.labels.nothingToDoText[c.imagify.bulk.imagifyAction]:imagifyBulk.labels.nothingToDoText.optimize,c.imagify.bulk.displayError({title:imagifyBulk.labels.nothingToDoTitle,html:g,type:"info"}))),c.imagify.bulk.status={},a(c).off("beforeunload",c.imagify.bulk.getConfirmMessage),c.imagify.bulk.displayFolderRow("resting",b.find(".imagify-row-folder-type").not(".updating")),b.find(".imagify-row-progress").slideUp().attr("aria-hidden","true").find(".bar").removeAttr("style").find(".percent").text("0%"),a('.imagify-bulk-table [name="group[]"]:checked').length?a("#imagify-bulk-action").removeAttr("disabled").find(".dashicons").removeClass("rotate"):a("#imagify-bulk-action").find(".dashicons").removeClass("rotate")},share:function(a){var d,e;a.preventDefault(),c.innerWidth?(d=(c.innerWidth-700)/2,e=(c.innerHeight-290)/2):(d=(b.body.clientWidth-700)/2,e=(b.body.clientHeight-290)/2),c.open(this.href,"","status=no, scrollbars=no, menubar=no, top="+e+", left="+d+", width=700, height=290")},addStatsHeartbeat:function(a,b){b[imagifyBulk.heartbeatIDs.stats]=Object.keys(c.imagify.bulk.getFolderTypes())},processStatsHeartbeat:function(a,b){void 0!==b[imagifyBulk.heartbeatIDs.stats]&&c.imagify.bulk.updateStats(b[imagifyBulk.heartbeatIDs.stats])},addQueueHeartbeat:function(a,b){c.imagify.bulk.processingMedia.length&&(b[imagifyBulk.heartbeatIDs.queue]=c.imagify.bulk.processingMedia)},processQueueHeartbeat:function(b,d){void 0!==d[imagifyBulk.heartbeatIDs.queue]&&a.each(d[imagifyBulk.heartbeatIDs.queue],function(b,d){a(c).trigger("mediaProcessed.imagify",[d])})},addRequirementsHeartbeat:function(a,b){b[imagifyBulk.heartbeatIDs.requirements]=1},processRequirementsHeartbeat:function(a,b){void 0!==b[imagifyBulk.heartbeatIDs.requirements]&&(b=b[imagifyBulk.heartbeatIDs.requirements],imagifyBulk.curlMissing=b.curl_missing,imagifyBulk.editorMissing=b.editor_missing,imagifyBulk.extHttpBlocked=b.external_http_blocked,imagifyBulk.apiDown=b.api_down,imagifyBulk.keyIsValid=b.key_is_valid,imagifyBulk.isOverQuota=b.is_over_quota)},drawOverviewChart:function(d){var e,f;if(this.charts.overview.canvas||(this.charts.overview.canvas=b.getElementById("imagify-overview-chart"),this.charts.overview.canvas)){if(d=d&&a.isArray(d)?d:[],this.charts.overview.donut)return void(d.length&&(0===d.reduce(function(a,b){return a+b},0)&&(d[0]=1),this.charts.overview.donut.data.datasets[0].data=d,this.charts.overview.donut.update()));this.charts.overview.data.datasets[0].data=[parseInt(this.charts.overview.canvas.getAttribute("data-unoptimized"),10),parseInt(this.charts.overview.canvas.getAttribute("data-optimized"),10),parseInt(this.charts.overview.canvas.getAttribute("data-errors"),10)],e=a.extend({},this.charts.overview.data),d.length&&(e.datasets[0].data=d),0===e.datasets[0].data.reduce(function(a,b){return a+b},0)&&(e.datasets[0].data[0]=1),this.charts.overview.donut=new c.imagify.Chart(this.charts.overview.canvas,{type:"doughnut",data:e,options:{legend:{display:!1},events:[],animation:{easing:"easeOutBounce"},tooltips:{displayColors:!1,callbacks:{label:function(a,b){return b.datasets[a.datasetIndex].data[a.index]}}},responsive:!1,cutoutPercentage:85}}),f='
    ',a.each(e.labels,function(a,b){f+='
  • '+b+"
  • "}),f+="
",b.getElementById("imagify-overview-chart-legend").innerHTML=f}},drawFileChart:function(b){var d=this.charts.files.donuts;b.each(function(){var b=parseInt(a(this).closest(".imagify-chart").next(".imagipercent").text().replace("%",""),10);if(void 0!==d[this.id])return d[this.id].data.datasets[0].data[0]=b,d[this.id].data.datasets[0].data[1]=100-b,void d[this.id].update();d[this.id]=new c.imagify.Chart(this,{type:"doughnut",data:{datasets:[{data:[b,100-b],backgroundColor:["#00B3D3","#D8D8D8"],borderColor:"#fff",borderWidth:1}]},options:{legend:{display:!1},events:[],animation:{easing:"easeOutBounce"},tooltips:{enabled:!1},responsive:!1}})}),this.charts.files.donuts=d},drawShareChart:function(){var d;if(this.charts.share.canvas||(this.charts.share.canvas=b.getElementById("imagify-ac-chart"),this.charts.share.canvas)){if(d=parseInt(a(this.charts.share.canvas).closest(".imagify-ac-chart").attr("data-percent"),10),this.charts.share.donut)return this.charts.share.donut.data.datasets[0].data[0]=d,this.charts.share.donut.data.datasets[0].data[1]=100-d,void this.charts.share.donut.update();this.charts.share.donut=new c.imagify.Chart(this.charts.share.canvas,{type:"doughnut",data:{datasets:[{data:[d,100-d],backgroundColor:["#40B1D0","#FFFFFF"],borderWidth:0}]},options:{legend:{display:!1},events:[],animation:{easing:"easeOutBounce"},tooltips:{enabled:!1},responsive:!1,cutoutPercentage:70}})}}},c.imagify.bulk.init()}(jQuery,document,window); \ No newline at end of file +window.imagify=window.imagify||{},function(a,b){var c=a.propHooks.checked;a.propHooks.checked={set:function(b,d,e){var f;return f=void 0===c?b[e]=d:c(b,d,e),a(b).trigger("change.imagify"),f}},a.fn.imagifyHide=function(b,c){return b&&b>0?this.hide(b,function(){a(this).addClass("hidden").css("display",""),void 0!==c&&c()}):(this.addClass("hidden"),void 0!==c&&c()),this.attr("aria-hidden","true")},a.fn.imagifyShow=function(b,c){return void 0!==c&&c(),b&&b>0?this.show(b,function(){a(this).removeClass("hidden").css("display","")}):this.removeClass("hidden"),this.attr("aria-hidden","false")}}(jQuery),function(a,b,c,d){c.imagify.bulk={charts:{overview:{canvas:!1,donut:!1,data:{labels:[imagifyBulk.labels.overviewChartLabels.unoptimized,imagifyBulk.labels.overviewChartLabels.optimized,imagifyBulk.labels.overviewChartLabels.error],datasets:[{data:[],backgroundColor:["#10121A","#46B1CE","#C51162"],borderWidth:0}]}},files:{donuts:{}},share:{canvas:!1,donut:!1}},folderTypesQueue:[],status:{},displayedWaitMessage:!1,hasMultipleRows:!0,imagifyAction:"",processIsStopped:!1,processingMedia:[],globalGain:0,globalOriginalSize:0,globalOptimizedSize:0,folderTypesData:{},defaultThumb:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACEAAAAhBAMAAAClyt9cAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAABtQTFRFR3BMjo6Oh4eHqqqq4uLigoKC+fn5fn5+fHx8SBBv5wAAAAF0Uk5TAEDm2GYAAABWSURBVCjPY2BgEBIEAyERBhgQUoKAIAc0EXXjEDQRRTNzBzRdBokhaGoM2CQc0NQwJJegqWFgM3VAUSNsbGwugCKiqBQUpIAiAgICoyIDKyIIB0JAEQA54jRBweNV0AAAAABJRU5ErkJggg==",init:function(){var d=a(b);this.drawOverviewChart(),this.hasMultipleRows=a('.imagify-bulk-table [name="group[]"]').length>1,a(".imagify-selector-button").on("click.imagify",this.openSelectorFromButton),a(".imagify-selector-list input").on("change.imagify init.imagify",this.syncSelectorFromRadio).filter(":checked").trigger("init.imagify"),d.on("keypress.imagify click.imagify",this.closeSelectors),a('.imagify-bulk-table [name="group[]"]').on("change.imagify init.imagify",this.toggleOptimizationButton).trigger("init.imagify"),a(".imagify-show-table-details").on("click.imagify open.imagify close.imagify",this.toggleOptimizationDetails),a("#imagify-bulk-action").on("click.imagify",this.maybeLaunchAllProcesses),a(".imagify-share-networks a").on("click.imagify",this.share),a(c).on("processQueue.imagify",this.processQueue).on("optimizeFiles.imagify",this.optimizeFiles).on("queueEmpty.imagify",this.queueEmpty),imagifyBulk.ajaxActions.getStats&&a('.imagify-bulk-table [data-group-id="library"][data-context="wp"]').length&&(imagifyBulk.imagifybeatIDs.stats=!1),imagifyBulk.imagifybeatIDs.stats&&d.on("imagifybeat-send",this.addStatsImagifybeat).on("imagifybeat-tick",this.processStatsImagifybeat),d.on("imagifybeat-send",this.addQueueImagifybeat).on("imagifybeat-tick",this.processQueueImagifybeat),d.on("imagifybeat-send",this.addRequirementsImagifybeat).on("imagifybeat-tick",this.processRequirementsImagifybeat)},getAjaxUrl:function(a,b){var d=ajaxurl+c.imagify.concat+"_wpnonce="+imagifyBulk.ajaxNonce+"&action="+imagifyBulk.ajaxActions[a];return b&&b.context&&(d+="&context="+b.context),"getMediaIds"!==a&&"bulkProcess"!==a||(d+="&imagify_action="+c.imagify.bulk.imagifyAction),d},getFolderTypes:function(){return a.isEmptyObject(c.imagify.bulk.folderTypesData)?(a(".imagify-row-folder-type").each(function(){var b=a(this),d={groupID:b.data("group-id"),context:b.data("context")},e=d.groupID+"|"+d.context;c.imagify.bulk.folderTypesData[e]=d}),c.imagify.bulk.folderTypesData):c.imagify.bulk.folderTypesData},getConfirmMessage:function(){return imagifyBulk.labels.processing},closeLevelSelector:function(a,b){if(a&&a.length)return void 0!==b&&b>0?void c.setTimeout(function(){c.imagify.bulk.closeLevelSelector(a)},b):void a.attr("aria-hidden","true")},stopProcess:function(b,d){this.processIsStopped=!0,c.imagify.bulk.status[d.groupID]={isError:!0,id:b},a(c).trigger("queueEmpty.imagify")},hasBlockingError:function(b){return b=void 0!==b&&b,imagifyBulk.curlMissing?(b&&c.imagify.bulk.displayError({html:imagifyBulk.labels.curlMissing}),!0):imagifyBulk.editorMissing?(b&&c.imagify.bulk.displayError({html:imagifyBulk.labels.editorMissing}),!0):imagifyBulk.extHttpBlocked?(b&&c.imagify.bulk.displayError({html:imagifyBulk.labels.extHttpBlocked}),!0):imagifyBulk.apiDown?(b&&c.imagify.bulk.displayError({html:imagifyBulk.labels.apiDown}),!0):imagifyBulk.keyIsValid?!!imagifyBulk.isOverQuota&&(b&&c.imagify.bulk.displayError({title:imagifyBulk.labels.overQuotaTitle,html:a("#tmpl-imagify-overquota-alert").html(),type:"info",customClass:"imagify-swal-has-subtitle imagify-swal-error-header",showConfirmButton:!1}),!0):(b&&c.imagify.bulk.displayError({title:imagifyBulk.labels.invalidAPIKeyTitle,type:"info"}),!0)},displayError:function(b,c,d){var e={title:"",html:"",type:"error",customClass:"",width:620,padding:0,showCloseButton:!0,showConfirmButton:!0};a.isPlainObject(b)?d=a.extend({},e,b):(d=d||{},d=a.extend({},e,{title:b||"",html:c||""},d)),d.title=d.title||imagifyBulk.labels.error,d.customClass+=" imagify-sweet-alert",swal(d).catch(swal.noop)},displayErrorInRow:function(b,c){var d,e;return b=a(b()),d=b.find(".imagify-cell-status ~ td"),e=d.length,c=c||"",d.remove(),b.find(".imagify-cell-status").after(''+c+""),b},displayFolderRow:function(a,b){var d,e,f,g;return"resting"===a?(b.next(".imagify-row-waiting, .imagify-row-working").remove(),void b.imagifyShow()):(d=b.next(".imagify-row-waiting, .imagify-row-working"),"waiting"===a?(f="#d2d3d6",g=imagifyBulk.labels.waitingOtimizationsText):(f="#40b1d0",g=imagifyBulk.labels.imagesOptimizedText.replace("%s","0")),d.length?(d.hasClass("imagify-row-"+a)||(d.attr("class","imagify-row-"+a),d.find(".imagify-cell-checkbox svg").attr("fill",f),d.children(".imagify-cell-count-optimized").html(g)),b.imagifyHide(),void d.imagifyShow()):(d=b.clone().attr({class:"imagify-row-"+a,"aria-hidden":"false"}),e=c.imagify.template("imagify-spinner"),d.children(".imagify-cell-checkbox").html(e()).find("svg").attr("fill",f),d.children(".imagify-cell-title").html(''+d.children(".imagify-cell-title").text()+""),d.children(".imagify-cell-count-optimized").html(g),d.children(".imagify-cell-count-errors, .imagify-cell-optimized-size, .imagify-cell-original-size, .imagify-cell-level").text(""),void b.imagifyHide().after(d)))},displayShareBox:function(){var b,d,e,f,g=imagifyBulk.labels.textToShare;if(!this.globalGain||this.folderTypesQueue.length)return this.globalGain=0,this.globalOriginalSize=0,void(this.globalOptimizedSize=0);b=(100-this.globalOptimizedSize/this.globalOriginalSize*100).toFixed(2),d=c.imagify.humanSize(this.globalGain,1),e=c.imagify.humanSize(this.globalOriginalSize,1),g=g.replace("%1$s",d),g=g.replace("%2$s",e),g=encodeURIComponent(g),f=a(".imagify-row-complete"),f.find(".imagify-ac-rt-total-gain").html(d),f.find(".imagify-ac-rt-total-original").html(e),f.find(".imagify-ac-chart").attr("data-percent",b),f.find(".imagify-sn-twitter").attr("href",imagifyBulk.labels.twitterShareURL+"&text="+g),this.drawShareChart(),f.addClass("done").imagifyShow(),a("html, body").animate({scrollTop:f.offset().top},200),this.globalGain=0,this.globalOriginalSize=0,this.globalOptimizedSize=0},updateStats:function(b){var d;b&&a.isPlainObject(b)&&(c.imagify.bulk.charts.overview.donut.data&&(d=c.imagify.bulk.charts.overview.donut.data.datasets[0].data,b.unoptimized_attachments===d[0]&&b.optimized_attachments===d[1]&&b.errors_attachments===d[2])||(b.unconsumed_quota=b.unconsumed_quota.toFixed(1),a(".imagify-meteo-icon").html(b.quota_icon),a(".imagify-unconsumed-percent").html(b.unconsumed_quota+"%"),a(".imagify-unconsumed-bar").css("width",b.unconsumed_quota+"%").parent().attr("class",b.quota_class),a("#imagify-overview-chart-percent").html(b.optimized_attachments_percent+"%"),a(".imagify-total-percent").html(b.optimized_attachments_percent+"%"),c.imagify.bulk.drawOverviewChart([b.unoptimized_attachments,b.optimized_attachments,b.errors_attachments]),a("#imagify-total-optimized-attachments").html(b.already_optimized_attachments),a("#imagify-original-bar").find(".imagify-barnb").html(b.original_human),a("#imagify-optimized-bar").css("width",100-b.optimized_percent+"%").find(".imagify-barnb").html(b.optimized_human),a("#imagify-total-optimized-attachments-pct").html(b.optimized_percent+"%")))},openSelectorFromButton:function(b){var c=a("#"+a(this).attr("aria-controls"));b.stopPropagation(),a(".imagify-selector-list").not(c).attr("aria-hidden","true"),c.attr("aria-hidden","false").find(":checked").trigger("focus.imagify")},syncSelectorFromRadio:function(){var b=a(this).closest(".imagify-selector-choice");b.addClass("imagify-selector-current-value").attr("aria-current","true").siblings(".imagify-selector-choice").removeClass("imagify-selector-current-value").attr("aria-current","false"),b.closest(".imagify-selector-list").siblings(".imagify-selector-button").find(".imagify-selector-current-value-info").html(b.find("label").html())},closeSelectors:function(b){"keypress"===b.type&&27!==b.keyCode&&13!==b.keyCode||c.imagify.bulk.closeLevelSelector(a('.imagify-selector-list[aria-hidden="false"]'))},toggleOptimizationButton:function(){if(!c.imagify.bulk.hasMultipleRows&&!this.checked)return void a(this).prop("checked",!0);a('.imagify-bulk-table [name="group[]"]:checked').length?a("#imagify-bulk-action").removeAttr("disabled"):a("#imagify-bulk-action").attr("disabled","disabled")},toggleOptimizationDetails:function(b){var c,d=a(this),e=d.closest(".imagify-bulk-table").find(".imagify-bulk-table-details");c="open"===b.type||"close"!==b.type&&e.hasClass("hidden"),c?(d.html(d.data("label-hide")+''),e.imagifyShow()):(d.html(d.data("label-show")+''),e.imagifyHide())},maybeLaunchAllProcesses:function(){var b;if(!a(this).attr("disabled")&&a('.imagify-bulk-table [name="group[]"]:checked').length&&!c.imagify.bulk.hasBlockingError(!0)){if(b=a("#tmpl-imagify-bulk-infos"),!b.length)return void c.imagify.bulk.launchAllProcesses();swal({title:imagifyBulk.labels.bulkInfoTitle,html:b.html(),type:"",customClass:"imagify-sweet-alert imagify-swal-has-subtitle imagify-before-bulk-infos",showCancelButton:!0,padding:0,width:554,confirmButtonText:imagifyBulk.labels.confirmBulk,cancelButtonText:imagifySwal.labels.cancelButtonText,reverseButtons:!0}).then(function(){var d=a('.imagify-bulk-table [name="group[]"]:checked').first().closest(".imagify-row-folder-type");a.get(c.imagify.bulk.getAjaxUrl("bulkInfoSeen",{context:d.data("context")})),b.remove(),c.imagify.bulk.launchAllProcesses()}).catch(swal.noop)}},launchAllProcesses:function(){var b=a(c),d=a("#imagify-bulk-action"),e=!0;d.attr("disabled","disabled").find(".dashicons").addClass("rotate"),b.on("beforeunload",this.getConfirmMessage),a(".imagify-row-complete").imagifyHide(200,function(){a(this).removeClass("done")}),a(".imagify-show-table-details").trigger("close.imagify"),this.folderTypesQueue=[],this.status={},this.displayedWaitMessage=!1,this.processIsStopped=!1,this.imagifyAction="optimize",this.globalGain=0,this.globalOriginalSize=0,this.globalOptimizedSize=0,a('.imagify-bulk-table [name="group[]"]:checked').each(function(){var b=a(this),d=b.closest(".imagify-row-folder-type"),f=d.data("group-id"),g=d.data("context"),h=d.find('.imagify-cell-level [name="level['+f+']"]:checked').val();if(c.imagify.bulk.folderTypesQueue.push({groupID:f,context:g,level:void 0===h?-1:parseInt(h,10)}),c.imagify.bulk.status[f]={isError:!1,id:"waiting"},e)return e=!1,!0;c.imagify.bulk.displayFolderRow("waiting",d)}),c.imagify.beat.interval(15),c.imagify.beat.disableSuspend(),b.trigger("processQueue.imagify")},processQueue:function(){var b,d;if(!c.imagify.bulk.processIsStopped){if(!c.imagify.bulk.folderTypesQueue.length)return void a(c).trigger("queueEmpty.imagify");c.imagify.bulk.displayedWaitMessage||(swal({title:imagifyBulk.labels.waitTitle,html:imagifyBulk.labels.waitText,showConfirmButton:!1,padding:0,imageUrl:imagifyBulk.waitImageUrl,customClass:"imagify-sweet-alert"}).catch(swal.noop),c.imagify.bulk.displayedWaitMessage=!0),d=c.imagify.bulk.folderTypesQueue.shift(),b=a("#cb-select-"+d.groupID).closest(".imagify-row-folder-type"),c.imagify.bulk.status[d.groupID].id="fetching",c.imagify.bulk.displayFolderRow("working",b),a.get(c.imagify.bulk.getAjaxUrl("getMediaIds",d)).done(function(e){var f;if(swal.close(),!c.imagify.bulk.processIsStopped){if(f=e.data&&e.data.message?e.data.message:imagifyBulk.ajaxErrorText,!e.success)return void c.imagify.bulk.stopProcess(f,d);if(!e.data||!a.isPlainObject(e.data)&&!a.isArray(e.data))return void c.imagify.bulk.stopProcess(f,d);if(!a.isEmptyObject(e.data))return void a(c).trigger("optimizeFiles.imagify",[d,e.data]);if(c.imagify.bulk.status[d.groupID].id="no-images",c.imagify.bulk.hasMultipleRows&&a("#cb-select-"+d.groupID).prop("checked",!1),!c.imagify.bulk.folderTypesQueue.length)return void a(c).trigger("queueEmpty.imagify");c.imagify.bulk.displayFolderRow("resting",b),a(c).trigger("processQueue.imagify")}}).fail(function(){c.imagify.bulk.stopProcess("get-unoptimized-images",d)})}},optimizeFiles:function(b,d,e){var f,g,h,i,j,k,l,m,n,o,p,q={groupID:d.groupID,mediaID:0,thumbnail:"",filename:"",status:"",icon:"",label:"",thumbnailsCount:"",originalSizeHuman:"",newSizeHuman:"",percentHuman:"",overallSavingHuman:""};c.imagify.bulk.processIsStopped||(f=a("#cb-select-"+d.groupID).closest(".imagify-row-folder-type"),g=f.next(".imagify-row-working"),i=g.find(".imagify-cell-count-errors span"),o=parseInt(i.text(),10),j=f.closest(".imagify-bulk-table"),k=j.find(".imagify-row-progress"),l=k.find(".bar"),"optimize"===c.imagify.bulk.imagifyAction&&(h=g.find(".imagify-cell-count-optimized span"),n=parseInt(h.text(),10)),c.imagify.bulk.status[d.groupID].id="optimizing",j.find(".imagify-bulk-table-details thead").html(a("#tmpl-imagify-file-header-"+d.groupID).html()),m=j.find(".imagify-bulk-table-details tbody").text(""),l.css("width","0%").find(".percent").text("0%"),k.slideDown().attr("aria-hidden","false"),p=new c.imagify.Optimizer({groupID:d.groupID,context:d.context,level:d.level,bufferSize:imagifyBulk.bufferSizes[d.context],ajaxUrl:c.imagify.bulk.getAjaxUrl("bulkProcess",d),files:e,defaultThumb:c.imagify.bulk.defaultThumb,doneEvent:"mediaProcessed.imagify"}),p.before(function(b){var e;c.imagify.bulk.processIsStopped||(e=c.imagify.template("imagify-file-row-"+d.groupID),c.imagify.bulk.processingMedia.push({context:d.context,mediaID:b.mediaID}),m.prepend(e(a.extend({},q,b,{status:"compressing",icon:"admin-generic rotate",label:imagifyBulk.labels.optimizing}))))}),p.each(function(b){var e,f;if(!c.imagify.bulk.processIsStopped){if(e=c.imagify.template("imagify-file-row-"+d.groupID),f=a("#"+d.groupID+"-"+b.mediaID),a.each(c.imagify.bulk.processingMedia,function(a,e){return e.context!==d.context||e.mediaID!==b.mediaID||(c.imagify.bulk.processingMedia.splice(a,1),!1)}),l.css("width",b.progress+"%").find(".percent").html(b.progress+"%"),b.success)return"already-optimized"!==b.status?(f.replaceWith(e(a.extend({},q,b,{status:"complete",icon:"yes",label:imagifyBulk.labels.complete}))),c.imagify.bulk.drawFileChart(a("#"+d.groupID+"-"+b.mediaID).find(".imagify-cell-percentage canvas"))):f.replaceWith(c.imagify.bulk.displayErrorInRow(e(a.extend({},q,b,{status:"complete",icon:"yes",label:imagifyBulk.labels.alreadyOptimized})),b.error)),void("optimize"===c.imagify.bulk.imagifyAction&&(n+=1,h.text(n)));f.replaceWith(c.imagify.bulk.displayErrorInRow(e(a.extend({},q,b,{status:"error",icon:"dismiss",label:imagifyBulk.labels.error})),b.error||b)),i.length?(o+=1,i.text(o)):(o=1,i=g.find(".imagify-cell-count-errors").html(imagifyBulk.labels.imagesErrorText.replace("%s","1")).find("span")),"over-quota"===b.status&&(p.stopProcess(),c.imagify.bulk.stopProcess(b.status,d))}}),p.done(function(b){c.imagify.bulk.hasMultipleRows&&a("#cb-select-"+d.groupID).prop("checked",!1),b.globalOriginalSize&&(c.imagify.bulk.globalGain+=parseInt(b.globalGain,10),c.imagify.bulk.globalOriginalSize+=parseInt(b.globalOriginalSize,10),c.imagify.bulk.globalOptimizedSize+=parseInt(b.globalOptimizedSize,10)),c.imagify.bulk.processIsStopped||(c.imagify.beat.resetInterval(),c.imagify.beat.enableSuspend(),a.isEmptyObject(c.imagify.bulk.status)||c.imagify.bulk.status[d.groupID].isError||(c.imagify.bulk.status[d.groupID].id="done"),f.addClass("updating"),a.get(c.imagify.bulk.getAjaxUrl("getFolderData",d)).done(function(b){c.imagify.bulk.processIsStopped||(b.success&&a.each(b.data,function(a,b){f.children(".imagify-cell-"+a).html(b)}),c.imagify.bulk.displayFolderRow("resting",f))}).always(function(){c.imagify.bulk.processIsStopped||(f.removeClass("updating"),c.imagify.bulk.folderTypesQueue.length?a(c).trigger("processQueue.imagify"):a(c).trigger("queueEmpty.imagify"))}))}),p.run())},queueEmpty:function(){var b=a(".imagify-bulk-table"),d={},e=!1,f=!0,g="";c.imagify.beat.resetInterval(),c.imagify.beat.enableSuspend(),c.imagify.bulk.displayShareBox(),c.imagify.bulk.folderTypesQueue=[],imagifyBulk.imagifybeatIDs.stats||a.get(c.imagify.bulk.getAjaxUrl("getStats"),{types:c.imagify.bulk.getFolderTypes()}).done(function(a){a.success&&c.imagify.bulk.updateStats(a.data)}),a.isEmptyObject(c.imagify.bulk.status)||(a.each(c.imagify.bulk.status,function(a,b){return b.isError?(e=b.id,f=!1,!1):"no-images"!==b.id?(f=!1,!1):void 0}),e?("invalid-api-key"===e?d={title:imagifyBulk.labels.invalidAPIKeyTitle,type:"info"}:"over-quota"===e?d={title:imagifyBulk.labels.overQuotaTitle,html:a("#tmpl-imagify-overquota-alert").html(),type:"info",customClass:"imagify-swal-has-subtitle imagify-swal-error-header",showConfirmButton:!1}:"get-unoptimized-images"!==e&&"consumed-all-data"!==e||(d={title:imagifyBulk.labels.getUnoptimizedImagesErrorTitle,html:imagifyBulk.labels.getUnoptimizedImagesErrorText,type:"info"}),c.imagify.bulk.displayError(d)):f&&(g=imagifyBulk.labels.nothingToDoText.hasOwnProperty(c.imagify.bulk.imagifyAction)?imagifyBulk.labels.nothingToDoText[c.imagify.bulk.imagifyAction]:imagifyBulk.labels.nothingToDoText.optimize,c.imagify.bulk.displayError({title:imagifyBulk.labels.nothingToDoTitle,html:g,type:"info"}))),c.imagify.bulk.status={},a(c).off("beforeunload",c.imagify.bulk.getConfirmMessage),c.imagify.bulk.displayFolderRow("resting",b.find(".imagify-row-folder-type").not(".updating")),b.find(".imagify-row-progress").slideUp().attr("aria-hidden","true").find(".bar").removeAttr("style").find(".percent").text("0%"),a('.imagify-bulk-table [name="group[]"]:checked').length?a("#imagify-bulk-action").removeAttr("disabled").find(".dashicons").removeClass("rotate"):a("#imagify-bulk-action").find(".dashicons").removeClass("rotate")},share:function(a){var d,e;a.preventDefault(),c.innerWidth?(d=(c.innerWidth-700)/2,e=(c.innerHeight-290)/2):(d=(b.body.clientWidth-700)/2,e=(b.body.clientHeight-290)/2),c.open(this.href,"","status=no, scrollbars=no, menubar=no, top="+e+", left="+d+", width=700, height=290")},addStatsImagifybeat:function(a,b){b[imagifyBulk.imagifybeatIDs.stats]=Object.keys(c.imagify.bulk.getFolderTypes())},processStatsImagifybeat:function(a,b){void 0!==b[imagifyBulk.imagifybeatIDs.stats]&&c.imagify.bulk.updateStats(b[imagifyBulk.imagifybeatIDs.stats])},addQueueImagifybeat:function(a,b){c.imagify.bulk.processingMedia.length&&(b[imagifyBulk.imagifybeatIDs.queue]=c.imagify.bulk.processingMedia)},processQueueImagifybeat:function(b,d){void 0!==d[imagifyBulk.imagifybeatIDs.queue]&&a.each(d[imagifyBulk.imagifybeatIDs.queue],function(b,d){a(c).trigger("mediaProcessed.imagify",[d])})},addRequirementsImagifybeat:function(a,b){b[imagifyBulk.imagifybeatIDs.requirements]=1},processRequirementsImagifybeat:function(a,b){void 0!==b[imagifyBulk.imagifybeatIDs.requirements]&&(b=b[imagifyBulk.imagifybeatIDs.requirements],imagifyBulk.curlMissing=b.curl_missing,imagifyBulk.editorMissing=b.editor_missing,imagifyBulk.extHttpBlocked=b.external_http_blocked,imagifyBulk.apiDown=b.api_down,imagifyBulk.keyIsValid=b.key_is_valid,imagifyBulk.isOverQuota=b.is_over_quota)},drawOverviewChart:function(d){var e,f;if(this.charts.overview.canvas||(this.charts.overview.canvas=b.getElementById("imagify-overview-chart"),this.charts.overview.canvas)){if(d=d&&a.isArray(d)?d:[],this.charts.overview.donut)return void(d.length&&(0===d.reduce(function(a,b){return a+b},0)&&(d[0]=1),this.charts.overview.donut.data.datasets[0].data=d,this.charts.overview.donut.update()));this.charts.overview.data.datasets[0].data=[parseInt(this.charts.overview.canvas.getAttribute("data-unoptimized"),10),parseInt(this.charts.overview.canvas.getAttribute("data-optimized"),10),parseInt(this.charts.overview.canvas.getAttribute("data-errors"),10)],e=a.extend({},this.charts.overview.data),d.length&&(e.datasets[0].data=d),0===e.datasets[0].data.reduce(function(a,b){return a+b},0)&&(e.datasets[0].data[0]=1),this.charts.overview.donut=new c.imagify.Chart(this.charts.overview.canvas,{type:"doughnut",data:e,options:{legend:{display:!1},events:[],animation:{easing:"easeOutBounce"},tooltips:{displayColors:!1,callbacks:{label:function(a,b){return b.datasets[a.datasetIndex].data[a.index]}}},responsive:!1,cutoutPercentage:85}}),f='
    ',a.each(e.labels,function(a,b){f+='
  • '+b+"
  • "}),f+="
",b.getElementById("imagify-overview-chart-legend").innerHTML=f}},drawFileChart:function(b){var d=this.charts.files.donuts;b.each(function(){var b=parseInt(a(this).closest(".imagify-chart").next(".imagipercent").text().replace("%",""),10);if(void 0!==d[this.id])return d[this.id].data.datasets[0].data[0]=b,d[this.id].data.datasets[0].data[1]=100-b,void d[this.id].update();d[this.id]=new c.imagify.Chart(this,{type:"doughnut",data:{datasets:[{data:[b,100-b],backgroundColor:["#00B3D3","#D8D8D8"],borderColor:"#fff",borderWidth:1}]},options:{legend:{display:!1},events:[],animation:{easing:"easeOutBounce"},tooltips:{enabled:!1},responsive:!1}})}),this.charts.files.donuts=d},drawShareChart:function(){var d;if(this.charts.share.canvas||(this.charts.share.canvas=b.getElementById("imagify-ac-chart"),this.charts.share.canvas)){if(d=parseInt(a(this.charts.share.canvas).closest(".imagify-ac-chart").attr("data-percent"),10),this.charts.share.donut)return this.charts.share.donut.data.datasets[0].data[0]=d,this.charts.share.donut.data.datasets[0].data[1]=100-d,void this.charts.share.donut.update();this.charts.share.donut=new c.imagify.Chart(this.charts.share.canvas,{type:"doughnut",data:{datasets:[{data:[d,100-d],backgroundColor:["#40B1D0","#FFFFFF"],borderWidth:0}]},options:{legend:{display:!1},events:[],animation:{easing:"easeOutBounce"},tooltips:{enabled:!1},responsive:!1,cutoutPercentage:70}})}}},c.imagify.bulk.init()}(jQuery,document,window); \ No newline at end of file diff --git a/assets/js/files-list.js b/assets/js/files-list.js index 70f4c0a61..4db5de82c 100644 --- a/assets/js/files-list.js +++ b/assets/js/files-list.js @@ -51,10 +51,6 @@ window.imagify.drawMeAChart = function( canvas ) { // Update the chart in the media modal when a media is selected, and the ones already printed. $( w ).on( 'canvasprinted.imagify', this.updateChart ).trigger( 'canvasprinted.imagify' ); - if ( ! this.hasHeartbeat() ) { - return; - } - // Handle bulk actions. this.insertBulkActionTags(); @@ -63,21 +59,23 @@ window.imagify.drawMeAChart = function( canvas ) { // Optimize, restore, etc. $document.on( 'click.imagify', '.button-imagify-optimize, .button-imagify-manual-reoptimize, .button-imagify-generate-webp, .button-imagify-restore, .button-imagify-refresh-status', this.processOptimization ); - $document.on( 'heartbeat-send', this.addToHeartbeat ); - $document.on( 'heartbeat-tick', this.processHeartbeat ); + $document.on( 'imagifybeat-send', this.addToImagifybeat ); + $document.on( 'imagifybeat-tick', this.processImagifybeat ); // Some items may be processed in background on page load. $processing = $( '.wp-list-table.imagify-files .button-imagify-processing' ); if ( $processing.length ) { - // Fasten Heartbeat for a minute. - w.wp.heartbeat.interval( 5, 12 ); - + // Some media are already being processed. + // Lock the items, so we can check their status with Imagifybeat. $processing.closest( 'tr' ).find( '.check-column [name="bulk_select[]"]' ).each( function() { var id = w.imagify.filesList.sanitizeId( this.value ); w.imagify.filesList.lockItem( w.imagifyFiles.context, id ); } ); + + // Fasten Imagifybeat. + w.imagify.beat.interval( 15 ); } }, @@ -190,61 +188,52 @@ window.imagify.drawMeAChart = function( canvas ) { // The work is done. w.imagify.filesList.displayProcessResult( context, id, r.data.columns ); } else { - // Still processing in background: we're waiting for the result by poking Heartbeat. - // Set the heartbeat interval to 5 sec for 60 seconds (12 ticks). - w.wp.heartbeat.interval( 5, 12 ); + // Still processing in background: we're waiting for the result by poking Imagifybeat. + // Set the Imagifybeat interval to 15 seconds. + w.imagify.beat.interval( 15 ); } } ); }, - // Heartbeat =============================================================================== + // Imagifybeat ============================================================================= /** - * Tell if we can use Heartbeat. - * - * @return {bool} - */ - hasHeartbeat: function() { - return w.imagifyFiles && w.imagifyFiles.heartbeatId && w.wp && w.wp.heartbeat ? true : false; - }, - - /** - * Send the media IDs and their status to heartbeat. + * Send the media IDs and their status to Imagifybeat. * * @param {object} e Event object. - * @param {object} data Object containing all Heartbeat IDs. + * @param {object} data Object containing all Imagifybeat IDs. */ - addToHeartbeat: function ( e, data ) { + addToImagifybeat: function ( e, data ) { var $boxes = $( '.wp-list-table.imagify-files .check-column [name="bulk_select[]"]' ); if ( ! $boxes.length ) { return; } - data[ w.imagifyFiles.heartbeatId ] = {}; + data[ w.imagifyFiles.imagifybeatID ] = {}; $boxes.each( function() { var id = w.imagify.filesList.sanitizeId( this.value ), context = w.imagifyFiles.context, locked = w.imagify.filesList.isItemLocked( context, id ) ? 1 : 0; - data[ w.imagifyFiles.heartbeatId ][ context ] = data[ w.imagifyFiles.heartbeatId ][ context ] || {}; - data[ w.imagifyFiles.heartbeatId ][ context ][ '_' + id ] = locked; + data[ w.imagifyFiles.imagifybeatID ][ context ] = data[ w.imagifyFiles.imagifybeatID ][ context ] || {}; + data[ w.imagifyFiles.imagifybeatID ][ context ][ '_' + id ] = locked; } ); }, /** - * Listen for the custom event "heartbeat-tick" on $(document). + * Listen for the custom event "imagifybeat-tick" on $(document). * * @param {object} e Event object. - * @param {object} data Object containing all Heartbeat IDs. + * @param {object} data Object containing all Imagifybeat IDs. */ - processHeartbeat: function ( e, data ) { - if ( typeof data[ w.imagifyFiles.heartbeatId ] === 'undefined' ) { + processImagifybeat: function ( e, data ) { + if ( typeof data[ w.imagifyFiles.imagifybeatID ] === 'undefined' ) { return; } - $.each( data[ w.imagifyFiles.heartbeatId ], function( contextId, columns ) { + $.each( data[ w.imagifyFiles.imagifybeatID ], function( contextId, columns ) { var context, id; context = $.trim( contextId ).match( /^(.+)_(\d+)$/ ); @@ -283,6 +272,12 @@ window.imagify.drawMeAChart = function( canvas ) { $row.find( '.check-column [type="checkbox"]' ).prop( 'checked', false ); w.imagify.filesList.unlockItem( context, id ); + + if ( ! w.imagify.filesList.working.length ) { + // Work is done. + // Reset Imagifybeat interval. + w.imagify.beat.resetInterval(); + } }, /** diff --git a/assets/js/files-list.min.js b/assets/js/files-list.min.js index 0e5506b71..5a0275385 100644 --- a/assets/js/files-list.min.js +++ b/assets/js/files-list.min.js @@ -1 +1 @@ -window.imagify.drawMeAChart=function(a){a.each(function(){var a=parseInt(jQuery(this).closest(".imagify-chart").next(".imagify-chart-value").text(),10);new window.imagify.Chart(this,{type:"doughnut",data:{datasets:[{data:[a,100-a],backgroundColor:["#00B3D3","#D8D8D8"],borderColor:"#fff",borderWidth:1}]},options:{legend:{display:!1},events:[],animation:{easing:"easeOutBounce"},tooltips:{enabled:!1},responsive:!1}})})},function(a,b,c,d){c.imagify.filesList={working:[],init:function(){var d,e=a(b);a(c).on("canvasprinted.imagify",this.updateChart).trigger("canvasprinted.imagify"),this.hasHeartbeat()&&(this.insertBulkActionTags(),a("#doaction, #doaction2").on("click.imagify",this.processBulkAction),e.on("click.imagify",".button-imagify-optimize, .button-imagify-manual-reoptimize, .button-imagify-generate-webp, .button-imagify-restore, .button-imagify-refresh-status",this.processOptimization),e.on("heartbeat-send",this.addToHeartbeat),e.on("heartbeat-tick",this.processHeartbeat),d=a(".wp-list-table.imagify-files .button-imagify-processing"),d.length&&(c.wp.heartbeat.interval(5,12),d.closest("tr").find('.check-column [name="bulk_select[]"]').each(function(){var a=c.imagify.filesList.sanitizeId(this.value);c.imagify.filesList.lockItem(c.imagifyFiles.context,a)})))},updateChart:function(b,d){var e;d=d||".imagify-consumption-chart",e=a(d),c.imagify.drawMeAChart(e),e.closest(".imagify-datas-list").siblings(".imagify-datas-details").hide()},insertBulkActionTags:function(){var b='";(c.imagifyFiles.backupOption||a(".file-has-backup").length)&&(b+='"),a('.bulkactions select[name="action"] option:first-child, .bulkactions select[name="action2"] option:first-child').after(b)},processBulkAction:function(b){var c,d=a(this).prev("select").val();"imagify-bulk-optimize"!==d&&"imagify-bulk-restore"!==d&&"imagify-bulk-refresh-status"!==d||(b.preventDefault(),c=d.replace("imagify-bulk-",""),a('input[name="bulk_select[]"]:checked').closest("tr").find(".button-imagify-"+c).each(function(b,c){setTimeout(function(){a(c).trigger("click.imagify")},500*b)}))},processOptimization:function(b){var d,e,f,g=a(this),h=g.closest("tr"),i=h.find('.check-column [type="checkbox"]'),j=imagify.filesList.sanitizeId(i.val()),k=c.imagifyFiles.context;b.preventDefault(),imagify.filesList.isItemLocked(k,j)||(imagify.filesList.lockItem(k,j),e=g.attr("href"),f=c.imagify.template("imagify-button-processing"),d=g.closest(".column-actions, .column-status"),d.html(f({label:g.data("processing-label")})),a.get(e.replace("admin-post.php","admin-ajax.php")).done(function(a){if(!a.success)return a.data&&a.data.row?h.html(''+a.data.row+""):d.html(a.data),h.find('.check-column [type="checkbox"]').prop("checked",!1),void imagify.filesList.unlockItem(k,j);a.data&&a.data.columns?c.imagify.filesList.displayProcessResult(k,j,a.data.columns):c.wp.heartbeat.interval(5,12)}))},hasHeartbeat:function(){return!!(c.imagifyFiles&&c.imagifyFiles.heartbeatId&&c.wp&&c.wp.heartbeat)},addToHeartbeat:function(b,d){var e=a('.wp-list-table.imagify-files .check-column [name="bulk_select[]"]');e.length&&(d[c.imagifyFiles.heartbeatId]={},e.each(function(){var a=c.imagify.filesList.sanitizeId(this.value),b=c.imagifyFiles.context,e=c.imagify.filesList.isItemLocked(b,a)?1:0;d[c.imagifyFiles.heartbeatId][b]=d[c.imagifyFiles.heartbeatId][b]||{},d[c.imagifyFiles.heartbeatId][b]["_"+a]=e}))},processHeartbeat:function(b,d){void 0!==d[c.imagifyFiles.heartbeatId]&&a.each(d[c.imagifyFiles.heartbeatId],function(b,d){var e,f;(e=a.trim(b).match(/^(.+)_(\d+)$/))&&(f=c.imagify.filesList.sanitizeId(e[2]),(e=c.imagify.filesList.sanitizeContext(e[1]))===c.imagifyFiles.context&&c.imagify.filesList.displayProcessResult(e,f,d))})},displayProcessResult:function(b,d,e){var f=c.imagify.filesList.getContainers(d);a.each(e,function(a,b){f.children(".column-"+a).html(b)}),f.find('.check-column [type="checkbox"]').prop("checked",!1),c.imagify.filesList.unlockItem(b,d)},getContainers:function(b){return a('.wp-list-table.imagify-files .check-column [name="bulk_select[]"][value="'+b+'"]').closest("tr")},sanitizeId:function(a){return parseInt(a,10)},sanitizeContext:function(a){return(a=a.replace("/[^a-z0-9_-]/gi","").toLowerCase())||"wp"},lockItem:function(a,b){this.isItemLocked(a,b)||this.working.push(a+"_"+b)},unlockItem:function(a,b){var c=a+"_"+b,d=_.indexOf(this.working,c);d>-1&&this.working.splice(d,1)},isItemLocked:function(a,b){return _.indexOf(this.working,a+"_"+b)>-1}},c.imagify.filesList.init()}(jQuery,document,window),function(a){for(var b=0,c=["ms","moz","webkit","o"],d=0;d=l&&j<=m&&(c=i.attr("data-lazy-src"),d!==c&&c&&i.attr("src",c).removeAttr("data-lazy-src"),i.next("noscript").remove())})}var g,h=a("#imagify-files-list-form").find("[data-lazy-src]");h.length&&(a(c).on("scroll resize orientationchange",e),f())}(jQuery,document,window); \ No newline at end of file +window.imagify.drawMeAChart=function(a){a.each(function(){var a=parseInt(jQuery(this).closest(".imagify-chart").next(".imagify-chart-value").text(),10);new window.imagify.Chart(this,{type:"doughnut",data:{datasets:[{data:[a,100-a],backgroundColor:["#00B3D3","#D8D8D8"],borderColor:"#fff",borderWidth:1}]},options:{legend:{display:!1},events:[],animation:{easing:"easeOutBounce"},tooltips:{enabled:!1},responsive:!1}})})},function(a,b,c,d){c.imagify.filesList={working:[],init:function(){var d,e=a(b);a(c).on("canvasprinted.imagify",this.updateChart).trigger("canvasprinted.imagify"),this.insertBulkActionTags(),a("#doaction, #doaction2").on("click.imagify",this.processBulkAction),e.on("click.imagify",".button-imagify-optimize, .button-imagify-manual-reoptimize, .button-imagify-generate-webp, .button-imagify-restore, .button-imagify-refresh-status",this.processOptimization),e.on("imagifybeat-send",this.addToImagifybeat),e.on("imagifybeat-tick",this.processImagifybeat),d=a(".wp-list-table.imagify-files .button-imagify-processing"),d.length&&(d.closest("tr").find('.check-column [name="bulk_select[]"]').each(function(){var a=c.imagify.filesList.sanitizeId(this.value);c.imagify.filesList.lockItem(c.imagifyFiles.context,a)}),c.imagify.beat.interval(15))},updateChart:function(b,d){var e;d=d||".imagify-consumption-chart",e=a(d),c.imagify.drawMeAChart(e),e.closest(".imagify-datas-list").siblings(".imagify-datas-details").hide()},insertBulkActionTags:function(){var b='";(c.imagifyFiles.backupOption||a(".file-has-backup").length)&&(b+='"),a('.bulkactions select[name="action"] option:first-child, .bulkactions select[name="action2"] option:first-child').after(b)},processBulkAction:function(b){var c,d=a(this).prev("select").val();"imagify-bulk-optimize"!==d&&"imagify-bulk-restore"!==d&&"imagify-bulk-refresh-status"!==d||(b.preventDefault(),c=d.replace("imagify-bulk-",""),a('input[name="bulk_select[]"]:checked').closest("tr").find(".button-imagify-"+c).each(function(b,c){setTimeout(function(){a(c).trigger("click.imagify")},500*b)}))},processOptimization:function(b){var d,e,f,g=a(this),h=g.closest("tr"),i=h.find('.check-column [type="checkbox"]'),j=imagify.filesList.sanitizeId(i.val()),k=c.imagifyFiles.context;b.preventDefault(),imagify.filesList.isItemLocked(k,j)||(imagify.filesList.lockItem(k,j),e=g.attr("href"),f=c.imagify.template("imagify-button-processing"),d=g.closest(".column-actions, .column-status"),d.html(f({label:g.data("processing-label")})),a.get(e.replace("admin-post.php","admin-ajax.php")).done(function(a){if(!a.success)return a.data&&a.data.row?h.html(''+a.data.row+""):d.html(a.data),h.find('.check-column [type="checkbox"]').prop("checked",!1),void imagify.filesList.unlockItem(k,j);a.data&&a.data.columns?c.imagify.filesList.displayProcessResult(k,j,a.data.columns):c.imagify.beat.interval(15)}))},addToImagifybeat:function(b,d){var e=a('.wp-list-table.imagify-files .check-column [name="bulk_select[]"]');e.length&&(d[c.imagifyFiles.imagifybeatID]={},e.each(function(){var a=c.imagify.filesList.sanitizeId(this.value),b=c.imagifyFiles.context,e=c.imagify.filesList.isItemLocked(b,a)?1:0;d[c.imagifyFiles.imagifybeatID][b]=d[c.imagifyFiles.imagifybeatID][b]||{},d[c.imagifyFiles.imagifybeatID][b]["_"+a]=e}))},processImagifybeat:function(b,d){void 0!==d[c.imagifyFiles.imagifybeatID]&&a.each(d[c.imagifyFiles.imagifybeatID],function(b,d){var e,f;(e=a.trim(b).match(/^(.+)_(\d+)$/))&&(f=c.imagify.filesList.sanitizeId(e[2]),(e=c.imagify.filesList.sanitizeContext(e[1]))===c.imagifyFiles.context&&c.imagify.filesList.displayProcessResult(e,f,d))})},displayProcessResult:function(b,d,e){var f=c.imagify.filesList.getContainers(d);a.each(e,function(a,b){f.children(".column-"+a).html(b)}),f.find('.check-column [type="checkbox"]').prop("checked",!1),c.imagify.filesList.unlockItem(b,d),c.imagify.filesList.working.length||c.imagify.beat.resetInterval()},getContainers:function(b){return a('.wp-list-table.imagify-files .check-column [name="bulk_select[]"][value="'+b+'"]').closest("tr")},sanitizeId:function(a){return parseInt(a,10)},sanitizeContext:function(a){return(a=a.replace("/[^a-z0-9_-]/gi","").toLowerCase())||"wp"},lockItem:function(a,b){this.isItemLocked(a,b)||this.working.push(a+"_"+b)},unlockItem:function(a,b){var c=a+"_"+b,d=_.indexOf(this.working,c);d>-1&&this.working.splice(d,1)},isItemLocked:function(a,b){return _.indexOf(this.working,a+"_"+b)>-1}},c.imagify.filesList.init()}(jQuery,document,window),function(a){for(var b=0,c=["ms","moz","webkit","o"],d=0;d=l&&j<=m&&(c=i.attr("data-lazy-src"),d!==c&&c&&i.attr("src",c).removeAttr("data-lazy-src"),i.next("noscript").remove())})}var g,h=a("#imagify-files-list-form").find("[data-lazy-src]");h.length&&(a(c).on("scroll resize orientationchange",e),f())}(jQuery,document,window); \ No newline at end of file diff --git a/assets/js/media-modal.js b/assets/js/media-modal.js index 45bbd8f28..9d01ef490 100755 --- a/assets/js/media-modal.js +++ b/assets/js/media-modal.js @@ -55,23 +55,18 @@ window.imagify.drawMeAChart = function( canvas ) { $document.on( 'click', '.imagify-datas-more-action a', this.toggleSlide ); - if ( ! this.hasHeartbeat() ) { - return; - } - // Optimize, restore, etc. $document.on( 'click', '.button-imagify-restore, .button-imagify-optimize, .button-imagify-manual-reoptimize, .button-imagify-optimize-missing-sizes, .button-imagify-generate-webp', this.processOptimization ); - $document.on( 'heartbeat-send', this.addToHeartbeat ); - $document.on( 'heartbeat-tick', this.processHeartbeat ); + $document.on( 'imagifybeat-send', this.addToImagifybeat ); + $document.on( 'imagifybeat-tick', this.processImagifybeat ); // Some items may be processed in background on page load. $processing = $( '.imagify-data-actions-container .button-imagify-processing' ); if ( $processing.length ) { - // Fasten Heartbeat for a minute. - w.wp.heartbeat.interval( 5, 12 ); - + // Some media are already being processed. + // Lock the items, so we can check their status with Imagifybeat. $processing.closest( '.imagify-data-actions-container' ).each( function() { var $this = $( this ), id = w.imagify.modal.sanitizeId( $this.data( 'id' ) ), @@ -79,6 +74,9 @@ window.imagify.drawMeAChart = function( canvas ) { w.imagify.modal.lockItem( context, id ); } ); + + // Fasten Imagifybeat. + w.imagify.beat.interval( 15 ); } }, @@ -136,38 +134,29 @@ window.imagify.drawMeAChart = function( canvas ) { // The work is done. w.imagify.modal.displayProcessResult( context, id, response.data.html ); } else { - // Still processing in background: we're waiting for the result by poking Heartbeat. - // Set the heartbeat interval to 5 sec for 60 seconds (12 ticks). - w.wp.heartbeat.interval( 5, 12 ); + // Still processing in background: we're waiting for the result by poking Imagifybeat. + // Set the Imagifybeat interval to 15 seconds. + w.imagify.beat.interval( 15 ); } } ); }, - // Heartbeat =============================================================================== - - /** - * Tell if we can use Heartbeat. - * - * @return {bool} - */ - hasHeartbeat: function() { - return w.imagifyModal && w.imagifyModal.heartbeatId && w.wp && w.wp.heartbeat ? true : false; - }, + // Imagifybeat ============================================================================= /** - * Send the media IDs and their status to heartbeat. + * Send the media IDs and their status to Imagifybeat. * * @param {object} e Event object. - * @param {object} data Object containing all Heartbeat IDs. + * @param {object} data Object containing all Imagifybeat IDs. */ - addToHeartbeat: function ( e, data ) { + addToImagifybeat: function ( e, data ) { var $containers = $( '.imagify-data-actions-container' ); if ( ! $containers.length ) { return; } - data[ w.imagifyModal.heartbeatId ] = {}; + data[ w.imagifyModal.imagifybeatID ] = {}; $containers.each( function() { var $this = $( this ), @@ -175,23 +164,23 @@ window.imagify.drawMeAChart = function( canvas ) { context = w.imagify.modal.sanitizeContext( $this.data( 'context' ) ), locked = w.imagify.modal.isItemLocked( context, id ) ? 1 : 0; - data[ w.imagifyModal.heartbeatId ][ context ] = data[ w.imagifyModal.heartbeatId ][ context ] || {}; - data[ w.imagifyModal.heartbeatId ][ context ][ '_' + id ] = locked; + data[ w.imagifyModal.imagifybeatID ][ context ] = data[ w.imagifyModal.imagifybeatID ][ context ] || {}; + data[ w.imagifyModal.imagifybeatID ][ context ][ '_' + id ] = locked; } ); }, /** - * Listen for the custom event "heartbeat-tick" on $(document). + * Listen for the custom event "imagifybeat-tick" on $(document). * * @param {object} e Event object. - * @param {object} data Object containing all Heartbeat IDs. + * @param {object} data Object containing all Imagifybeat IDs. */ - processHeartbeat: function ( e, data ) { - if ( typeof data[ w.imagifyModal.heartbeatId ] === 'undefined' ) { + processImagifybeat: function ( e, data ) { + if ( typeof data[ w.imagifyModal.imagifybeatID ] === 'undefined' ) { return; } - $.each( data[ w.imagifyModal.heartbeatId ], function( contextId, htmlContent ) { + $.each( data[ w.imagifyModal.imagifybeatID ], function( contextId, htmlContent ) { var context, id; context = $.trim( contextId ).match( /^(.+)_(\d+)$/ ); @@ -223,7 +212,11 @@ window.imagify.drawMeAChart = function( canvas ) { w.imagify.modal.unlockItem( context, id ); if ( ! w.imagify.modal.working.length ) { + // Work is done. + // Open the last container being processed. w.imagify.modal.openSlide( $containers ); + // Reset Imagifybeat interval. + w.imagify.beat.resetInterval(); } }, diff --git a/assets/js/media-modal.min.js b/assets/js/media-modal.min.js index b99cb5955..eca1b1328 100755 --- a/assets/js/media-modal.min.js +++ b/assets/js/media-modal.min.js @@ -1 +1 @@ -window.imagify.drawMeAChart=function(a){a.each(function(){var a=parseInt(jQuery(this).closest(".imagify-chart").next(".imagify-chart-value").text(),10);new window.imagify.Chart(this,{type:"doughnut",data:{datasets:[{data:[a,100-a],backgroundColor:["#00B3D3","#D8D8D8"],borderColor:"#fff",borderWidth:1}]},options:{legend:{display:!1},events:[],animation:{easing:"easeOutBounce"},tooltips:{enabled:!1},responsive:!1}})})},function(a,b,c,d){c.imagify.modal={working:[],init:function(){var d,e=a(b);a(c).on("canvasprinted.imagify",this.updateChart).trigger("canvasprinted.imagify"),a(".imagify-datas-details").hide(),e.on("click",".imagify-datas-more-action a",this.toggleSlide),this.hasHeartbeat()&&(e.on("click",".button-imagify-restore, .button-imagify-optimize, .button-imagify-manual-reoptimize, .button-imagify-optimize-missing-sizes, .button-imagify-generate-webp",this.processOptimization),e.on("heartbeat-send",this.addToHeartbeat),e.on("heartbeat-tick",this.processHeartbeat),d=a(".imagify-data-actions-container .button-imagify-processing"),d.length&&(c.wp.heartbeat.interval(5,12),d.closest(".imagify-data-actions-container").each(function(){var b=a(this),d=c.imagify.modal.sanitizeId(b.data("id")),e=c.imagify.modal.sanitizeContext(b.data("context"));c.imagify.modal.lockItem(e,d)})))},updateChart:function(b,d){var e;d=d||".imagify-consumption-chart",e=a(d),c.imagify.drawMeAChart(e),e.closest(".imagify-datas-list").siblings(".imagify-datas-details").hide()},processOptimization:function(b){var d,e,f=a(this),g=f.parents(".imagify-data-actions-container"),h=c.imagify.modal.sanitizeId(g.data("id")),i=c.imagify.modal.sanitizeContext(g.data("context"));b.preventDefault(),c.imagify.modal.isItemLocked(i,h)||(c.imagify.modal.lockItem(i,h),d=f.attr("href"),e=c.imagify.template("imagify-button-processing"),g.html(e({label:f.data("processing-label")})),a.get(d.replace("admin-post.php","admin-ajax.php")).done(function(a){a.data&&a.data.html?c.imagify.modal.displayProcessResult(i,h,a.data.html):c.wp.heartbeat.interval(5,12)}))},hasHeartbeat:function(){return!!(c.imagifyModal&&c.imagifyModal.heartbeatId&&c.wp&&c.wp.heartbeat)},addToHeartbeat:function(b,d){var e=a(".imagify-data-actions-container");e.length&&(d[c.imagifyModal.heartbeatId]={},e.each(function(){var b=a(this),e=c.imagify.modal.sanitizeId(b.data("id")),f=c.imagify.modal.sanitizeContext(b.data("context")),g=c.imagify.modal.isItemLocked(f,e)?1:0;d[c.imagifyModal.heartbeatId][f]=d[c.imagifyModal.heartbeatId][f]||{},d[c.imagifyModal.heartbeatId][f]["_"+e]=g}))},processHeartbeat:function(b,d){void 0!==d[c.imagifyModal.heartbeatId]&&a.each(d[c.imagifyModal.heartbeatId],function(b,d){var e,f;(e=a.trim(b).match(/^(.+)_(\d+)$/))&&(f=c.imagify.modal.sanitizeId(e[2]),e=c.imagify.modal.sanitizeContext(e[1]),c.imagify.modal.displayProcessResult(e,f,d))})},displayProcessResult:function(a,b,d){var e=c.imagify.modal.getContainers(a,b);e.html(d),c.imagify.modal.unlockItem(a,b),c.imagify.modal.working.length||c.imagify.modal.openSlide(e)},openSlide:function(b){b.each(function(){var b=a(this),c=b.find(".imagify-datas-more-action a").data("close");b.find(".imagify-datas-more-action a").addClass("is-open").find(".the-text").text(c),b.find(".imagify-datas-details").show().addClass("is-open")})},toggleSlide:function(b){var c=a(this);b.preventDefault(),c.hasClass("is-open")?(a(c.attr("href")).slideUp(300).removeClass("is-open"),c.removeClass("is-open").find(".the-text").text(c.data("open"))):(a(c.attr("href")).slideDown(300).addClass("is-open"),c.addClass("is-open").find(".the-text").text(c.data("close")))},getContainers:function(b,c){return a('.imagify-data-actions-container[data-id="'+c+'"][data-context="'+b+'"]')},sanitizeId:function(a){return parseInt(a,10)},sanitizeContext:function(a){return(a=a.replace("/[^a-z0-9_-]/gi","").toLowerCase())||"wp"},lockItem:function(a,b){this.isItemLocked(a,b)||this.working.push(a+"_"+b)},unlockItem:function(a,b){var c=a+"_"+b,d=_.indexOf(this.working,c);d>-1&&this.working.splice(d,1)},isItemLocked:function(a,b){return _.indexOf(this.working,a+"_"+b)>-1}},c.imagify.modal.init()}(jQuery,document,window); \ No newline at end of file +window.imagify.drawMeAChart=function(a){a.each(function(){var a=parseInt(jQuery(this).closest(".imagify-chart").next(".imagify-chart-value").text(),10);new window.imagify.Chart(this,{type:"doughnut",data:{datasets:[{data:[a,100-a],backgroundColor:["#00B3D3","#D8D8D8"],borderColor:"#fff",borderWidth:1}]},options:{legend:{display:!1},events:[],animation:{easing:"easeOutBounce"},tooltips:{enabled:!1},responsive:!1}})})},function(a,b,c,d){c.imagify.modal={working:[],init:function(){var d,e=a(b);a(c).on("canvasprinted.imagify",this.updateChart).trigger("canvasprinted.imagify"),a(".imagify-datas-details").hide(),e.on("click",".imagify-datas-more-action a",this.toggleSlide),e.on("click",".button-imagify-restore, .button-imagify-optimize, .button-imagify-manual-reoptimize, .button-imagify-optimize-missing-sizes, .button-imagify-generate-webp",this.processOptimization),e.on("imagifybeat-send",this.addToImagifybeat),e.on("imagifybeat-tick",this.processImagifybeat),d=a(".imagify-data-actions-container .button-imagify-processing"),d.length&&(d.closest(".imagify-data-actions-container").each(function(){var b=a(this),d=c.imagify.modal.sanitizeId(b.data("id")),e=c.imagify.modal.sanitizeContext(b.data("context"));c.imagify.modal.lockItem(e,d)}),c.imagify.beat.interval(15))},updateChart:function(b,d){var e;d=d||".imagify-consumption-chart",e=a(d),c.imagify.drawMeAChart(e),e.closest(".imagify-datas-list").siblings(".imagify-datas-details").hide()},processOptimization:function(b){var d,e,f=a(this),g=f.parents(".imagify-data-actions-container"),h=c.imagify.modal.sanitizeId(g.data("id")),i=c.imagify.modal.sanitizeContext(g.data("context"));b.preventDefault(),c.imagify.modal.isItemLocked(i,h)||(c.imagify.modal.lockItem(i,h),d=f.attr("href"),e=c.imagify.template("imagify-button-processing"),g.html(e({label:f.data("processing-label")})),a.get(d.replace("admin-post.php","admin-ajax.php")).done(function(a){a.data&&a.data.html?c.imagify.modal.displayProcessResult(i,h,a.data.html):c.imagify.beat.interval(15)}))},addToImagifybeat:function(b,d){var e=a(".imagify-data-actions-container");e.length&&(d[c.imagifyModal.imagifybeatID]={},e.each(function(){var b=a(this),e=c.imagify.modal.sanitizeId(b.data("id")),f=c.imagify.modal.sanitizeContext(b.data("context")),g=c.imagify.modal.isItemLocked(f,e)?1:0;d[c.imagifyModal.imagifybeatID][f]=d[c.imagifyModal.imagifybeatID][f]||{},d[c.imagifyModal.imagifybeatID][f]["_"+e]=g}))},processImagifybeat:function(b,d){void 0!==d[c.imagifyModal.imagifybeatID]&&a.each(d[c.imagifyModal.imagifybeatID],function(b,d){var e,f;(e=a.trim(b).match(/^(.+)_(\d+)$/))&&(f=c.imagify.modal.sanitizeId(e[2]),e=c.imagify.modal.sanitizeContext(e[1]),c.imagify.modal.displayProcessResult(e,f,d))})},displayProcessResult:function(a,b,d){var e=c.imagify.modal.getContainers(a,b);e.html(d),c.imagify.modal.unlockItem(a,b),c.imagify.modal.working.length||(c.imagify.modal.openSlide(e),c.imagify.beat.resetInterval())},openSlide:function(b){b.each(function(){var b=a(this),c=b.find(".imagify-datas-more-action a").data("close");b.find(".imagify-datas-more-action a").addClass("is-open").find(".the-text").text(c),b.find(".imagify-datas-details").show().addClass("is-open")})},toggleSlide:function(b){var c=a(this);b.preventDefault(),c.hasClass("is-open")?(a(c.attr("href")).slideUp(300).removeClass("is-open"),c.removeClass("is-open").find(".the-text").text(c.data("open"))):(a(c.attr("href")).slideDown(300).addClass("is-open"),c.addClass("is-open").find(".the-text").text(c.data("close")))},getContainers:function(b,c){return a('.imagify-data-actions-container[data-id="'+c+'"][data-context="'+b+'"]')},sanitizeId:function(a){return parseInt(a,10)},sanitizeContext:function(a){return(a=a.replace("/[^a-z0-9_-]/gi","").toLowerCase())||"wp"},lockItem:function(a,b){this.isItemLocked(a,b)||this.working.push(a+"_"+b)},unlockItem:function(a,b){var c=a+"_"+b,d=_.indexOf(this.working,c);d>-1&&this.working.splice(d,1)},isItemLocked:function(a,b){return _.indexOf(this.working,a+"_"+b)>-1}},c.imagify.modal.init()}(jQuery,document,window); \ No newline at end of file diff --git a/assets/js/options.js b/assets/js/options.js index 5556be2b4..8d8507fda 100755 --- a/assets/js/options.js +++ b/assets/js/options.js @@ -510,13 +510,13 @@ window.imagify = window.imagify || {}; // Launch optimization. this.$button.on( 'click.imagify', { imagifyOptionsBulk: this }, this.maybeLaunchAllProcesses ); - // Heartbeat for optimization queue. + // Imagifybeat for optimization queue. $( d ) - .on( 'heartbeat-send', { imagifyOptionsBulk: this }, this.addQueueHeartbeat ) - .on( 'heartbeat-tick', { imagifyOptionsBulk: this }, this.processQueueHeartbeat ) - // Heartbeat for requirements. - .on( 'heartbeat-send', this.addRequirementsHeartbeat ) - .on( 'heartbeat-tick', { imagifyOptionsBulk: this }, this.processRequirementsHeartbeat ); + .on( 'imagifybeat-send', { imagifyOptionsBulk: this }, this.addQueueImagifybeat ) + .on( 'imagifybeat-tick', { imagifyOptionsBulk: this }, this.processQueueImagifybeat ) + // Imagifybeat for requirements. + .on( 'imagifybeat-send', this.addRequirementsImagifybeat ) + .on( 'imagifybeat-tick', { imagifyOptionsBulk: this }, this.processRequirementsImagifybeat ); }, // Event callbacks ========================================================================= @@ -565,6 +565,10 @@ window.imagify = window.imagify || {}; // Add a message to be displayed when the user wants to quit the page. $( w ).on( 'beforeunload', e.data.imagifyOptionsBulk.getConfirmMessage ); + // Fasten Imagifybeat: 1 tick every 15 seconds, and disable suspend. + w.imagify.beat.interval( 15 ); + w.imagify.beat.disableSuspend(); + // Fetch IDs of media to optimize. e.data.imagifyOptionsBulk.fetchIDs(); }, @@ -578,58 +582,58 @@ window.imagify = window.imagify || {}; return imagifyOptions.bulk.labels.processing; }, - // Heartbeat =============================================================================== + // Imagifybeat ============================================================================= /** - * Add a Heartbeat ID on "heartbeat-send" event to sync the optimization queue. + * Add a Imagifybeat ID on "imagifybeat-send" event to sync the optimization queue. * * @param {object} e Event object. - * @param {object} data Object containing all Heartbeat IDs. + * @param {object} data Object containing all Imagifybeat IDs. */ - addQueueHeartbeat: function ( e, data ) { + addQueueImagifybeat: function ( e, data ) { if ( e.data.imagifyOptionsBulk && e.data.imagifyOptionsBulk.processingQueue.length ) { - data[ imagifyOptions.bulk.heartbeatIDs.queue ] = e.data.imagifyOptionsBulk.processingQueue; + data[ imagifyOptions.bulk.imagifybeatIDs.queue ] = e.data.imagifyOptionsBulk.processingQueue; } }, /** - * Listen for the custom event "heartbeat-tick" on $(document). + * Listen for the custom event "imagifybeat-tick" on $(document). * It allows to update various data periodically. * * @param {object} e Event object. - * @param {object} data Object containing all Heartbeat IDs. + * @param {object} data Object containing all Imagifybeat IDs. */ - processQueueHeartbeat: function ( e, data ) { - if ( e.data.imagifyOptionsBulk && typeof data[ imagifyOptions.bulk.heartbeatIDs.queue ] !== 'undefined' ) { - $.each( data[ imagifyOptions.bulk.heartbeatIDs.queue ], function ( i, mediaData ) { + processQueueImagifybeat: function ( e, data ) { + if ( e.data.imagifyOptionsBulk && typeof data[ imagifyOptions.bulk.imagifybeatIDs.queue ] !== 'undefined' ) { + $.each( data[ imagifyOptions.bulk.imagifybeatIDs.queue ], function ( i, mediaData ) { e.data.imagifyOptionsBulk.mediaProcessed( mediaData ); } ); } }, /** - * Add a Heartbeat ID for requirements on "heartbeat-send" event. + * Add a Imagifybeat ID for requirements on "imagifybeat-send" event. * * @param {object} e Event object. - * @param {object} data Object containing all Heartbeat IDs. + * @param {object} data Object containing all Imagifybeat IDs. */ - addRequirementsHeartbeat: function ( e, data ) { - data[ imagifyOptions.bulk.heartbeatIDs.requirements ] = 1; + addRequirementsImagifybeat: function ( e, data ) { + data[ imagifyOptions.bulk.imagifybeatIDs.requirements ] = 1; }, /** - * Listen for the custom event "heartbeat-tick" on $(document). + * Listen for the custom event "imagifybeat-tick" on $(document). * It allows to update requirements status periodically. * * @param {object} e Event object. - * @param {object} data Object containing all Heartbeat IDs. + * @param {object} data Object containing all Imagifybeat IDs. */ - processRequirementsHeartbeat: function ( e, data ) { - if ( e.data.imagifyOptionsBulk && typeof data[ imagifyOptions.bulk.heartbeatIDs.requirements ] === 'undefined' ) { + processRequirementsImagifybeat: function ( e, data ) { + if ( e.data.imagifyOptionsBulk && typeof data[ imagifyOptions.bulk.imagifybeatIDs.requirements ] === 'undefined' ) { return; } - data = data[ imagifyOptions.bulk.heartbeatIDs.requirements ]; + data = data[ imagifyOptions.bulk.imagifybeatIDs.requirements ]; imagifyOptions.bulk.curlMissing = data.curl_missing; imagifyOptions.bulk.editorMissing = data.editor_missing; @@ -915,6 +919,10 @@ window.imagify = window.imagify || {}; this.processedMedia = 0; this.totalMedia = 0; + // Reset Imagifybeat interval and enable suspend. + w.imagify.beat.resetInterval(); + w.imagify.beat.enableSuspend(); + // Unlink the message displayed when the user wants to quit the page. $( w ).off( 'beforeunload', this.getConfirmMessage ); diff --git a/assets/js/options.min.js b/assets/js/options.min.js index e9c380e83..191496caa 100755 --- a/assets/js/options.min.js +++ b/assets/js/options.min.js @@ -1 +1 @@ -window.imagify=window.imagify||{},function(a,b,c,d){var e=!1,f=!1;a("#imagify-settings #api_key").on("blur",function(){var b=a(this),d=b.val();return""!==a.trim(d)&&(a("#check_api_key").val()===d?(a("#imagify-check-api-container").html(' '+imagifyOptions.labels.ValidApiKeyText),!1):(!0===e?f.abort():(a("#imagify-check-api-container").remove(),b.after(''+imagifyOptions.labels.waitApiKeyCheckText+"")),e=!0,void(f=a.get(ajaxurl+c.imagify.concat+"action=imagify_check_api_key_validity&api_key="+b.val()+"&imagifycheckapikeynonce="+a("#imagifycheckapikeynonce").val()).done(function(b){b.success?(a("#imagify-check-api-container").remove(),swal({title:imagifyOptions.labels.ApiKeyCheckSuccessTitle,html:imagifyOptions.labels.ApiKeyCheckSuccessText,type:"success",padding:0,customClass:"imagify-sweet-alert"}).then(function(){location.reload()})):a("#imagify-check-api-container").html(' '+b.data),e=!1}))))}),a(".imagify-options-line").css("cursor","pointer").on("click",function(b){"INPUT"!==b.target.nodeName&&a('input[aria-describedby="'+a(this).attr("id")+'"]').trigger("click")}),a(".imagify-settings th span").on("click",function(){var b=a(this).parent().next("td").find("input:checkbox");1===b.length&&b.trigger("click")}),a(".imagify-options-line").find("input").on("change focus",function(){var b=a(this).closest(".imagify-options-line").prev("label").prev("input");b[0].checked||b.prop("checked",!0)}),a(".imagify-settings-section").find("#imagify_backup").on("change",function(){var b=a(this),c=b.siblings("#backup-dir-is-writable"),d={action:"imagify_check_backup_dir_is_writable",_wpnonce:c.data("nonce")};if(b.is(":checked"))return void a.getJSON(ajaxurl,d).done(function(b){a.isPlainObject(b)&&b.success&&(b.data.is_writable?c.addClass("hidden"):c.removeClass("hidden"))});swal({title:imagifyOptions.labels.noBackupTitle,html:imagifyOptions.labels.noBackupText,type:"warning",customClass:"imagify-sweet-alert",padding:0,showCancelButton:!0,cancelButtonText:imagifySwal.labels.cancelButtonText,reverseButtons:!0}).then(function(){c.addClass("hidden")},function(){b.prop("checked",!0)})})}(jQuery,document,window),function(a,b,c,d){a.imagifyUser&&c.getJSON(ajaxurl,a.imagifyUser).done(function(a){c.isPlainObject(a)&&a.success&&(a.data.id=null,a.data.plan_id=null,a.data.is=[],c.each(a.data,function(b,d){var e=".imagify-user-"+b.replace(/_/g,"-");0===b.indexOf("is_")?d&&a.data.is.push(e):"is"!==b&&c(e).text(d)}),a.data.is.push("best-plan"),c(a.data.is.join(",")).removeClass("hidden"))})}(window,document,jQuery),function(a,b,c,d){function e(b){var d,e,f,g,h,i=!1,j=null;b&&(f=c("#imagify-custom-folders-selected"),g=f.find(".imagify-custom-folder-line"),h=g.find('[value="'+b+'"]'),h.length||(b=b.split("#///#"),d=b[1].replace(/\/+$/,"").toLowerCase(),e=a.imagify.template("imagify-custom-folder"),g.each(function(){var a=c(this),h=a.data("path").replace(/\/+$/,"").toLowerCase();return""!==h&&0===d.indexOf(h)?(i=!0,!1):d'+imagifyOptions.labels.filesTreeSubTitle+'

'+imagifyOptions.labels.cleaningInfo+'

    '+a.data+"
",type:"",customClass:"imagify-sweet-alert imagify-swal-has-subtitle imagify-folders-selection",showCancelButton:!0,padding:0,confirmButtonText:imagifyOptions.labels.confirmFilesTreeBtn,cancelButtonText:imagifySwal.labels.cancelButtonText,reverseButtons:!0}).then(function(){var a=c("#imagify-folders-tree input").serializeArray();a.length&&c.each(a,function(a,b){e(b.value)})}).catch(swal.noop)}).fail(function(){swal({title:imagifyOptions.labels.error,type:"error",customClass:"imagify-sweet-alert",padding:0})}).always(function(){b.removeAttr("disabled").next("img").attr("aria-hidden","true")}))}),c(b).on("click.imagify","#imagify-folders-tree [data-folder]",function(){var a=c(this),b=a.nextAll(".imagify-folders-sub-tree"),d=[];if(!a.attr("disabled")&&!a.siblings(":checkbox").is(":checked")){if(a.attr("disabled","disabled").addClass("imagify-loading"),b.length)return a.hasClass("imagify-is-open")?(b.addClass("hidden"),a.removeClass(" imagify-is-open")):(b.removeClass("hidden"),a.addClass("imagify-is-open")),void a.removeAttr("disabled").removeClass("imagify-loading");c("#imagify-custom-folders-selected").find("input").each(function(){d.push(this.value)}),c.post(imagifyOptions.getFilesTree,{folder:a.data("folder"),selected:d},null,"json").done(function(b){if(!b.success)return void swal({title:imagifyOptions.labels.error,html:b.data||"",type:"error",padding:0,customClass:"imagify-sweet-alert"});a.addClass("imagify-is-open").parent().append('
    '+b.data+"
")}).fail(function(){swal({title:imagifyOptions.labels.error,type:"error",padding:0,customClass:"imagify-sweet-alert"})}).always(function(){a.removeAttr("disabled").removeClass("imagify-loading")})}}),c("#imagify-custom-folders").on("click.imagify",".imagify-custom-folders-remove",function(){var b=c(this).closest(".imagify-custom-folder-line").addClass("imagify-will-remove");a.setTimeout(function(){b.remove(),c("#imagify-custom-folders-selected").siblings(".imagify-success.hidden").removeClass("hidden")},750)}),c("#imagify-add-themes-to-custom-folder").on("click.imagify",function(){var a=c(this);e(a.data("theme")),e(a.data("theme-parent")),a.replaceWith("

"+imagifyOptions.labels.themesAdded+"

")}))}(window,document,jQuery),function(a,b,c,d){imagifyOptions.bulk&&(a.imagify.optionsBulk={fetchQueue:[],queue:[],processingQueue:[],fetchError:!1,error:!1,working:!1,processIsStopped:!0,processedMedia:0,totalMedia:0,$button:null,$progressWrap:null,$progressBar:null,$progressText:null,init:function(){this.$button=c("#imagify-generate-webp-versions"),this.$progressWrap=this.$button.siblings(".imagify-progress"),this.$progressBar=this.$progressWrap.find(".bar"),this.$progressText=this.$progressBar.find(".percent"),c("#imagify_convert_to_webp").on("change.imagify init.imagify",{imagifyOptionsBulk:this},this.toggleButton).trigger("init.imagify"),this.$button.on("click.imagify",{imagifyOptionsBulk:this},this.maybeLaunchAllProcesses),c(b).on("heartbeat-send",{imagifyOptionsBulk:this},this.addQueueHeartbeat).on("heartbeat-tick",{imagifyOptionsBulk:this},this.processQueueHeartbeat).on("heartbeat-send",this.addRequirementsHeartbeat).on("heartbeat-tick",{imagifyOptionsBulk:this},this.processRequirementsHeartbeat)},toggleButton:function(a){this.checked?a.data.imagifyOptionsBulk.$button.removeAttr("disabled"):a.data.imagifyOptionsBulk.$button.attr("disabled","disabled")},maybeLaunchAllProcesses:function(b){b.data.imagifyOptionsBulk&&!b.data.imagifyOptionsBulk.working&&(b.data.imagifyOptionsBulk.hasBlockingError(!0)||(b.data.imagifyOptionsBulk.fetchQueue=imagifyOptions.bulk.contexts,b.data.imagifyOptionsBulk.queue=[],b.data.imagifyOptionsBulk.processingQueue=[],b.data.imagifyOptionsBulk.fetchError=!1,b.data.imagifyOptionsBulk.error=!1,b.data.imagifyOptionsBulk.working=!0,b.data.imagifyOptionsBulk.processIsStopped=!1,b.data.imagifyOptionsBulk.processedMedia=0,b.data.imagifyOptionsBulk.totalMedia=0,b.data.imagifyOptionsBulk.$button.attr("disabled","disabled").find(".dashicons").addClass("rotate"),c(a).on("beforeunload",b.data.imagifyOptionsBulk.getConfirmMessage),b.data.imagifyOptionsBulk.fetchIDs()))},getConfirmMessage:function(){return imagifyOptions.bulk.labels.processing},addQueueHeartbeat:function(a,b){a.data.imagifyOptionsBulk&&a.data.imagifyOptionsBulk.processingQueue.length&&(b[imagifyOptions.bulk.heartbeatIDs.queue]=a.data.imagifyOptionsBulk.processingQueue)},processQueueHeartbeat:function(a,b){a.data.imagifyOptionsBulk&&void 0!==b[imagifyOptions.bulk.heartbeatIDs.queue]&&c.each(b[imagifyOptions.bulk.heartbeatIDs.queue],function(b,c){a.data.imagifyOptionsBulk.mediaProcessed(c)})},addRequirementsHeartbeat:function(a,b){b[imagifyOptions.bulk.heartbeatIDs.requirements]=1},processRequirementsHeartbeat:function(a,b){a.data.imagifyOptionsBulk&&void 0===b[imagifyOptions.bulk.heartbeatIDs.requirements]||(b=b[imagifyOptions.bulk.heartbeatIDs.requirements],imagifyOptions.bulk.curlMissing=b.curl_missing,imagifyOptions.bulk.editorMissing=b.editor_missing,imagifyOptions.bulk.extHttpBlocked=b.external_http_blocked,imagifyOptions.bulk.apiDown=b.api_down,imagifyOptions.bulk.keyIsValid=b.key_is_valid,imagifyOptions.bulk.isOverQuota=b.is_over_quota)},fetchIDs:function(){var a,b;if(!this.processIsStopped){if(!this.fetchQueue.length)return this.queue.length?(this.$progressBar.removeAttr("style"),this.$progressText.text("0"+(this.totalMedia?"/"+this.totalMedia:"")),this.$progressWrap.slideDown().attr("aria-hidden","false"),void this.processQueue()):(this.fetchError||(this.fetchError="no-images"),this.stopProcess(this.fetchError),void(this.fetchError=!1));a=this,b=this.fetchQueue.shift(),c.get(this.getAjaxUrl("getMediaIds",b)).done(function(d){var e;if(!a.processIsStopped)return e=d.data&&d.data.message?d.data.message:imagifyOptions.bulk.ajaxErrorText,d.success&&c.isArray(d.data)?void(d.data.length&&(a.totalMedia+=d.data.length,a.queue.push({context:b,optimizeURL:a.getAjaxUrl("bulkProcess",b),mediaIDs:d.data}))):void(a.fetchError||(a.fetchError=e))}).fail(function(){a.fetchError||(a.fetchError="get-unoptimized-images")}).always(function(){a.fetchIDs()})}},processQueue:function(){var a=this;this.processIsStopped||(this.queue.length||this.processingQueue.length)&&c.each(this.queue,function(b,d){if(a.processingQueue.length>=imagifyOptions.bulk.bufferSize)return!1;c.each(d.mediaIDs,function(){if(a.processMedia({context:d.context,mediaID:d.mediaIDs.shift(),optimizeURL:d.optimizeURL}),d.mediaIDs.length||a.queue.shift(),a.processingQueue.length>=imagifyOptions.bulk.bufferSize)return!1})})},processMedia:function(a){var b=this,d={context:a.context,mediaID:a.mediaID};this.processingQueue.push({context:a.context,mediaID:a.mediaID}),c.post({url:a.optimizeURL,data:{media_id:a.mediaID,context:a.context},dataType:"json"}).done(function(a){a.success||b.mediaProcessed(d)}).fail(function(){b.mediaProcessed(d)})},mediaProcessed:function(a){var b=this;this.processIsStopped||(c.each(this.processingQueue,function(c,d){if(a.context===d.context&&a.mediaID===d.mediaID)return b.processingQueue.splice(c,1),!1}),++this.processedMedia,a.progress=Math.floor(this.processedMedia/this.totalMedia*100),this.$progressBar.css("width",a.progress+"%"),this.$progressText.text(this.processedMedia+"/"+this.totalMedia),this.queue.length||this.processingQueue.length?this.processQueue():this.totalMedia===this.processedMedia&&this.queueEmpty())},queueEmpty:function(){var b={};!1!==this.error&&(b="invalid-api-key"===this.error?{title:imagifyOptions.bulk.labels.invalidAPIKeyTitle,type:"info"}:"over-quota"===this.error?{title:imagifyOptions.bulk.labels.overQuotaTitle,html:c("#tmpl-imagify-overquota-alert").html(),type:"info",customClass:"imagify-swal-has-subtitle imagify-swal-error-header",showConfirmButton:!1}:"get-unoptimized-images"===this.error||"consumed-all-data"===this.error?{title:imagifyOptions.bulk.labels.getUnoptimizedImagesErrorTitle,html:imagifyOptions.bulk.labels.getUnoptimizedImagesErrorText,type:"info"}:"no-images"===this.error?{title:imagifyOptions.bulk.labels.nothingToDoTitle,html:imagifyOptions.bulk.labels.nothingToDoText,type:"info"}:{title:imagifyOptions.bulk.labels.error,html:this.error,type:"info"},this.displayError(b),this.error=!1),this.fetchQueue=[],this.queue=[],this.processingQueue=[],this.fetchError=!1,this.working=!1,this.processIsStopped=!1,this.processedMedia=0,this.totalMedia=0,c(a).off("beforeunload",this.getConfirmMessage),this.$progressWrap.slideUp().attr("aria-hidden","true"),this.$progressBar.removeAttr("style"),this.$progressText.text("0"),this.$button.removeAttr("disabled").find(".dashicons").removeClass("rotate")},hasBlockingError:function(a){return a=void 0!==a&&a,imagifyOptions.bulk.curlMissing?(a&&this.displayError({html:imagifyOptions.bulk.labels.curlMissing}),!0):imagifyOptions.bulk.editorMissing?(a&&this.displayError({html:imagifyOptions.bulk.labels.editorMissing}),!0):imagifyOptions.bulk.extHttpBlocked?(a&&this.displayError({html:imagifyOptions.bulk.labels.extHttpBlocked}),!0):imagifyOptions.bulk.apiDown?(a&&this.displayError({html:imagifyOptions.bulk.labels.apiDown}),!0):imagifyOptions.bulk.keyIsValid?!!imagifyOptions.bulk.isOverQuota&&(a&&this.displayError({title:imagifyOptions.bulk.labels.overQuotaTitle,html:c("#tmpl-imagify-overquota-alert").html(),type:"info",customClass:"imagify-swal-has-subtitle imagify-swal-error-header",showConfirmButton:!1}),!0):(a&&this.displayError({title:imagifyOptions.bulk.labels.invalidAPIKeyTitle,type:"info"}),!0)},displayError:function(a,b,d){var e={title:"",html:"",type:"error",customClass:"",width:620,padding:0,showCloseButton:!0,showConfirmButton:!0};c.isPlainObject(a)?d=c.extend({},e,a):(d=d||{},d=c.extend({},e,{title:a||"",html:b||""},d)),d.title=d.title||imagifyOptions.bulk.labels.error,d.customClass+=" imagify-sweet-alert",swal(d).catch(swal.noop)},getAjaxUrl:function(b,c){var d;return d=ajaxurl+a.imagify.concat+"_wpnonce="+imagifyOptions.bulk.ajaxNonce,d+="&action="+imagifyOptions.bulk.ajaxActions[b],d+="&context="+c,d+="&imagify_action=generate_webp"},stopProcess:function(a){this.processIsStopped=!0,this.error=a,this.queueEmpty()}},a.imagify.optionsBulk.init())}(window,document,jQuery),function(a,b,c,d){var e=c.propHooks.checked;c.propHooks.checked={set:function(a,b,d){var f;return f=void 0===e?a[d]=b:e(a,b,d),c(a).trigger("change.imagify"),f}},c(".imagify-select-all").on("click.imagify",function(){var a=c(this),b=a.data("action"),d=a.closest(".imagify-select-all-buttons"),e=d.prev(".imagify-check-group"),f="imagify-is-inactive";if(a.hasClass(f))return!1;d.find(".imagify-select-all").removeClass(f).attr("aria-disabled","false"),a.addClass(f).attr("aria-disabled","true"),e.find(".imagify-row-check").prop("checked",function(){return!c(this).is(":hidden,:disabled")&&"select"===b})}),c(".imagify-check-group .imagify-row-check").on("change.imagify",function(){var a=c(this).closest(".imagify-check-group"),b=a.find(".imagify-row-check"),d=b.filter(":visible:enabled").length,e=b.filter(":visible:enabled:checked").length,f=a.next(".imagify-select-all-buttons"),g="imagify-is-inactive";0===e&&f.find('[data-action="unselect"]').addClass(g).attr("aria-disabled","true"),e===d&&f.find('[data-action="select"]').addClass(g).attr("aria-disabled","true"),e!==d&&e>0&&f.find(".imagify-select-all").removeClass(g).attr("aria-disabled","false")})}(window,document,jQuery); \ No newline at end of file +window.imagify=window.imagify||{},function(a,b,c,d){var e=!1,f=!1;a("#imagify-settings #api_key").on("blur",function(){var b=a(this),d=b.val();return""!==a.trim(d)&&(a("#check_api_key").val()===d?(a("#imagify-check-api-container").html(' '+imagifyOptions.labels.ValidApiKeyText),!1):(!0===e?f.abort():(a("#imagify-check-api-container").remove(),b.after(''+imagifyOptions.labels.waitApiKeyCheckText+"")),e=!0,void(f=a.get(ajaxurl+c.imagify.concat+"action=imagify_check_api_key_validity&api_key="+b.val()+"&imagifycheckapikeynonce="+a("#imagifycheckapikeynonce").val()).done(function(b){b.success?(a("#imagify-check-api-container").remove(),swal({title:imagifyOptions.labels.ApiKeyCheckSuccessTitle,html:imagifyOptions.labels.ApiKeyCheckSuccessText,type:"success",padding:0,customClass:"imagify-sweet-alert"}).then(function(){location.reload()})):a("#imagify-check-api-container").html(' '+b.data),e=!1}))))}),a(".imagify-options-line").css("cursor","pointer").on("click",function(b){"INPUT"!==b.target.nodeName&&a('input[aria-describedby="'+a(this).attr("id")+'"]').trigger("click")}),a(".imagify-settings th span").on("click",function(){var b=a(this).parent().next("td").find("input:checkbox");1===b.length&&b.trigger("click")}),a(".imagify-options-line").find("input").on("change focus",function(){var b=a(this).closest(".imagify-options-line").prev("label").prev("input");b[0].checked||b.prop("checked",!0)}),a(".imagify-settings-section").find("#imagify_backup").on("change",function(){var b=a(this),c=b.siblings("#backup-dir-is-writable"),d={action:"imagify_check_backup_dir_is_writable",_wpnonce:c.data("nonce")};if(b.is(":checked"))return void a.getJSON(ajaxurl,d).done(function(b){a.isPlainObject(b)&&b.success&&(b.data.is_writable?c.addClass("hidden"):c.removeClass("hidden"))});swal({title:imagifyOptions.labels.noBackupTitle,html:imagifyOptions.labels.noBackupText,type:"warning",customClass:"imagify-sweet-alert",padding:0,showCancelButton:!0,cancelButtonText:imagifySwal.labels.cancelButtonText,reverseButtons:!0}).then(function(){c.addClass("hidden")},function(){b.prop("checked",!0)})})}(jQuery,document,window),function(a,b,c,d){a.imagifyUser&&c.getJSON(ajaxurl,a.imagifyUser).done(function(a){c.isPlainObject(a)&&a.success&&(a.data.id=null,a.data.plan_id=null,a.data.is=[],c.each(a.data,function(b,d){var e=".imagify-user-"+b.replace(/_/g,"-");0===b.indexOf("is_")?d&&a.data.is.push(e):"is"!==b&&c(e).text(d)}),a.data.is.push("best-plan"),c(a.data.is.join(",")).removeClass("hidden"))})}(window,document,jQuery),function(a,b,c,d){function e(b){var d,e,f,g,h,i=!1,j=null;b&&(f=c("#imagify-custom-folders-selected"),g=f.find(".imagify-custom-folder-line"),h=g.find('[value="'+b+'"]'),h.length||(b=b.split("#///#"),d=b[1].replace(/\/+$/,"").toLowerCase(),e=a.imagify.template("imagify-custom-folder"),g.each(function(){var a=c(this),h=a.data("path").replace(/\/+$/,"").toLowerCase();return""!==h&&0===d.indexOf(h)?(i=!0,!1):d'+imagifyOptions.labels.filesTreeSubTitle+'

'+imagifyOptions.labels.cleaningInfo+'

    '+a.data+"
",type:"",customClass:"imagify-sweet-alert imagify-swal-has-subtitle imagify-folders-selection",showCancelButton:!0,padding:0,confirmButtonText:imagifyOptions.labels.confirmFilesTreeBtn,cancelButtonText:imagifySwal.labels.cancelButtonText,reverseButtons:!0}).then(function(){var a=c("#imagify-folders-tree input").serializeArray();a.length&&c.each(a,function(a,b){e(b.value)})}).catch(swal.noop)}).fail(function(){swal({title:imagifyOptions.labels.error,type:"error",customClass:"imagify-sweet-alert",padding:0})}).always(function(){b.removeAttr("disabled").next("img").attr("aria-hidden","true")}))}),c(b).on("click.imagify","#imagify-folders-tree [data-folder]",function(){var a=c(this),b=a.nextAll(".imagify-folders-sub-tree"),d=[];if(!a.attr("disabled")&&!a.siblings(":checkbox").is(":checked")){if(a.attr("disabled","disabled").addClass("imagify-loading"),b.length)return a.hasClass("imagify-is-open")?(b.addClass("hidden"),a.removeClass(" imagify-is-open")):(b.removeClass("hidden"),a.addClass("imagify-is-open")),void a.removeAttr("disabled").removeClass("imagify-loading");c("#imagify-custom-folders-selected").find("input").each(function(){d.push(this.value)}),c.post(imagifyOptions.getFilesTree,{folder:a.data("folder"),selected:d},null,"json").done(function(b){if(!b.success)return void swal({title:imagifyOptions.labels.error,html:b.data||"",type:"error",padding:0,customClass:"imagify-sweet-alert"});a.addClass("imagify-is-open").parent().append('
    '+b.data+"
")}).fail(function(){swal({title:imagifyOptions.labels.error,type:"error",padding:0,customClass:"imagify-sweet-alert"})}).always(function(){a.removeAttr("disabled").removeClass("imagify-loading")})}}),c("#imagify-custom-folders").on("click.imagify",".imagify-custom-folders-remove",function(){var b=c(this).closest(".imagify-custom-folder-line").addClass("imagify-will-remove");a.setTimeout(function(){b.remove(),c("#imagify-custom-folders-selected").siblings(".imagify-success.hidden").removeClass("hidden")},750)}),c("#imagify-add-themes-to-custom-folder").on("click.imagify",function(){var a=c(this);e(a.data("theme")),e(a.data("theme-parent")),a.replaceWith("

"+imagifyOptions.labels.themesAdded+"

")}))}(window,document,jQuery),function(a,b,c,d){imagifyOptions.bulk&&(a.imagify.optionsBulk={fetchQueue:[],queue:[],processingQueue:[],fetchError:!1,error:!1,working:!1,processIsStopped:!0,processedMedia:0,totalMedia:0,$button:null,$progressWrap:null,$progressBar:null,$progressText:null,init:function(){this.$button=c("#imagify-generate-webp-versions"),this.$progressWrap=this.$button.siblings(".imagify-progress"),this.$progressBar=this.$progressWrap.find(".bar"),this.$progressText=this.$progressBar.find(".percent"),c("#imagify_convert_to_webp").on("change.imagify init.imagify",{imagifyOptionsBulk:this},this.toggleButton).trigger("init.imagify"),this.$button.on("click.imagify",{imagifyOptionsBulk:this},this.maybeLaunchAllProcesses),c(b).on("imagifybeat-send",{imagifyOptionsBulk:this},this.addQueueImagifybeat).on("imagifybeat-tick",{imagifyOptionsBulk:this},this.processQueueImagifybeat).on("imagifybeat-send",this.addRequirementsImagifybeat).on("imagifybeat-tick",{imagifyOptionsBulk:this},this.processRequirementsImagifybeat)},toggleButton:function(a){this.checked?a.data.imagifyOptionsBulk.$button.removeAttr("disabled"):a.data.imagifyOptionsBulk.$button.attr("disabled","disabled")},maybeLaunchAllProcesses:function(b){b.data.imagifyOptionsBulk&&!b.data.imagifyOptionsBulk.working&&(b.data.imagifyOptionsBulk.hasBlockingError(!0)||(b.data.imagifyOptionsBulk.fetchQueue=imagifyOptions.bulk.contexts,b.data.imagifyOptionsBulk.queue=[],b.data.imagifyOptionsBulk.processingQueue=[],b.data.imagifyOptionsBulk.fetchError=!1,b.data.imagifyOptionsBulk.error=!1,b.data.imagifyOptionsBulk.working=!0,b.data.imagifyOptionsBulk.processIsStopped=!1,b.data.imagifyOptionsBulk.processedMedia=0,b.data.imagifyOptionsBulk.totalMedia=0,b.data.imagifyOptionsBulk.$button.attr("disabled","disabled").find(".dashicons").addClass("rotate"),c(a).on("beforeunload",b.data.imagifyOptionsBulk.getConfirmMessage),a.imagify.beat.interval(15),a.imagify.beat.disableSuspend(),b.data.imagifyOptionsBulk.fetchIDs()))},getConfirmMessage:function(){return imagifyOptions.bulk.labels.processing},addQueueImagifybeat:function(a,b){a.data.imagifyOptionsBulk&&a.data.imagifyOptionsBulk.processingQueue.length&&(b[imagifyOptions.bulk.imagifybeatIDs.queue]=a.data.imagifyOptionsBulk.processingQueue)},processQueueImagifybeat:function(a,b){a.data.imagifyOptionsBulk&&void 0!==b[imagifyOptions.bulk.imagifybeatIDs.queue]&&c.each(b[imagifyOptions.bulk.imagifybeatIDs.queue],function(b,c){a.data.imagifyOptionsBulk.mediaProcessed(c)})},addRequirementsImagifybeat:function(a,b){b[imagifyOptions.bulk.imagifybeatIDs.requirements]=1},processRequirementsImagifybeat:function(a,b){a.data.imagifyOptionsBulk&&void 0===b[imagifyOptions.bulk.imagifybeatIDs.requirements]||(b=b[imagifyOptions.bulk.imagifybeatIDs.requirements],imagifyOptions.bulk.curlMissing=b.curl_missing,imagifyOptions.bulk.editorMissing=b.editor_missing,imagifyOptions.bulk.extHttpBlocked=b.external_http_blocked,imagifyOptions.bulk.apiDown=b.api_down,imagifyOptions.bulk.keyIsValid=b.key_is_valid,imagifyOptions.bulk.isOverQuota=b.is_over_quota)},fetchIDs:function(){var a,b;if(!this.processIsStopped){if(!this.fetchQueue.length)return this.queue.length?(this.$progressBar.removeAttr("style"),this.$progressText.text("0"+(this.totalMedia?"/"+this.totalMedia:"")),this.$progressWrap.slideDown().attr("aria-hidden","false"),void this.processQueue()):(this.fetchError||(this.fetchError="no-images"),this.stopProcess(this.fetchError),void(this.fetchError=!1));a=this,b=this.fetchQueue.shift(),c.get(this.getAjaxUrl("getMediaIds",b)).done(function(d){var e;if(!a.processIsStopped)return e=d.data&&d.data.message?d.data.message:imagifyOptions.bulk.ajaxErrorText,d.success&&c.isArray(d.data)?void(d.data.length&&(a.totalMedia+=d.data.length,a.queue.push({context:b,optimizeURL:a.getAjaxUrl("bulkProcess",b),mediaIDs:d.data}))):void(a.fetchError||(a.fetchError=e))}).fail(function(){a.fetchError||(a.fetchError="get-unoptimized-images")}).always(function(){a.fetchIDs()})}},processQueue:function(){var a=this;this.processIsStopped||(this.queue.length||this.processingQueue.length)&&c.each(this.queue,function(b,d){if(a.processingQueue.length>=imagifyOptions.bulk.bufferSize)return!1;c.each(d.mediaIDs,function(){if(a.processMedia({context:d.context,mediaID:d.mediaIDs.shift(),optimizeURL:d.optimizeURL}),d.mediaIDs.length||a.queue.shift(),a.processingQueue.length>=imagifyOptions.bulk.bufferSize)return!1})})},processMedia:function(a){var b=this,d={context:a.context,mediaID:a.mediaID};this.processingQueue.push({context:a.context,mediaID:a.mediaID}),c.post({url:a.optimizeURL,data:{media_id:a.mediaID,context:a.context},dataType:"json"}).done(function(a){a.success||b.mediaProcessed(d)}).fail(function(){b.mediaProcessed(d)})},mediaProcessed:function(a){var b=this;this.processIsStopped||(c.each(this.processingQueue,function(c,d){if(a.context===d.context&&a.mediaID===d.mediaID)return b.processingQueue.splice(c,1),!1}),++this.processedMedia,a.progress=Math.floor(this.processedMedia/this.totalMedia*100),this.$progressBar.css("width",a.progress+"%"),this.$progressText.text(this.processedMedia+"/"+this.totalMedia),this.queue.length||this.processingQueue.length?this.processQueue():this.totalMedia===this.processedMedia&&this.queueEmpty())},queueEmpty:function(){var b={};!1!==this.error&&(b="invalid-api-key"===this.error?{title:imagifyOptions.bulk.labels.invalidAPIKeyTitle,type:"info"}:"over-quota"===this.error?{title:imagifyOptions.bulk.labels.overQuotaTitle,html:c("#tmpl-imagify-overquota-alert").html(),type:"info",customClass:"imagify-swal-has-subtitle imagify-swal-error-header",showConfirmButton:!1}:"get-unoptimized-images"===this.error||"consumed-all-data"===this.error?{title:imagifyOptions.bulk.labels.getUnoptimizedImagesErrorTitle,html:imagifyOptions.bulk.labels.getUnoptimizedImagesErrorText,type:"info"}:"no-images"===this.error?{title:imagifyOptions.bulk.labels.nothingToDoTitle,html:imagifyOptions.bulk.labels.nothingToDoText,type:"info"}:{title:imagifyOptions.bulk.labels.error,html:this.error,type:"info"},this.displayError(b),this.error=!1),this.fetchQueue=[],this.queue=[],this.processingQueue=[],this.fetchError=!1,this.working=!1,this.processIsStopped=!1,this.processedMedia=0,this.totalMedia=0,a.imagify.beat.resetInterval(),a.imagify.beat.enableSuspend(),c(a).off("beforeunload",this.getConfirmMessage),this.$progressWrap.slideUp().attr("aria-hidden","true"),this.$progressBar.removeAttr("style"),this.$progressText.text("0"),this.$button.removeAttr("disabled").find(".dashicons").removeClass("rotate")},hasBlockingError:function(a){return a=void 0!==a&&a,imagifyOptions.bulk.curlMissing?(a&&this.displayError({html:imagifyOptions.bulk.labels.curlMissing}),!0):imagifyOptions.bulk.editorMissing?(a&&this.displayError({html:imagifyOptions.bulk.labels.editorMissing}),!0):imagifyOptions.bulk.extHttpBlocked?(a&&this.displayError({html:imagifyOptions.bulk.labels.extHttpBlocked}),!0):imagifyOptions.bulk.apiDown?(a&&this.displayError({html:imagifyOptions.bulk.labels.apiDown}),!0):imagifyOptions.bulk.keyIsValid?!!imagifyOptions.bulk.isOverQuota&&(a&&this.displayError({title:imagifyOptions.bulk.labels.overQuotaTitle,html:c("#tmpl-imagify-overquota-alert").html(),type:"info",customClass:"imagify-swal-has-subtitle imagify-swal-error-header",showConfirmButton:!1}),!0):(a&&this.displayError({title:imagifyOptions.bulk.labels.invalidAPIKeyTitle,type:"info"}),!0)},displayError:function(a,b,d){var e={title:"",html:"",type:"error",customClass:"",width:620,padding:0,showCloseButton:!0,showConfirmButton:!0};c.isPlainObject(a)?d=c.extend({},e,a):(d=d||{},d=c.extend({},e,{title:a||"",html:b||""},d)),d.title=d.title||imagifyOptions.bulk.labels.error,d.customClass+=" imagify-sweet-alert",swal(d).catch(swal.noop)},getAjaxUrl:function(b,c){var d;return d=ajaxurl+a.imagify.concat+"_wpnonce="+imagifyOptions.bulk.ajaxNonce,d+="&action="+imagifyOptions.bulk.ajaxActions[b],d+="&context="+c,d+="&imagify_action=generate_webp"},stopProcess:function(a){this.processIsStopped=!0,this.error=a,this.queueEmpty()}},a.imagify.optionsBulk.init())}(window,document,jQuery),function(a,b,c,d){var e=c.propHooks.checked;c.propHooks.checked={set:function(a,b,d){var f;return f=void 0===e?a[d]=b:e(a,b,d),c(a).trigger("change.imagify"),f}},c(".imagify-select-all").on("click.imagify",function(){var a=c(this),b=a.data("action"),d=a.closest(".imagify-select-all-buttons"),e=d.prev(".imagify-check-group"),f="imagify-is-inactive";if(a.hasClass(f))return!1;d.find(".imagify-select-all").removeClass(f).attr("aria-disabled","false"),a.addClass(f).attr("aria-disabled","true"),e.find(".imagify-row-check").prop("checked",function(){return!c(this).is(":hidden,:disabled")&&"select"===b})}),c(".imagify-check-group .imagify-row-check").on("change.imagify",function(){var a=c(this).closest(".imagify-check-group"),b=a.find(".imagify-row-check"),d=b.filter(":visible:enabled").length,e=b.filter(":visible:enabled:checked").length,f=a.next(".imagify-select-all-buttons"),g="imagify-is-inactive";0===e&&f.find('[data-action="unselect"]').addClass(g).attr("aria-disabled","true"),e===d&&f.find('[data-action="select"]').addClass(g).attr("aria-disabled","true"),e!==d&&e>0&&f.find(".imagify-select-all").removeClass(g).attr("aria-disabled","false")})}(window,document,jQuery); \ No newline at end of file diff --git a/classes/Imagifybeat/Actions.php b/classes/Imagifybeat/Actions.php new file mode 100644 index 000000000..ac34e1f1f --- /dev/null +++ b/classes/Imagifybeat/Actions.php @@ -0,0 +1,438 @@ + 'imagify_requirements', + 'bulk_optimization_stats' => 'imagify_bulk_optimization_stats', + 'bulk_optimization_status' => 'imagify_bulk_optimization_status', + 'options_optimization_status' => 'imagify_options_optimization_status', + 'library_optimization_status' => 'imagify_library_optimization_status', + 'custom_folders_optimization_status' => 'imagify_custom_folders_optimization_status', + ]; + + /** + * Class init: launch hooks. + * + * @since 1.9.3 + * @access public + * @author Grégory Viguier + */ + public function init() { + foreach ( $this->imagifybeat_ids as $action => $imagifybeat_id ) { + add_filter( 'imagifybeat_received', [ $this, 'add_' . $action . '_to_response' ], 10, 2 ); + } + } + + + /** ----------------------------------------------------------------------------------------- */ + /** IMAGIFYBEAT CALLBACKS =================================================================== */ + /** ----------------------------------------------------------------------------------------- */ + + /** + * Add requirements to Imagifybeat data. + * + * @since 1.9.3 + * @access public + * @author Grégory Viguier + * + * @param array $response The Imagifybeat response. + * @param array $data The $_POST data sent. + * @return array + */ + public function add_requirements_to_response( $response, $data ) { + $imagifybeat_id = $this->get_imagifybeat_id_for_callback( __FUNCTION__ ); + + if ( ! $imagifybeat_id || empty( $data[ $imagifybeat_id ] ) ) { + return $response; + } + + $is_blocked = \Imagify_Requirements::is_imagify_blocked(); + $is_api_up = \Imagify_Requirements::is_api_up(); + $is_key_valid = \Imagify_Requirements::is_api_key_valid(); + $is_over_quota = \Imagify_Requirements::is_over_quota(); + + $response[ $imagifybeat_id ] = [ + 'curl_missing' => ! \Imagify_Requirements::supports_curl(), + 'editor_missing' => ! \Imagify_Requirements::supports_image_editor(), + 'external_http_blocked' => $is_blocked, + 'api_down' => $is_blocked || ! $is_api_up, + 'key_is_valid' => ! $is_blocked && $is_api_up && $is_key_valid, + 'is_over_quota' => ! $is_blocked && $is_api_up && $is_key_valid && $is_over_quota, + ]; + + return $response; + } + + /** + * Add bulk stats to Imagifybeat data. + * + * @since 1.9.3 + * @access public + * @author Grégory Viguier + * + * @param array $response The Imagifybeat response. + * @param array $data The $_POST data sent. + * @return array + */ + public function add_bulk_optimization_stats_to_response( $response, $data ) { + $imagifybeat_id = $this->get_imagifybeat_id_for_callback( __FUNCTION__ ); + + if ( ! $imagifybeat_id || empty( $data[ $imagifybeat_id ] ) ) { + return $response; + } + + $folder_types = array_flip( array_filter( $data[ $imagifybeat_id ] ) ); + + $response[ $imagifybeat_id ] = imagify_get_bulk_stats( + $folder_types, + [ + 'fullset' => true, + ] + ); + + return $response; + } + + /** + * Look for media where status has changed, compared to what Imagifybeat sends. + * This is used in the bulk optimization page. + * + * @since 1.9.3 + * @access public + * @author Grégory Viguier + * + * @param array $response The Imagifybeat response. + * @param array $data The $_POST data sent. + * @return array + */ + public function add_bulk_optimization_status_to_response( $response, $data ) { + $imagifybeat_id = $this->get_imagifybeat_id_for_callback( __FUNCTION__ ); + + if ( ! $imagifybeat_id || empty( $data[ $imagifybeat_id ] ) || ! is_array( $data[ $imagifybeat_id ] ) ) { + return $response; + } + + $statuses = []; + + foreach ( $data[ $imagifybeat_id ] as $item ) { + if ( empty( $statuses[ $item['context'] ] ) ) { + $statuses[ $item['context'] ] = []; + } + + $statuses[ $item['context'] ][ '_' . $item['mediaID'] ] = 1; + } + + $results = $this->get_modified_optimization_statuses( $statuses ); + + if ( ! $results ) { + return $response; + } + + $response[ $imagifybeat_id ] = []; + + // Sanitize received data and grab some other info. + foreach ( $results as $context_id => $media_atts ) { + $process = imagify_get_optimization_process( $media_atts['media_id'], $media_atts['context'] ); + $optim_data = $process->get_data(); + + if ( $optim_data->is_optimized() ) { + // Successfully optimized. + $full_size_data = $optim_data->get_size_data(); + $response[ $imagifybeat_id ][] = [ + 'mediaID' => $media_atts['media_id'], + 'context' => $media_atts['context'], + 'success' => true, + 'status' => 'optimized', + // Raw data. + 'originalOverallSize' => $full_size_data['original_size'], + 'newOverallSize' => $full_size_data['optimized_size'], + 'overallSaving' => $full_size_data['original_size'] - $full_size_data['optimized_size'], + 'thumbnailsCount' => $optim_data->get_optimized_sizes_count(), + // Human readable data. + 'originalSizeHuman' => imagify_size_format( $full_size_data['original_size'], 2 ), + 'newSizeHuman' => imagify_size_format( $full_size_data['optimized_size'], 2 ), + 'overallSavingHuman' => imagify_size_format( $full_size_data['original_size'] - $full_size_data['optimized_size'], 2 ), + 'originalOverallSizeHuman' => imagify_size_format( $full_size_data['original_size'], 2 ), + 'percentHuman' => $full_size_data['percent'] . '%', + ]; + } elseif ( $optim_data->is_already_optimized() ) { + // Already optimized. + $response[ $imagifybeat_id ][] = [ + 'mediaID' => $media_atts['media_id'], + 'context' => $media_atts['context'], + 'success' => true, + 'status' => 'already-optimized', + ]; + } else { + // Error. + $full_size_data = $optim_data->get_size_data(); + $message = ! empty( $full_size_data['error'] ) ? $full_size_data['error'] : ''; + $status = 'error'; + + if ( 'You\'ve consumed all your data. You have to upgrade your account to continue' === $message ) { + $status = 'over-quota'; + } + + $response[ $imagifybeat_id ][] = [ + 'mediaID' => $media_atts['media_id'], + 'context' => $media_atts['context'], + 'success' => false, + 'status' => $status, + 'error' => imagify_translate_api_message( $message ), + ]; + } + } + + return $response; + } + + /** + * Look for media where status has changed, compared to what Imagifybeat sends. + * This is used in the settings page. + * + * @since 1.9 + * @author Grégory Viguier + * + * @param array $response The Imagifybeat response. + * @param array $data The $_POST data sent. + * @return array + */ + public function add_options_optimization_status_to_response( $response, $data ) { + $imagifybeat_id = $this->get_imagifybeat_id_for_callback( __FUNCTION__ ); + + if ( ! $imagifybeat_id || empty( $data[ $imagifybeat_id ] ) || ! is_array( $data[ $imagifybeat_id ] ) ) { + return $response; + } + + $statuses = []; + + foreach ( $data[ $imagifybeat_id ] as $item ) { + if ( empty( $statuses[ $item['context'] ] ) ) { + $statuses[ $item['context'] ] = []; + } + + $statuses[ $item['context'] ][ '_' . $item['mediaID'] ] = 1; + } + + $results = $this->get_modified_optimization_statuses( $statuses ); + + if ( ! $results ) { + return $response; + } + + $response[ $imagifybeat_id ] = []; + + foreach ( $results as $result ) { + $response[ $imagifybeat_id ][] = [ + 'mediaID' => $result['media_id'], + 'context' => $result['context'], + ]; + } + + return $response; + } + + /** + * Look for media where status has changed, compared to what Imagifybeat sends. + * This is used in the WP Media Library. + * + * @since 1.9.3 + * @access public + * @author Grégory Viguier + * + * @param array $response The Imagifybeat response. + * @param array $data The $_POST data sent. + * @return array + */ + public function add_library_optimization_status_to_response( $response, $data ) { + $imagifybeat_id = $this->get_imagifybeat_id_for_callback( __FUNCTION__ ); + + if ( ! $imagifybeat_id || empty( $data[ $imagifybeat_id ] ) || ! is_array( $data[ $imagifybeat_id ] ) ) { + return $response; + } + + $response[ $imagifybeat_id ] = $this->get_modified_optimization_statuses( $data[ $imagifybeat_id ] ); + + if ( ! $response[ $imagifybeat_id ] ) { + return $response; + } + + // Sanitize received data and grab some other info. + foreach ( $response[ $imagifybeat_id ] as $context_id => $media_atts ) { + $process = imagify_get_optimization_process( $media_atts['media_id'], $media_atts['context'] ); + + $response[ $imagifybeat_id ][ $context_id ] = get_imagify_media_column_content( $process, false ); + } + + return $response; + } + + /** + * Look for media where status has changed, compared to what Imagifybeat sends. + * This is used in the custom folders list (the "Other Media" page). + * + * @since 1.9.3 + * @access public + * @author Grégory Viguier + * + * @param array $response The Imagifybeat response. + * @param array $data The $_POST data sent. + * @return array + */ + public function add_custom_folders_optimization_status_to_response( $response, $data ) { + $imagifybeat_id = $this->get_imagifybeat_id_for_callback( __FUNCTION__ ); + + if ( ! $imagifybeat_id || empty( $data[ $imagifybeat_id ] ) || ! is_array( $data[ $imagifybeat_id ] ) ) { + return $response; + } + + $response[ $imagifybeat_id ] = $this->get_modified_optimization_statuses( $data[ $imagifybeat_id ] ); + + if ( ! $response[ $imagifybeat_id ] ) { + return $response; + } + + $admin_ajax_post = \Imagify_Admin_Ajax_Post::get_instance(); + $list_table = new \Imagify_Files_List_Table( [ + 'screen' => 'imagify-files', + ] ); + + // Sanitize received data and grab some other info. + foreach ( $response[ $imagifybeat_id ] as $context_id => $media_atts ) { + $process = imagify_get_optimization_process( $media_atts['media_id'], $media_atts['context'] ); + + $response[ $imagifybeat_id ][ $context_id ] = $admin_ajax_post->get_media_columns( $process, $list_table ); + } + + return $response; + } + + + /** ----------------------------------------------------------------------------------------- */ + /** TOOLS =================================================================================== */ + /** ----------------------------------------------------------------------------------------- */ + + /** + * Look for media where status has changed, compared to what Imagifybeat sends. + * + * @since 1.9.3 + * @access public + * @author Grégory Viguier + * + * @param array $data The data received. + * @return array + */ + public function get_modified_optimization_statuses( $data ) { + if ( ! $data ) { + return []; + } + + $output = []; + + // Sanitize received data and grab some other info. + foreach ( $data as $context => $media_statuses ) { + if ( ! $context || ! $media_statuses || ! is_array( $media_statuses ) ) { + continue; + } + + // Sanitize the IDs: IDs come as strings, prefixed with an undescore character (to prevent JavaScript from screwing everything). + $media_ids = array_keys( $media_statuses ); + $media_ids = array_map( function( $media_id ) { + return (int) substr( $media_id, 1 ); + }, $media_ids ); + $media_ids = array_filter( $media_ids ); + + if ( ! $media_ids ) { + continue; + } + + // Sanitize the context. + $context_instance = imagify_get_context( $context ); + $context = $context_instance->get_name(); + $process_class_name = imagify_get_optimization_process_class_name( $context ); + $transient_name = sprintf( $process_class_name::LOCK_NAME, $context, '%' ); + $is_network_wide = $context_instance->is_network_wide(); + + \Imagify_DB::cache_process_locks( $context, $media_ids ); + + // Now that everything is cached for this context, we can get the transients without hitting the DB. + foreach ( $media_ids as $id ) { + $is_locked = (bool) $media_statuses[ '_' . $id ]; + $option_name = str_replace( '%', $id, $transient_name ); + + if ( $is_network_wide ) { + $in_db = (bool) get_site_transient( $option_name ); + } else { + $in_db = (bool) get_transient( $option_name ); + } + + if ( $is_locked === $in_db ) { + continue; + } + + $output[ $context . '_' . $id ] = [ + 'media_id' => $id, + 'context' => $context, + ]; + } + } + + return $output; + } + + /** + * Get an Imagifybeat ID, given an action. + * + * @since 1.9.3 + * @access public + * @author Grégory Viguier + * + * @param string $action An action corresponding to the ID we want. + * @return string|bool The ID. False on failure. + */ + public function get_imagifybeat_id( $action ) { + if ( ! empty( $this->imagifybeat_ids[ $action ] ) ) { + return $this->imagifybeat_ids[ $action ]; + } + + return false; + } + + /** + * Get an Imagifybeat ID, given a callback name. + * + * @since 1.9.3 + * @access private + * @author Grégory Viguier + * + * @param string $callback A method’s name. + * @return string|bool The ID. False on failure. + */ + private function get_imagifybeat_id_for_callback( $callback ) { + if ( preg_match( '@^add_(?.+)_to_response$@', $callback, $matches ) ) { + return $this->get_imagifybeat_id( $matches['id'] ); + } + + return false; + } +} diff --git a/classes/Imagifybeat/Core.php b/classes/Imagifybeat/Core.php new file mode 100644 index 000000000..c847afe80 --- /dev/null +++ b/classes/Imagifybeat/Core.php @@ -0,0 +1,172 @@ +id and the JS global 'pagenow'. + if ( ! empty( $_POST['screen_id'] ) ) { + $screen_id = sanitize_key( $_POST['screen_id'] ); + } else { + $screen_id = 'front'; + } + + if ( ! empty( $_POST['data'] ) ) { + $data = wp_unslash( (array) $_POST['data'] ); + } + + if ( 1 !== $nonce_state ) { + /** + * Filters the nonces to send. + * + * @since 1.9.3 + * @author Grégory Viguier + * + * @param array $response The Imagifybeat response. + * @param array $data The $_POST data sent. + * @param string $screen_id The screen id. + */ + $response = apply_filters( 'imagifybeat_refresh_nonces', $response, $data, $screen_id ); + + if ( false === $nonce_state ) { + // User is logged in but nonces have expired. + $response['nonces_expired'] = true; + wp_send_json( $response ); + } + } + + if ( ! empty( $data ) ) { + /** + * Filters the Imagifybeat response received. + * + * @since 1.9.3 + * @author Grégory Viguier + * + * @param array $response The Imagifybeat response. + * @param array $data The $_POST data sent. + * @param string $screen_id The screen id. + */ + $response = apply_filters( 'imagifybeat_received', $response, $data, $screen_id ); + } + + /** + * Filters the Imagifybeat response sent. + * + * @since 1.9.3 + * @author Grégory Viguier + * + * @param array $response The Imagifybeat response. + * @param string $screen_id The screen id. + */ + $response = apply_filters( 'imagifybeat_send', $response, $screen_id ); + + /** + * Fires when Imagifybeat ticks in logged-in environments. + * + * Allows the transport to be easily replaced with long-polling. + * + * @since 1.9.3 + * @author Grégory Viguier + * + * @param array $response The Imagifybeat response. + * @param string $screen_id The screen id. + */ + do_action( 'imagifybeat_tick', $response, $screen_id ); + + // Send the current time according to the server. + $response['server_time'] = time(); + + wp_send_json( $response ); + } + + /** + * Add the latest Imagifybeat nonce to the Imagifybeat response. + * + * @since 1.9.3 + * @access public + * @author Grégory Viguier + * + * @param array $response The Imagifybeat response. + * @return array The Imagifybeat response. + */ + public function refresh_imagifybeat_nonces( $response ) { + // Refresh the Imagifybeat nonce. + $response['imagifybeat_nonce'] = wp_create_nonce( 'imagifybeat-nonce' ); + return $response; + } + + /** + * Get Imagifybeat settings. + * + * @since 1.9.3 + * @access public + * @author Grégory Viguier + * + * @return array + */ + public function get_settings() { + global $pagenow; + + $settings = []; + + if ( ! is_admin() ) { + $settings['ajaxurl'] = admin_url( 'admin-ajax.php', 'relative' ); + } + + if ( is_user_logged_in() ) { + $settings['nonce'] = wp_create_nonce( 'imagifybeat-nonce' ); + } + + if ( 'customize.php' === $pagenow ) { + $settings['screenId'] = 'customize'; + } + + /** + * Filters the Imagifybeat settings. + * + * @since 1.9.3 + * @author Grégory Viguier + * + * @param array $settings Imagifybeat settings array. + */ + return (array) apply_filters( 'imagifybeat_settings', $settings ); + } +} diff --git a/inc/3rd-party/nextgen-gallery/inc/admin/heartbeat.php b/inc/3rd-party/nextgen-gallery/inc/admin/heartbeat.php deleted file mode 100644 index f852c43cb..000000000 --- a/inc/3rd-party/nextgen-gallery/inc/admin/heartbeat.php +++ /dev/null @@ -1,13 +0,0 @@ - true, - ) ); - - return $response; -} - -add_filter( 'heartbeat_received', 'imagify_heartbeat_requirements_received', 10, 2 ); -/** - * Prepare the data that goes back with the Heartbeat API. - * - * @since 1.7.1 - * @author Grégory Viguier - * - * @param array $response The Heartbeat response. - * @param array $data The $_POST data sent. - * @return array - */ -function imagify_heartbeat_requirements_received( $response, $data ) { - $heartbeat_id = 'imagify_bulk_requirements'; - - if ( empty( $data[ $heartbeat_id ] ) ) { - return $response; - } - - $response[ $heartbeat_id ] = array( - 'curl_missing' => ! Imagify_Requirements::supports_curl(), - 'editor_missing' => ! Imagify_Requirements::supports_image_editor(), - 'external_http_blocked' => Imagify_Requirements::is_imagify_blocked(), - 'api_down' => Imagify_Requirements::is_imagify_blocked() || ! Imagify_Requirements::is_api_up(), - 'key_is_valid' => ! Imagify_Requirements::is_imagify_blocked() && Imagify_Requirements::is_api_up() && Imagify_Requirements::is_api_key_valid(), - 'is_over_quota' => ! Imagify_Requirements::is_imagify_blocked() && Imagify_Requirements::is_api_up() && Imagify_Requirements::is_api_key_valid() && Imagify_Requirements::is_over_quota(), - ); - - return $response; -} - -add_filter( 'heartbeat_received', 'imagify_heartbeat_bulk_optimization_status_received', 10, 2 ); -/** - * Look for media where status has changed, compared to what Heartbeat sends. - * This is used in the bulk optimization page. - * - * @since 1.9 - * @author Grégory Viguier - * - * @param array $response The Heartbeat response. - * @param array $data The $_POST data sent. - * @return array - */ -function imagify_heartbeat_bulk_optimization_status_received( $response, $data ) { - $heartbeat_id = 'imagify_bulk_queue'; - - if ( empty( $data[ $heartbeat_id ] ) || ! is_array( $data[ $heartbeat_id ] ) ) { - return $response; - } - - $statuses = []; - - foreach ( $data[ $heartbeat_id ] as $item ) { - if ( empty( $statuses[ $item['context'] ] ) ) { - $statuses[ $item['context'] ] = []; - } - - $statuses[ $item['context'] ][ '_' . $item['mediaID'] ] = 1; - } - - $results = imagify_get_modified_optimization_statusses( $statuses ); - - if ( ! $results ) { - return $response; - } - - $response[ $heartbeat_id ] = []; - - // Sanitize received data and grab some other info. - foreach ( $results as $context_id => $media_atts ) { - $process = imagify_get_optimization_process( $media_atts['media_id'], $media_atts['context'] ); - $optim_data = $process->get_data(); - - if ( $optim_data->is_optimized() ) { - // Successfully optimized. - $full_size_data = $optim_data->get_size_data(); - $response[ $heartbeat_id ][] = [ - 'mediaID' => $media_atts['media_id'], - 'context' => $media_atts['context'], - 'success' => true, - 'status' => 'optimized', - // Raw data. - 'originalOverallSize' => $full_size_data['original_size'], - 'newOverallSize' => $full_size_data['optimized_size'], - 'overallSaving' => $full_size_data['original_size'] - $full_size_data['optimized_size'], - 'thumbnailsCount' => $optim_data->get_optimized_sizes_count(), - // Human readable data. - 'originalSizeHuman' => imagify_size_format( $full_size_data['original_size'], 2 ), - 'newSizeHuman' => imagify_size_format( $full_size_data['optimized_size'], 2 ), - 'overallSavingHuman' => imagify_size_format( $full_size_data['original_size'] - $full_size_data['optimized_size'], 2 ), - 'originalOverallSizeHuman' => imagify_size_format( $full_size_data['original_size'], 2 ), - 'percentHuman' => $full_size_data['percent'] . '%', - ]; - } elseif ( $optim_data->is_already_optimized() ) { - // Already optimized. - $response[ $heartbeat_id ][] = [ - 'mediaID' => $media_atts['media_id'], - 'context' => $media_atts['context'], - 'success' => true, - 'status' => 'already-optimized', - ]; - } else { - // Error. - $full_size_data = $optim_data->get_size_data(); - $message = ! empty( $full_size_data['error'] ) ? $full_size_data['error'] : ''; - $status = 'error'; - - if ( 'You\'ve consumed all your data. You have to upgrade your account to continue' === $message ) { - $status = 'over-quota'; - } - - $response[ $heartbeat_id ][] = [ - 'mediaID' => $media_atts['media_id'], - 'context' => $media_atts['context'], - 'success' => false, - 'status' => $status, - 'error' => imagify_translate_api_message( $message ), - ]; - } - } - - return $response; -} - -add_filter( 'heartbeat_received', 'imagify_heartbeat_options_bulk_optimization_status_received', 10, 2 ); -/** - * Look for media where status has changed, compared to what Heartbeat sends. - * This is used in the settings page. - * - * @since 1.9 - * @author Grégory Viguier - * - * @param array $response The Heartbeat response. - * @param array $data The $_POST data sent. - * @return array - */ -function imagify_heartbeat_options_bulk_optimization_status_received( $response, $data ) { - $heartbeat_id = 'imagify_options_bulk_queue'; - - if ( empty( $data[ $heartbeat_id ] ) || ! is_array( $data[ $heartbeat_id ] ) ) { - return $response; - } - - $statuses = []; - - foreach ( $data[ $heartbeat_id ] as $item ) { - if ( empty( $statuses[ $item['context'] ] ) ) { - $statuses[ $item['context'] ] = []; - } - - $statuses[ $item['context'] ][ '_' . $item['mediaID'] ] = 1; - } - - $results = imagify_get_modified_optimization_statusses( $statuses ); - - if ( ! $results ) { - return $response; - } - - $response[ $heartbeat_id ] = []; - - foreach ( $results as $result ) { - $response[ $heartbeat_id ][] = [ - 'mediaID' => $result['media_id'], - 'context' => $result['context'], - ]; - } - - return $response; -} - -add_filter( 'heartbeat_received', 'imagify_heartbeat_optimization_status_received', 10, 2 ); -/** - * Look for media where status has changed, compared to what Heartbeat sends. - * This is used in the WP Media Library. - * - * @since 1.9 - * @author Grégory Viguier - * - * @param array $response The Heartbeat response. - * @param array $data The $_POST data sent. - * @return array - */ -function imagify_heartbeat_optimization_status_received( $response, $data ) { - $heartbeat_id = get_imagify_localize_script_translations( 'media-modal' ); - $heartbeat_id = $heartbeat_id['heartbeatId']; - - if ( empty( $data[ $heartbeat_id ] ) || ! is_array( $data[ $heartbeat_id ] ) ) { - return $response; - } - - $response[ $heartbeat_id ] = imagify_get_modified_optimization_statusses( $data[ $heartbeat_id ] ); - - if ( ! $response[ $heartbeat_id ] ) { - return $response; - } - - // Sanitize received data and grab some other info. - foreach ( $response[ $heartbeat_id ] as $context_id => $media_atts ) { - $process = imagify_get_optimization_process( $media_atts['media_id'], $media_atts['context'] ); - - $response[ $heartbeat_id ][ $context_id ] = get_imagify_media_column_content( $process, false ); - } - - return $response; -} - -add_filter( 'heartbeat_received', 'imagify_heartbeat_custom_folders_optimization_status_received', 10, 2 ); -/** - * Look for media where status has changed, compared to what Heartbeat sends. - * This is used in the custom folders list (the "Other Media" page). - * - * @since 1.9 - * @author Grégory Viguier - * - * @param array $response The Heartbeat response. - * @param array $data The $_POST data sent. - * @return array - */ -function imagify_heartbeat_custom_folders_optimization_status_received( $response, $data ) { - $heartbeat_id = get_imagify_localize_script_translations( 'files-list' ); - $heartbeat_id = $heartbeat_id['heartbeatId']; - - if ( empty( $data[ $heartbeat_id ] ) || ! is_array( $data[ $heartbeat_id ] ) ) { - return $response; - } - - $response[ $heartbeat_id ] = imagify_get_modified_optimization_statusses( $data[ $heartbeat_id ] ); - - if ( ! $response[ $heartbeat_id ] ) { - return $response; - } - - $admin_ajax_post = Imagify_Admin_Ajax_Post::get_instance(); - $list_table = new Imagify_Files_List_Table( [ - 'screen' => 'imagify-files', - ] ); - - // Sanitize received data and grab some other info. - foreach ( $response[ $heartbeat_id ] as $context_id => $media_atts ) { - $process = imagify_get_optimization_process( $media_atts['media_id'], $media_atts['context'] ); - - $response[ $heartbeat_id ][ $context_id ] = $admin_ajax_post->get_media_columns( $process, $list_table ); - } - - return $response; -} -/** - * Look for media where status has changed, compared to what Heartbeat sends. - * - * @since 1.9 - * @author Grégory Viguier - * - * @param array $data The data received. - * @return array - */ -function imagify_get_modified_optimization_statusses( $data ) { - if ( ! $data ) { - return []; - } - - $output = []; - - // Sanitize received data and grab some other info. - foreach ( $data as $context => $media_statuses ) { - if ( ! $context || ! $media_statuses || ! is_array( $media_statuses ) ) { - continue; - } - - // Sanitize the IDs: IDs come as strings, prefixed with an undescore character (to prevent JavaScript from screwing everything). - $media_ids = array_keys( $media_statuses ); - $media_ids = array_map( function( $media_id ) { - return (int) substr( $media_id, 1 ); - }, $media_ids ); - $media_ids = array_filter( $media_ids ); - - if ( ! $media_ids ) { - continue; - } - - // Sanitize the context. - $context_instance = imagify_get_context( $context ); - $context = $context_instance->get_name(); - $process_class_name = imagify_get_optimization_process_class_name( $context ); - $transient_name = sprintf( $process_class_name::LOCK_NAME, $context, '%' ); - $is_network_wide = $context_instance->is_network_wide(); - - Imagify_DB::cache_process_locks( $context, $media_ids ); - - // Now that everything is cached for this context, we can get the transients without hitting the DB. - foreach ( $media_ids as $id ) { - $is_locked = (bool) $media_statuses[ '_' . $id ]; - $option_name = str_replace( '%', $id, $transient_name ); - - if ( $is_network_wide ) { - $in_db = (bool) get_site_transient( $option_name ); - } else { - $in_db = (bool) get_transient( $option_name ); - } - - if ( $is_locked === $in_db ) { - continue; - } - - $output[ $context . '_' . $id ] = [ - 'media_id' => $id, - 'context' => $context, - ]; - } - } - - return $output; -} - - -if ( Imagify_Views::get_instance()->is_bulk_page() || Imagify_Views::get_instance()->is_settings_page() ) { - add_filter( 'heartbeat_settings', '_imagify_heartbeat_settings', IMAGIFY_INT_MAX ); -} -/** - * Update the Heartbeat API settings. - * - * @since 1.4.5 - * - * @param array $settings Heartbeat API settings. - * @return array - */ -function _imagify_heartbeat_settings( $settings ) { - $settings['interval'] = 30; - return $settings; -} diff --git a/inc/classes/class-imagify-assets.php b/inc/classes/class-imagify-assets.php index cbf22c980..b0909d48f 100755 --- a/inc/classes/class-imagify-assets.php +++ b/inc/classes/class-imagify-assets.php @@ -206,7 +206,9 @@ public function register_styles_and_scripts() { $this->register_script( 'twentytwenty', 'jquery.twentytwenty', array( 'jquery', 'event-move', 'chart', 'admin' ) )->defer_localization( 'imagifyTTT' ); - $this->register_script( 'media-modal', 'media-modal', array( 'jquery', 'heartbeat', 'underscore', 'chart', 'admin' ) )->localize( 'imagifyModal' ); + $this->register_script( 'beat', 'beat', array( 'jquery' ) )->localize( 'imagifybeatSettings' ); + + $this->register_script( 'media-modal', 'media-modal', array( 'jquery', 'beat', 'underscore', 'chart', 'admin' ) )->localize( 'imagifyModal' ); $this->register_script( 'pricing-modal', 'pricing-modal', array( 'jquery', 'admin' ) )->defer_localization( 'imagifyPricingModal' ); @@ -214,11 +216,11 @@ public function register_styles_and_scripts() { $this->register_script( 'async', 'imagify-gulp' ); - $this->register_script( 'bulk', 'bulk', array( 'jquery', 'heartbeat', 'underscore', 'chart', 'sweetalert', 'async', 'admin' ) )->defer_localization( 'imagifyBulk' ); + $this->register_script( 'bulk', 'bulk', array( 'jquery', 'beat', 'underscore', 'chart', 'sweetalert', 'async', 'admin' ) )->defer_localization( 'imagifyBulk' ); - $this->register_script( 'options', 'options', array( 'jquery', 'heartbeat', 'sweetalert', 'underscore', 'admin' ) )->defer_localization( 'imagifyOptions' ); + $this->register_script( 'options', 'options', array( 'jquery', 'beat', 'sweetalert', 'underscore', 'admin' ) )->defer_localization( 'imagifyOptions' ); - $this->register_script( 'files-list', 'files-list', array( 'jquery', 'heartbeat', 'underscore', 'chart', 'admin' ) )->defer_localization( 'imagifyFiles' ); + $this->register_script( 'files-list', 'files-list', array( 'jquery', 'beat', 'underscore', 'chart', 'admin' ) )->defer_localization( 'imagifyFiles' ); } /** @@ -491,8 +493,6 @@ public function enqueue_script( $handles ) { $this->current_handle = $handle; $this->current_handle_type = 'js'; - $this->maybe_register_heartbeat( $handle ); - if ( ! empty( $this->scripts[ $handle ] ) ) { // If we registered it, it's one of our scripts. $handle = self::JS_PREFIX . $handle; @@ -756,63 +756,6 @@ protected function prefix_dependencies( $dependencies, $type = 'js' ) { return $depts; } - /** - * Make sure Heartbeat is registered if the given script requires it. - * Lots of people love deregister Heartbeat. - * - * @since 1.6.11 - * @author Grégory Viguier - * - * @param string $handle Name of the script. Should be unique. - */ - protected function maybe_register_heartbeat( $handle ) { - global $wp_version; - - if ( wp_script_is( 'heartbeat', 'registered' ) ) { - return; - } - - if ( ! empty( $this->scripts[ $handle ] ) ) { - // If we registered it, it's one of our scripts. - $handle = self::JS_PREFIX . $handle; - } - - $wp_scripts = wp_scripts(); - $dependencies = $wp_scripts->query( $handle ); - - if ( ! $dependencies || ! $dependencies->deps ) { - return; - } - - $dependencies = array_flip( $dependencies->deps ); - - if ( ! isset( $dependencies['heartbeat'] ) ) { - return; - } - - $suffix = SCRIPT_DEBUG ? '' : '.min'; - $depts = [ 'jquery' ]; - - if ( version_compare( $wp_version, '5.0.0' ) >= 0 ) { - $depts[] = 'wp-hooks'; - } - - wp_register_script( 'heartbeat', "/wp-includes/js/heartbeat$suffix.js", $depts, false, true ); // phpcs:ignore WordPress.WP.EnqueuedResourceParameters.NoExplicitVersion - - if ( $wp_scripts->get_data( 'heartbeat', 'data' ) ) { - return; - } - - /** This filter is documented in /wp-includes/script-loader.php */ - $data = apply_filters( 'heartbeat_settings', [] ); - - if ( empty( $data['nonce'] ) ) { - $data = wp_heartbeat_settings( $data ); - } - - wp_localize_script( 'heartbeat', 'heartbeatSettings', $data ); - } - /** * Tell if debug is on. * diff --git a/inc/classes/class-imagify-plugin.php b/inc/classes/class-imagify-plugin.php index 4a4b7c1ad..184dfe3f2 100644 --- a/inc/classes/class-imagify-plugin.php +++ b/inc/classes/class-imagify-plugin.php @@ -58,6 +58,8 @@ public function init() { Imagify_Admin_Ajax_Post::get_instance()->init(); Imagify_Settings::get_instance()->init(); Imagify_Views::get_instance()->init(); + \Imagify\Imagifybeat\Core::get_instance()->init(); + \Imagify\Imagifybeat\Actions::get_instance()->init(); } if ( ! wp_doing_ajax() ) { @@ -121,7 +123,6 @@ public function include_files() { } require_once $inc_path . 'admin/upgrader.php'; - require_once $inc_path . 'admin/heartbeat.php'; require_once $inc_path . 'admin/upload.php'; require_once $inc_path . 'admin/media.php'; require_once $inc_path . 'admin/meta-boxes.php'; diff --git a/inc/deprecated/classes/class-imagify-assets-deprecated.php b/inc/deprecated/classes/class-imagify-assets-deprecated.php index 193878303..ed1e56703 100755 --- a/inc/deprecated/classes/class-imagify-assets-deprecated.php +++ b/inc/deprecated/classes/class-imagify-assets-deprecated.php @@ -40,4 +40,65 @@ public function print_support_script() { scripts[ $handle ] ) ) { + // If we registered it, it's one of our scripts. + $handle = self::JS_PREFIX . $handle; + } + + $wp_scripts = wp_scripts(); + $dependencies = $wp_scripts->query( $handle ); + + if ( ! $dependencies || ! $dependencies->deps ) { + return; + } + + $dependencies = array_flip( $dependencies->deps ); + + if ( ! isset( $dependencies['heartbeat'] ) ) { + return; + } + + $suffix = SCRIPT_DEBUG ? '' : '.min'; + $depts = [ 'jquery' ]; + + if ( version_compare( $wp_version, '5.0.0' ) >= 0 ) { + $depts[] = 'wp-hooks'; + } + + wp_register_script( 'heartbeat', "/wp-includes/js/heartbeat$suffix.js", $depts, false, true ); // phpcs:ignore WordPress.WP.EnqueuedResourceParameters.NoExplicitVersion + + if ( $wp_scripts->get_data( 'heartbeat', 'data' ) ) { + return; + } + + /** This filter is documented in /wp-includes/script-loader.php */ + $data = apply_filters( 'heartbeat_settings', [] ); + + if ( empty( $data['nonce'] ) ) { + $data = wp_heartbeat_settings( $data ); + } + + wp_localize_script( 'heartbeat', 'heartbeatSettings', $data ); + } } diff --git a/inc/deprecated/deprecated.php b/inc/deprecated/deprecated.php index f4fe4a9e8..8f427b19f 100644 --- a/inc/deprecated/deprecated.php +++ b/inc/deprecated/deprecated.php @@ -1283,4 +1283,383 @@ function imagify_check_user_capacity( $describer = 'manage', $post_id = null ) { } } + /** + * Update the Heartbeat API settings. + * + * @since 1.4.5 + * @since 1.9.3 Deprecated. + * @deprecated + * + * @param array $settings Heartbeat API settings. + * @return array + */ + function _imagify_heartbeat_settings( $settings ) { + _deprecated_function( __FUNCTION__ . '()', '1.9.3' ); + + $settings['interval'] = 30; + return $settings; + } + + /** + * Prepare the data that goes back with the Imagifybeat API. + * + * @since 1.4.5 + * @since 1.9.3 Deprecated. + * @deprecated + * + * @param array $response The Imagifybeat response. + * @param array $data The $_POST data sent. + * @return array + */ + function _imagify_heartbeat_received( $response, $data ) { + _deprecated_function( __FUNCTION__ . '()', '1.9.3', '\\Imagify\\Imagifybeat\\Actions::get_instance()->add_bulk_optimization_stats_to_response()' ); + + $heartbeat_id = 'imagify_bulk_data'; + + if ( empty( $data[ $heartbeat_id ] ) ) { + return $response; + } + + $folder_types = array_flip( array_filter( $data[ $heartbeat_id ] ) ); + + $response[ $heartbeat_id ] = imagify_get_bulk_stats( $folder_types, array( + 'fullset' => true, + ) ); + + return $response; + } + + /** + * Prepare the data that goes back with the Imagifybeat API. + * + * @since 1.7.1 + * @since 1.9.3 Deprecated. + * @author Grégory Viguier + * @deprecated + * + * @param array $response The Imagifybeat response. + * @param array $data The $_POST data sent. + * @return array + */ + function imagify_heartbeat_requirements_received( $response, $data ) { + _deprecated_function( __FUNCTION__ . '()', '1.9.3', '\\Imagify\\Imagifybeat\\Actions::get_instance()->add_requirements_to_response()' ); + + $heartbeat_id = 'imagify_bulk_requirements'; + + if ( empty( $data[ $heartbeat_id ] ) ) { + return $response; + } + + $response[ $heartbeat_id ] = array( + 'curl_missing' => ! Imagify_Requirements::supports_curl(), + 'editor_missing' => ! Imagify_Requirements::supports_image_editor(), + 'external_http_blocked' => Imagify_Requirements::is_imagify_blocked(), + 'api_down' => Imagify_Requirements::is_imagify_blocked() || ! Imagify_Requirements::is_api_up(), + 'key_is_valid' => ! Imagify_Requirements::is_imagify_blocked() && Imagify_Requirements::is_api_up() && Imagify_Requirements::is_api_key_valid(), + 'is_over_quota' => ! Imagify_Requirements::is_imagify_blocked() && Imagify_Requirements::is_api_up() && Imagify_Requirements::is_api_key_valid() && Imagify_Requirements::is_over_quota(), + ); + + return $response; + } + + /** + * Look for media where status has changed, compared to what Imagifybeat sends. + * This is used in the bulk optimization page. + * + * @since 1.9 + * @since 1.9.3 Deprecated. + * @author Grégory Viguier + * @deprecated + * + * @param array $response The Imagifybeat response. + * @param array $data The $_POST data sent. + * @return array + */ + function imagify_heartbeat_bulk_optimization_status_received( $response, $data ) { + _deprecated_function( __FUNCTION__ . '()', '1.9.3', '\\Imagify\\Imagifybeat\\Actions::get_instance()->add_bulk_optimization_status_to_response()' ); + + $heartbeat_id = 'imagify_bulk_queue'; + + if ( empty( $data[ $heartbeat_id ] ) || ! is_array( $data[ $heartbeat_id ] ) ) { + return $response; + } + + $statuses = []; + + foreach ( $data[ $heartbeat_id ] as $item ) { + if ( empty( $statuses[ $item['context'] ] ) ) { + $statuses[ $item['context'] ] = []; + } + + $statuses[ $item['context'] ][ '_' . $item['mediaID'] ] = 1; + } + + $results = imagify_get_modified_optimization_statusses( $statuses ); + + if ( ! $results ) { + return $response; + } + + $response[ $heartbeat_id ] = []; + + // Sanitize received data and grab some other info. + foreach ( $results as $context_id => $media_atts ) { + $process = imagify_get_optimization_process( $media_atts['media_id'], $media_atts['context'] ); + $optim_data = $process->get_data(); + + if ( $optim_data->is_optimized() ) { + // Successfully optimized. + $full_size_data = $optim_data->get_size_data(); + $response[ $heartbeat_id ][] = [ + 'mediaID' => $media_atts['media_id'], + 'context' => $media_atts['context'], + 'success' => true, + 'status' => 'optimized', + // Raw data. + 'originalOverallSize' => $full_size_data['original_size'], + 'newOverallSize' => $full_size_data['optimized_size'], + 'overallSaving' => $full_size_data['original_size'] - $full_size_data['optimized_size'], + 'thumbnailsCount' => $optim_data->get_optimized_sizes_count(), + // Human readable data. + 'originalSizeHuman' => imagify_size_format( $full_size_data['original_size'], 2 ), + 'newSizeHuman' => imagify_size_format( $full_size_data['optimized_size'], 2 ), + 'overallSavingHuman' => imagify_size_format( $full_size_data['original_size'] - $full_size_data['optimized_size'], 2 ), + 'originalOverallSizeHuman' => imagify_size_format( $full_size_data['original_size'], 2 ), + 'percentHuman' => $full_size_data['percent'] . '%', + ]; + } elseif ( $optim_data->is_already_optimized() ) { + // Already optimized. + $response[ $heartbeat_id ][] = [ + 'mediaID' => $media_atts['media_id'], + 'context' => $media_atts['context'], + 'success' => true, + 'status' => 'already-optimized', + ]; + } else { + // Error. + $full_size_data = $optim_data->get_size_data(); + $message = ! empty( $full_size_data['error'] ) ? $full_size_data['error'] : ''; + $status = 'error'; + + if ( 'You\'ve consumed all your data. You have to upgrade your account to continue' === $message ) { + $status = 'over-quota'; + } + + $response[ $heartbeat_id ][] = [ + 'mediaID' => $media_atts['media_id'], + 'context' => $media_atts['context'], + 'success' => false, + 'status' => $status, + 'error' => imagify_translate_api_message( $message ), + ]; + } + } + + return $response; + } + + /** + * Look for media where status has changed, compared to what Imagifybeat sends. + * This is used in the settings page. + * + * @since 1.9 + * @since 1.9.3 Deprecated. + * @author Grégory Viguier + * @deprecated + * + * @param array $response The Imagifybeat response. + * @param array $data The $_POST data sent. + * @return array + */ + function imagify_heartbeat_options_bulk_optimization_status_received( $response, $data ) { + _deprecated_function( __FUNCTION__ . '()', '1.9.3', '\\Imagify\\Imagifybeat\\Actions::get_instance()->add_options_optimization_status_to_response()' ); + + $heartbeat_id = 'imagify_options_bulk_queue'; + + if ( empty( $data[ $heartbeat_id ] ) || ! is_array( $data[ $heartbeat_id ] ) ) { + return $response; + } + + $statuses = []; + + foreach ( $data[ $heartbeat_id ] as $item ) { + if ( empty( $statuses[ $item['context'] ] ) ) { + $statuses[ $item['context'] ] = []; + } + + $statuses[ $item['context'] ][ '_' . $item['mediaID'] ] = 1; + } + + $results = imagify_get_modified_optimization_statusses( $statuses ); + + if ( ! $results ) { + return $response; + } + + $response[ $heartbeat_id ] = []; + + foreach ( $results as $result ) { + $response[ $heartbeat_id ][] = [ + 'mediaID' => $result['media_id'], + 'context' => $result['context'], + ]; + } + + return $response; + } + + /** + * Look for media where status has changed, compared to what Imagifybeat sends. + * This is used in the WP Media Library. + * + * @since 1.9 + * @since 1.9.3 Deprecated. + * @author Grégory Viguier + * @deprecated + * + * @param array $response The Imagifybeat response. + * @param array $data The $_POST data sent. + * @return array + */ + function imagify_heartbeat_optimization_status_received( $response, $data ) { + _deprecated_function( __FUNCTION__ . '()', '1.9.3', '\\Imagify\\Imagifybeat\\Actions::get_instance()->add_library_optimization_status_to_response()' ); + + $heartbeat_id = get_imagify_localize_script_translations( 'media-modal' ); + $heartbeat_id = $heartbeat_id['heartbeatId']; + + if ( empty( $data[ $heartbeat_id ] ) || ! is_array( $data[ $heartbeat_id ] ) ) { + return $response; + } + + $response[ $heartbeat_id ] = imagify_get_modified_optimization_statusses( $data[ $heartbeat_id ] ); + + if ( ! $response[ $heartbeat_id ] ) { + return $response; + } + + // Sanitize received data and grab some other info. + foreach ( $response[ $heartbeat_id ] as $context_id => $media_atts ) { + $process = imagify_get_optimization_process( $media_atts['media_id'], $media_atts['context'] ); + + $response[ $heartbeat_id ][ $context_id ] = get_imagify_media_column_content( $process, false ); + } + + return $response; + } + + /** + * Look for media where status has changed, compared to what Imagifybeat sends. + * This is used in the custom folders list (the "Other Media" page). + * + * @since 1.9 + * @since 1.9.3 Deprecated. + * @author Grégory Viguier + * @deprecated + * + * @param array $response The Imagifybeat response. + * @param array $data The $_POST data sent. + * @return array + */ + function imagify_heartbeat_custom_folders_optimization_status_received( $response, $data ) { + _deprecated_function( __FUNCTION__ . '()', '1.9.3', '\\Imagify\\Imagifybeat\\Actions::get_instance()->add_custom_folders_optimization_status_to_response()' ); + + $heartbeat_id = get_imagify_localize_script_translations( 'files-list' ); + $heartbeat_id = $heartbeat_id['heartbeatId']; + + if ( empty( $data[ $heartbeat_id ] ) || ! is_array( $data[ $heartbeat_id ] ) ) { + return $response; + } + + $response[ $heartbeat_id ] = imagify_get_modified_optimization_statusses( $data[ $heartbeat_id ] ); + + if ( ! $response[ $heartbeat_id ] ) { + return $response; + } + + $admin_ajax_post = Imagify_Admin_Ajax_Post::get_instance(); + $list_table = new Imagify_Files_List_Table( [ + 'screen' => 'imagify-files', + ] ); + + // Sanitize received data and grab some other info. + foreach ( $response[ $heartbeat_id ] as $context_id => $media_atts ) { + $process = imagify_get_optimization_process( $media_atts['media_id'], $media_atts['context'] ); + + $response[ $heartbeat_id ][ $context_id ] = $admin_ajax_post->get_media_columns( $process, $list_table ); + } + + return $response; + } + + /** + * Look for media where status has changed, compared to what Imagifybeat sends. + * + * @since 1.9 + * @since 1.9.3 Deprecated. + * @author Grégory Viguier + * @deprecated + * + * @param array $data The data received. + * @return array + */ + function imagify_get_modified_optimization_statusses( $data ) { + _deprecated_function( __FUNCTION__ . '()', '1.9.3', '\\Imagify\\Imagifybeat\\Actions::get_instance()->get_modified_optimization_statuses()' ); + + if ( ! $data ) { + return []; + } + + $output = []; + + // Sanitize received data and grab some other info. + foreach ( $data as $context => $media_statuses ) { + if ( ! $context || ! $media_statuses || ! is_array( $media_statuses ) ) { + continue; + } + + // Sanitize the IDs: IDs come as strings, prefixed with an undescore character (to prevent JavaScript from screwing everything). + $media_ids = array_keys( $media_statuses ); + $media_ids = array_map( function( $media_id ) { + return (int) substr( $media_id, 1 ); + }, $media_ids ); + $media_ids = array_filter( $media_ids ); + + if ( ! $media_ids ) { + continue; + } + + // Sanitize the context. + $context_instance = imagify_get_context( $context ); + $context = $context_instance->get_name(); + $process_class_name = imagify_get_optimization_process_class_name( $context ); + $transient_name = sprintf( $process_class_name::LOCK_NAME, $context, '%' ); + $is_network_wide = $context_instance->is_network_wide(); + + Imagify_DB::cache_process_locks( $context, $media_ids ); + + // Now that everything is cached for this context, we can get the transients without hitting the DB. + foreach ( $media_ids as $id ) { + $is_locked = (bool) $media_statuses[ '_' . $id ]; + $option_name = str_replace( '%', $id, $transient_name ); + + if ( $is_network_wide ) { + $in_db = (bool) get_site_transient( $option_name ); + } else { + $in_db = (bool) get_transient( $option_name ); + } + + if ( $is_locked === $in_db ) { + continue; + } + + $output[ $context . '_' . $id ] = [ + 'media_id' => $id, + 'context' => $context, + ]; + } + } + + return $output; + } + endif; diff --git a/inc/functions/i18n.php b/inc/functions/i18n.php index fed968a8a..aab78b854 100755 --- a/inc/functions/i18n.php +++ b/inc/functions/i18n.php @@ -13,6 +13,8 @@ function get_imagify_localize_script_translations( $context ) { global $post_id; + $imagifybeat_actions = \Imagify\Imagifybeat\Actions::get_instance(); + switch ( $context ) { case 'admin-bar': if ( is_admin() ) { @@ -81,9 +83,9 @@ function get_imagify_localize_script_translations( $context ) { 'apiDown' => Imagify_Requirements::is_imagify_blocked() || ! Imagify_Requirements::is_api_up(), 'keyIsValid' => ! Imagify_Requirements::is_imagify_blocked() && Imagify_Requirements::is_api_up() && Imagify_Requirements::is_api_key_valid(), 'isOverQuota' => ! Imagify_Requirements::is_imagify_blocked() && Imagify_Requirements::is_api_up() && Imagify_Requirements::is_api_key_valid() && Imagify_Requirements::is_over_quota(), - 'heartbeatIDs' => [ - 'queue' => 'imagify_options_bulk_queue', - 'requirements' => 'imagify_bulk_requirements', + 'imagifybeatIDs' => [ + 'queue' => $imagifybeat_actions->get_imagifybeat_id( 'bulk_optimization_status' ), + 'requirements' => $imagifybeat_actions->get_imagifybeat_id( 'requirements' ), ], 'ajaxActions' => [ 'getMediaIds' => 'imagify_get_media_ids', @@ -176,9 +178,12 @@ function get_imagify_localize_script_translations( $context ) { ], ]; + case 'beat': + return \Imagify\Imagifybeat\Core::get_instance()->get_settings(); + case 'media-modal': return [ - 'heartbeatId' => 'imagify_optimization_status', + 'imagifybeatID' => $imagifybeat_actions->get_imagifybeat_id( 'library_optimization_status' ), ]; case 'library': @@ -199,10 +204,10 @@ function get_imagify_localize_script_translations( $context ) { 'apiDown' => Imagify_Requirements::is_imagify_blocked() || ! Imagify_Requirements::is_api_up(), 'keyIsValid' => ! Imagify_Requirements::is_imagify_blocked() && Imagify_Requirements::is_api_up() && Imagify_Requirements::is_api_key_valid(), 'isOverQuota' => ! Imagify_Requirements::is_imagify_blocked() && Imagify_Requirements::is_api_up() && Imagify_Requirements::is_api_key_valid() && Imagify_Requirements::is_over_quota(), - 'heartbeatIDs' => [ - 'stats' => 'imagify_bulk_data', - 'queue' => 'imagify_bulk_queue', - 'requirements' => 'imagify_bulk_requirements', + 'imagifybeatIDs' => [ + 'stats' => $imagifybeat_actions->get_imagifybeat_id( 'bulk_optimization_stats' ), + 'queue' => $imagifybeat_actions->get_imagifybeat_id( 'bulk_optimization_status' ), + 'requirements' => $imagifybeat_actions->get_imagifybeat_id( 'requirements' ), ], 'waitImageUrl' => IMAGIFY_ASSETS_IMG_URL . 'popin-loader.svg', 'ajaxActions' => [ @@ -266,7 +271,7 @@ function get_imagify_localize_script_translations( $context ) { ]; if ( get_transient( 'imagify_large_library' ) ) { - // On huge media libraries, don't use heartbeat, and fetch stats only when the process ends. + // On huge media libraries, don't use Imagifybeat, and fetch stats only when the process ends. $translations['ajaxActions']['getStats'] = 'imagify_bulk_get_stats'; } @@ -297,10 +302,10 @@ function get_imagify_localize_script_translations( $context ) { case 'files-list': return [ - 'backupOption' => get_imagify_option( 'backup' ), - 'context' => 'custom-folders', - 'heartbeatId' => 'imagify_custom_folders_optimization_status', - 'labels' => [ + 'backupOption' => get_imagify_option( 'backup' ), + 'context' => 'custom-folders', + 'imagifybeatID' => $imagifybeat_actions->get_imagifybeat_id( 'custom_folders_optimization_status' ), + 'labels' => [ 'bulkActionsOptimize' => __( 'Optimize', 'imagify' ), 'bulkActionsRestore' => __( 'Restore Original', 'imagify' ), ], From b76f68a6ca288521fec4d1f2ede150d7a9534b26 Mon Sep 17 00:00:00 2001 From: Git I Hate You Date: Thu, 13 Jun 2019 15:59:01 +0200 Subject: [PATCH 07/11] =?UTF-8?q?Hotfix:=20typo=20"Resizement"=20Frenglish?= =?UTF-8?q?=20=F0=9F=91=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- classes/Optimization/Process/AbstractProcess.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/classes/Optimization/Process/AbstractProcess.php b/classes/Optimization/Process/AbstractProcess.php index aa1ea00c2..74bb1c925 100644 --- a/classes/Optimization/Process/AbstractProcess.php +++ b/classes/Optimization/Process/AbstractProcess.php @@ -643,7 +643,7 @@ public function optimize_size( $size, $optimization_level = null ) { $response = $this->maybe_resize( $thumb_size, $file ); if ( ! is_wp_error( $response ) ) { - // Resizement succeeded: optimize the file. + // Resizing succeeded: optimize the file. $response = $file->optimize( [ 'backup' => ! $response['backuped'] && $this->can_backup( $size ), 'backup_path' => $media->get_raw_backup_path(), @@ -1082,7 +1082,7 @@ public function maybe_resize( $size, $file ) { 'no_dimensions', sprintf( /* translators: %s is an error message. */ - __( 'Resizement failed: %s', 'imagify' ), + __( 'Resizing failed: %s', 'imagify' ), __( 'Imagify could not get the image dimensions.', 'imagify' ) ) ); @@ -1107,7 +1107,7 @@ public function maybe_resize( $size, $file ) { 'resize_failure', sprintf( /* translators: %s is an error message. */ - __( 'Resizement failed: %s', 'imagify' ), + __( 'Resizing failed: %s', 'imagify' ), $resized_path->get_error_message() ) ); From e534d84dc9b733250eb0e7aaf058031037d769a2 Mon Sep 17 00:00:00 2001 From: Git I Hate You Date: Fri, 14 Jun 2019 17:46:05 +0200 Subject: [PATCH 08/11] Namespace Composer class loader itself Use [Composer for WordPress](https://github.com/dangoodman/composer-for-wordpress) Composer plugin as dev dependency to "namespace" the Composer class loader itself. This will prevent conflicts with plugins using an old version of Composer. --- composer.json | 2 ++ 1 file changed, 2 insertions(+) diff --git a/composer.json b/composer.json index 6d2358032..604c62119 100644 --- a/composer.json +++ b/composer.json @@ -21,6 +21,7 @@ ], "type": "wordpress-plugin", "config": { + "classloader-suffix": "WPMediaImagifyWordPressPlugin", "classmap-authoritative": true, "sort-packages": true }, @@ -34,6 +35,7 @@ "composer/installers": "~1.0" }, "require-dev": { + "dangoodman/composer-for-wordpress": "^2.0", "dealerdirect/phpcodesniffer-composer-installer": "^0.4.4", "phpcompatibility/phpcompatibility-wp": "*", "squizlabs/php_codesniffer": "^3.2", From 4279ee12fd4a42c2a71190ce8534fc1a249a413e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9gory=20Viguier?= Date: Fri, 14 Jun 2019 21:13:11 +0200 Subject: [PATCH 09/11] Closes #368: Add compatibility with WP Rocket CDN (#383) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * The Webp\Picture\Display class now handles CDNs It should also work with lazyload. The CDN URL must be provided by constant, filter, or option. * Created the option that stores the CDN URL * Added 2 methods to display text and hidden input fields * Display a setting field for the CDN URL Also moved the webp info block to be faded out if the "display webp" option is disabled. * Required css and js for the CDN URL field * CDN URL: added support for WP Rocket It syncs the CDN URL with the one from WPR. Also moved WPR compat to a new class. * Fixed setting displaying as 'filter' instead of 'option' --- assets/css/options.css | 54 +++-- assets/css/options.min.css | 2 +- assets/js/options.js | 41 ++-- assets/js/options.min.js | 2 +- classes/Webp/Picture/Display.php | 238 ++++++++++++++++++----- composer.json | 3 +- inc/3rd-party/3rd-party.php | 2 +- inc/3rd-party/wp-rocket.php | 28 --- inc/3rd-party/wp-rocket/classes/Main.php | 99 ++++++++++ inc/3rd-party/wp-rocket/wp-rocket.php | 8 + inc/classes/class-imagify-options.php | 14 ++ inc/classes/class-imagify-settings.php | 140 +++++++++++-- inc/deprecated/3rd-party.php | 29 +++ views/part-settings-webp.php | 104 +++++++--- 14 files changed, 617 insertions(+), 147 deletions(-) delete mode 100644 inc/3rd-party/wp-rocket.php create mode 100755 inc/3rd-party/wp-rocket/classes/Main.php create mode 100644 inc/3rd-party/wp-rocket/wp-rocket.php diff --git a/assets/css/options.css b/assets/css/options.css index f4d6a6053..ea65f0ac2 100755 --- a/assets/css/options.css +++ b/assets/css/options.css @@ -181,12 +181,6 @@ p.imagify-api-key-invite-title { padding-top: 35px; } -.imagify-settings input[type="text"] { - color: #4A4A4A; - font-weight: 600; - box-shadow: none; -} - .imagify-settings div.submit.submit { border-top: 1px solid #D9D9D9; margin-top: 2em; @@ -242,12 +236,14 @@ label + .imagify-info, margin-left: 38px; padding-right: 25px; } +.imagify-options-line { + -webkit-transition: opacity .3s; + transition: opacity .3s; +} label ~ .imagify-options-line { display: block; margin: 8px 0 20px 40px; font-size: 14px; - -webkit-transition: opacity .3s; - transition: opacity .3s; } .imagify-options-line + .imagify-info { margin-left: 38px; @@ -266,21 +262,30 @@ label[for="imagify_sizes_full"] + .imagify-info { } .imagify-settings.imagify-settings [type="checkbox"]:not(:checked) + label ~ .imagify-options-line, -.imagify-settings.imagify-settings [type="checkbox"]:not(:checked) + label .imagify-visual-label { +.imagify-settings.imagify-settings [type="checkbox"]:not(:checked) + label .imagify-visual-label, +:checked + label ~ .imagify-options-line :checked + label ~ .imagify-options-line .imagify-faded { opacity: .5; } .imagify-settings.imagify-settings [type="checkbox"]:checked + label ~ .imagify-options-line, -.imagify-settings.imagify-settings [type="checkbox"]:checked + label .imagify-visual-label { +.imagify-settings.imagify-settings [type="checkbox"]:checked + label .imagify-visual-label, +.imagify-settings.imagify-settings :not(:checked) + label ~ .imagify-options-line :not(:checked) + label ~ .imagify-options-line { opacity: 1; } +.imagify-radio-group + .imagify-options-line { + display: block; + margin: 0 0 0 1.7em; + font-size: 14px; +} + .imagify-checkbox-marged { max-width: 500px; margin-left: 45px; } -#imagify_resize_larger_w { - width: 5em; +.imagify-settings [type="text"], +.imagify-settings [type="number"] { + width: 20em; height: auto; padding: 6px; margin: 0 6px; @@ -290,6 +295,31 @@ label[for="imagify_sizes_full"] + .imagify-info { color: #338EA6; font-weight: bold; } +.imagify-settings [type="number"] { + width: 5em; +} +.imagify-settings ::-webkit-input-placeholder { + color: #B1B1B1; + font-weight: 400; +} +.imagify-settings ::-moz-placeholder { + color: #B1B1B1; + font-weight: 400; + opacity: 1; +} +.imagify-settings :-ms-input-placeholder { + color: #B1B1B1; + font-weight: 400; +} +.imagify-settings :-moz-placeholder { + color: #B1B1B1; + font-weight: 400; + opacity: 1; +} +.imagify-settings ::placeholder { + color: #B1B1B1; + font-weight: 400; +} .imagify-menu-bar-img { box-sizing: border-box; diff --git a/assets/css/options.min.css b/assets/css/options.min.css index cb0f0e189..c93ff7ae9 100755 --- a/assets/css/options.min.css +++ b/assets/css/options.min.css @@ -1 +1 @@ -.wrap.imagify-settings{margin-right:0}.imagify-settings.imagify-have-rocket{margin-right:20px}#imagify-check-api-container{display:block;margin-top:6px;font-weight:700}#imagify-check-api-container .dashicons{font-size:25px}#imagify-check-api-container .dashicons-no:before{color:#f06e57;vertical-align:-1px}#imagify-check-api-container .imagify-icon{font-size:1.8em;margin-right:3px;margin-left:1px;color:#8BC34A;vertical-align:-2px}.imagify-account-info-col .imagify-api-line{padding:22px 26px;background:#343A49}.imagify-api-line label,p.imagify-api-key-invite-title{display:block;margin-bottom:6px;font-size:14px;text-transform:uppercase;letter-spacing:.02em;font-weight:700;color:#343A49}.imagify-account-info-col .imagify-api-line label{color:#E5EBEF;display:inline-block}.imagify-api-line.imagify-api-line input[type=text]{width:100%;padding:6px 10px;border:1px solid #40B1D0;font-family:"PT Mono",Consolas,monospace;font-size:14px;letter-spacing:.01em;font-weight:700;color:#40B1D0;background:0 0;-webkit-box-shadow:none;box-shadow:none}.imagify-no-api-key .imagify-api-line{margin:3em 0 0;padding:2em 0 0;border-top:1px solid #D5D6D9}.imagify-no-api-key .imagify-api-line input[type=text]{margin-top:5px;width:400px;max-width:100%}.imagify-settings .imagify-no-api-key div.submit.submit{border:0;padding:0 16px;margin-top:0;background:#FFF}.imagify-settings .imagify-no-api-key div.submit.submit p{padding-bottom:0}.imagify-options-title{margin:.75em 0 0;font-size:24px;letter-spacing:.02em;font-weight:700;color:#343A49}.imagify-options-subtitle{padding-bottom:.3em;margin-bottom:20px;border-bottom:1px solid #D2D3D6;font-size:14px;letter-spacing:.01em;font-weight:700;text-transform:uppercase;color:#626E7B}.imagify-options-subtitle a{font-size:12px;color:#338EA6;text-transform:none;letter-spacing:0}.imagify-options-subtitle .imagify-info{margin-left:15px}.imagify-setting-line{border-top:1px solid #D2D3D6;padding:25px 0 13px;margin:1em 0}.imagify-options-subtitle+.imagify-setting-line{border-top:0;padding-top:8px}.imagify-setting-optim-level{display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-webkit-box-align:center;-ms-flex-align:center;align-items:center;padding:8px 0 18px}.imagify-setting-optim-level>p{margin:0}.imagify-setting-optim-level .imagify-inline-options{-ms-flex-preferred-size:60%;flex-basis:60%;-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1;width:auto;display:-webkit-box;display:-ms-flexbox;display:flex;background:#2E3243;border-radius:3px}.imagify-setting-optim-level .imagify-inline-options label{display:block!important;width:100%;font-size:14px!important;border-radius:3px!important}.imagify-setting-optim-level .imagify-visual-comparison-text{-ms-flex-preferred-size:40%;flex-basis:40%;-ms-flex-negative:1;flex-shrink:1;padding-left:20px;color:#626E7B;-webkit-box-sizing:border-box;box-sizing:border-box}.imagify-setting-optim-level.imagify-setting-optim-level .imagify-visual-comparison-btn{padding-top:5px;margin-top:2px;border-radius:2px;text-transform:none;letter-spacing:0;text-shadow:none!important}@media (max-width:782px){.imagify-settings .form-table th{padding-top:2em;padding-bottom:.5em}}.imagify-settings .form-table td{vertical-align:top}.imagify-settings .form-table th span{cursor:pointer}.imagify-middle th{padding-top:35px}.imagify-settings input[type=text]{color:#4A4A4A;font-weight:600;-webkit-box-shadow:none;box-shadow:none}.imagify-settings div.submit.submit{border-top:1px solid #D9D9D9;margin-top:2em;padding:18px 0 7px 30px}.imagify-settings .hidden+div.submit.submit{margin-top:-1px}.imagify-settings p.submit{float:left;margin-top:0}.imagify-settings p.submit .button{margin:0 5px}.imagify-sub-header th{text-align:right}.imagify-sub-header .form-table{margin:0}.imagify-sub-header td,.imagify-sub-header th{padding-top:0;padding-bottom:0}.imagify-sub-header [for=api_key]{padding-top:5px}@media (max-width:1120px){.imagify-settings .imagify-logo-block{margin-right:0}.imagify-settings .imagify-rate-us.imagify-rate-us{margin:1em 0 -1em}}.imagify-settings .imagify-rate-us{margin-right:25px;margin-left:auto}.imagify-visual-label,label+.imagify-info{display:inline-block;width:550px;max-width:calc(100% - 38px);margin-left:38px;padding-right:25px}label~.imagify-options-line{display:block;margin:8px 0 20px 40px;font-size:14px;-webkit-transition:opacity .3s;-o-transition:opacity .3s;transition:opacity .3s}.imagify-options-line+.imagify-info{margin-left:38px}label+.imagify-info{margin-top:10px}.imagify-options-line+.imagify-info+.imagify-options-line{margin-top:20px}.imagify-visual-label{vertical-align:-5px}label[for=imagify_sizes_full]+.imagify-info{vertical-align:middle}.imagify-settings.imagify-settings [type=checkbox]:not(:checked)+label .imagify-visual-label,.imagify-settings.imagify-settings [type=checkbox]:not(:checked)+label~.imagify-options-line{opacity:.5}.imagify-settings.imagify-settings [type=checkbox]:checked+label .imagify-visual-label,.imagify-settings.imagify-settings [type=checkbox]:checked+label~.imagify-options-line{opacity:1}.imagify-checkbox-marged{max-width:500px;margin-left:45px}#imagify_resize_larger_w{width:5em;height:auto;padding:6px;margin:0 6px;border:1px solid #8BA6B4;-webkit-box-shadow:none;box-shadow:none;border-radius:2px;color:#338EA6;font-weight:700}.imagify-menu-bar-img{-webkit-box-sizing:border-box;box-sizing:border-box;max-width:100%;height:auto;margin-top:0;border:1px solid #8BA6B4}.imagify-col.imagify-main{float:left;width:calc(100% - 320px);padding-left:0;padding-right:0}.imagify-have-rocket .imagify-main{float:none;width:1265px;max-width:100%}.imagify-sidebar{float:left;width:300px;max-width:100%}.imagify-sidebar-section{border:1px solid #BBB;background:#1F2332;position:relative;padding:10px 20px;text-align:center;color:#F2F2F2}.imagify-sidebar-section+.imagify-sidebar-section{margin-top:2em}@media (max-width:820px){.imagify-main,.imagify-sidebar{float:none;width:auto}.imagify-settings{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column}.imagify-sidebar{-webkit-box-ordinal-group:3;-ms-flex-order:2;order:2;max-width:none;margin-left:0;margin-top:25px}.wp-media-products{text-align:center}.wp-media-products li{display:inline-block;width:100%;max-width:276px}}@media (min-width:1400px){.imagify-main{width:74%}}.imagify-sidebar-close{position:absolute;top:8px;right:12px;text-decoration:none}.imagify-sidebar-close i{font-size:2em;color:rgba(255,255,255,.5)}p.imagify-sidebar-title{margin:1.2em 0 1.5em;text-align:left;color:#F56640;text-transform:uppercase;letter-spacing:.015em;word-spacing:.015em;font-weight:700}p.imagify-sidebar-description{margin:1.5em 0;text-align:left;font-weight:500;color:#F2F2F2}.imagify-sidebar-description strong{color:#39CE9A}.imagify-rocket-cta-promo{display:block;padding:8px 10px;margin:1.3em 0 .5em;border:2px dashed #F56640;border-radius:3px;font-size:18px;font-weight:700;color:#F56640}.imagify-rocket-cta-promo strong,a.btn-rocket{color:#F2F2F2}a.btn-rocket{display:block;font-size:15px;padding:10px 12px;margin:0 0 1.5em;background:#F56640;border-radius:3px;text-transform:uppercase;font-weight:700;text-decoration:none}a.btn-rocket:focus,a.btn-rocket:hover{background:#AC2B15}.imagify-sidebar-section ul{margin-top:20px}.imagify-sidebar-section li{position:relative;margin:1.2em 0;padding-left:25px;text-align:left}.imagify-sidebar-section li:before{content:"✓";position:absolute;left:0;top:0;color:#39CE9A;font-size:18px}label[for=imagify_admin_bar_menu],label[for=imagify_partner_links]{font-weight:400!important;color:#626E7B!important}.imagify-select-all-buttons{margin-top:8px}.imagify-link-like.imagify-select-all{font-weight:700;font-size:12px;color:#3694AE}.imagify-select-all.imagify-is-inactive{color:inherit;text-decoration:none;cursor:default}.imagify-fts-header{padding:10px 16px;background:#343A49;color:#FFF}.imagify-fts-header i{font-size:1.8em;margin-right:12px}.imagify-fts-header p{margin:0;color:#FFF}#imagify-add-themes-to-custom-folder strong,.imagify-fts-header strong{color:#40B1D0;font-weight:700}.imagify-fts-content{padding:16px;background:#F4F7F9;border:1px solid #CDD0D4;border-top:0}.imagify-fts-content p{margin-top:0}.imagify-kindof-title{margin-top:2em;padding:0 0 10px;border-bottom:1px solid #D2D3D6;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between;font-weight:700}.imagify-settings .imagify-button-mini{padding:4px 13px 4px 10px}.imagify-settings .imagify-button-mini .dashicons-plus{vertical-align:-7.5px}.imagify-settings .imagify-button-mini.imagify-button-primary:focus,.imagify-settings .imagify-button-mini.imagify-button-primary:hover{color:#FFF}p.imagify-custom-folder-line{position:relative;margin:0;padding:12px 15px;color:#4A5362;font-weight:500;-webkit-transition:all .75s;-o-transition:all .75s;transition:all .75s}.imagify-custom-folder-line.imagify-will-remove{background:#C51162;color:#FFF;-webkit-transform:translateX(-120px);-ms-transform:translateX(-120px);transform:translateX(-120px);opacity:0}.imagify-custom-folder-line:first-child{margin-top:-.5em}.imagify-custom-folder-line+.imagify-custom-folder-line{border-top:1px solid #E9EFF2}.imagify-custom-folders-remove{position:absolute;right:0;top:6px;border:0;padding:5px 10px 4px;-webkit-box-shadow:none;box-shadow:none;color:#7A8996;border-radius:16px;font-size:13px;line-height:18px;background:#FFF;-webkit-transition:all .275s;-o-transition:all .275s;transition:all .275s;cursor:pointer}.imagify-custom-folders-remove-text{max-width:0;overflow:hidden;white-space:nowrap;display:inline-block;-webkit-transform:scale(0);-ms-transform:scale(0);transform:scale(0);opacity:0;-webkit-transition:all .275s;-o-transition:all .275s;transition:all .275s}.imagify-custom-folders-remove:focus,.imagify-custom-folders-remove:hover{background:#D9EFF6;color:#225E6E}.imagify-custom-folders-remove:focus .imagify-custom-folders-remove-text,.imagify-custom-folders-remove:hover .imagify-custom-folders-remove-text{max-width:6em;-webkit-transform:scale(1);-ms-transform:scale(1);transform:scale(1);opacity:1}.imagify-settings .progress{height:8px;margin-top:1em;background:#343A49}.imagify-settings .bar{position:relative;width:1px;height:8px;background:#46B1CE;-webkit-transition:width .5s;-o-transition:width .5s;transition:width .5s}.imagify-settings .percent{position:absolute;top:6px;right:0;padding:0 5px;line-height:1.85;font-size:14px;font-weight:700;color:#40B1D0}.dashicons.rotate{-webkit-animation:icon-rotate 2.6s infinite linear;animation:icon-rotate 2.6s infinite linear}@-webkit-keyframes icon-rotate{from{-webkit-transform:rotate(0);transform:rotate(0)}to{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@keyframes icon-rotate{from{-webkit-transform:rotate(0);transform:rotate(0)}to{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}.imagify-add-custom-folder+.imagify-loader{display:none;vertical-align:middle}.imagify-add-custom-folder[disabled]+.imagify-loader{display:inline-block}.imagify-folders-information{position:relative;margin:-5px 0 20px;padding:10px 10px 10px 40px;text-align:left;background:#F2F2F2}.imagify-folders-information i{position:absolute;left:10px;top:50%;margin-top:-10px}.imagify-folders-tree{margin:0;text-align:left}.imagify-folders-tree li{clear:left}.imagify-folders-tree .imagify-folder{-webkit-box-sizing:border-box;box-sizing:border-box;position:relative;width:48px;z-index:2;float:left;margin-top:-3px;padding:0 8px 0 0;border:0;background:0 0!important;-webkit-box-shadow:none;box-shadow:none;cursor:pointer;-webkit-transition:all .275s;-o-transition:all .275s;transition:all .275s}.imagify-folders-tree span.imagify-folder{padding-left:1.5px}.imagify-folders-tree .imagify-folder:before{content:"+";display:inline-block;width:13px;height:21px;font-size:1.5em;vertical-align:.15em}.imagify-folders-tree span.imagify-folder:before{content:''}.imagify-folders-tree .imagify-folder-icon path{-webkit-transition:all .275s;-o-transition:all .275s;transition:all .275s}.imagify-folders-tree .imagify-is-open .imagify-folder-icon path{stroke:#7A8996}.imagify-folders-tree .imagify-is-open.imagify-folder:before{content:"-";color:#7A8996}.imagify-folders-tree .imagify-is-open~label{color:#7A8996}.imagify-folders-tree .imagify-folder .imagify-loader,.imagify-folders-tree .imagify-folder.imagify-loading:before{display:none}.imagify-folders-tree .imagify-folder.imagify-loading .imagify-loader{display:inline-block;width:13px;height:21px;font-size:1.5em;vertical-align:.15em}.imagify-folders-tree .imagify-folder.imagify-loading .imagify-loader img{display:inline-block;width:100%;height:auto;vertical-align:middle}.imagify-folders-tree button.imagify-folder:focus,.imagify-folders-tree button.imagify-folder:focus path,.imagify-folders-tree button.imagify-folder:hover,.imagify-folders-tree button.imagify-folder:hover path{color:#3694AE;stroke:#3694AE}.imagify-folders-tree .imagify-folder.disabled,.imagify-folders-tree .imagify-folder:disabled{color:#7f7f7f}.imagify-swal-content .imagify-folders-tree label{position:relative;display:block;width:100%;padding:3px 0;font-size:15px;font-weight:500;vertical-align:top;-webkit-transition:all .475s;-o-transition:all .475s;transition:all .475s}.imagify-folders-tree input:focus+label,.imagify-swal-content .imagify-folders-tree label:hover{background:#F4F7F9}.imagify-folders-tree .imagify-folder-already-selected input:focus+label,.imagify-folders-tree .imagify-folder-already-selected label,.imagify-folders-tree .imagify-folder-already-selected label:hover{background:#40B1D0;color:#FFF;border-radius:3px;cursor:default}.imagify-folders-tree .imagify-folder-already-selected button,.imagify-folders-tree .imagify-folder-already-selected button path{color:#FFF;stroke:#FFF;cursor:default}.imagify-folders-tree .imagify-folder-already-selected button:focus path,.imagify-folders-tree .imagify-folder-already-selected button:hover path{stroke:#FFF}.imagify-folders-tree .imagify-folder-already-selected button:before{content:''}.imagify-add-ed-folder{position:absolute;top:0;bottom:0;right:0;font-size:11px;text-transform:uppercase;letter-spacing:.02em;word-spacing:.02em;color:#3694AE;background:#F4F7F9;opacity:0;-webkit-transform:translateX(15px);-ms-transform:translateX(15px);transform:translateX(15px);-webkit-transition:all .275s;-o-transition:all .275s;transition:all .275s}.imagify-folder-already-selected .imagify-add-ed-folder,input:checked+label .imagify-add-ed-folder,input:focus+label .imagify-add-ed-folder,label:hover .imagify-add-ed-folder{opacity:1;-webkit-transform:translateX(0);-ms-transform:translateX(0);transform:translateX(0)}input:checked+label .imagify-add-ed-folder{background:#FFF}input:checked+label:hover .imagify-add-ed-folder,input:checked:focus+label .imagify-add-ed-folder{background:#F4F7F9}.imagify-folder-already-selected .imagify-add-ed-folder{background:#40B1D0;color:#FFF}.imagify-fake-checkbox{position:relative;display:inline-block;width:14px;height:14px;margin:3.5px 15px 0 5px;border:1.5px solid #3694AE;border-radius:3px;vertical-align:-4px}.imagify-fake-checkbox:after{position:absolute;left:1px;top:0;content:"✓";color:#3694AE;font-size:14px;line-height:.9;font-style:normal;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen-Sans,Ubuntu,Cantarell,"Helvetica Neue",sans-serif;opacity:0;-webkit-transform:scale(0);-ms-transform:scale(0);transform:scale(0);-webkit-transition:all .475s;-o-transition:all .475s;transition:all .475s}.imagify-folder-already-selected .imagify-fake-checkbox:after,input:checked+label .imagify-fake-checkbox:after{opacity:1;-webkit-transform:scale(1);-ms-transform:scale(1);transform:scale(1)}.imagify-folder-already-selected .imagify-fake-checkbox{border-color:#40B1D0}.imagify-folder-already-selected .imagify-fake-checkbox:after{color:#FFF}.imagify-folders-sub-tree{position:relative;margin-left:.75em;padding-top:.6em;padding-left:1em;border-left:1px dotted rgba(98,110,123,.3)}.imagify-folders-sub-tree li{position:relative;margin-bottom:4px}.imagify-folders-sub-tree li:before{content:"";position:absolute;top:12px;left:-1em;height:1px;width:.9em;border-top:1px dotted rgba(98,110,123,.3)}.imagify-folders-sub-tree li:last-child:after{content:"";position:absolute;left:-1.1em;bottom:0;height:11px;width:3px;background:#FFF}.imagify-empty-folder{margin-top:-.5em}.imagify-empty-folder em{font-size:12px;font-weight:500;color:#A2AFBC} \ No newline at end of file +.wrap.imagify-settings{margin-right:0}.imagify-settings.imagify-have-rocket{margin-right:20px}#imagify-check-api-container{display:block;margin-top:6px;font-weight:700}#imagify-check-api-container .dashicons{font-size:25px}#imagify-check-api-container .dashicons-no:before{color:#f06e57;vertical-align:-1px}#imagify-check-api-container .imagify-icon{font-size:1.8em;margin-right:3px;margin-left:1px;color:#8BC34A;vertical-align:-2px}.imagify-account-info-col .imagify-api-line{padding:22px 26px;background:#343A49}.imagify-api-line label,p.imagify-api-key-invite-title{display:block;margin-bottom:6px;font-size:14px;text-transform:uppercase;letter-spacing:.02em;font-weight:700;color:#343A49}.imagify-account-info-col .imagify-api-line label{color:#E5EBEF;display:inline-block}.imagify-api-line.imagify-api-line input[type=text]{width:100%;padding:6px 10px;border:1px solid #40B1D0;font-family:"PT Mono",Consolas,monospace;font-size:14px;letter-spacing:.01em;font-weight:700;color:#40B1D0;background:0 0;-webkit-box-shadow:none;box-shadow:none}.imagify-no-api-key .imagify-api-line{margin:3em 0 0;padding:2em 0 0;border-top:1px solid #D5D6D9}.imagify-no-api-key .imagify-api-line input[type=text]{margin-top:5px;width:400px;max-width:100%}.imagify-settings .imagify-no-api-key div.submit.submit{border:0;padding:0 16px;margin-top:0;background:#FFF}.imagify-settings .imagify-no-api-key div.submit.submit p{padding-bottom:0}.imagify-options-title{margin:.75em 0 0;font-size:24px;letter-spacing:.02em;font-weight:700;color:#343A49}.imagify-options-subtitle{padding-bottom:.3em;margin-bottom:20px;border-bottom:1px solid #D2D3D6;font-size:14px;letter-spacing:.01em;font-weight:700;text-transform:uppercase;color:#626E7B}.imagify-options-subtitle a{font-size:12px;color:#338EA6;text-transform:none;letter-spacing:0}.imagify-options-subtitle .imagify-info{margin-left:15px}.imagify-setting-line{border-top:1px solid #D2D3D6;padding:25px 0 13px;margin:1em 0}.imagify-options-subtitle+.imagify-setting-line{border-top:0;padding-top:8px}.imagify-setting-optim-level{display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-webkit-box-align:center;-ms-flex-align:center;align-items:center;padding:8px 0 18px}.imagify-setting-optim-level>p{margin:0}.imagify-setting-optim-level .imagify-inline-options{-ms-flex-preferred-size:60%;flex-basis:60%;-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1;width:auto;display:-webkit-box;display:-ms-flexbox;display:flex;background:#2E3243;border-radius:3px}.imagify-setting-optim-level .imagify-inline-options label{display:block!important;width:100%;font-size:14px!important;border-radius:3px!important}.imagify-setting-optim-level .imagify-visual-comparison-text{-ms-flex-preferred-size:40%;flex-basis:40%;-ms-flex-negative:1;flex-shrink:1;padding-left:20px;color:#626E7B;-webkit-box-sizing:border-box;box-sizing:border-box}.imagify-setting-optim-level.imagify-setting-optim-level .imagify-visual-comparison-btn{padding-top:5px;margin-top:2px;border-radius:2px;text-transform:none;letter-spacing:0;text-shadow:none!important}@media (max-width:782px){.imagify-settings .form-table th{padding-top:2em;padding-bottom:.5em}}.imagify-settings .form-table td{vertical-align:top}.imagify-settings .form-table th span{cursor:pointer}.imagify-middle th{padding-top:35px}.imagify-settings div.submit.submit{border-top:1px solid #D9D9D9;margin-top:2em;padding:18px 0 7px 30px}.imagify-settings .hidden+div.submit.submit{margin-top:-1px}.imagify-settings p.submit{float:left;margin-top:0}.imagify-settings p.submit .button{margin:0 5px}.imagify-sub-header th{text-align:right}.imagify-sub-header .form-table{margin:0}.imagify-sub-header td,.imagify-sub-header th{padding-top:0;padding-bottom:0}.imagify-sub-header [for=api_key]{padding-top:5px}@media (max-width:1120px){.imagify-settings .imagify-logo-block{margin-right:0}.imagify-settings .imagify-rate-us.imagify-rate-us{margin:1em 0 -1em}}.imagify-settings .imagify-rate-us{margin-right:25px;margin-left:auto}.imagify-visual-label,label+.imagify-info{display:inline-block;width:550px;max-width:calc(100% - 38px);margin-left:38px;padding-right:25px}.imagify-options-line{-webkit-transition:opacity .3s;-o-transition:opacity .3s;transition:opacity .3s}label~.imagify-options-line{display:block;margin:8px 0 20px 40px;font-size:14px}.imagify-options-line+.imagify-info{margin-left:38px}label+.imagify-info{margin-top:10px}.imagify-options-line+.imagify-info+.imagify-options-line{margin-top:20px}.imagify-visual-label{vertical-align:-5px}label[for=imagify_sizes_full]+.imagify-info{vertical-align:middle}.imagify-settings.imagify-settings [type=checkbox]:not(:checked)+label .imagify-visual-label,.imagify-settings.imagify-settings [type=checkbox]:not(:checked)+label~.imagify-options-line,:checked+label~.imagify-options-line :checked+label~.imagify-options-line .imagify-faded{opacity:.5}.imagify-settings.imagify-settings :not(:checked)+label~.imagify-options-line :not(:checked)+label~.imagify-options-line,.imagify-settings.imagify-settings [type=checkbox]:checked+label .imagify-visual-label,.imagify-settings.imagify-settings [type=checkbox]:checked+label~.imagify-options-line{opacity:1}.imagify-radio-group+.imagify-options-line{display:block;margin:0 0 0 1.7em;font-size:14px}.imagify-checkbox-marged{max-width:500px;margin-left:45px}.imagify-settings [type=text],.imagify-settings [type=number]{width:20em;height:auto;padding:6px;margin:0 6px;border:1px solid #8BA6B4;-webkit-box-shadow:none;box-shadow:none;border-radius:2px;color:#338EA6;font-weight:700}.imagify-settings [type=number]{width:5em}.imagify-settings ::-webkit-input-placeholder{color:#B1B1B1;font-weight:400}.imagify-settings :-ms-input-placeholder{color:#B1B1B1;font-weight:400}.imagify-settings ::placeholder{color:#B1B1B1;font-weight:400}.imagify-menu-bar-img{-webkit-box-sizing:border-box;box-sizing:border-box;max-width:100%;height:auto;margin-top:0;border:1px solid #8BA6B4}.imagify-col.imagify-main{float:left;width:calc(100% - 320px);padding-left:0;padding-right:0}.imagify-have-rocket .imagify-main{float:none;width:1265px;max-width:100%}.imagify-sidebar{float:left;width:300px;max-width:100%}.imagify-sidebar-section{border:1px solid #BBB;background:#1F2332;position:relative;padding:10px 20px;text-align:center;color:#F2F2F2}.imagify-sidebar-section+.imagify-sidebar-section{margin-top:2em}@media (max-width:820px){.imagify-main,.imagify-sidebar{float:none;width:auto}.imagify-settings{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column}.imagify-sidebar{-webkit-box-ordinal-group:3;-ms-flex-order:2;order:2;max-width:none;margin-left:0;margin-top:25px}.wp-media-products{text-align:center}.wp-media-products li{display:inline-block;width:100%;max-width:276px}}@media (min-width:1400px){.imagify-main{width:74%}}.imagify-sidebar-close{position:absolute;top:8px;right:12px;text-decoration:none}.imagify-sidebar-close i{font-size:2em;color:rgba(255,255,255,.5)}p.imagify-sidebar-title{margin:1.2em 0 1.5em;text-align:left;color:#F56640;text-transform:uppercase;letter-spacing:.015em;word-spacing:.015em;font-weight:700}p.imagify-sidebar-description{margin:1.5em 0;text-align:left;font-weight:500;color:#F2F2F2}.imagify-sidebar-description strong{color:#39CE9A}.imagify-rocket-cta-promo{display:block;padding:8px 10px;margin:1.3em 0 .5em;border:2px dashed #F56640;border-radius:3px;font-size:18px;font-weight:700;color:#F56640}.imagify-rocket-cta-promo strong,a.btn-rocket{color:#F2F2F2}a.btn-rocket{display:block;font-size:15px;padding:10px 12px;margin:0 0 1.5em;background:#F56640;border-radius:3px;text-transform:uppercase;font-weight:700;text-decoration:none}a.btn-rocket:focus,a.btn-rocket:hover{background:#AC2B15}.imagify-sidebar-section ul{margin-top:20px}.imagify-sidebar-section li{position:relative;margin:1.2em 0;padding-left:25px;text-align:left}.imagify-sidebar-section li:before{content:"✓";position:absolute;left:0;top:0;color:#39CE9A;font-size:18px}label[for=imagify_admin_bar_menu],label[for=imagify_partner_links]{font-weight:400!important;color:#626E7B!important}.imagify-select-all-buttons{margin-top:8px}.imagify-link-like.imagify-select-all{font-weight:700;font-size:12px;color:#3694AE}.imagify-select-all.imagify-is-inactive{color:inherit;text-decoration:none;cursor:default}.imagify-fts-header{padding:10px 16px;background:#343A49;color:#FFF}.imagify-fts-header i{font-size:1.8em;margin-right:12px}.imagify-fts-header p{margin:0;color:#FFF}#imagify-add-themes-to-custom-folder strong,.imagify-fts-header strong{color:#40B1D0;font-weight:700}.imagify-fts-content{padding:16px;background:#F4F7F9;border:1px solid #CDD0D4;border-top:0}.imagify-fts-content p{margin-top:0}.imagify-kindof-title{margin-top:2em;padding:0 0 10px;border-bottom:1px solid #D2D3D6;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between;font-weight:700}.imagify-settings .imagify-button-mini{padding:4px 13px 4px 10px}.imagify-settings .imagify-button-mini .dashicons-plus{vertical-align:-7.5px}.imagify-settings .imagify-button-mini.imagify-button-primary:focus,.imagify-settings .imagify-button-mini.imagify-button-primary:hover{color:#FFF}p.imagify-custom-folder-line{position:relative;margin:0;padding:12px 15px;color:#4A5362;font-weight:500;-webkit-transition:all .75s;-o-transition:all .75s;transition:all .75s}.imagify-custom-folder-line.imagify-will-remove{background:#C51162;color:#FFF;-webkit-transform:translateX(-120px);-ms-transform:translateX(-120px);transform:translateX(-120px);opacity:0}.imagify-custom-folder-line:first-child{margin-top:-.5em}.imagify-custom-folder-line+.imagify-custom-folder-line{border-top:1px solid #E9EFF2}.imagify-custom-folders-remove{position:absolute;right:0;top:6px;border:0;padding:5px 10px 4px;-webkit-box-shadow:none;box-shadow:none;color:#7A8996;border-radius:16px;font-size:13px;line-height:18px;background:#FFF;-webkit-transition:all .275s;-o-transition:all .275s;transition:all .275s;cursor:pointer}.imagify-custom-folders-remove-text{max-width:0;overflow:hidden;white-space:nowrap;display:inline-block;-webkit-transform:scale(0);-ms-transform:scale(0);transform:scale(0);opacity:0;-webkit-transition:all .275s;-o-transition:all .275s;transition:all .275s}.imagify-custom-folders-remove:focus,.imagify-custom-folders-remove:hover{background:#D9EFF6;color:#225E6E}.imagify-custom-folders-remove:focus .imagify-custom-folders-remove-text,.imagify-custom-folders-remove:hover .imagify-custom-folders-remove-text{max-width:6em;-webkit-transform:scale(1);-ms-transform:scale(1);transform:scale(1);opacity:1}.imagify-settings .progress{height:8px;margin-top:1em;background:#343A49}.imagify-settings .bar{position:relative;width:1px;height:8px;background:#46B1CE;-webkit-transition:width .5s;-o-transition:width .5s;transition:width .5s}.imagify-settings .percent{position:absolute;top:6px;right:0;padding:0 5px;line-height:1.85;font-size:14px;font-weight:700;color:#40B1D0}.dashicons.rotate{-webkit-animation:icon-rotate 2.6s infinite linear;animation:icon-rotate 2.6s infinite linear}@-webkit-keyframes icon-rotate{from{-webkit-transform:rotate(0);transform:rotate(0)}to{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@keyframes icon-rotate{from{-webkit-transform:rotate(0);transform:rotate(0)}to{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}.imagify-add-custom-folder+.imagify-loader{display:none;vertical-align:middle}.imagify-add-custom-folder[disabled]+.imagify-loader{display:inline-block}.imagify-folders-information{position:relative;margin:-5px 0 20px;padding:10px 10px 10px 40px;text-align:left;background:#F2F2F2}.imagify-folders-information i{position:absolute;left:10px;top:50%;margin-top:-10px}.imagify-folders-tree{margin:0;text-align:left}.imagify-folders-tree li{clear:left}.imagify-folders-tree .imagify-folder{-webkit-box-sizing:border-box;box-sizing:border-box;position:relative;width:48px;z-index:2;float:left;margin-top:-3px;padding:0 8px 0 0;border:0;background:0 0!important;-webkit-box-shadow:none;box-shadow:none;cursor:pointer;-webkit-transition:all .275s;-o-transition:all .275s;transition:all .275s}.imagify-folders-tree span.imagify-folder{padding-left:1.5px}.imagify-folders-tree .imagify-folder:before{content:"+";display:inline-block;width:13px;height:21px;font-size:1.5em;vertical-align:.15em}.imagify-folders-tree span.imagify-folder:before{content:''}.imagify-folders-tree .imagify-folder-icon path{-webkit-transition:all .275s;-o-transition:all .275s;transition:all .275s}.imagify-folders-tree .imagify-is-open .imagify-folder-icon path{stroke:#7A8996}.imagify-folders-tree .imagify-is-open.imagify-folder:before{content:"-";color:#7A8996}.imagify-folders-tree .imagify-is-open~label{color:#7A8996}.imagify-folders-tree .imagify-folder .imagify-loader,.imagify-folders-tree .imagify-folder.imagify-loading:before{display:none}.imagify-folders-tree .imagify-folder.imagify-loading .imagify-loader{display:inline-block;width:13px;height:21px;font-size:1.5em;vertical-align:.15em}.imagify-folders-tree .imagify-folder.imagify-loading .imagify-loader img{display:inline-block;width:100%;height:auto;vertical-align:middle}.imagify-folders-tree button.imagify-folder:focus,.imagify-folders-tree button.imagify-folder:focus path,.imagify-folders-tree button.imagify-folder:hover,.imagify-folders-tree button.imagify-folder:hover path{color:#3694AE;stroke:#3694AE}.imagify-folders-tree .imagify-folder.disabled,.imagify-folders-tree .imagify-folder:disabled{color:#7f7f7f}.imagify-swal-content .imagify-folders-tree label{position:relative;display:block;width:100%;padding:3px 0;font-size:15px;font-weight:500;vertical-align:top;-webkit-transition:all .475s;-o-transition:all .475s;transition:all .475s}.imagify-folders-tree input:focus+label,.imagify-swal-content .imagify-folders-tree label:hover{background:#F4F7F9}.imagify-folders-tree .imagify-folder-already-selected input:focus+label,.imagify-folders-tree .imagify-folder-already-selected label,.imagify-folders-tree .imagify-folder-already-selected label:hover{background:#40B1D0;color:#FFF;border-radius:3px;cursor:default}.imagify-folders-tree .imagify-folder-already-selected button,.imagify-folders-tree .imagify-folder-already-selected button path{color:#FFF;stroke:#FFF;cursor:default}.imagify-folders-tree .imagify-folder-already-selected button:focus path,.imagify-folders-tree .imagify-folder-already-selected button:hover path{stroke:#FFF}.imagify-folders-tree .imagify-folder-already-selected button:before{content:''}.imagify-add-ed-folder{position:absolute;top:0;bottom:0;right:0;font-size:11px;text-transform:uppercase;letter-spacing:.02em;word-spacing:.02em;color:#3694AE;background:#F4F7F9;opacity:0;-webkit-transform:translateX(15px);-ms-transform:translateX(15px);transform:translateX(15px);-webkit-transition:all .275s;-o-transition:all .275s;transition:all .275s}.imagify-folder-already-selected .imagify-add-ed-folder,input:checked+label .imagify-add-ed-folder,input:focus+label .imagify-add-ed-folder,label:hover .imagify-add-ed-folder{opacity:1;-webkit-transform:translateX(0);-ms-transform:translateX(0);transform:translateX(0)}input:checked+label .imagify-add-ed-folder{background:#FFF}input:checked+label:hover .imagify-add-ed-folder,input:checked:focus+label .imagify-add-ed-folder{background:#F4F7F9}.imagify-folder-already-selected .imagify-add-ed-folder{background:#40B1D0;color:#FFF}.imagify-fake-checkbox{position:relative;display:inline-block;width:14px;height:14px;margin:3.5px 15px 0 5px;border:1.5px solid #3694AE;border-radius:3px;vertical-align:-4px}.imagify-fake-checkbox:after{position:absolute;left:1px;top:0;content:"✓";color:#3694AE;font-size:14px;line-height:.9;font-style:normal;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen-Sans,Ubuntu,Cantarell,"Helvetica Neue",sans-serif;opacity:0;-webkit-transform:scale(0);-ms-transform:scale(0);transform:scale(0);-webkit-transition:all .475s;-o-transition:all .475s;transition:all .475s}.imagify-folder-already-selected .imagify-fake-checkbox:after,input:checked+label .imagify-fake-checkbox:after{opacity:1;-webkit-transform:scale(1);-ms-transform:scale(1);transform:scale(1)}.imagify-folder-already-selected .imagify-fake-checkbox{border-color:#40B1D0}.imagify-folder-already-selected .imagify-fake-checkbox:after{color:#FFF}.imagify-folders-sub-tree{position:relative;margin-left:.75em;padding-top:.6em;padding-left:1em;border-left:1px dotted rgba(98,110,123,.3)}.imagify-folders-sub-tree li{position:relative;margin-bottom:4px}.imagify-folders-sub-tree li:before{content:"";position:absolute;top:12px;left:-1em;height:1px;width:.9em;border-top:1px dotted rgba(98,110,123,.3)}.imagify-folders-sub-tree li:last-child:after{content:"";position:absolute;left:-1.1em;bottom:0;height:11px;width:3px;background:#FFF}.imagify-empty-folder{margin-top:-.5em}.imagify-empty-folder em{font-size:12px;font-weight:500;color:#A2AFBC} \ No newline at end of file diff --git a/assets/js/options.js b/assets/js/options.js index 8d8507fda..19e10e6ca 100755 --- a/assets/js/options.js +++ b/assets/js/options.js @@ -7,7 +7,7 @@ window.imagify = window.imagify || {}; var busy = false, xhr = false; - $( '#imagify-settings #api_key' ).on( 'blur', function() { + $( '#imagify-settings #api_key' ).on( 'blur.imagify', function() { var obj = $( this ), value = obj.val(); @@ -54,28 +54,34 @@ window.imagify = window.imagify || {}; /** * Check the boxes by clicking "labels" (aria-describedby items). */ - $( '.imagify-options-line' ).css( 'cursor', 'pointer' ).on( 'click', function( e ) { + $( '.imagify-options-line' ).css( 'cursor', 'pointer' ).on( 'click.imagify', function( e ) { if ( 'INPUT' === e.target.nodeName ) { return; } - $( 'input[aria-describedby="' + $( this ).attr( 'id' ) + '"]' ).trigger( 'click' ); + $( 'input[aria-describedby="' + $( this ).attr( 'id' ) + '"]' ).trigger( 'click.imagify' ); } ); - $( '.imagify-settings th span' ).on( 'click', function() { - var $input = $( this ).parent().next( 'td' ).find( 'input:checkbox' ); + $( '.imagify-settings th span' ).on( 'click.imagify', function() { + var $input = $( this ).parent().next( 'td' ).find( ':checkbox' ); if ( 1 === $input.length ) { - $input.trigger( 'click' ); + $input.trigger( 'click.imagify' ); } } ); /** * Auto check on options-line input value change. */ - $( '.imagify-options-line' ).find( 'input' ).on( 'change focus', function() { - var $checkbox = $( this ).closest( '.imagify-options-line' ).prev( 'label' ).prev( 'input' ); + $( '.imagify-options-line' ).find( 'input' ).on( 'change.imagify focus.imagify', function() { + var $checkbox; - if ( ! $checkbox[0].checked ) { + if ( 'checkbox' === this.type && ! this.checked ) { + return; + } + + $checkbox = $( this ).closest( '.imagify-options-line' ).prev( 'label' ).prev( ':checkbox' ); + + if ( $checkbox.length && ! $checkbox[0].checked ) { $checkbox.prop( 'checked', true ); } } ); @@ -83,7 +89,7 @@ window.imagify = window.imagify || {}; /** * Imagify Backup alert. */ - $( '.imagify-settings-section' ).find( '#imagify_backup' ).on( 'change', function() { + $( '[name="imagify_settings[backup]"]' ).on( 'change.imagify', function() { var $_this = $( this ), $backupMessage = $_this.siblings( '#backup-dir-is-writable' ), params = { @@ -129,6 +135,17 @@ window.imagify = window.imagify || {}; ); } ); + /** + * Fade CDN URL field. + */ + $( '[name="imagify_settings[display_webp_method]"]' ).on( 'change.imagify init.imagify', function( e ) { + if ( 'picture' === e.target.value ) { + $( e.target ).closest( '.imagify-radio-group' ).next( '.imagify-options-line' ).removeClass( 'imagify-faded' ); + } else { + $( e.target ).closest( '.imagify-radio-group' ).next( '.imagify-options-line' ).addClass( 'imagify-faded' ); + } + } ).filter( ':checked' ).trigger( 'init.imagify' ); + } )(jQuery, document, window); @@ -563,7 +580,7 @@ window.imagify = window.imagify || {}; e.data.imagifyOptionsBulk.$button.attr( 'disabled', 'disabled' ).find( '.dashicons' ).addClass( 'rotate' ); // Add a message to be displayed when the user wants to quit the page. - $( w ).on( 'beforeunload', e.data.imagifyOptionsBulk.getConfirmMessage ); + $( w ).on( 'beforeunload.imagify', e.data.imagifyOptionsBulk.getConfirmMessage ); // Fasten Imagifybeat: 1 tick every 15 seconds, and disable suspend. w.imagify.beat.interval( 15 ); @@ -924,7 +941,7 @@ window.imagify = window.imagify || {}; w.imagify.beat.enableSuspend(); // Unlink the message displayed when the user wants to quit the page. - $( w ).off( 'beforeunload', this.getConfirmMessage ); + $( w ).off( 'beforeunload.imagify', this.getConfirmMessage ); // Reset the progress bar. this.$progressWrap.slideUp().attr( 'aria-hidden', 'true' ); diff --git a/assets/js/options.min.js b/assets/js/options.min.js index 191496caa..34c751bef 100755 --- a/assets/js/options.min.js +++ b/assets/js/options.min.js @@ -1 +1 @@ -window.imagify=window.imagify||{},function(a,b,c,d){var e=!1,f=!1;a("#imagify-settings #api_key").on("blur",function(){var b=a(this),d=b.val();return""!==a.trim(d)&&(a("#check_api_key").val()===d?(a("#imagify-check-api-container").html(' '+imagifyOptions.labels.ValidApiKeyText),!1):(!0===e?f.abort():(a("#imagify-check-api-container").remove(),b.after(''+imagifyOptions.labels.waitApiKeyCheckText+"")),e=!0,void(f=a.get(ajaxurl+c.imagify.concat+"action=imagify_check_api_key_validity&api_key="+b.val()+"&imagifycheckapikeynonce="+a("#imagifycheckapikeynonce").val()).done(function(b){b.success?(a("#imagify-check-api-container").remove(),swal({title:imagifyOptions.labels.ApiKeyCheckSuccessTitle,html:imagifyOptions.labels.ApiKeyCheckSuccessText,type:"success",padding:0,customClass:"imagify-sweet-alert"}).then(function(){location.reload()})):a("#imagify-check-api-container").html(' '+b.data),e=!1}))))}),a(".imagify-options-line").css("cursor","pointer").on("click",function(b){"INPUT"!==b.target.nodeName&&a('input[aria-describedby="'+a(this).attr("id")+'"]').trigger("click")}),a(".imagify-settings th span").on("click",function(){var b=a(this).parent().next("td").find("input:checkbox");1===b.length&&b.trigger("click")}),a(".imagify-options-line").find("input").on("change focus",function(){var b=a(this).closest(".imagify-options-line").prev("label").prev("input");b[0].checked||b.prop("checked",!0)}),a(".imagify-settings-section").find("#imagify_backup").on("change",function(){var b=a(this),c=b.siblings("#backup-dir-is-writable"),d={action:"imagify_check_backup_dir_is_writable",_wpnonce:c.data("nonce")};if(b.is(":checked"))return void a.getJSON(ajaxurl,d).done(function(b){a.isPlainObject(b)&&b.success&&(b.data.is_writable?c.addClass("hidden"):c.removeClass("hidden"))});swal({title:imagifyOptions.labels.noBackupTitle,html:imagifyOptions.labels.noBackupText,type:"warning",customClass:"imagify-sweet-alert",padding:0,showCancelButton:!0,cancelButtonText:imagifySwal.labels.cancelButtonText,reverseButtons:!0}).then(function(){c.addClass("hidden")},function(){b.prop("checked",!0)})})}(jQuery,document,window),function(a,b,c,d){a.imagifyUser&&c.getJSON(ajaxurl,a.imagifyUser).done(function(a){c.isPlainObject(a)&&a.success&&(a.data.id=null,a.data.plan_id=null,a.data.is=[],c.each(a.data,function(b,d){var e=".imagify-user-"+b.replace(/_/g,"-");0===b.indexOf("is_")?d&&a.data.is.push(e):"is"!==b&&c(e).text(d)}),a.data.is.push("best-plan"),c(a.data.is.join(",")).removeClass("hidden"))})}(window,document,jQuery),function(a,b,c,d){function e(b){var d,e,f,g,h,i=!1,j=null;b&&(f=c("#imagify-custom-folders-selected"),g=f.find(".imagify-custom-folder-line"),h=g.find('[value="'+b+'"]'),h.length||(b=b.split("#///#"),d=b[1].replace(/\/+$/,"").toLowerCase(),e=a.imagify.template("imagify-custom-folder"),g.each(function(){var a=c(this),h=a.data("path").replace(/\/+$/,"").toLowerCase();return""!==h&&0===d.indexOf(h)?(i=!0,!1):d'+imagifyOptions.labels.filesTreeSubTitle+'

'+imagifyOptions.labels.cleaningInfo+'

    '+a.data+"
",type:"",customClass:"imagify-sweet-alert imagify-swal-has-subtitle imagify-folders-selection",showCancelButton:!0,padding:0,confirmButtonText:imagifyOptions.labels.confirmFilesTreeBtn,cancelButtonText:imagifySwal.labels.cancelButtonText,reverseButtons:!0}).then(function(){var a=c("#imagify-folders-tree input").serializeArray();a.length&&c.each(a,function(a,b){e(b.value)})}).catch(swal.noop)}).fail(function(){swal({title:imagifyOptions.labels.error,type:"error",customClass:"imagify-sweet-alert",padding:0})}).always(function(){b.removeAttr("disabled").next("img").attr("aria-hidden","true")}))}),c(b).on("click.imagify","#imagify-folders-tree [data-folder]",function(){var a=c(this),b=a.nextAll(".imagify-folders-sub-tree"),d=[];if(!a.attr("disabled")&&!a.siblings(":checkbox").is(":checked")){if(a.attr("disabled","disabled").addClass("imagify-loading"),b.length)return a.hasClass("imagify-is-open")?(b.addClass("hidden"),a.removeClass(" imagify-is-open")):(b.removeClass("hidden"),a.addClass("imagify-is-open")),void a.removeAttr("disabled").removeClass("imagify-loading");c("#imagify-custom-folders-selected").find("input").each(function(){d.push(this.value)}),c.post(imagifyOptions.getFilesTree,{folder:a.data("folder"),selected:d},null,"json").done(function(b){if(!b.success)return void swal({title:imagifyOptions.labels.error,html:b.data||"",type:"error",padding:0,customClass:"imagify-sweet-alert"});a.addClass("imagify-is-open").parent().append('
    '+b.data+"
")}).fail(function(){swal({title:imagifyOptions.labels.error,type:"error",padding:0,customClass:"imagify-sweet-alert"})}).always(function(){a.removeAttr("disabled").removeClass("imagify-loading")})}}),c("#imagify-custom-folders").on("click.imagify",".imagify-custom-folders-remove",function(){var b=c(this).closest(".imagify-custom-folder-line").addClass("imagify-will-remove");a.setTimeout(function(){b.remove(),c("#imagify-custom-folders-selected").siblings(".imagify-success.hidden").removeClass("hidden")},750)}),c("#imagify-add-themes-to-custom-folder").on("click.imagify",function(){var a=c(this);e(a.data("theme")),e(a.data("theme-parent")),a.replaceWith("

"+imagifyOptions.labels.themesAdded+"

")}))}(window,document,jQuery),function(a,b,c,d){imagifyOptions.bulk&&(a.imagify.optionsBulk={fetchQueue:[],queue:[],processingQueue:[],fetchError:!1,error:!1,working:!1,processIsStopped:!0,processedMedia:0,totalMedia:0,$button:null,$progressWrap:null,$progressBar:null,$progressText:null,init:function(){this.$button=c("#imagify-generate-webp-versions"),this.$progressWrap=this.$button.siblings(".imagify-progress"),this.$progressBar=this.$progressWrap.find(".bar"),this.$progressText=this.$progressBar.find(".percent"),c("#imagify_convert_to_webp").on("change.imagify init.imagify",{imagifyOptionsBulk:this},this.toggleButton).trigger("init.imagify"),this.$button.on("click.imagify",{imagifyOptionsBulk:this},this.maybeLaunchAllProcesses),c(b).on("imagifybeat-send",{imagifyOptionsBulk:this},this.addQueueImagifybeat).on("imagifybeat-tick",{imagifyOptionsBulk:this},this.processQueueImagifybeat).on("imagifybeat-send",this.addRequirementsImagifybeat).on("imagifybeat-tick",{imagifyOptionsBulk:this},this.processRequirementsImagifybeat)},toggleButton:function(a){this.checked?a.data.imagifyOptionsBulk.$button.removeAttr("disabled"):a.data.imagifyOptionsBulk.$button.attr("disabled","disabled")},maybeLaunchAllProcesses:function(b){b.data.imagifyOptionsBulk&&!b.data.imagifyOptionsBulk.working&&(b.data.imagifyOptionsBulk.hasBlockingError(!0)||(b.data.imagifyOptionsBulk.fetchQueue=imagifyOptions.bulk.contexts,b.data.imagifyOptionsBulk.queue=[],b.data.imagifyOptionsBulk.processingQueue=[],b.data.imagifyOptionsBulk.fetchError=!1,b.data.imagifyOptionsBulk.error=!1,b.data.imagifyOptionsBulk.working=!0,b.data.imagifyOptionsBulk.processIsStopped=!1,b.data.imagifyOptionsBulk.processedMedia=0,b.data.imagifyOptionsBulk.totalMedia=0,b.data.imagifyOptionsBulk.$button.attr("disabled","disabled").find(".dashicons").addClass("rotate"),c(a).on("beforeunload",b.data.imagifyOptionsBulk.getConfirmMessage),a.imagify.beat.interval(15),a.imagify.beat.disableSuspend(),b.data.imagifyOptionsBulk.fetchIDs()))},getConfirmMessage:function(){return imagifyOptions.bulk.labels.processing},addQueueImagifybeat:function(a,b){a.data.imagifyOptionsBulk&&a.data.imagifyOptionsBulk.processingQueue.length&&(b[imagifyOptions.bulk.imagifybeatIDs.queue]=a.data.imagifyOptionsBulk.processingQueue)},processQueueImagifybeat:function(a,b){a.data.imagifyOptionsBulk&&void 0!==b[imagifyOptions.bulk.imagifybeatIDs.queue]&&c.each(b[imagifyOptions.bulk.imagifybeatIDs.queue],function(b,c){a.data.imagifyOptionsBulk.mediaProcessed(c)})},addRequirementsImagifybeat:function(a,b){b[imagifyOptions.bulk.imagifybeatIDs.requirements]=1},processRequirementsImagifybeat:function(a,b){a.data.imagifyOptionsBulk&&void 0===b[imagifyOptions.bulk.imagifybeatIDs.requirements]||(b=b[imagifyOptions.bulk.imagifybeatIDs.requirements],imagifyOptions.bulk.curlMissing=b.curl_missing,imagifyOptions.bulk.editorMissing=b.editor_missing,imagifyOptions.bulk.extHttpBlocked=b.external_http_blocked,imagifyOptions.bulk.apiDown=b.api_down,imagifyOptions.bulk.keyIsValid=b.key_is_valid,imagifyOptions.bulk.isOverQuota=b.is_over_quota)},fetchIDs:function(){var a,b;if(!this.processIsStopped){if(!this.fetchQueue.length)return this.queue.length?(this.$progressBar.removeAttr("style"),this.$progressText.text("0"+(this.totalMedia?"/"+this.totalMedia:"")),this.$progressWrap.slideDown().attr("aria-hidden","false"),void this.processQueue()):(this.fetchError||(this.fetchError="no-images"),this.stopProcess(this.fetchError),void(this.fetchError=!1));a=this,b=this.fetchQueue.shift(),c.get(this.getAjaxUrl("getMediaIds",b)).done(function(d){var e;if(!a.processIsStopped)return e=d.data&&d.data.message?d.data.message:imagifyOptions.bulk.ajaxErrorText,d.success&&c.isArray(d.data)?void(d.data.length&&(a.totalMedia+=d.data.length,a.queue.push({context:b,optimizeURL:a.getAjaxUrl("bulkProcess",b),mediaIDs:d.data}))):void(a.fetchError||(a.fetchError=e))}).fail(function(){a.fetchError||(a.fetchError="get-unoptimized-images")}).always(function(){a.fetchIDs()})}},processQueue:function(){var a=this;this.processIsStopped||(this.queue.length||this.processingQueue.length)&&c.each(this.queue,function(b,d){if(a.processingQueue.length>=imagifyOptions.bulk.bufferSize)return!1;c.each(d.mediaIDs,function(){if(a.processMedia({context:d.context,mediaID:d.mediaIDs.shift(),optimizeURL:d.optimizeURL}),d.mediaIDs.length||a.queue.shift(),a.processingQueue.length>=imagifyOptions.bulk.bufferSize)return!1})})},processMedia:function(a){var b=this,d={context:a.context,mediaID:a.mediaID};this.processingQueue.push({context:a.context,mediaID:a.mediaID}),c.post({url:a.optimizeURL,data:{media_id:a.mediaID,context:a.context},dataType:"json"}).done(function(a){a.success||b.mediaProcessed(d)}).fail(function(){b.mediaProcessed(d)})},mediaProcessed:function(a){var b=this;this.processIsStopped||(c.each(this.processingQueue,function(c,d){if(a.context===d.context&&a.mediaID===d.mediaID)return b.processingQueue.splice(c,1),!1}),++this.processedMedia,a.progress=Math.floor(this.processedMedia/this.totalMedia*100),this.$progressBar.css("width",a.progress+"%"),this.$progressText.text(this.processedMedia+"/"+this.totalMedia),this.queue.length||this.processingQueue.length?this.processQueue():this.totalMedia===this.processedMedia&&this.queueEmpty())},queueEmpty:function(){var b={};!1!==this.error&&(b="invalid-api-key"===this.error?{title:imagifyOptions.bulk.labels.invalidAPIKeyTitle,type:"info"}:"over-quota"===this.error?{title:imagifyOptions.bulk.labels.overQuotaTitle,html:c("#tmpl-imagify-overquota-alert").html(),type:"info",customClass:"imagify-swal-has-subtitle imagify-swal-error-header",showConfirmButton:!1}:"get-unoptimized-images"===this.error||"consumed-all-data"===this.error?{title:imagifyOptions.bulk.labels.getUnoptimizedImagesErrorTitle,html:imagifyOptions.bulk.labels.getUnoptimizedImagesErrorText,type:"info"}:"no-images"===this.error?{title:imagifyOptions.bulk.labels.nothingToDoTitle,html:imagifyOptions.bulk.labels.nothingToDoText,type:"info"}:{title:imagifyOptions.bulk.labels.error,html:this.error,type:"info"},this.displayError(b),this.error=!1),this.fetchQueue=[],this.queue=[],this.processingQueue=[],this.fetchError=!1,this.working=!1,this.processIsStopped=!1,this.processedMedia=0,this.totalMedia=0,a.imagify.beat.resetInterval(),a.imagify.beat.enableSuspend(),c(a).off("beforeunload",this.getConfirmMessage),this.$progressWrap.slideUp().attr("aria-hidden","true"),this.$progressBar.removeAttr("style"),this.$progressText.text("0"),this.$button.removeAttr("disabled").find(".dashicons").removeClass("rotate")},hasBlockingError:function(a){return a=void 0!==a&&a,imagifyOptions.bulk.curlMissing?(a&&this.displayError({html:imagifyOptions.bulk.labels.curlMissing}),!0):imagifyOptions.bulk.editorMissing?(a&&this.displayError({html:imagifyOptions.bulk.labels.editorMissing}),!0):imagifyOptions.bulk.extHttpBlocked?(a&&this.displayError({html:imagifyOptions.bulk.labels.extHttpBlocked}),!0):imagifyOptions.bulk.apiDown?(a&&this.displayError({html:imagifyOptions.bulk.labels.apiDown}),!0):imagifyOptions.bulk.keyIsValid?!!imagifyOptions.bulk.isOverQuota&&(a&&this.displayError({title:imagifyOptions.bulk.labels.overQuotaTitle,html:c("#tmpl-imagify-overquota-alert").html(),type:"info",customClass:"imagify-swal-has-subtitle imagify-swal-error-header",showConfirmButton:!1}),!0):(a&&this.displayError({title:imagifyOptions.bulk.labels.invalidAPIKeyTitle,type:"info"}),!0)},displayError:function(a,b,d){var e={title:"",html:"",type:"error",customClass:"",width:620,padding:0,showCloseButton:!0,showConfirmButton:!0};c.isPlainObject(a)?d=c.extend({},e,a):(d=d||{},d=c.extend({},e,{title:a||"",html:b||""},d)),d.title=d.title||imagifyOptions.bulk.labels.error,d.customClass+=" imagify-sweet-alert",swal(d).catch(swal.noop)},getAjaxUrl:function(b,c){var d;return d=ajaxurl+a.imagify.concat+"_wpnonce="+imagifyOptions.bulk.ajaxNonce,d+="&action="+imagifyOptions.bulk.ajaxActions[b],d+="&context="+c,d+="&imagify_action=generate_webp"},stopProcess:function(a){this.processIsStopped=!0,this.error=a,this.queueEmpty()}},a.imagify.optionsBulk.init())}(window,document,jQuery),function(a,b,c,d){var e=c.propHooks.checked;c.propHooks.checked={set:function(a,b,d){var f;return f=void 0===e?a[d]=b:e(a,b,d),c(a).trigger("change.imagify"),f}},c(".imagify-select-all").on("click.imagify",function(){var a=c(this),b=a.data("action"),d=a.closest(".imagify-select-all-buttons"),e=d.prev(".imagify-check-group"),f="imagify-is-inactive";if(a.hasClass(f))return!1;d.find(".imagify-select-all").removeClass(f).attr("aria-disabled","false"),a.addClass(f).attr("aria-disabled","true"),e.find(".imagify-row-check").prop("checked",function(){return!c(this).is(":hidden,:disabled")&&"select"===b})}),c(".imagify-check-group .imagify-row-check").on("change.imagify",function(){var a=c(this).closest(".imagify-check-group"),b=a.find(".imagify-row-check"),d=b.filter(":visible:enabled").length,e=b.filter(":visible:enabled:checked").length,f=a.next(".imagify-select-all-buttons"),g="imagify-is-inactive";0===e&&f.find('[data-action="unselect"]').addClass(g).attr("aria-disabled","true"),e===d&&f.find('[data-action="select"]').addClass(g).attr("aria-disabled","true"),e!==d&&e>0&&f.find(".imagify-select-all").removeClass(g).attr("aria-disabled","false")})}(window,document,jQuery); \ No newline at end of file +window.imagify=window.imagify||{},function(a,b,c,d){var e=!1,f=!1;a("#imagify-settings #api_key").on("blur.imagify",function(){var b=a(this),d=b.val();return""!==a.trim(d)&&(a("#check_api_key").val()===d?(a("#imagify-check-api-container").html(' '+imagifyOptions.labels.ValidApiKeyText),!1):(!0===e?f.abort():(a("#imagify-check-api-container").remove(),b.after(''+imagifyOptions.labels.waitApiKeyCheckText+"")),e=!0,void(f=a.get(ajaxurl+c.imagify.concat+"action=imagify_check_api_key_validity&api_key="+b.val()+"&imagifycheckapikeynonce="+a("#imagifycheckapikeynonce").val()).done(function(b){b.success?(a("#imagify-check-api-container").remove(),swal({title:imagifyOptions.labels.ApiKeyCheckSuccessTitle,html:imagifyOptions.labels.ApiKeyCheckSuccessText,type:"success",padding:0,customClass:"imagify-sweet-alert"}).then(function(){location.reload()})):a("#imagify-check-api-container").html(' '+b.data),e=!1}))))}),a(".imagify-options-line").css("cursor","pointer").on("click.imagify",function(b){"INPUT"!==b.target.nodeName&&a('input[aria-describedby="'+a(this).attr("id")+'"]').trigger("click.imagify")}),a(".imagify-settings th span").on("click.imagify",function(){var b=a(this).parent().next("td").find(":checkbox");1===b.length&&b.trigger("click.imagify")}),a(".imagify-options-line").find("input").on("change.imagify focus.imagify",function(){var b;("checkbox"!==this.type||this.checked)&&(b=a(this).closest(".imagify-options-line").prev("label").prev(":checkbox"),b.length&&!b[0].checked&&b.prop("checked",!0))}),a('[name="imagify_settings[backup]"]').on("change.imagify",function(){var b=a(this),c=b.siblings("#backup-dir-is-writable"),d={action:"imagify_check_backup_dir_is_writable",_wpnonce:c.data("nonce")};if(b.is(":checked"))return void a.getJSON(ajaxurl,d).done(function(b){a.isPlainObject(b)&&b.success&&(b.data.is_writable?c.addClass("hidden"):c.removeClass("hidden"))});swal({title:imagifyOptions.labels.noBackupTitle,html:imagifyOptions.labels.noBackupText,type:"warning",customClass:"imagify-sweet-alert",padding:0,showCancelButton:!0,cancelButtonText:imagifySwal.labels.cancelButtonText,reverseButtons:!0}).then(function(){c.addClass("hidden")},function(){b.prop("checked",!0)})}),a('[name="imagify_settings[display_webp_method]"]').on("change.imagify init.imagify",function(b){"picture"===b.target.value?a(b.target).closest(".imagify-radio-group").next(".imagify-options-line").removeClass("imagify-faded"):a(b.target).closest(".imagify-radio-group").next(".imagify-options-line").addClass("imagify-faded")}).filter(":checked").trigger("init.imagify")}(jQuery,document,window),function(a,b,c,d){a.imagifyUser&&c.getJSON(ajaxurl,a.imagifyUser).done(function(a){c.isPlainObject(a)&&a.success&&(a.data.id=null,a.data.plan_id=null,a.data.is=[],c.each(a.data,function(b,d){var e=".imagify-user-"+b.replace(/_/g,"-");0===b.indexOf("is_")?d&&a.data.is.push(e):"is"!==b&&c(e).text(d)}),a.data.is.push("best-plan"),c(a.data.is.join(",")).removeClass("hidden"))})}(window,document,jQuery),function(a,b,c,d){function e(b){var d,e,f,g,h,i=!1,j=null;b&&(f=c("#imagify-custom-folders-selected"),g=f.find(".imagify-custom-folder-line"),h=g.find('[value="'+b+'"]'),h.length||(b=b.split("#///#"),d=b[1].replace(/\/+$/,"").toLowerCase(),e=a.imagify.template("imagify-custom-folder"),g.each(function(){var a=c(this),h=a.data("path").replace(/\/+$/,"").toLowerCase();return""!==h&&0===d.indexOf(h)?(i=!0,!1):d'+imagifyOptions.labels.filesTreeSubTitle+'

'+imagifyOptions.labels.cleaningInfo+'

    '+a.data+"
",type:"",customClass:"imagify-sweet-alert imagify-swal-has-subtitle imagify-folders-selection",showCancelButton:!0,padding:0,confirmButtonText:imagifyOptions.labels.confirmFilesTreeBtn,cancelButtonText:imagifySwal.labels.cancelButtonText,reverseButtons:!0}).then(function(){var a=c("#imagify-folders-tree input").serializeArray();a.length&&c.each(a,function(a,b){e(b.value)})}).catch(swal.noop)}).fail(function(){swal({title:imagifyOptions.labels.error,type:"error",customClass:"imagify-sweet-alert",padding:0})}).always(function(){b.removeAttr("disabled").next("img").attr("aria-hidden","true")}))}),c(b).on("click.imagify","#imagify-folders-tree [data-folder]",function(){var a=c(this),b=a.nextAll(".imagify-folders-sub-tree"),d=[];if(!a.attr("disabled")&&!a.siblings(":checkbox").is(":checked")){if(a.attr("disabled","disabled").addClass("imagify-loading"),b.length)return a.hasClass("imagify-is-open")?(b.addClass("hidden"),a.removeClass(" imagify-is-open")):(b.removeClass("hidden"),a.addClass("imagify-is-open")),void a.removeAttr("disabled").removeClass("imagify-loading");c("#imagify-custom-folders-selected").find("input").each(function(){d.push(this.value)}),c.post(imagifyOptions.getFilesTree,{folder:a.data("folder"),selected:d},null,"json").done(function(b){if(!b.success)return void swal({title:imagifyOptions.labels.error,html:b.data||"",type:"error",padding:0,customClass:"imagify-sweet-alert"});a.addClass("imagify-is-open").parent().append('
    '+b.data+"
")}).fail(function(){swal({title:imagifyOptions.labels.error,type:"error",padding:0,customClass:"imagify-sweet-alert"})}).always(function(){a.removeAttr("disabled").removeClass("imagify-loading")})}}),c("#imagify-custom-folders").on("click.imagify",".imagify-custom-folders-remove",function(){var b=c(this).closest(".imagify-custom-folder-line").addClass("imagify-will-remove");a.setTimeout(function(){b.remove(),c("#imagify-custom-folders-selected").siblings(".imagify-success.hidden").removeClass("hidden")},750)}),c("#imagify-add-themes-to-custom-folder").on("click.imagify",function(){var a=c(this);e(a.data("theme")),e(a.data("theme-parent")),a.replaceWith("

"+imagifyOptions.labels.themesAdded+"

")}))}(window,document,jQuery),function(a,b,c,d){imagifyOptions.bulk&&(a.imagify.optionsBulk={fetchQueue:[],queue:[],processingQueue:[],fetchError:!1,error:!1,working:!1,processIsStopped:!0,processedMedia:0,totalMedia:0,$button:null,$progressWrap:null,$progressBar:null,$progressText:null,init:function(){this.$button=c("#imagify-generate-webp-versions"),this.$progressWrap=this.$button.siblings(".imagify-progress"),this.$progressBar=this.$progressWrap.find(".bar"),this.$progressText=this.$progressBar.find(".percent"),c("#imagify_convert_to_webp").on("change.imagify init.imagify",{imagifyOptionsBulk:this},this.toggleButton).trigger("init.imagify"),this.$button.on("click.imagify",{imagifyOptionsBulk:this},this.maybeLaunchAllProcesses),c(b).on("imagifybeat-send",{imagifyOptionsBulk:this},this.addQueueImagifybeat).on("imagifybeat-tick",{imagifyOptionsBulk:this},this.processQueueImagifybeat).on("imagifybeat-send",this.addRequirementsImagifybeat).on("imagifybeat-tick",{imagifyOptionsBulk:this},this.processRequirementsImagifybeat)},toggleButton:function(a){this.checked?a.data.imagifyOptionsBulk.$button.removeAttr("disabled"):a.data.imagifyOptionsBulk.$button.attr("disabled","disabled")},maybeLaunchAllProcesses:function(b){b.data.imagifyOptionsBulk&&!b.data.imagifyOptionsBulk.working&&(b.data.imagifyOptionsBulk.hasBlockingError(!0)||(b.data.imagifyOptionsBulk.fetchQueue=imagifyOptions.bulk.contexts,b.data.imagifyOptionsBulk.queue=[],b.data.imagifyOptionsBulk.processingQueue=[],b.data.imagifyOptionsBulk.fetchError=!1,b.data.imagifyOptionsBulk.error=!1,b.data.imagifyOptionsBulk.working=!0,b.data.imagifyOptionsBulk.processIsStopped=!1,b.data.imagifyOptionsBulk.processedMedia=0,b.data.imagifyOptionsBulk.totalMedia=0,b.data.imagifyOptionsBulk.$button.attr("disabled","disabled").find(".dashicons").addClass("rotate"),c(a).on("beforeunload.imagify",b.data.imagifyOptionsBulk.getConfirmMessage),a.imagify.beat.interval(15),a.imagify.beat.disableSuspend(),b.data.imagifyOptionsBulk.fetchIDs()))},getConfirmMessage:function(){return imagifyOptions.bulk.labels.processing},addQueueImagifybeat:function(a,b){a.data.imagifyOptionsBulk&&a.data.imagifyOptionsBulk.processingQueue.length&&(b[imagifyOptions.bulk.imagifybeatIDs.queue]=a.data.imagifyOptionsBulk.processingQueue)},processQueueImagifybeat:function(a,b){a.data.imagifyOptionsBulk&&void 0!==b[imagifyOptions.bulk.imagifybeatIDs.queue]&&c.each(b[imagifyOptions.bulk.imagifybeatIDs.queue],function(b,c){a.data.imagifyOptionsBulk.mediaProcessed(c)})},addRequirementsImagifybeat:function(a,b){b[imagifyOptions.bulk.imagifybeatIDs.requirements]=1},processRequirementsImagifybeat:function(a,b){a.data.imagifyOptionsBulk&&void 0===b[imagifyOptions.bulk.imagifybeatIDs.requirements]||(b=b[imagifyOptions.bulk.imagifybeatIDs.requirements],imagifyOptions.bulk.curlMissing=b.curl_missing,imagifyOptions.bulk.editorMissing=b.editor_missing,imagifyOptions.bulk.extHttpBlocked=b.external_http_blocked,imagifyOptions.bulk.apiDown=b.api_down,imagifyOptions.bulk.keyIsValid=b.key_is_valid,imagifyOptions.bulk.isOverQuota=b.is_over_quota)},fetchIDs:function(){var a,b;if(!this.processIsStopped){if(!this.fetchQueue.length)return this.queue.length?(this.$progressBar.removeAttr("style"),this.$progressText.text("0"+(this.totalMedia?"/"+this.totalMedia:"")),this.$progressWrap.slideDown().attr("aria-hidden","false"),void this.processQueue()):(this.fetchError||(this.fetchError="no-images"),this.stopProcess(this.fetchError),void(this.fetchError=!1));a=this,b=this.fetchQueue.shift(),c.get(this.getAjaxUrl("getMediaIds",b)).done(function(d){var e;if(!a.processIsStopped)return e=d.data&&d.data.message?d.data.message:imagifyOptions.bulk.ajaxErrorText,d.success&&c.isArray(d.data)?void(d.data.length&&(a.totalMedia+=d.data.length,a.queue.push({context:b,optimizeURL:a.getAjaxUrl("bulkProcess",b),mediaIDs:d.data}))):void(a.fetchError||(a.fetchError=e))}).fail(function(){a.fetchError||(a.fetchError="get-unoptimized-images")}).always(function(){a.fetchIDs()})}},processQueue:function(){var a=this;this.processIsStopped||(this.queue.length||this.processingQueue.length)&&c.each(this.queue,function(b,d){if(a.processingQueue.length>=imagifyOptions.bulk.bufferSize)return!1;c.each(d.mediaIDs,function(){if(a.processMedia({context:d.context,mediaID:d.mediaIDs.shift(),optimizeURL:d.optimizeURL}),d.mediaIDs.length||a.queue.shift(),a.processingQueue.length>=imagifyOptions.bulk.bufferSize)return!1})})},processMedia:function(a){var b=this,d={context:a.context,mediaID:a.mediaID};this.processingQueue.push({context:a.context,mediaID:a.mediaID}),c.post({url:a.optimizeURL,data:{media_id:a.mediaID,context:a.context},dataType:"json"}).done(function(a){a.success||b.mediaProcessed(d)}).fail(function(){b.mediaProcessed(d)})},mediaProcessed:function(a){var b=this;this.processIsStopped||(c.each(this.processingQueue,function(c,d){if(a.context===d.context&&a.mediaID===d.mediaID)return b.processingQueue.splice(c,1),!1}),++this.processedMedia,a.progress=Math.floor(this.processedMedia/this.totalMedia*100),this.$progressBar.css("width",a.progress+"%"),this.$progressText.text(this.processedMedia+"/"+this.totalMedia),this.queue.length||this.processingQueue.length?this.processQueue():this.totalMedia===this.processedMedia&&this.queueEmpty())},queueEmpty:function(){var b={};!1!==this.error&&(b="invalid-api-key"===this.error?{title:imagifyOptions.bulk.labels.invalidAPIKeyTitle,type:"info"}:"over-quota"===this.error?{title:imagifyOptions.bulk.labels.overQuotaTitle,html:c("#tmpl-imagify-overquota-alert").html(),type:"info",customClass:"imagify-swal-has-subtitle imagify-swal-error-header",showConfirmButton:!1}:"get-unoptimized-images"===this.error||"consumed-all-data"===this.error?{title:imagifyOptions.bulk.labels.getUnoptimizedImagesErrorTitle,html:imagifyOptions.bulk.labels.getUnoptimizedImagesErrorText,type:"info"}:"no-images"===this.error?{title:imagifyOptions.bulk.labels.nothingToDoTitle,html:imagifyOptions.bulk.labels.nothingToDoText,type:"info"}:{title:imagifyOptions.bulk.labels.error,html:this.error,type:"info"},this.displayError(b),this.error=!1),this.fetchQueue=[],this.queue=[],this.processingQueue=[],this.fetchError=!1,this.working=!1,this.processIsStopped=!1,this.processedMedia=0,this.totalMedia=0,a.imagify.beat.resetInterval(),a.imagify.beat.enableSuspend(),c(a).off("beforeunload.imagify",this.getConfirmMessage),this.$progressWrap.slideUp().attr("aria-hidden","true"),this.$progressBar.removeAttr("style"),this.$progressText.text("0"),this.$button.removeAttr("disabled").find(".dashicons").removeClass("rotate")},hasBlockingError:function(a){return a=void 0!==a&&a,imagifyOptions.bulk.curlMissing?(a&&this.displayError({html:imagifyOptions.bulk.labels.curlMissing}),!0):imagifyOptions.bulk.editorMissing?(a&&this.displayError({html:imagifyOptions.bulk.labels.editorMissing}),!0):imagifyOptions.bulk.extHttpBlocked?(a&&this.displayError({html:imagifyOptions.bulk.labels.extHttpBlocked}),!0):imagifyOptions.bulk.apiDown?(a&&this.displayError({html:imagifyOptions.bulk.labels.apiDown}),!0):imagifyOptions.bulk.keyIsValid?!!imagifyOptions.bulk.isOverQuota&&(a&&this.displayError({title:imagifyOptions.bulk.labels.overQuotaTitle,html:c("#tmpl-imagify-overquota-alert").html(),type:"info",customClass:"imagify-swal-has-subtitle imagify-swal-error-header",showConfirmButton:!1}),!0):(a&&this.displayError({title:imagifyOptions.bulk.labels.invalidAPIKeyTitle,type:"info"}),!0)},displayError:function(a,b,d){var e={title:"",html:"",type:"error",customClass:"",width:620,padding:0,showCloseButton:!0,showConfirmButton:!0};c.isPlainObject(a)?d=c.extend({},e,a):(d=d||{},d=c.extend({},e,{title:a||"",html:b||""},d)),d.title=d.title||imagifyOptions.bulk.labels.error,d.customClass+=" imagify-sweet-alert",swal(d).catch(swal.noop)},getAjaxUrl:function(b,c){var d;return d=ajaxurl+a.imagify.concat+"_wpnonce="+imagifyOptions.bulk.ajaxNonce,d+="&action="+imagifyOptions.bulk.ajaxActions[b],d+="&context="+c,d+="&imagify_action=generate_webp"},stopProcess:function(a){this.processIsStopped=!0,this.error=a,this.queueEmpty()}},a.imagify.optionsBulk.init())}(window,document,jQuery),function(a,b,c,d){var e=c.propHooks.checked;c.propHooks.checked={set:function(a,b,d){var f;return f=void 0===e?a[d]=b:e(a,b,d),c(a).trigger("change.imagify"),f}},c(".imagify-select-all").on("click.imagify",function(){var a=c(this),b=a.data("action"),d=a.closest(".imagify-select-all-buttons"),e=d.prev(".imagify-check-group"),f="imagify-is-inactive";if(a.hasClass(f))return!1;d.find(".imagify-select-all").removeClass(f).attr("aria-disabled","false"),a.addClass(f).attr("aria-disabled","true"),e.find(".imagify-row-check").prop("checked",function(){return!c(this).is(":hidden,:disabled")&&"select"===b})}),c(".imagify-check-group .imagify-row-check").on("change.imagify",function(){var a=c(this).closest(".imagify-check-group"),b=a.find(".imagify-row-check"),d=b.filter(":visible:enabled").length,e=b.filter(":visible:enabled:checked").length,f=a.next(".imagify-select-all-buttons"),g="imagify-is-inactive";0===e&&f.find('[data-action="unselect"]').addClass(g).attr("aria-disabled","true"),e===d&&f.find('[data-action="select"]').addClass(g).attr("aria-disabled","true"),e!==d&&e>0&&f.find(".imagify-select-all").removeClass(g).attr("aria-disabled","false")})}(window,document,jQuery); \ No newline at end of file diff --git a/classes/Webp/Picture/Display.php b/classes/Webp/Picture/Display.php index 57576c5c5..f28c41232 100644 --- a/classes/Webp/Picture/Display.php +++ b/classes/Webp/Picture/Display.php @@ -50,7 +50,7 @@ public function __construct() { * @author Grégory Viguier */ public function init() { - add_action( 'template_redirect', [ $this, 'start_content_process' ], 6 ); + add_action( 'template_redirect', [ $this, 'start_content_process' ], -1000 ); } /** ----------------------------------------------------------------------------------------- */ @@ -167,10 +167,16 @@ public function process_content( $content ) { */ protected function build_picture_tag( $image ) { $to_remove = [ - 'alt' => '', - 'data-lazy-src' => '', - 'data-src' => '', - 'sizes' => '', + 'alt' => '', + 'data-lazy-src' => '', + 'data-src' => '', + 'src' => '', + 'data-lazy-srcset' => '', + 'data-srcset' => '', + 'srcset' => '', + 'data-lazy-sizes' => '', + 'data-sizes' => '', + 'sizes' => '', ]; $attributes = array_diff_key( $image['attributes'], $to_remove ); @@ -216,9 +222,10 @@ protected function build_picture_tag( $image ) { * @return string A tag. */ protected function build_source_tag( $image ) { - $attributes = [ - 'type' => 'image/webp', - 'srcset' => [ + $srcset_source = ! empty( $image['srcset_attribute'] ) ? $image['srcset_attribute'] : $image['src_attribute'] . 'set'; + $attributes = [ + 'type' => 'image/webp', + $srcset_source => [ $image['src']['webp_url'], ], ]; @@ -232,14 +239,27 @@ protected function build_source_tag( $image ) { continue; } - $attributes['srcset'][] = $srcset['webp_url'] . ' ' . $srcset['descriptor']; + $attributes[ $srcset_source ][] = $srcset['webp_url'] . ' ' . $srcset['descriptor']; } } - $attributes['srcset'] = implode( ', ', $attributes['srcset'] ); + $attributes[ $srcset_source ] = implode( ', ', $attributes[ $srcset_source ] ); - if ( ! empty( $image['attributes']['sizes'] ) ) { - $attributes['sizes'] = $image['attributes']['sizes']; + foreach ( [ 'data-lazy-srcset', 'data-srcset', 'srcset' ] as $srcset_attr ) { + if ( ! empty( $image['attributes'][ $srcset_attr ] ) && $srcset_attr !== $srcset_source ) { + $attributes[ $srcset_attr ] = $image['attributes'][ $srcset_attr ]; + } + } + + if ( 'srcset' !== $srcset_source && empty( $attributes['srcset'] ) && ! empty( $image['attributes']['src'] ) ) { + // Lazyload: the "src" attr should contain a placeholder (a data image or a blank.gif ). + $attributes['srcset'] = $image['attributes']['src']; + } + + foreach ( [ 'data-lazy-sizes', 'data-sizes', 'sizes' ] as $sizes_attr ) { + if ( ! empty( $image['attributes'][ $sizes_attr ] ) ) { + $attributes[ $sizes_attr ] = $image['attributes'][ $sizes_attr ]; + } } /** @@ -268,19 +288,6 @@ protected function build_source_tag( $image ) { * @return string A tag. */ protected function build_img_tag( $image ) { - $attributes = $image['attributes']; - $attributes['src'] = $image['src']['url']; - - if ( ! empty( $image['srcset'] ) ) { - $attributes['srcset'] = []; - - foreach ( $image['srcset'] as $srcset ) { - $attributes['srcset'][] = $srcset['url'] . ' ' . $srcset['descriptor']; - } - - $attributes['srcset'] = implode( ', ', $attributes['srcset'] ); - } - $to_remove = [ 'class' => '', 'height' => '', @@ -290,7 +297,7 @@ protected function build_img_tag( $image ) { 'width' => '', ]; - $attributes = array_diff_key( $attributes, $to_remove ); + $attributes = array_diff_key( $image['attributes'], $to_remove ); /** * Filter the attributes to be added to the tag. @@ -385,6 +392,10 @@ protected function get_images( $content ) { } foreach ( $image['srcset'] as $j => $srcset ) { + if ( ! is_array( $srcset ) ) { + continue; + } + if ( empty( $srcset['webp_exists'] ) || empty( $srcset['webp_url'] ) ) { unset( $images[ $i ]['srcset'][ $j ]['webp_url'] ); } @@ -444,7 +455,16 @@ protected function process_image( $image ) { } // Deal with the src attribute. - if ( empty( $attributes['src'] ) ) { + $src_source = false; + + foreach ( [ 'data-lazy-src', 'data-src', 'src' ] as $src_attr ) { + if ( ! empty( $attributes[ $src_attr ] ) ) { + $src_source = $src_attr; + break; + } + } + + if ( ! $src_source ) { // No src attribute. return false; } @@ -455,7 +475,7 @@ protected function process_image( $image ) { $extensions = implode( '|', $extensions ); } - if ( ! preg_match( '@^(?(?:https?:)?//.+\.(?' . $extensions . '))(?\?.*)?$@i', $attributes['src'], $src ) ) { + if ( ! preg_match( '@^(?(?:https?:)?//.+\.(?' . $extensions . '))(?\?.*)?$@i', $attributes[ $src_source ], $src ) ) { // Not a supported image format. return false; } @@ -465,22 +485,33 @@ protected function process_image( $image ) { $webp_url .= ! empty( $src['query'] ) ? $src['query'] : ''; $data = [ - 'tag' => $image, - 'attributes' => $attributes, - 'src' => [ - 'url' => $attributes['src'], + 'tag' => $image, + 'attributes' => $attributes, + 'src_attribute' => $src_source, + 'src' => [ + 'url' => $attributes[ $src_source ], 'webp_url' => $webp_url, 'webp_path' => $webp_path, 'webp_exists' => $webp_path && $this->filesystem->exists( $webp_path ), ], - 'srcset' => [], + 'srcset_attribute' => false, + 'srcset' => [], ]; - unset( $data['attributes']['src'], $data['attributes']['srcset'] ); - // Deal with the srcset attribute. - if ( ! empty( $attributes['srcset'] ) ) { - $srcset = explode( ',', $attributes['srcset'] ); + $srcset_source = false; + + foreach ( [ 'data-lazy-srcset', 'data-srcset', 'srcset' ] as $srcset_attr ) { + if ( ! empty( $attributes[ $srcset_attr ] ) ) { + $srcset_source = $srcset_attr; + break; + } + } + + if ( $srcset_source ) { + $data['srcset_attribute'] = $srcset_source; + + $srcset = explode( ',', $attributes[ $srcset_source ] ); foreach ( $srcset as $srcs ) { $srcs = preg_split( '/\s+/', trim( $srcs ) ); @@ -533,7 +564,7 @@ protected function process_image( $image ) { return false; } - if ( ! isset( $data['tag'], $data['attributes'], $data['src'], $data['srcset'] ) ) { + if ( ! isset( $data['tag'], $data['attributes'], $data['src_attribute'], $data['src'], $data['srcset_attribute'], $data['srcset'] ) ) { return false; } @@ -565,21 +596,36 @@ protected function is_html( $content ) { * @return string|bool The file path. False on failure. */ protected function url_to_path( $url ) { - static $scheme; static $uploads_url; static $uploads_dir; static $root_url; static $root_dir; + static $cdn_url; + static $domain_url; - if ( ! isset( $scheme ) ) { - $scheme = is_ssl() ? 'https' : 'http'; - $uploads_url = set_url_scheme( $this->filesystem->get_upload_baseurl(), $scheme ); + if ( ! isset( $uploads_url ) ) { + $uploads_url = set_url_scheme( $this->filesystem->get_upload_baseurl() ); $uploads_dir = $this->filesystem->get_upload_basedir( true ); - $root_url = set_url_scheme( $this->filesystem->get_site_root_url(), $scheme ); + $root_url = set_url_scheme( $this->filesystem->get_site_root_url() ); $root_dir = $this->filesystem->get_site_root(); + $cdn_url = $this->get_cdn_source(); + $cdn_url = $cdn_url['url'] ? set_url_scheme( $cdn_url['url'] ) : false; + $domain_url = false; + + if ( $cdn_url ) { + $domain_url = wp_parse_url( $root_url ); + + if ( ! empty( $domain_url['scheme'] ) && ! empty( $domain_url['host'] ) ) { + $domain_url = $domain_url['scheme'] . '://' . $domain_url['host'] . '/'; + } + } } - $url = set_url_scheme( $url, $scheme ); + $url = set_url_scheme( $url ); + + if ( $domain_url && stripos( $url, $cdn_url ) === 0 ) { + $url = str_ireplace( $cdn_url, $domain_url, $url ); + } if ( stripos( $url, $uploads_url ) === 0 ) { return str_ireplace( $uploads_url, $uploads_dir, $url ); @@ -591,4 +637,108 @@ protected function url_to_path( $url ) { return false; } + + /** + * Get the CDN "source". + * + * @since 1.9.3 + * @access public + * @author Grégory Viguier + * + * @param string $option_url An URL to use instead of the one stored in the option. It is used only if no constant/filter. + * @return array { + * @type string $source Where does it come from? Possible values are 'constant', 'filter', or 'option'. + * @type string $name Who? Can be a constant name, a plugin name, or an empty string. + * @type string $url The CDN URL, with a trailing slash. An empty string if no URL is set. + * } + */ + public function get_cdn_source( $option_url = '' ) { + if ( defined( 'IMAGIFY_CDN_URL' ) && IMAGIFY_CDN_URL && is_string( IMAGIFY_CDN_URL ) ) { + // Use a constant. + $source = [ + 'source' => 'constant', + 'name' => 'IMAGIFY_CDN_URL', + 'url' => IMAGIFY_CDN_URL, + ]; + } else { + // Maybe use a filter. + $filter_source = [ + 'name' => null, + 'url' => null, + ]; + + /** + * Provide a custom CDN source. + * + * @since 1.9.3 + * @author Grégory Viguier + * + * @param array $filter_source { + * @type $name string The name of which provides the URL (plugin name, etc). + * @type $url string The CDN URL. + * } + */ + $filter_source = apply_filters( 'imagify_cdn_source', $filter_source ); + + if ( ! empty( $filter_source['url'] ) ) { + $source = [ + 'source' => 'filter', + 'name' => ! empty( $filter_source['name'] ) ? $filter_source['name'] : '', + 'url' => $filter_source['url'], + ]; + } + } + + if ( empty( $source['url'] ) ) { + // No constant, no filter: use the option. + $source = [ + 'source' => 'option', + 'name' => '', + 'url' => $option_url && is_string( $option_url ) ? $option_url : get_imagify_option( 'cdn_url' ), + ]; + } + + if ( empty( $source['url'] ) ) { + // Nothing set. + return [ + 'source' => 'option', + 'name' => '', + 'url' => '', + ]; + } + + $source['url'] = $this->sanitize_cdn_url( $source['url'] ); + + if ( empty( $source['url'] ) ) { + // Not an URL. + return [ + 'source' => 'option', + 'name' => '', + 'url' => '', + ]; + } + + return $source; + } + + /** + * Sanitize the CDN URL value. + * + * @since 1.9.3 + * @access public + * @author Grégory Viguier + * + * @param string $url The URL to sanitize. + * @return string + */ + public function sanitize_cdn_url( $url ) { + $url = sanitize_text_field( $url ); + + if ( ! $url || ! preg_match( '@^https?://.+\.[^.]+@i', $url ) ) { + // Not an URL. + return ''; + } + + return trailingslashit( $url ); + } } diff --git a/composer.json b/composer.json index 604c62119..3418fc98c 100644 --- a/composer.json +++ b/composer.json @@ -48,7 +48,8 @@ "Imagify\\ThirdParty\\EnableMediaReplace\\": "inc/3rd-party/enable-media-replace/classes/", "Imagify\\ThirdParty\\FormidablePro\\": "inc/3rd-party/formidable-pro/classes/", "Imagify\\ThirdParty\\NGG\\": "inc/3rd-party/nextgen-gallery/classes/", - "Imagify\\ThirdParty\\RegenerateThumbnails\\": "inc/3rd-party/regenerate-thumbnails/classes/" + "Imagify\\ThirdParty\\RegenerateThumbnails\\": "inc/3rd-party/regenerate-thumbnails/classes/", + "Imagify\\ThirdParty\\WPRocket\\": "inc/3rd-party/wp-rocket/classes/" }, "classmap": [ "inc/classes", diff --git a/inc/3rd-party/3rd-party.php b/inc/3rd-party/3rd-party.php index dc3295855..52c3ab6b8 100755 --- a/inc/3rd-party/3rd-party.php +++ b/inc/3rd-party/3rd-party.php @@ -12,7 +12,7 @@ require IMAGIFY_PATH . 'inc/3rd-party/regenerate-thumbnails/regenerate-thumbnails.php'; require IMAGIFY_PATH . 'inc/3rd-party/screets-lc.php'; require IMAGIFY_PATH . 'inc/3rd-party/wp-real-media-library.php'; -require IMAGIFY_PATH . 'inc/3rd-party/wp-rocket.php'; +require IMAGIFY_PATH . 'inc/3rd-party/wp-rocket/wp-rocket.php'; require IMAGIFY_PATH . 'inc/3rd-party/yoast-seo.php'; /** diff --git a/inc/3rd-party/wp-rocket.php b/inc/3rd-party/wp-rocket.php deleted file mode 100644 index 426f10bff..000000000 --- a/inc/3rd-party/wp-rocket.php +++ /dev/null @@ -1,28 +0,0 @@ -dequeue_script( array( 'sweetalert-core', 'sweetalert', 'notices' ) ); - } - -endif; diff --git a/inc/3rd-party/wp-rocket/classes/Main.php b/inc/3rd-party/wp-rocket/classes/Main.php new file mode 100755 index 000000000..185edb4da --- /dev/null +++ b/inc/3rd-party/wp-rocket/classes/Main.php @@ -0,0 +1,99 @@ +dequeue_script( array( 'sweetalert-core', 'sweetalert', 'notices' ) ); + } + + /** + * Provide a custom CDN source. + * + * @since 1.9.3 + * @author Grégory Viguier + * + * @param array $source { + * An array of arguments. + * + * @type $name string The name of which provides the URL (plugin name, etc). + * @type $url string The CDN URL. + * } + * @return array + */ + public function set_cdn_source( $source ) { + if ( ! function_exists( 'get_rocket_cdn_cnames' ) || ! function_exists( 'get_rocket_option' ) ) { + return $source; + } + + if ( ! get_rocket_option( 'cdn' ) ) { + return $source; + } + + $url = get_rocket_cdn_cnames( [ 'all', 'images' ] ); + + if ( ! $url ) { + return $source; + } + + $url = reset( $url ); + + if ( ! $url ) { + return $source; + } + + if ( ! preg_match( '@^(https?:)?//@i', $url ) ) { + $url = '//' . $url; + } + + $scheme = wp_parse_url( \Imagify_Filesystem::get_instance()->get_site_root_url() ); + $scheme = ! empty( $scheme['scheme'] ) ? $scheme['scheme'] : null; + $url = set_url_scheme( $url, $scheme ); + + $source['name'] = 'WP Rocket'; + $source['url'] = $url; + + return $source; + } +} diff --git a/inc/3rd-party/wp-rocket/wp-rocket.php b/inc/3rd-party/wp-rocket/wp-rocket.php new file mode 100644 index 000000000..ced2a28cb --- /dev/null +++ b/inc/3rd-party/wp-rocket/wp-rocket.php @@ -0,0 +1,8 @@ +init(); + +endif; diff --git a/inc/classes/class-imagify-options.php b/inc/classes/class-imagify-options.php index b1e8e952c..fdee187b7 100644 --- a/inc/classes/class-imagify-options.php +++ b/inc/classes/class-imagify-options.php @@ -44,6 +44,7 @@ class Imagify_Options extends Imagify_Abstract_Options { 'convert_to_webp' => 0, 'display_webp' => 0, 'display_webp_method' => 'picture', + 'cdn_url' => '', 'exif' => 0, 'disallowed-sizes' => array(), 'admin_bar_menu' => 0, @@ -190,6 +191,19 @@ public function sanitize_and_validate_value( $key, $value, $default ) { // For an invalid value, return the "reset" value. $reset_values = $this->get_reset_values(); return $reset_values[ $key ]; + + case 'cdn_url': + $cdn_source = \Imagify\Webp\Picture\Display::get_instance()->get_cdn_source( $value ); + + if ( 'option' !== $cdn_source['source'] ) { + /** + * If the URL is defined via constant or filter, unset the option. + * This is useful when the CDN is disabled: there is no need to do anything then. + */ + return ''; + } + + return $cdn_source['url']; } return false; diff --git a/inc/classes/class-imagify-settings.php b/inc/classes/class-imagify-settings.php index e7341f1a9..fe4d7f31c 100644 --- a/inc/classes/class-imagify-settings.php +++ b/inc/classes/class-imagify-settings.php @@ -458,14 +458,14 @@ public function update_site_option_on_network() { * {current_value} int|bool USE ONLY WHEN DEALING WITH DATA THAT IS NOT SAVED IN THE PLUGIN OPTIONS. If not provided, the field will automatically get the value from the options. */ public function field_checkbox( $args ) { - $args = array_merge( array( + $args = array_merge( [ 'option_name' => '', 'label' => '', 'info' => '', - 'attributes' => array(), + 'attributes' => [], // To not use the plugin settings: use an integer. 'current_value' => null, - ), $args ); + ], $args ); if ( ! $args['option_name'] || ! $args['label'] ) { return; @@ -473,17 +473,17 @@ public function field_checkbox( $args ) { if ( is_numeric( $args['current_value'] ) || is_bool( $args['current_value'] ) ) { // We don't use the plugin settings. - $current_value = (int) (bool) $args['current_values']; + $current_value = (int) (bool) $args['current_value']; } else { // This is a normal plugin setting. $current_value = $this->options->get( $args['option_name'] ); } $option_name_class = sanitize_html_class( $args['option_name'] ); - $attributes = array( + $attributes = [ 'name' => $this->option_name . '[' . $args['option_name'] . ']', 'id' => 'imagify_' . $option_name_class, - ); + ]; if ( $args['info'] && empty( $attributes['aria-describedby'] ) ) { $attributes['aria-describedby'] = 'describe-' . $option_name_class; @@ -524,17 +524,16 @@ public function field_checkbox( $args ) { * {current_values} array USE ONLY WHEN DEALING WITH DATA THAT IS NOT SAVED IN THE PLUGIN OPTIONS. If not provided, the field will automatically get the value from the options. */ public function field_checkbox_list( $args ) { - - $args = array_merge( array( + $args = array_merge( [ 'option_name' => '', 'legend' => '', - 'values' => array(), - 'disabled_values' => array(), + 'values' => [], + 'disabled_values' => [], 'reverse_check' => false, - 'attributes' => array(), + 'attributes' => [], // To not use the plugin settings: use an array. 'current_values' => false, - ), $args ); + ], $args ); if ( ! $args['option_name'] || ! $args['values'] ) { return; @@ -549,11 +548,11 @@ public function field_checkbox_list( $args ) { } $option_name_class = sanitize_html_class( $args['option_name'] ); - $attributes = array_merge( array( + $attributes = array_merge( [ 'name' => $this->option_name . '[' . $args['option_name'] . ( $args['reverse_check'] ? '-checked' : '' ) . '][]', 'id' => 'imagify_' . $option_name_class . '_%s', 'class' => 'imagify-row-check', - ), $args['attributes'] ); + ], $args['attributes'] ); $id_attribute = $attributes['id']; unset( $attributes['id'] ); @@ -657,11 +656,11 @@ public function field_radio_list( $args ) { } $option_name_class = sanitize_html_class( $args['option_name'] ); - $attributes = array_merge( array( + $attributes = array_merge( [ 'name' => $this->option_name . '[' . $args['option_name'] . ']', 'id' => 'imagify_' . $option_name_class . '_%s', 'class' => 'imagify-row-radio', - ), $args['attributes'] ); + ], $args['attributes'] ); $id_attribute = $attributes['id']; unset( $attributes['id'] ); @@ -697,6 +696,115 @@ public function field_radio_list( $args ) { 'value'. + * {current_value} int|bool USE ONLY WHEN DEALING WITH DATA THAT IS NOT SAVED IN THE PLUGIN OPTIONS. If not provided, the field will automatically get the value from the options. + */ + public function field_text_box( $args ) { + $args = array_merge( [ + 'option_name' => '', + 'label' => '', + 'info' => '', + 'attributes' => [], + // To not use the plugin settings. + 'current_value' => null, + ], $args ); + + if ( ! $args['option_name'] || ! $args['label'] ) { + return; + } + + if ( is_numeric( $args['current_value'] ) || is_string( $args['current_value'] ) ) { + // We don't use the plugin settings. + $current_value = $args['current_value']; + } else { + // This is a normal plugin setting. + $current_value = $this->options->get( $args['option_name'] ); + } + + $option_name_class = sanitize_html_class( $args['option_name'] ); + $attributes = [ + 'name' => $this->option_name . '[' . $args['option_name'] . ']', + 'id' => 'imagify_' . $option_name_class, + ]; + + if ( $args['info'] && empty( $attributes['aria-describedby'] ) ) { + $attributes['aria-describedby'] = 'describe-' . $option_name_class; + } + + $attributes = array_merge( $attributes, $args['attributes'] ); + $args['attributes'] = self::build_attributes( $attributes ); + ?> + + + /> + + + + + + 'value'. + * {current_value} int|bool USE ONLY WHEN DEALING WITH DATA THAT IS NOT SAVED IN THE PLUGIN OPTIONS. If not provided, the field will automatically get the value from the options. + */ + public function field_hidden( $args ) { + $args = array_merge( [ + 'option_name' => '', + 'attributes' => [], + // To not use the plugin settings. + 'current_value' => null, + ], $args ); + + if ( ! $args['option_name'] ) { + return; + } + + if ( is_numeric( $args['current_value'] ) || is_string( $args['current_value'] ) ) { + // We don't use the plugin settings. + $current_value = $args['current_value']; + } else { + // This is a normal plugin setting. + $current_value = $this->options->get( $args['option_name'] ); + } + + $option_name_class = sanitize_html_class( $args['option_name'] ); + $attributes = [ + 'name' => $this->option_name . '[' . $args['option_name'] . ']', + 'id' => 'imagify_' . $option_name_class, + ]; + + $attributes = array_merge( $attributes, $args['attributes'] ); + $args['attributes'] = self::build_attributes( $attributes ); + ?> + /> + dequeue_script( array( 'sweetalert-core', 'sweetalert', 'notices' ) ); + } + +endif; diff --git a/views/part-settings-webp.php b/views/part-settings-webp.php index d1a7d09a4..1ccf1caa4 100755 --- a/views/part-settings-webp.php +++ b/views/part-settings-webp.php @@ -22,9 +22,6 @@ $settings->field_checkbox( [ 'option_name' => 'display_webp', 'label' => __( 'Display images in webp format on the site', 'imagify' ), - 'attributes' => [ - 'aria-describedby' => 'describe-convert_to_webp', - ], ] ); ?> @@ -33,53 +30,98 @@ $settings->field_radio_list( [ 'option_name' => 'display_webp_method', 'values' => [ - 'picture' => __( 'Use <picture> tags', 'imagify' ), 'rewrite' => __( 'Use rewrite rules', 'imagify' ), + /* translators: 1 and 2 are tag opening and closing. */ + 'picture' => sprintf( __( 'Use <picture> tags %1$s(preferred)%2$s', 'imagify' ), '', '' ), ], 'attributes' => [ 'aria-describedby' => 'describe-convert_to_webp', ], ] ); ?> + +
+ get_cdn_source(); + + if ( 'option' !== $cdn_source['source'] ) { + if ( 'constant' === $cdn_source['source'] ) { + printf( + /* translators: 1 is an URL, 2 is a php constant name. */ + esc_html__( 'Your CDN URL is set to %1$s by the constant %2$s.', 'imagify' ), + '' . esc_url( $cdn_source['url'] ) . '', + '' . esc_html( $cdn_source['name'] ) . '' + ); + } elseif ( ! empty( $cdn_source['name'] ) ) { + printf( + /* translators: 1 is an URL, 2 is a plugin name. */ + esc_html__( 'Your CDN URL is set to %1$s by %2$s.', 'imagify' ), + '' . esc_url( $cdn_source['url'] ) . '', + '' . esc_html( $cdn_source['name'] ) . '' + ); + } else { + printf( + /* translators: %s is an URL. */ + esc_html__( 'Your CDN URL is set to %1$s by filter.', 'imagify' ), + '' . esc_url( $cdn_source['url'] ) . '' + ); + } + + $settings->field_hidden( [ + 'option_name' => 'cdn_url', + 'current_value' => $cdn_source['url'], + ] ); + } else { + $settings->field_text_box( [ + 'option_name' => 'cdn_url', + 'label' => __( 'If you use a CDN, specify the URL:', 'imagify' ), + 'attributes' => [ + 'size' => 30, + 'placeholder' => __( 'https://cdn.example.com', 'imagify' ), + ], + ] ); + } + ?> +
- -
- - tag opening, 4 is the tag closing. */ - esc_html__( 'The first option replaces the %1$s tags with %2$s tags. %3$sThis is the preferred solution but some themes may break%4$s, so make sure to verify that everything seems fine.', 'imagify' ), - '<img>', - '<picture>', - '', - '' - ); +
+ + get_file_path( true ); - echo '
'; + if ( $conf_file_path ) { + printf( + /* translators: 1 is a file name, 2 is a tag opening, 3 is the tag closing. */ + esc_html__( 'The first option adds rewrite rules to your site’s configuration file (%1$s) and does not alter your pages code. %2$sThis does not work with CDN though.%3$s', 'imagify' ), + '' . esc_html( $conf_file_path ) . '', + '', + '' + ); - $conf_file_path = \Imagify\Webp\Display::get_instance()->get_file_path( true ); + echo '
'; + } - if ( $conf_file_path ) { printf( - /* translators: 1 is a file name, 2 is a tag opening, 3 is the tag closing. */ - esc_html__( 'The second option adds rewrite rules to your site’s configuration file (%1$s) and does not alter your pages code. %2$sThis does not work with CDN though.%3$s', 'imagify' ), - '' . esc_html( $conf_file_path ) . '', + /* translators: 1 and 2 are HTML tag names, 3 is a tag opening, 4 is the tag closing. */ + esc_html__( 'The second option replaces the %1$s tags with %2$s tags. %3$sThis is the preferred solution but some themes may break%4$s, so make sure to verify that everything seems fine.', 'imagify' ), + '<img>', + '<picture>', '', '' ); echo '
'; - } - /** - * Add more information about webp. - * - * @since 1.9 - * @author Grégory Viguier - */ - do_action( 'imagify_settings_webp_info' ); - ?> + /** + * Add more information about webp. + * + * @since 1.9 + * @author Grégory Viguier + */ + do_action( 'imagify_settings_webp_info' ); + ?> +
Date: Fri, 14 Jun 2019 23:07:32 +0200 Subject: [PATCH 10/11] Hotfix: better wording to explain the role of the "Generate missing webp versions" button --- views/part-settings-webp.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/views/part-settings-webp.php b/views/part-settings-webp.php index 1ccf1caa4..86c71ee0d 100755 --- a/views/part-settings-webp.php +++ b/views/part-settings-webp.php @@ -135,7 +135,7 @@ echo esc_html( sprintf( /* translators: %s is a formatted number (don’t use %d). */ - _n( 'It seems that you have %s media without webp versions. You can generate them here if a backup copy is available.', 'It seems that you have %s media without webp versions. You can generate them here if backup copies are available.', $count, 'imagify' ), + _n( 'It seems that you have %s optimized image without webp versions. You can generate them here if a backup copy is available.', 'It seems that you have %s optimized images without webp versions. You can generate them here if backup copies are available.', $count, 'imagify' ), number_format_i18n( $count ) ) ); From a4324027e491bd29cc0b441040117a7e34f7ed17 Mon Sep 17 00:00:00 2001 From: Git I Hate You Date: Fri, 14 Jun 2019 23:33:02 +0200 Subject: [PATCH 11/11] Hotfix: bump to version 1.9.3 + changelog --- imagify.php | 4 ++-- package.json | 2 +- readme.txt | 14 ++++++++++++-- 3 files changed, 15 insertions(+), 5 deletions(-) diff --git a/imagify.php b/imagify.php index a5d1c1aea..3d7e6ee6c 100644 --- a/imagify.php +++ b/imagify.php @@ -3,7 +3,7 @@ * Plugin Name: Imagify * Plugin URI: https://wordpress.org/plugins/imagify/ * Description: Dramaticaly reduce image file sizes without losing quality, make your website load faster, boost your SEO and save money on your bandwidth using Imagify, the new most advanced image optimization tool. - * Version: 1.9.2 + * Version: 1.9.3 * Requires PHP: 5.4 * Author: WP Media * Author URI: https://wp-media.me/ @@ -20,7 +20,7 @@ defined( 'ABSPATH' ) || die( 'Cheatin’ uh?' ); // Imagify defines. -define( 'IMAGIFY_VERSION', '1.9.2' ); +define( 'IMAGIFY_VERSION', '1.9.3' ); define( 'IMAGIFY_SLUG', 'imagify' ); define( 'IMAGIFY_FILE', __FILE__ ); define( 'IMAGIFY_PATH', realpath( plugin_dir_path( IMAGIFY_FILE ) ) . '/' ); diff --git a/package.json b/package.json index ba23f7b89..1fae99922 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "imagify", "description": "Imagify Image Optimizer. Dramatically reduce image file sizes without losing quality, make your website load faster, boost your SEO and save money on your bandwidth.", - "version": "1.9.2", + "version": "1.9.3", "homepage": "https://wordpress.org/plugins/imagify/", "license": "GPL-2.0", "private": true, diff --git a/readme.txt b/readme.txt index 1f1879cae..58e82b229 100755 --- a/readme.txt +++ b/readme.txt @@ -2,8 +2,8 @@ Contributors: wp_media, GregLone Tags: compress image, images, performance, optimization, photos, upload, resize, gif, png, jpg, reduce image size, retina Requires at least: 4.0.0 -Tested up to: 5.2 -Stable tag: 1.9.2 +Tested up to: 5.2.1 +Stable tag: 1.9.3 Dramatically reduce image file sizes without losing quality, make your website load faster, boost your SEO and save money on your bandwidth. @@ -138,6 +138,16 @@ When the plugin is disabled, your existing images remain optimized. Backups of t 4. Other Media Page == Changelog == += 1.9.3 - 2019/06/17 = +* Improvement: better compatibility with CDNs when displaying webp images with `<picture>` tags. There is now a new setting field to fill in the CDN URL in use. +* Improvement: don’t use Heartbeat anymore. This speeds up the optimization process and prevents other plugins to break everything when they remove Heartbeat. +* Fix: a fatal error upon plugin deactivation. +* Fix: an occasional fatal error preventing the optimization process to work. +* Fix: conflict with plugins using an ancient version of Composer. +* Fix: php notices displayed on the bulk optimization page on rare cases. +* Fix: a php notice about "Non-string needles" with php 7.3. +* Fix: a php notice displayed when restoring a custom file. + = 1.9.2 - 2019/05/16 = * Fix: don’t display support bubble anymore.