| 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 |
|