From d916c150dd6593fb27e7cbade5d13ce22fa54d9d Mon Sep 17 00:00:00 2001 From: MichaelDaum Date: Tue, 21 May 2024 13:29:44 +0200 Subject: [PATCH] Item15326: upgrade to latest available imagesLoaded module --- .../Plugins/JQueryPlugin/IMAGESLOADED.pm | 2 +- .../imagesloaded/imagesloaded.uncompressed.js | 254 +++++++----------- 2 files changed, 100 insertions(+), 156 deletions(-) diff --git a/JQueryPlugin/lib/Foswiki/Plugins/JQueryPlugin/IMAGESLOADED.pm b/JQueryPlugin/lib/Foswiki/Plugins/JQueryPlugin/IMAGESLOADED.pm index e71a75f73a..3df500db92 100644 --- a/JQueryPlugin/lib/Foswiki/Plugins/JQueryPlugin/IMAGESLOADED.pm +++ b/JQueryPlugin/lib/Foswiki/Plugins/JQueryPlugin/IMAGESLOADED.pm @@ -28,7 +28,7 @@ sub new { my $this = bless( $class->SUPER::new( name => 'ImagesLoaded', - version => '4.1.4', + version => '5.0.0', author => 'David DeSandro', homepage => 'http://imagesloaded.desandro.com/', javascript => ['imagesloaded.js'], diff --git a/JQueryPlugin/pub/System/JQueryPlugin/plugins/imagesloaded/imagesloaded.uncompressed.js b/JQueryPlugin/pub/System/JQueryPlugin/plugins/imagesloaded/imagesloaded.uncompressed.js index a230750b3e..db5d882a9e 100644 --- a/JQueryPlugin/pub/System/JQueryPlugin/plugins/imagesloaded/imagesloaded.uncompressed.js +++ b/JQueryPlugin/pub/System/JQueryPlugin/plugins/imagesloaded/imagesloaded.uncompressed.js @@ -1,24 +1,18 @@ /*! - * imagesLoaded PACKAGED v4.1.4 + * imagesLoaded PACKAGED v5.0.0 * JavaScript is all like "You images are done yet or what?" * MIT License */ /** - * EvEmitter v1.1.0 + * EvEmitter v2.1.1 * Lil' event emitter * MIT License */ -/* jshint unused: true, undef: true, strict: true */ - ( function( global, factory ) { // universal module definition - /* jshint strict: false */ /* globals define, module, window */ - if ( typeof define == 'function' && define.amd ) { - // AMD - RequireJS - define( 'ev-emitter/ev-emitter',factory ); - } else if ( typeof module == 'object' && module.exports ) { + if ( typeof module == 'object' && module.exports ) { // CommonJS - Browserify, Webpack module.exports = factory(); } else { @@ -28,22 +22,19 @@ }( typeof window != 'undefined' ? window : this, function() { - - function EvEmitter() {} -var proto = EvEmitter.prototype; +let proto = EvEmitter.prototype; proto.on = function( eventName, listener ) { - if ( !eventName || !listener ) { - return; - } + if ( !eventName || !listener ) return this; + // set events hash - var events = this._events = this._events || {}; + let events = this._events = this._events || {}; // set listeners array - var listeners = events[ eventName ] = events[ eventName ] || []; + let listeners = events[ eventName ] = events[ eventName ] || []; // only add once - if ( listeners.indexOf( listener ) == -1 ) { + if ( !listeners.includes( listener ) ) { listeners.push( listener ); } @@ -51,16 +42,15 @@ proto.on = function( eventName, listener ) { }; proto.once = function( eventName, listener ) { - if ( !eventName || !listener ) { - return; - } + if ( !eventName || !listener ) return this; + // add event this.on( eventName, listener ); // set once flag // set onceEvents hash - var onceEvents = this._onceEvents = this._onceEvents || {}; + let onceEvents = this._onceEvents = this._onceEvents || {}; // set onceListeners object - var onceListeners = onceEvents[ eventName ] = onceEvents[ eventName ] || {}; + let onceListeners = onceEvents[ eventName ] = onceEvents[ eventName ] || {}; // set flag onceListeners[ listener ] = true; @@ -68,11 +58,10 @@ proto.once = function( eventName, listener ) { }; proto.off = function( eventName, listener ) { - var listeners = this._events && this._events[ eventName ]; - if ( !listeners || !listeners.length ) { - return; - } - var index = listeners.indexOf( listener ); + let listeners = this._events && this._events[ eventName ]; + if ( !listeners || !listeners.length ) return this; + + let index = listeners.indexOf( listener ); if ( index != -1 ) { listeners.splice( index, 1 ); } @@ -81,19 +70,17 @@ proto.off = function( eventName, listener ) { }; proto.emitEvent = function( eventName, args ) { - var listeners = this._events && this._events[ eventName ]; - if ( !listeners || !listeners.length ) { - return; - } + let listeners = this._events && this._events[ eventName ]; + if ( !listeners || !listeners.length ) return this; + // copy over to avoid interference if .off() in listener - listeners = listeners.slice(0); + listeners = listeners.slice( 0 ); args = args || []; // once stuff - var onceListeners = this._onceEvents && this._onceEvents[ eventName ]; + let onceListeners = this._onceEvents && this._onceEvents[ eventName ]; - for ( var i=0; i < listeners.length; i++ ) { - var listener = listeners[i] - var isOnce = onceListeners && onceListeners[ listener ]; + for ( let listener of listeners ) { + let isOnce = onceListeners && onceListeners[ listener ]; if ( isOnce ) { // remove listener // remove before trigger to prevent recursion @@ -111,79 +98,44 @@ proto.emitEvent = function( eventName, args ) { proto.allOff = function() { delete this._events; delete this._onceEvents; + return this; }; return EvEmitter; -})); - +} ) ); /*! - * imagesLoaded v4.1.4 + * imagesLoaded v5.0.0 * JavaScript is all like "You images are done yet or what?" * MIT License */ -( function( window, factory ) { 'use strict'; +( function( window, factory ) { // universal module definition - - /*global define: false, module: false, require: false */ - - if ( typeof define == 'function' && define.amd ) { - // AMD - define( [ - 'ev-emitter/ev-emitter' - ], function( EvEmitter ) { - return factory( window, EvEmitter ); - }); - } else if ( typeof module == 'object' && module.exports ) { + if ( typeof module == 'object' && module.exports ) { // CommonJS - module.exports = factory( - window, - require('ev-emitter') - ); + module.exports = factory( window, require('ev-emitter') ); } else { // browser global - window.imagesLoaded = factory( - window, - window.EvEmitter - ); + window.imagesLoaded = factory( window, window.EvEmitter ); } -})( typeof window !== 'undefined' ? window : this, - -// -------------------------- factory -------------------------- // - -function factory( window, EvEmitter ) { +} )( typeof window !== 'undefined' ? window : this, + function factory( window, EvEmitter ) { - - -var $ = window.jQuery; -var console = window.console; +let $ = window.jQuery; +let console = window.console; // -------------------------- helpers -------------------------- // -// extend objects -function extend( a, b ) { - for ( var prop in b ) { - a[ prop ] = b[ prop ]; - } - return a; -} - -var arraySlice = Array.prototype.slice; - // turn element or nodeList into an array function makeArray( obj ) { - if ( Array.isArray( obj ) ) { - // use object if already an array - return obj; - } + // use object if already an array + if ( Array.isArray( obj ) ) return obj; - var isArrayLike = typeof obj == 'object' && typeof obj.length == 'number'; - if ( isArrayLike ) { - // convert nodeList to array - return arraySlice.call( obj ); - } + let isArrayLike = typeof obj == 'object' && typeof obj.length == 'number'; + // convert nodeList to array + if ( isArrayLike ) return [ ...obj ]; // array of single index return [ obj ]; @@ -192,9 +144,10 @@ function makeArray( obj ) { // -------------------------- imagesLoaded -------------------------- // /** - * @param {Array, Element, NodeList, String} elem - * @param {Object or Function} options - if function, use as callback + * @param {[Array, Element, NodeList, String]} elem + * @param {[Object, Function]} options - if function, use as callback * @param {Function} onAlways - callback function + * @returns {ImagesLoaded} */ function ImagesLoaded( elem, options, onAlways ) { // coerce ImagesLoaded() without new, to be new ImagesLoaded() @@ -202,35 +155,30 @@ function ImagesLoaded( elem, options, onAlways ) { return new ImagesLoaded( elem, options, onAlways ); } // use elem as selector string - var queryElem = elem; + let queryElem = elem; if ( typeof elem == 'string' ) { queryElem = document.querySelectorAll( elem ); } // bail if bad element if ( !queryElem ) { - console.error( 'Bad element for imagesLoaded ' + ( queryElem || elem ) ); + console.error(`Bad element for imagesLoaded ${queryElem || elem}`); return; } this.elements = makeArray( queryElem ); - this.options = extend( {}, this.options ); + this.options = {}; // shift arguments if no options set if ( typeof options == 'function' ) { onAlways = options; } else { - extend( this.options, options ); + Object.assign( this.options, options ); } - if ( onAlways ) { - this.on( 'always', onAlways ); - } + if ( onAlways ) this.on( 'always', onAlways ); this.getImages(); - - if ( $ ) { - // add jQuery Deferred object - this.jqDeferred = new $.Deferred(); - } + // add jQuery Deferred object + if ( $ ) this.jqDeferred = new $.Deferred(); // HACK check async to allow time to bind listeners setTimeout( this.check.bind( this ) ); @@ -238,8 +186,6 @@ function ImagesLoaded( elem, options, onAlways ) { ImagesLoaded.prototype = Object.create( EvEmitter.prototype ); -ImagesLoaded.prototype.options = {}; - ImagesLoaded.prototype.getImages = function() { this.images = []; @@ -247,12 +193,14 @@ ImagesLoaded.prototype.getImages = function() { this.elements.forEach( this.addElementImages, this ); }; +const elementNodeTypes = [ 1, 9, 11 ]; + /** - * @param {Node} element + * @param {Node} elem */ ImagesLoaded.prototype.addElementImages = function( elem ) { // filter siblings - if ( elem.nodeName == 'IMG' ) { + if ( elem.nodeName === 'IMG' ) { this.addImage( elem ); } // get background image on element @@ -262,44 +210,35 @@ ImagesLoaded.prototype.addElementImages = function( elem ) { // find children // no non-element nodes, #143 - var nodeType = elem.nodeType; - if ( !nodeType || !elementNodeTypes[ nodeType ] ) { - return; - } - var childImgs = elem.querySelectorAll('img'); + let { nodeType } = elem; + if ( !nodeType || !elementNodeTypes.includes( nodeType ) ) return; + + let childImgs = elem.querySelectorAll('img'); // concat childElems to filterFound array - for ( var i=0; i < childImgs.length; i++ ) { - var img = childImgs[i]; + for ( let img of childImgs ) { this.addImage( img ); } // get child background images if ( typeof this.options.background == 'string' ) { - var children = elem.querySelectorAll( this.options.background ); - for ( i=0; i < children.length; i++ ) { - var child = children[i]; + let children = elem.querySelectorAll( this.options.background ); + for ( let child of children ) { this.addElementBackgroundImages( child ); } } }; -var elementNodeTypes = { - 1: true, - 9: true, - 11: true -}; +const reURL = /url\((['"])?(.*?)\1\)/gi; ImagesLoaded.prototype.addElementBackgroundImages = function( elem ) { - var style = getComputedStyle( elem ); - if ( !style ) { - // Firefox returns null if in a hidden iframe https://bugzil.la/548397 - return; - } + let style = getComputedStyle( elem ); + // Firefox returns null if in a hidden iframe https://bugzil.la/548397 + if ( !style ) return; + // get url inside url("...") - var reURL = /url\((['"])?(.*?)\1\)/gi; - var matches = reURL.exec( style.backgroundImage ); + let matches = reURL.exec( style.backgroundImage ); while ( matches !== null ) { - var url = matches && matches[2]; + let url = matches && matches[2]; if ( url ) { this.addBackground( url, elem ); } @@ -311,17 +250,16 @@ ImagesLoaded.prototype.addElementBackgroundImages = function( elem ) { * @param {Image} img */ ImagesLoaded.prototype.addImage = function( img ) { - var loadingImage = new LoadingImage( img ); + let loadingImage = new LoadingImage( img ); this.images.push( loadingImage ); }; ImagesLoaded.prototype.addBackground = function( url, elem ) { - var background = new Background( url, elem ); + let background = new Background( url, elem ); this.images.push( background ); }; ImagesLoaded.prototype.check = function() { - var _this = this; this.progressedCount = 0; this.hasAnyBroken = false; // complete if no images @@ -330,17 +268,18 @@ ImagesLoaded.prototype.check = function() { return; } - function onProgress( image, elem, message ) { + /* eslint-disable-next-line func-style */ + let onProgress = ( image, elem, message ) => { // HACK - Chrome triggers event before object properties have changed. #83 - setTimeout( function() { - _this.progress( image, elem, message ); - }); - } + setTimeout( () => { + this.progress( image, elem, message ); + } ); + }; this.images.forEach( function( loadingImage ) { loadingImage.once( 'progress', onProgress ); loadingImage.check(); - }); + } ); }; ImagesLoaded.prototype.progress = function( image, elem, message ) { @@ -352,22 +291,22 @@ ImagesLoaded.prototype.progress = function( image, elem, message ) { this.jqDeferred.notify( this, image ); } // check if completed - if ( this.progressedCount == this.images.length ) { + if ( this.progressedCount === this.images.length ) { this.complete(); } if ( this.options.debug && console ) { - console.log( 'progress: ' + message, image, elem ); + console.log( `progress: ${message}`, image, elem ); } }; ImagesLoaded.prototype.complete = function() { - var eventName = this.hasAnyBroken ? 'fail' : 'done'; + let eventName = this.hasAnyBroken ? 'fail' : 'done'; this.isComplete = true; this.emitEvent( eventName, [ this ] ); this.emitEvent( 'always', [ this ] ); if ( this.jqDeferred ) { - var jqMethod = this.hasAnyBroken ? 'reject' : 'resolve'; + let jqMethod = this.hasAnyBroken ? 'reject' : 'resolve'; this.jqDeferred[ jqMethod ]( this ); } }; @@ -383,7 +322,7 @@ LoadingImage.prototype = Object.create( EvEmitter.prototype ); LoadingImage.prototype.check = function() { // If complete is true and browser supports natural sizes, // try to check for image status manually. - var isComplete = this.getIsImageComplete(); + let isComplete = this.getIsImageComplete(); if ( isComplete ) { // report based on naturalWidth this.confirm( this.img.naturalWidth !== 0, 'naturalWidth' ); @@ -392,12 +331,16 @@ LoadingImage.prototype.check = function() { // If none of the checks above matched, simulate loading on detached element. this.proxyImage = new Image(); + // add crossOrigin attribute. #204 + if ( this.img.crossOrigin ) { + this.proxyImage.crossOrigin = this.img.crossOrigin; + } this.proxyImage.addEventListener( 'load', this ); this.proxyImage.addEventListener( 'error', this ); // bind to image as well for Firefox. #191 this.img.addEventListener( 'load', this ); this.img.addEventListener( 'error', this ); - this.proxyImage.src = this.img.src; + this.proxyImage.src = this.img.currentSrc || this.img.src; }; LoadingImage.prototype.getIsImageComplete = function() { @@ -408,14 +351,17 @@ LoadingImage.prototype.getIsImageComplete = function() { LoadingImage.prototype.confirm = function( isLoaded, message ) { this.isLoaded = isLoaded; - this.emitEvent( 'progress', [ this, this.img, message ] ); + let { parentNode } = this.img; + // emit progress with parent or self + let elem = parentNode.nodeName === 'PICTURE' ? parentNode : this.img; + this.emitEvent( 'progress', [ this, elem, message ] ); }; // ----- events ----- // // trigger specified handler for event type LoadingImage.prototype.handleEvent = function( event ) { - var method = 'on' + event.type; + let method = 'on' + event.type; if ( this[ method ] ) { this[ method ]( event ); } @@ -454,7 +400,7 @@ Background.prototype.check = function() { this.img.addEventListener( 'error', this ); this.img.src = this.url; // check if image is already complete - var isComplete = this.getIsImageComplete(); + let isComplete = this.getIsImageComplete(); if ( isComplete ) { this.confirm( this.img.naturalWidth !== 0, 'naturalWidth' ); this.unbindEvents(); @@ -475,15 +421,14 @@ Background.prototype.confirm = function( isLoaded, message ) { ImagesLoaded.makeJQueryPlugin = function( jQuery ) { jQuery = jQuery || window.jQuery; - if ( !jQuery ) { - return; - } + if ( !jQuery ) return; + // set local variable $ = jQuery; // $().imagesLoaded() - $.fn.imagesLoaded = function( options, callback ) { - var instance = new ImagesLoaded( this, options, callback ); - return instance.jqDeferred.promise( $(this) ); + $.fn.imagesLoaded = function( options, onAlways ) { + let instance = new ImagesLoaded( this, options, onAlways ); + return instance.jqDeferred.promise( $( this ) ); }; }; // try making plugin @@ -493,5 +438,4 @@ ImagesLoaded.makeJQueryPlugin(); return ImagesLoaded; -}); - +} );