PluginProbe
Elementor Website Builder – more than just a page builder / 3.1.4
Elementor Website Builder – more than just a page builder v3.1.4
4.3.0-beta3 4.3.0-beta2 4.3.0-beta1 4.2.4 4.2.3 4.2.2 4.2.1 4.2.0 4.1.5 4.2.0-beta2 4.2.0-dev2 4.2.0-beta1 4.1.4 4.1.3 4.1.2 4.1.1 4.1.0 4.1.0-beta3 4.1.0-dev3 4.0.9 4.1.0-beta2 4.1.0-dev2 4.0.8 4.1.0-beta1 4.1.0-dev1 All 452 releases
elementor / assets / lib / imagesloaded / imagesloaded.js

imagesloaded.js in Elementor Website Builder – more than just a page builder 3.1.4, at assets/lib/imagesloaded/imagesloaded.js

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