vendor: 12,516 bytes, lines 1-441
1/*! 2 * imagesLoaded PACKAGED v5.0.0 3 * JavaScript is all like "You images are done yet or what?" 4 * MIT License 5 */ 6 7/** 8 * EvEmitter v2.1.1 9 * Lil' event emitter 10 * MIT License 11 */ 12 13( function( global, factory ) { 14 // universal module definition 15 if ( typeof module == 'object' && module.exports ) { 16 // CommonJS - Browserify, Webpack 17 module.exports = factory(); 18 } else { 19 // Browser globals 20 global.EvEmitter = factory(); 21 } 22 23}( typeof window != 'undefined' ? window : this, function() { 24 25function EvEmitter() {} 26 27let proto = EvEmitter.prototype; 28 29proto.on = function( eventName, listener ) { 30 if ( !eventName || !listener ) return this; 31 32 // set events hash 33 let events = this._events = this._events || {}; 34 // set listeners array 35 let listeners = events[ eventName ] = events[ eventName ] || []; 36 // only add once 37 if ( !listeners.includes( listener ) ) { 38 listeners.push( listener ); 39 } 40 41 return this; 42}; 43 44proto.once = function( eventName, listener ) { 45 if ( !eventName || !listener ) return this; 46 47 // add event 48 this.on( eventName, listener ); 49 // set once flag 50 // set onceEvents hash 51 let onceEvents = this._onceEvents = this._onceEvents || {}; 52 // set onceListeners object 53 let onceListeners = onceEvents[ eventName ] = onceEvents[ eventName ] || {}; 54 // set flag 55 onceListeners[ listener ] = true; 56 57 return this; 58}; 59 60proto.off = function( eventName, listener ) { 61 let listeners = this._events && this._events[ eventName ]; 62 if ( !listeners || !listeners.length ) return this; 63 64 let index = listeners.indexOf( listener ); 65 if ( index != -1 ) { 66 listeners.splice( index, 1 ); 67 } 68 69 return this; 70}; 71 72proto.emitEvent = function( eventName, args ) { 73 let listeners = this._events && this._events[ eventName ]; 74 if ( !listeners || !listeners.length ) return this; 75 76 // copy over to avoid interference if .off() in listener 77 listeners = listeners.slice( 0 ); 78 args = args || []; 79 // once stuff 80 let onceListeners = this._onceEvents && this._onceEvents[ eventName ]; 81 82 for ( let listener of listeners ) { 83 let isOnce = onceListeners && onceListeners[ listener ]; 84 if ( isOnce ) { 85 // remove listener 86 // remove before trigger to prevent recursion 87 this.off( eventName, listener ); 88 // unset once flag 89 delete onceListeners[ listener ]; 90 } 91 // trigger listener 92 listener.apply( this, args ); 93 } 94 95 return this; 96}; 97 98proto.allOff = function() { 99 delete this._events; 100 delete this._onceEvents; 101 return this; 102}; 103 104return EvEmitter; 105 106} ) ); 107/*! 108 * imagesLoaded v5.0.0 109 * JavaScript is all like "You images are done yet or what?" 110 * MIT License 111 */ 112 113( function( window, factory ) { 114 // universal module definition 115 if ( typeof module == 'object' && module.exports ) { 116 // CommonJS 117 module.exports = factory( window, require('ev-emitter') ); 118 } else { 119 // browser global 120 window.imagesLoaded = factory( window, window.EvEmitter ); 121 } 122 123} )( typeof window !== 'undefined' ? window : this, 124 function factory( window, EvEmitter ) { 125 126let $ = window.jQuery; 127let console = window.console; 128 129// -------------------------- helpers -------------------------- // 130 131// turn element or nodeList into an array 132function makeArray( obj ) { 133 // use object if already an array 134 if ( Array.isArray( obj ) ) return obj; 135 136 let isArrayLike = typeof obj == 'object' && typeof obj.length == 'number'; 137 // convert nodeList to array 138 if ( isArrayLike ) return [ ...obj ]; 139 140 // array of single index 141 return [ obj ]; 142} 143 144// -------------------------- imagesLoaded -------------------------- // 145 146/** 147 * @param {[Array, Element, NodeList, String]} elem 148 * @param {[Object, Function]} options - if function, use as callback 149 * @param {Function} onAlways - callback function 150 * @returns {ImagesLoaded} 151 */ 152function ImagesLoaded( elem, options, onAlways ) { 153 // coerce ImagesLoaded() without new, to be new ImagesLoaded() 154 if ( !( this instanceof ImagesLoaded ) ) { 155 return new ImagesLoaded( elem, options, onAlways ); 156 } 157 // use elem as selector string 158 let queryElem = elem; 159 if ( typeof elem == 'string' ) { 160 queryElem = document.querySelectorAll( elem ); 161 } 162 // bail if bad element 163 if ( !queryElem ) { 164 console.error(`Bad element for imagesLoaded ${queryElem || elem}`); 165 return; 166 } 167 168 this.elements = makeArray( queryElem ); 169 this.options = {}; 170 // shift arguments if no options set 171 if ( typeof options == 'function' ) { 172 onAlways = options; 173 } else { 174 Object.assign( this.options, options ); 175 } 176 177 if ( onAlways ) this.on( 'always', onAlways ); 178 179 this.getImages(); 180 // add jQuery Deferred object 181 if ( $ ) this.jqDeferred = new $.Deferred(); 182 183 // HACK check async to allow time to bind listeners 184 setTimeout( this.check.bind( this ) ); 185} 186 187ImagesLoaded.prototype = Object.create( EvEmitter.prototype ); 188 189ImagesLoaded.prototype.getImages = function() { 190 this.images = []; 191 192 // filter & find items if we have an item selector 193 this.elements.forEach( this.addElementImages, this ); 194}; 195 196const elementNodeTypes = [ 1, 9, 11 ]; 197 198/** 199 * @param {Node} elem 200 */ 201ImagesLoaded.prototype.addElementImages = function( elem ) { 202 // filter siblings 203 if ( elem.nodeName === 'IMG' ) { 204 this.addImage( elem ); 205 } 206 // get background image on element 207 if ( this.options.background === true ) { 208 this.addElementBackgroundImages( elem ); 209 } 210 211 // find children 212 // no non-element nodes, #143 213 let { nodeType } = elem; 214 if ( !nodeType || !elementNodeTypes.includes( nodeType ) ) return; 215 216 let childImgs = elem.querySelectorAll('img'); 217 // concat childElems to filterFound array 218 for ( let img of childImgs ) { 219 this.addImage( img ); 220 } 221 222 // get child background images 223 if ( typeof this.options.background == 'string' ) { 224 let children = elem.querySelectorAll( this.options.background ); 225 for ( let child of children ) { 226 this.addElementBackgroundImages( child ); 227 } 228 } 229}; 230 231const reURL = /url\((['"])?(.*?)\1\)/gi; 232 233ImagesLoaded.prototype.addElementBackgroundImages = function( elem ) { 234 let style = getComputedStyle( elem ); 235 // Firefox returns null if in a hidden iframe https://bugzil.la/548397 236 if ( !style ) return; 237 238 // get url inside url("...") 239 let matches = reURL.exec( style.backgroundImage ); 240 while ( matches !== null ) { 241 let url = matches && matches[2]; 242 if ( url ) { 243 this.addBackground( url, elem ); 244 } 245 matches = reURL.exec( style.backgroundImage ); 246 } 247}; 248 249/** 250 * @param {Image} img 251 */ 252ImagesLoaded.prototype.addImage = function( img ) { 253 let loadingImage = new LoadingImage( img ); 254 this.images.push( loadingImage ); 255}; 256 257ImagesLoaded.prototype.addBackground = function( url, elem ) { 258 let background = new Background( url, elem ); 259 this.images.push( background ); 260}; 261 262ImagesLoaded.prototype.check = function() { 263 this.progressedCount = 0; 264 this.hasAnyBroken = false; 265 // complete if no images 266 if ( !this.images.length ) { 267 this.complete(); 268 return; 269 } 270 271 /* eslint-disable-next-line func-style */ 272 let onProgress = ( image, elem, message ) => { 273 // HACK - Chrome triggers event before object properties have changed. #83 274 setTimeout( () => { 275 this.progress( image, elem, message ); 276 } ); 277 }; 278 279 this.images.forEach( function( loadingImage ) { 280 loadingImage.once( 'progress', onProgress ); 281 loadingImage.check(); 282 } ); 283}; 284 285ImagesLoaded.prototype.progress = function( image, elem, message ) { 286 this.progressedCount++; 287 this.hasAnyBroken = this.hasAnyBroken || !image.isLoaded; 288 // progress event 289 this.emitEvent( 'progress', [ this, image, elem ] ); 290 if ( this.jqDeferred && this.jqDeferred.notify ) { 291 this.jqDeferred.notify( this, image ); 292 } 293 // check if completed 294 if ( this.progressedCount === this.images.length ) { 295 this.complete(); 296 } 297 298 if ( this.options.debug && console ) { 299 console.log( `progress: ${message}`, image, elem ); 300 } 301}; 302 303ImagesLoaded.prototype.complete = function() { 304 let eventName = this.hasAnyBroken ? 'fail' : 'done'; 305 this.isComplete = true; 306 this.emitEvent( eventName, [ this ] ); 307 this.emitEvent( 'always', [ this ] ); 308 if ( this.jqDeferred ) { 309 let jqMethod = this.hasAnyBroken ? 'reject' : 'resolve'; 310 this.jqDeferred[ jqMethod ]( this ); 311 } 312}; 313 314// -------------------------- -------------------------- // 315 316function LoadingImage( img ) { 317 this.img = img; 318} 319 320LoadingImage.prototype = Object.create( EvEmitter.prototype ); 321 322LoadingImage.prototype.check = function() { 323 // If complete is true and browser supports natural sizes, 324 // try to check for image status manually. 325 let isComplete = this.getIsImageComplete(); 326 if ( isComplete ) { 327 // report based on naturalWidth 328 this.confirm( this.img.naturalWidth !== 0, 'naturalWidth' ); 329 return; 330 } 331 332 // If none of the checks above matched, simulate loading on detached element. 333 this.proxyImage = new Image(); 334 // add crossOrigin attribute. #204 335 if ( this.img.crossOrigin ) { 336 this.proxyImage.crossOrigin = this.img.crossOrigin; 337 } 338 this.proxyImage.addEventListener( 'load', this ); 339 this.proxyImage.addEventListener( 'error', this ); 340 // bind to image as well for Firefox. #191 341 this.img.addEventListener( 'load', this ); 342 this.img.addEventListener( 'error', this ); 343 this.proxyImage.src = this.img.currentSrc || this.img.src; 344}; 345 346LoadingImage.prototype.getIsImageComplete = function() { 347 // check for non-zero, non-undefined naturalWidth 348 // fixes Safari+InfiniteScroll+Masonry bug infinite-scroll#671 349 return this.img.complete && this.img.naturalWidth; 350}; 351 352LoadingImage.prototype.confirm = function( isLoaded, message ) { 353 this.isLoaded = isLoaded; 354 let { parentNode } = this.img; 355 // emit progress with parent <picture> or self <img> 356 let elem = parentNode.nodeName === 'PICTURE' ? parentNode : this.img; 357 this.emitEvent( 'progress', [ this, elem, message ] ); 358}; 359 360// ----- events ----- // 361 362// trigger specified handler for event type 363LoadingImage.prototype.handleEvent = function( event ) { 364 let method = 'on' + event.type; 365 if ( this[ method ] ) { 366 this[ method ]( event ); 367 } 368}; 369 370LoadingImage.prototype.onload = function() { 371 this.confirm( true, 'onload' ); 372 this.unbindEvents(); 373}; 374 375LoadingImage.prototype.onerror = function() { 376 this.confirm( false, 'onerror' ); 377 this.unbindEvents(); 378}; 379 380LoadingImage.prototype.unbindEvents = function() { 381 this.proxyImage.removeEventListener( 'load', this ); 382 this.proxyImage.removeEventListener( 'error', this ); 383 this.img.removeEventListener( 'load', this ); 384 this.img.removeEventListener( 'error', this ); 385}; 386 387// -------------------------- Background -------------------------- // 388 389function Background( url, element ) { 390 this.url = url; 391 this.element = element; 392 this.img = new Image(); 393} 394 395// inherit LoadingImage prototype 396Background.prototype = Object.create( LoadingImage.prototype ); 397 398Background.prototype.check = function() { 399 this.img.addEventListener( 'load', this ); 400 this.img.addEventListener( 'error', this ); 401 this.img.src = this.url; 402 // check if image is already complete 403 let isComplete = this.getIsImageComplete(); 404 if ( isComplete ) { 405 this.confirm( this.img.naturalWidth !== 0, 'naturalWidth' ); 406 this.unbindEvents(); 407 } 408}; 409 410Background.prototype.unbindEvents = function() { 411 this.img.removeEventListener( 'load', this ); 412 this.img.removeEventListener( 'error', this ); 413}; 414 415Background.prototype.confirm = function( isLoaded, message ) { 416 this.isLoaded = isLoaded; 417 this.emitEvent( 'progress', [ this, this.element, message ] ); 418}; 419 420// -------------------------- jQuery -------------------------- // 421 422ImagesLoaded.makeJQueryPlugin = function( jQuery ) { 423 jQuery = jQuery || window.jQuery; 424 if ( !jQuery ) return; 425 426 // set local variable 427 $ = jQuery; 428 // $().imagesLoaded() 429 $.fn.imagesLoaded = function( options, onAlways ) { 430 let instance = new ImagesLoaded( this, options, onAlways ); 431 return instance.jqDeferred.promise( $( this ) ); 432 }; 433}; 434// try making plugin 435ImagesLoaded.makeJQueryPlugin(); 436 437// -------------------------- -------------------------- // 438 439return ImagesLoaded; 440 441} );
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.