PluginProbe
Imagify Image Optimization: Optimize Images | Compress & Convert to WebP/AVIF / 1.10
Imagify Image Optimization: Optimize Images | Compress & Convert to WebP/AVIF v1.10
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 / files-list.js

files-list.js in Imagify Image Optimization: Optimize Images | Compress & Convert to WebP/AVIF 1.10, at assets/js/files-list.js

458 lines 13.1 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
38 (function($, d, w, undefined) { // eslint-disable-line no-unused-vars, no-shadow, no-shadow-restricted-names
39
40 w.imagify.filesList = {
41
42 working: [],
43
44 /*
45 * Init.
46 */
47 init: function () {
48 var $document = $( d ),
49 $processing;
50
51 // Update the chart in the media modal when a media is selected, and the ones already printed.
52 $( w ).on( 'canvasprinted.imagify', this.updateChart ).trigger( 'canvasprinted.imagify' );
53
54 // Handle bulk actions.
55 this.insertBulkActionTags();
56
57 $( '#doaction, #doaction2' ).on( 'click.imagify', this.processBulkAction );
58
59 // Optimize, restore, etc.
60 $document.on( 'click.imagify', '.button-imagify-optimize, .button-imagify-manual-reoptimize, .button-imagify-generate-webp, .button-imagify-delete-webp, .button-imagify-restore, .button-imagify-refresh-status', this.processOptimization );
61
62 $document.on( 'imagifybeat-send', this.addToImagifybeat );
63 $document.on( 'imagifybeat-tick', this.processImagifybeat );
64
65 // Some items may be processed in background on page load.
66 $processing = $( '.wp-list-table.imagify-files .button-imagify-processing' );
67
68 if ( $processing.length ) {
69 // Some media are already being processed.
70 // Lock the items, so we can check their status with Imagifybeat.
71 $processing.closest( 'tr' ).find( '.check-column [name="bulk_select[]"]' ).each( function() {
72 var id = w.imagify.filesList.sanitizeId( this.value );
73
74 w.imagify.filesList.lockItem( w.imagifyFiles.context, id );
75 } );
76
77 // Fasten Imagifybeat.
78 w.imagify.beat.interval( 15 );
79 }
80 },
81
82 // Charts ==================================================================================
83
84 /**
85 * Update the chart in the media modal when a media is selected, and the ones already printed.
86 *
87 * @param {object} e Event.
88 * @param {string} selector A CSS selector.
89 */
90 updateChart: function( e, selector ) {
91 var $canvas;
92
93 selector = selector || '.imagify-consumption-chart';
94 $canvas = $( selector );
95
96 w.imagify.drawMeAChart( $canvas );
97
98 $canvas.closest( '.imagify-datas-list' ).siblings( '.imagify-datas-details' ).hide();
99 },
100
101 // Bulk optimization =======================================================================
102
103 /**
104 * Insert the bulk actions in the <select> tag.
105 */
106 insertBulkActionTags: function() {
107 var bulkActions = '<option value="imagify-bulk-optimize">' + w.imagifyFiles.labels.bulkActionsOptimize + '</option>';
108
109 if ( w.imagifyFiles.backupOption || $( '.file-has-backup' ).length ) {
110 // If the backup option is enabled, or if we have items that can be restored.
111 bulkActions += '<option value="imagify-bulk-restore">' + w.imagifyFiles.labels.bulkActionsRestore + '</option>';
112 }
113
114 $( '.bulkactions select[name="action"] option:first-child, .bulkactions select[name="action2"] option:first-child' ).after( bulkActions );
115 },
116
117 /**
118 * Process one of these actions: bulk restore, bulk optimize, or bulk refresh-status.
119 *
120 * @param {object} e Event.
121 */
122 processBulkAction: function( e ) {
123 var value = $( this ).prev( 'select' ).val(),
124 action;
125
126 if ( 'imagify-bulk-optimize' !== value && 'imagify-bulk-restore' !== value && 'imagify-bulk-refresh-status' !== value ) {
127 return;
128 }
129
130 e.preventDefault();
131
132 action = value.replace( 'imagify-bulk-', '' );
133
134 $( 'input[name="bulk_select[]"]:checked' ).closest( 'tr' ).find( '.button-imagify-' + action ).each( function ( index, el ) {
135 setTimeout( function() {
136 $( el ).trigger( 'click.imagify' );
137 }, index * 500 );
138 } );
139 },
140
141 // Optimization ============================================================================
142
143 /**
144 * Process one of these actions: optimize, re-optimize, restore, or refresh-status.
145 *
146 * @param {object} e Event.
147 */
148 processOptimization: function( e ) {
149 var $button = $( this ),
150 $row = $button.closest( 'tr' ),
151 $checkbox = $row.find( '.check-column [type="checkbox"]' ),
152 id = imagify.filesList.sanitizeId( $checkbox.val() ),
153 context = w.imagifyFiles.context,
154 $parent, href, processingTemplate;
155
156 e.preventDefault();
157
158 if ( imagify.filesList.isItemLocked( context, id ) ) {
159 return;
160 }
161
162 imagify.filesList.lockItem( context, id );
163
164 href = $button.attr( 'href' );
165 processingTemplate = w.imagify.template( 'imagify-button-processing' );
166 $parent = $button.closest( '.column-actions, .column-status' );
167
168 $parent.html( processingTemplate( {
169 label: $button.data( 'processing-label' )
170 } ) );
171
172 $.get( href.replace( 'admin-post.php', 'admin-ajax.php' ) )
173 .done( function( r ) {
174 if ( ! r.success ) {
175 if ( r.data && r.data.row ) {
176 $row.html( '<td class="colspanchange" colspan="' + $row.children().length + '">' + r.data.row + '</td>' );
177 } else {
178 $parent.html( r.data );
179 }
180
181 $row.find( '.check-column [type="checkbox"]' ).prop( 'checked', false );
182
183 imagify.filesList.unlockItem( context, id );
184 return;
185 }
186
187 if ( r.data && r.data.columns ) {
188 // The work is done.
189 w.imagify.filesList.displayProcessResult( context, id, r.data.columns );
190 } else {
191 // Still processing in background: we're waiting for the result by poking Imagifybeat.
192 // Set the Imagifybeat interval to 15 seconds.
193 w.imagify.beat.interval( 15 );
194 }
195 } );
196 },
197
198 // Imagifybeat =============================================================================
199
200 /**
201 * Send the media IDs and their status to Imagifybeat.
202 *
203 * @param {object} e Event object.
204 * @param {object} data Object containing all Imagifybeat IDs.
205 */
206 addToImagifybeat: function ( e, data ) {
207 var $boxes = $( '.wp-list-table.imagify-files .check-column [name="bulk_select[]"]' );
208
209 if ( ! $boxes.length ) {
210 return;
211 }
212
213 data[ w.imagifyFiles.imagifybeatID ] = {};
214
215 $boxes.each( function() {
216 var id = w.imagify.filesList.sanitizeId( this.value ),
217 context = w.imagifyFiles.context,
218 locked = w.imagify.filesList.isItemLocked( context, id ) ? 1 : 0;
219
220 data[ w.imagifyFiles.imagifybeatID ][ context ] = data[ w.imagifyFiles.imagifybeatID ][ context ] || {};
221 data[ w.imagifyFiles.imagifybeatID ][ context ][ '_' + id ] = locked;
222 } );
223 },
224
225 /**
226 * Listen for the custom event "imagifybeat-tick" on $(document).
227 *
228 * @param {object} e Event object.
229 * @param {object} data Object containing all Imagifybeat IDs.
230 */
231 processImagifybeat: function ( e, data ) {
232 if ( typeof data[ w.imagifyFiles.imagifybeatID ] === 'undefined' ) {
233 return;
234 }
235
236 $.each( data[ w.imagifyFiles.imagifybeatID ], function( contextId, columns ) {
237 var context, id;
238
239 context = $.trim( contextId ).match( /^(.+)_(\d+)$/ );
240
241 if ( ! context ) {
242 return;
243 }
244
245 id = w.imagify.filesList.sanitizeId( context[2] );
246 context = w.imagify.filesList.sanitizeContext( context[1] );
247
248 if ( context !== w.imagifyFiles.context ) {
249 return;
250 }
251
252 w.imagify.filesList.displayProcessResult( context, id, columns );
253 } );
254 },
255
256 // DOM manipulation tools ==================================================================
257
258 /**
259 * Display a successful process result.
260 *
261 * @param {string} context The media context.
262 * @param {int} id The media ID.
263 * @param {string} columns A list of HTML, keyed by column name.
264 */
265 displayProcessResult: function( context, id, columns ) {
266 var $row = w.imagify.filesList.getContainers( id );
267
268 $.each( columns, function( k, v ) {
269 $row.children( '.column-' + k ).html( v );
270 } );
271
272 $row.find( '.check-column [type="checkbox"]' ).prop( 'checked', false );
273
274 w.imagify.filesList.unlockItem( context, id );
275
276 if ( ! w.imagify.filesList.working.length ) {
277 // Work is done.
278 // Reset Imagifybeat interval.
279 w.imagify.beat.resetInterval();
280 }
281 },
282
283 /**
284 * Get all containers matching the given id.
285 *
286 * @param {int} id The media ID.
287 * @return {object} A jQuery collection.
288 */
289 getContainers: function( id ) {
290 return $( '.wp-list-table.imagify-files .check-column [name="bulk_select[]"][value="' + id + '"]' ).closest( 'tr' );
291 },
292
293 // Sanitization ============================================================================
294
295 /**
296 * Sanitize a media ID.
297 *
298 * @param {int|string} id A media ID.
299 * @return {int}
300 */
301 sanitizeId: function( id ) {
302 return parseInt( id, 10 );
303 },
304
305 /**
306 * Sanitize a media context.
307 *
308 * @param {string} context A media context.
309 * @return {string}
310 */
311 sanitizeContext: function( context ) {
312 context = context.replace( '/[^a-z0-9_-]/gi', '' ).toLowerCase();
313 return context ? context : 'wp';
314 },
315
316 // Locks ===================================================================================
317
318 /**
319 * Lock an item.
320 *
321 * @param {string} context The media context.
322 * @param {int} id The media ID.
323 */
324 lockItem: function( context, id ) {
325 if ( ! this.isItemLocked( context, id ) ) {
326 this.working.push( context + '_' + id );
327 }
328 },
329
330 /**
331 * Unlock an item.
332 *
333 * @param {string} context The media context.
334 * @param {int} id The media ID.
335 */
336 unlockItem: function( context, id ) {
337 var name = context + '_' + id,
338 i = _.indexOf( this.working, name );
339
340 if ( i > -1 ) {
341 this.working.splice( i, 1 );
342 }
343 },
344
345 /**
346 * Tell if an item is locked.
347 *
348 * @param {string} context The media context.
349 * @param {int} id The media ID.
350 * @return {bool}
351 */
352 isItemLocked: function( context, id ) {
353 return _.indexOf( this.working, context + '_' + id ) > -1;
354 }
355 };
356
357 w.imagify.filesList.init();
358
359 } )(jQuery, document, window);
360
361
362 (function(w) { // eslint-disable-line no-shadow, no-shadow-restricted-names
363
364 /**
365 * requestAnimationFrame polyfill by Erik Möller.
366 * Fixes from Paul Irish and Tino Zijdel.
367 * MIT license - http://paulirish.com/2011/requestanimationframe-for-smart-animating/ - http://my.opera.com/emoller/blog/2011/12/20/requestanimationframe-for-smart-er-animating.
368 */
369 var lastTime = 0,
370 vendors = ['ms', 'moz', 'webkit', 'o'];
371
372 for ( var x = 0; x < vendors.length && ! w.requestAnimationFrame; ++x ) {
373 w.requestAnimationFrame = w[vendors[x] + 'RequestAnimationFrame'];
374 w.cancelAnimationFrame = w[vendors[x] + 'CancelAnimationFrame'] || w[vendors[x] + 'CancelRequestAnimationFrame'];
375 }
376
377 if ( ! w.requestAnimationFrame ) {
378 w.requestAnimationFrame = function( callback ) {
379 var currTime = new Date().getTime(),
380 timeToCall = Math.max( 0, 16 - ( currTime - lastTime ) ),
381 id = setTimeout( function() {
382 callback( currTime + timeToCall );
383 }, timeToCall );
384
385 lastTime = currTime + timeToCall;
386 return id;
387 };
388 }
389
390 if ( ! w.cancelAnimationFrame ) {
391 w.cancelAnimationFrame = function( id ) {
392 clearTimeout( id );
393 };
394 }
395
396 })(window);
397
398
399 (function($, d, w, undefined) { // eslint-disable-line no-unused-vars, no-shadow, no-shadow-restricted-names
400
401 /**
402 * LazyLoad images in the list.
403 */
404 var lazyImages = $( '#imagify-files-list-form' ).find( '[data-lazy-src]' ),
405 lazyTimer;
406
407 function lazyLoadThumbnails() {
408 w.cancelAnimationFrame( lazyTimer );
409 lazyTimer = w.requestAnimationFrame( lazyLoadThumbnailsCallback ); // eslint-disable-line no-use-before-define
410 }
411
412 function lazyLoadThumbnailsCallback() {
413 var $w = $( w ),
414 winScroll = $w.scrollTop(),
415 winHeight = $w.outerHeight();
416
417 $.each( lazyImages, function() {
418 var $image = $( this ),
419 imgTop = $image.offset().top,
420 imgBottom = imgTop + $image.outerHeight(),
421 screenTopThresholded = winScroll - 150,
422 screenBottomThresholded = winScroll + winHeight + 150,
423 src;
424
425 lazyImages = lazyImages.not( $image );
426
427 if ( ! lazyImages.length ) {
428 $w.off( 'scroll resize orientationchange', lazyLoadThumbnails );
429 }
430
431 /**
432 * Hidden images that are above the fold and below the top, are reported as:
433 * - offset: window scroll,
434 * - height: 0,
435 * (at least in Firefox).
436 * That's why I use <= and >=.
437 *
438 * 150 is the threshold.
439 */
440 if ( imgBottom >= screenTopThresholded && imgTop <= screenBottomThresholded ) {
441 src = $image.attr( 'data-lazy-src' );
442
443 if ( undefined !== src && src ) {
444 $image.attr( 'src', src ).removeAttr( 'data-lazy-src' );
445 }
446
447 $image.next( 'noscript' ).remove();
448 }
449 } );
450 }
451
452 if ( lazyImages.length ) {
453 $( w ).on( 'scroll resize orientationchange', lazyLoadThumbnails );
454 lazyLoadThumbnailsCallback();
455 }
456
457 } )(jQuery, document, window);
458