PluginProbe
Imagify Image Optimization: Optimize Images | Compress & Convert to WebP/AVIF / 2.3.3
Imagify Image Optimization: Optimize Images | Compress & Convert to WebP/AVIF v2.3.3
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
imagify / assets / js / media-modal.js

media-modal.js in Imagify Image Optimization: Optimize Images | Compress & Convert to WebP/AVIF 2.3.3, at assets/js/media-modal.js

346 lines 10.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 /**
2 * Mini chart.
3 *
4 * @param {element} canvas The canvas element.
5 */
6 window.imagify.drawMeAChart = function( canvas ) {
7 canvas.each( function() {
8 var value = parseInt( jQuery( this ).closest( '.imagify-chart' ).next( '.imagify-chart-value' ).text(), 10 );
9
10 new window.imagify.Chart( this, { // eslint-disable-line no-new
11 type: 'doughnut',
12 data: {
13 datasets: [ {
14 data: [ value, 100 - value ],
15 backgroundColor: [ '#00B3D3', '#D8D8D8' ],
16 borderColor: '#fff',
17 borderWidth: 1
18 } ]
19 },
20 options: {
21 legend: {
22 display: false
23 },
24 events: [],
25 animation: {
26 easing: 'easeOutBounce'
27 },
28 tooltips: {
29 enabled: false
30 },
31 responsive: false
32 }
33 } );
34 } );
35 };
36
37 (function($, d, w, undefined) { // eslint-disable-line no-unused-vars, no-shadow, no-shadow-restricted-names
38
39 w.imagify.modal = {
40
41 working: [],
42
43 /*
44 * Init.
45 */
46 init: function () {
47 var $document = $( d ),
48 $processing;
49
50 // Update the chart in the media modal when a media is selected, and the ones already printed.
51 $( w ).on( 'canvasprinted.imagify', this.updateChart ).trigger( 'canvasprinted.imagify' );
52
53 // Toggle slide in custom column.
54 $( '.imagify-datas-details' ).hide();
55
56 $document.on( 'click', '.imagify-datas-more-action a', this.toggleSlide );
57
58 // Optimize, restore, etc.
59 $document.on( 'click', '.button-imagify-restore, .button-imagify-optimize, .button-imagify-manual-reoptimize, .button-imagify-optimize-missing-sizes, .button-imagify-generate-webp, .button-imagify-delete-webp', this.processOptimization );
60
61 $document.on( 'imagifybeat-send', this.addToImagifybeat );
62 $document.on( 'imagifybeat-tick', this.processImagifybeat );
63
64 // Some items may be processed in background on page load.
65 $processing = $( '.imagify-data-actions-container .button-imagify-processing' );
66
67 if ( $processing.length ) {
68 // Some media are already being processed.
69 // Lock the items, so we can check their status with Imagifybeat.
70 $processing.closest( '.imagify-data-actions-container' ).each( function() {
71 var $this = $( this ),
72 id = w.imagify.modal.sanitizeId( $this.data( 'id' ) ),
73 context = w.imagify.modal.sanitizeContext( $this.data( 'context' ) );
74
75 w.imagify.modal.lockItem( context, id );
76 } );
77
78 // Fasten Imagifybeat.
79 w.imagify.beat.interval( 15 );
80 }
81 },
82
83 // Charts ==================================================================================
84
85 /**
86 * Update the chart in the media modal when a media is selected, and the ones already printed.
87 *
88 * @param {object} e Event.
89 * @param {string} selector A CSS selector.
90 */
91 updateChart: function( e, selector ) {
92 var $canvas;
93
94 selector = selector || '.imagify-consumption-chart';
95 $canvas = $( selector );
96
97 w.imagify.drawMeAChart( $canvas );
98
99 $canvas.closest( '.imagify-datas-list' ).siblings( '.imagify-datas-details' ).hide();
100 },
101
102 // Optimization ============================================================================
103
104 /**
105 * Process to one of these actions: restore, optimize, re-optimize, or optimize missing sizes.
106 *
107 * @param {object} e Event.
108 */
109 processOptimization: function( e ) {
110 var $obj = $( this ),
111 $container = $obj.parents( '.imagify-data-actions-container' ),
112 id = w.imagify.modal.sanitizeId( $container.data( 'id' ) ),
113 context = w.imagify.modal.sanitizeContext( $container.data( 'context' ) ),
114 href, processingTemplate, previousHtml;
115
116 e.preventDefault();
117
118 if ( w.imagify.modal.isItemLocked( context, id ) ) {
119 return;
120 }
121
122 w.imagify.modal.lockItem( context, id );
123
124 href = $obj.attr( 'href' );
125 processingTemplate = w.imagify.template( 'imagify-button-processing' );
126 previousHtml = $container.html();
127
128 $container.html( processingTemplate( {
129 label: $obj.data( 'processing-label' )
130 } ) );
131
132 $.get( {
133 url: href.replace( 'admin-post.php', 'admin-ajax.php' ),
134 timeout: 60000 // Throw an error if not completed after 60 sec.
135 } )
136 .done( function( response ) {
137 if ( response.data && response.data.html ) {
138 // The work is done.
139 w.imagify.modal.displayProcessResult( context, id, response.data.html );
140 } else {
141 // Still processing in background: we're waiting for the result by poking Imagifybeat.
142 // Set the Imagifybeat interval to 15 seconds.
143 w.imagify.beat.interval( 15 );
144 }
145 } )
146 .fail( function() {
147 // The request errored out or timed out: unlock the item and restore the
148 // previous button state instead of leaving it stuck on "Optimizing..."
149 // until Imagifybeat's next tick catches the mismatch.
150 w.imagify.modal.unlockItem( context, id );
151 $container.html( previousHtml );
152 } );
153 },
154
155 // Imagifybeat =============================================================================
156
157 /**
158 * Send the media IDs and their status to Imagifybeat.
159 *
160 * @param {object} e Event object.
161 * @param {object} data Object containing all Imagifybeat IDs.
162 */
163 addToImagifybeat: function ( e, data ) {
164 var $containers = $( '.imagify-data-actions-container' );
165
166 if ( ! $containers.length ) {
167 return;
168 }
169
170 data[ w.imagifyModal.imagifybeatID ] = {};
171
172 $containers.each( function() {
173 var $this = $( this ),
174 id = w.imagify.modal.sanitizeId( $this.data( 'id' ) ),
175 context = w.imagify.modal.sanitizeContext( $this.data( 'context' ) ),
176 locked = w.imagify.modal.isItemLocked( context, id ) ? 1 : 0;
177
178 data[ w.imagifyModal.imagifybeatID ][ context ] = data[ w.imagifyModal.imagifybeatID ][ context ] || {};
179 data[ w.imagifyModal.imagifybeatID ][ context ][ '_' + id ] = locked;
180 } );
181 },
182
183 /**
184 * Listen for the custom event "imagifybeat-tick" on $(document).
185 *
186 * @param {object} e Event object.
187 * @param {object} data Object containing all Imagifybeat IDs.
188 */
189 processImagifybeat: function ( e, data ) {
190 if ( typeof data[ w.imagifyModal.imagifybeatID ] === 'undefined' ) {
191 return;
192 }
193
194 $.each( data[ w.imagifyModal.imagifybeatID ], function( contextId, htmlContent ) {
195 var context, id;
196
197 context = String( contextId ).trim().match( /^(.+)_(\d+)$/ );
198
199 if ( ! context ) {
200 return;
201 }
202
203 id = w.imagify.modal.sanitizeId( context[2] );
204 context = w.imagify.modal.sanitizeContext( context[1] );
205
206 w.imagify.modal.displayProcessResult( context, id, htmlContent );
207 } );
208 },
209
210 // DOM manipulation tools ==================================================================
211
212 /**
213 * Display the process result.
214 *
215 * @param {string} context The media context.
216 * @param {int} id The media ID.
217 * @param {string} htmlContent The HTML to insert.
218 */
219 displayProcessResult: function( context, id, htmlContent ) {
220 var $containers = w.imagify.modal.getContainers( context, id );
221
222 $containers.html( htmlContent );
223 w.imagify.modal.unlockItem( context, id );
224
225 if ( ! w.imagify.modal.working.length ) {
226 // Work is done.
227 // Open the last container being processed.
228 w.imagify.modal.openSlide( $containers );
229 // Reset Imagifybeat interval.
230 w.imagify.beat.resetInterval();
231 }
232 },
233
234 /**
235 * Open a slide rapidly.
236 *
237 * @param {object} $containers A jQuery collection.
238 */
239 openSlide: function( $containers ) {
240 $containers.each( function() {
241 var $container = $( this ),
242 text = $container.find( '.imagify-datas-more-action a' ).data( 'close' );
243
244 $container.find( '.imagify-datas-more-action a' ).addClass( 'is-open' ).find( '.the-text' ).text( text );
245 $container.find( '.imagify-datas-details' ).show().addClass( 'is-open' );
246 } );
247 },
248
249 /**
250 * Toggle slide in custom column.
251 *
252 * @param {object} e Event.
253 */
254 toggleSlide: function( e ) {
255 var $this = $( this );
256
257 e.preventDefault();
258
259 if ( $this.hasClass( 'is-open' ) ) {
260 $( $this.attr( 'href' ) ).slideUp( 300 ).removeClass( 'is-open' );
261 $this.removeClass( 'is-open' ).find( '.the-text' ).text( $this.data( 'open' ) );
262 } else {
263 $( $this.attr( 'href' ) ).slideDown( 300 ).addClass( 'is-open' );
264 $this.addClass( 'is-open' ).find( '.the-text' ).text( $this.data( 'close' ) );
265 }
266 },
267
268 /**
269 * Get all containers matching the given context and id.
270 *
271 * @param {string} context The media context.
272 * @param {int} id The media ID.
273 * @return {object} A jQuery collection.
274 */
275 getContainers: function( context, id ) {
276 return $( '.imagify-data-actions-container[data-id="' + id + '"][data-context="' + context + '"]' );
277 },
278
279 // Sanitization ============================================================================
280
281 /**
282 * Sanitize a media ID.
283 *
284 * @param {int|string} id A media ID.
285 * @return {int}
286 */
287 sanitizeId: function( id ) {
288 return parseInt( id, 10 );
289 },
290
291 /**
292 * Sanitize a media context.
293 *
294 * @param {string} context A media context.
295 * @return {string}
296 */
297 sanitizeContext: function( context ) {
298 context = context.replace( '/[^a-z0-9_-]/gi', '' ).toLowerCase();
299 return context ? context : 'wp';
300 },
301
302 // Locks ===================================================================================
303
304 /**
305 * Lock an item.
306 *
307 * @param {string} context The media context.
308 * @param {int} id The media ID.
309 */
310 lockItem: function( context, id ) {
311 if ( ! this.isItemLocked( context, id ) ) {
312 this.working.push( context + '_' + id );
313 }
314 },
315
316 /**
317 * Unlock an item.
318 *
319 * @param {string} context The media context.
320 * @param {int} id The media ID.
321 */
322 unlockItem: function( context, id ) {
323 var name = context + '_' + id,
324 i = _.indexOf( this.working, name );
325
326 if ( i > -1 ) {
327 this.working.splice( i, 1 );
328 }
329 },
330
331 /**
332 * Tell if an item is locked.
333 *
334 * @param {string} context The media context.
335 * @param {int} id The media ID.
336 * @return {bool}
337 */
338 isItemLocked: function( context, id ) {
339 return _.indexOf( this.working, context + '_' + id ) > -1;
340 }
341 };
342
343 w.imagify.modal.init();
344
345 } )(jQuery, document, window);
346