PluginProbe
Imagify Image Optimization: Optimize Images | Compress & Convert to WebP/AVIF / trunk
Imagify Image Optimization: Optimize Images | Compress & Convert to WebP/AVIF vtrunk
2.3.4 2.3.3 2.3.2 2.3.1 2.3.0 2.2.9 2.2.8 trunk 1.10 1.3.3 1.3.4 1.3.5 1.3.5.1 1.3.5.2 1.3.6 1.3.6.1 1.4 1.4.1 1.4.2 1.4.3 1.4.4 1.4.5 1.4.6 1.4.7 1.5 All 103 releases
← All changes | assets/js/options.js +113 -11 2.2.8 → trunk View file →
@@ -45,9 +45,12 @@
45 45 } ).then( function() {
46 46 location.reload();
47 47 } );
48 48 }
49 -
49 + } )
50 + .always( function() {
51 + // Always release the lock, even when the request was aborted or failed,
52 + // so a following blur can trigger a fresh check instead of staying stuck.
50 53 busy = false;
51 54 } );
52 55 } );
53 56
@@ -145,8 +148,53 @@
145 148 $( e.target ).closest( '.imagify-radio-group' ).next( '.imagify-options-line' ).addClass( 'imagify-faded' );
146 149 }
147 150 } ).filter( ':checked' ).trigger( 'init.imagify' );
148 151
152 + /**
153 + * Reset Internal State button.
154 + */
155 + $( '#imagify-reset-internal-state' ).on( 'click.imagify', function() {
156 + var $button = $( this ),
157 + nonce = $button.data( 'nonce' ),
158 + $feedback = $( '#imagify-reset-internal-state-feedback' );
159 +
160 + swal( {
161 + title: imagifyOptions.resetInternalState.confirm,
162 + type: 'warning',
163 + customClass: 'imagify-sweet-alert',
164 + padding: 0,
165 + showCancelButton: true,
166 + cancelButtonText: imagifySwal.labels.cancelButtonText,
167 + reverseButtons: true
168 + } ).then(
169 + function() {
170 + $button.prop( 'disabled', true );
171 + $feedback.text( '' ).removeClass( 'imagify-success imagify-error' );
172 +
173 + $.post( ajaxurl, {
174 + 'action': imagifyOptions.resetInternalState.action,
175 + '_wpnonce': nonce
176 + } )
177 + .done( function( response ) {
178 + if ( response && response.success ) {
179 + $feedback.text( imagifyOptions.resetInternalState.success ).addClass( 'imagify-success' );
180 + } else {
181 + $feedback.text( imagifyOptions.resetInternalState.error ).addClass( 'imagify-error' );
182 + }
183 + } )
184 + .fail( function() {
185 + $feedback.text( imagifyOptions.resetInternalState.error ).addClass( 'imagify-error' );
186 + } )
187 + .always( function() {
188 + $button.prop( 'disabled', false );
189 + } );
190 + },
191 + function() {
192 + // User cancelled — do nothing.
193 + }
194 + );
195 + } );
196 +
149 197 } )(jQuery, document, window);
150 198
151 199
152 200 // Display Imagify User data =======================================================================
@@ -470,9 +518,9 @@
470 518 /*
471 519 * Init.
472 520 */
473 521 init: function () {
474 - var processed, progress;
522 + var progress;
475 523 this.$missingWebpElement = $('.generate-missing-webp');
476 524 this.$missingWebpMessage = $('.generate-missing-webp p');
477 525
478 526 this.$button = $( '#imagify-generate-webp-versions' );
@@ -510,12 +558,11 @@
510 558 w.imagify.beat.disableSuspend();
511 559
512 560 this.$missingWebpMessage.hide().attr('aria-hidden', 'true');
513 561
514 - processed = imagifyOptions.bulk.progress_next_gen.total - imagifyOptions.bulk.progress_next_gen.remaining;
515 - progress = Math.floor( processed / imagifyOptions.bulk.progress_next_gen.total * 100 );
516 - this.$progressBar.css( 'width', progress + '%' );
517 - this.$progressText.text( processed + '/' + imagifyOptions.bulk.progress_next_gen.total );
562 + progress = this.getProgress( imagifyOptions.bulk.progress_next_gen.total, imagifyOptions.bulk.progress_next_gen.remaining );
563 + this.$progressBar.css( 'width', progress.percent + '%' );
564 + this.$progressText.text( progress.processed + '/' + progress.total );
518 565
519 566 this.$progressWrap.slideDown().attr( 'aria-hidden', 'false' ).removeClass( 'hidden' );
520 567 }
521 568 },
@@ -577,8 +624,28 @@
577 624 data[ imagifyOptions.bulk.imagifybeatIDs.progress ] = imagifyOptions.bulk.contexts;
578 625 },
579 626
580 627 /**
628 + * Compute a display-safe progress state.
629 + *
630 + * `total` is a snapshot taken when the run started, while `remaining` is recounted on
631 + * every Imagifybeat tick. Anything that grows the workload mid-run pushes `remaining`
632 + * above `total`: uploading new media while the run is in progress, or switching the
633 + * Next-Gen format so that every media is suddenly missing one. `total - remaining` then
634 + * rendered as a negative count, and a snapshot of 0 divided by zero on top of that.
635 + *
636 + * Track the largest workload seen instead, so the count never goes negative and the
637 + * denominator reflects what is actually left to do.
638 + *
639 + * @param {number} total Number of media to process when the run started.
640 + * @param {number} remaining Number of media still waiting to be processed.
641 + * @return {object} Object with `processed`, `total` and `percent` keys.
642 + */
643 + getProgress: function ( total, remaining ) {
644 + return w.imagify.getProgress( total, remaining );
645 + },
646 +
647 + /**
581 648 * Listen for the custom event "imagifybeat-tick" on $(document).
582 649 * It allows to update various data periodically.
583 650 *
584 651 * @param {object} e Event object.
@@ -584,9 +651,9 @@
584 651 * @param {object} e Event object.
585 652 * @param {object} data Object containing all Imagifybeat IDs.
586 653 */
587 654 processQueueImagifybeat: function ( e, data ) {
588 - var images_status, processed, progress;
655 + var images_status, progress;
589 656
590 657 if ( e.data.imagifyOptionsBulk && typeof data[ imagifyOptions.bulk.imagifybeatIDs.progress ] === 'undefined' ) {
591 658 return;
592 659 }
@@ -602,12 +669,11 @@
602 669 e.data.imagifyOptionsBulk.processFinished();
603 670 return;
604 671 }
605 672
606 - processed = images_status.total - images_status.remaining;
607 - progress = Math.floor( processed / images_status.total * 100 );
608 - e.data.imagifyOptionsBulk.$progressBar.css( 'width', progress + '%' );
609 - e.data.imagifyOptionsBulk.$progressText.text( processed + '/' + images_status.total );
673 + progress = e.data.imagifyOptionsBulk.getProgress( images_status.total, images_status.remaining );
674 + e.data.imagifyOptionsBulk.$progressBar.css( 'width', progress.percent + '%' );
675 + e.data.imagifyOptionsBulk.$progressText.text( progress.processed + '/' + progress.total );
610 676 },
611 677
612 678 /**
613 679 * Add a Imagifybeat ID for requirements on "imagifybeat-send" event.
@@ -990,4 +1056,40 @@
990 1056 }
991 1057 } );
992 1058
993 1059 } )(window, document, jQuery);
1060 +
1061 +// Imagify Analytics opt-in toggle ================================================================
1062 +(function($) {
1063 +
1064 + var $checkbox = $( '#imagify-analytics-enabled' );
1065 +
1066 + if ( ! $checkbox.length ) {
1067 + return;
1068 + }
1069 +
1070 + $checkbox.on( 'change.imagify-analytics', function() {
1071 + var nonce = $( this ).data( 'nonce' );
1072 +
1073 + $.post( ajaxurl, {
1074 + action: 'imagify_toggle_tracking_optin',
1075 + value: $( this ).prop( 'checked' ) ? 1 : 0,
1076 + nonce: nonce
1077 + } );
1078 + } );
1079 +
1080 + $( document ).on( 'click.imagify-analytics', '#imagify-analytics-enable-from-modal', function() {
1081 + $( '.imagify-modal.modal-is-open .close-btn' ).trigger( 'click.imagify' );
1082 + $checkbox.prop( 'checked', true ).trigger( 'change.imagify-analytics' );
1083 + } );
1084 +
1085 +})(jQuery);
1086 +
1087 +// Imagify Analytics opt-in notice: toggle the data preview =======================================
1088 +(function($) {
1089 +
1090 + $( document ).on( 'click.imagify-analytics', '.imagify-analytics-preview-toggle', function( e ) {
1091 + e.preventDefault();
1092 + $( this ).closest( 'p' ).next( '.imagify-analytics-data-container' ).slideToggle();
1093 + } );
1094 +
1095 +})(jQuery);