PageSourceSearch

https://doveliyuchen.github.io/assets/js/imagesloaded.pkgd.js

js doveliyuchen.github.io collected 2026-10-03 09:03:18 UTC 22,440 bytes, 744 lines download raw bytes

1/*!
2 * imagesLoaded PACKAGED v3.0.2
3 * JavaScript is all like "You images are done yet or what?"
4 */
5
6/*!
7 * EventEmitter v4.1.0 - git.io/ee
8 * Oliver Caldwell
9 * MIT license
10 * @preserve
11 */
12
13(function (exports) {
14	// Place the script in strict mode
15	'use strict';
16
17	/**
18	 * Class for managing events.
19	 * Can be extended to provide event functionality in other classes.
20	 *
21	 * @class Manages event registering and emitting.
22	 */
23	function EventEmitter() {}
24
25	// Shortcuts to improve speed and size
26
27	// Easy access to the prototype
28	var proto = EventEmitter.prototype,
29		nativeIndexOf = Array.prototype.indexOf ? true : false;
30
31	/**
32	 * Finds the index of the listener for the event in it's storage array.
33	 *
34	 * @param {Function} listener Method to look for.
35	 * @param {Function[]} listeners Array of listeners to search through.
36	 * @return {Number} Index of the specified listener, -1 if not found
37	 * @api private
38	 */
39	function indexOfListener(listener, listeners) {
40		// Return the index via the native method if possible
41		if (nativeIndexOf) {
42			return listeners.indexOf(listener);
43		}
44
45		// There is no native method
46		// Use a manual loop to find the index
47		var i = listeners.length;
48		while (i--) {
49			// If the listener matches, return it's index
50			if (listeners[i] === listener) {
51				return i;
52			}
53		}
54
55		// Default to returning -1
56		return -1;
57	}
58
59	/**
60	 * Fetches the events object and creates one if required.
61	 *
62	 * @return {Object} The events storage object.
63	 * @api private
64	 */
65	proto._getEvents = function () {
66		return this._events || (this._events = {});
67	};
68
69	/**
70	 * Returns the listener array for the specified event.
71	 * Will initialise the event object and listener arrays if required.
72	 * Will return an object if you use a regex search. The object contains keys for each matched event. So /ba[rz]/ might return an object c
72ontaining bar and baz. But only if you have either defined them with defineEvent or added some listeners to them.
73	 * Each property in the object response is an array of listener functions.
74	 *
75	 * @param {String|RegExp} evt Name of the event to return the listeners from.
76	 * @return {Function[]|Object} All listener functions for the event.
77	 */
78	proto.getListeners = function (evt) {
79		// Create a shortcut to the storage object
80		// Initialise it if it does not exists yet
81		var events = this._getEvents(),
82			response,
83			key;
84
85		// Return a concatenated array of all matching events if
86		// the selector is a regular expression.
87		if (typeof evt === 'object') {
88			response = {};
89			for (key in events) {
90				if (events.hasOwnProperty(key) && evt.test(key)) {
91					response[key] = events[key];
92				}
93			}
94		}
95		else {
96			response = events[evt] || (events[evt] = []);
97		}
98
99		return response;
100	};
101
102	/**
103	 * Fetches the requested listeners via getListeners but will always return the results inside an object. This is mainly for internal use but others may find it useful.
104	 *
105	 * @param {String|RegExp} evt Name of the event to return the listeners from.
106	 * @return {Object} All listener functions for an event in an object.
107	 */
108	proto.getListenersAsObject = function (evt) {
109		var listeners = this.getListeners(evt),
110			response;
111
112		if (listeners instanceof Array) {
113			response = {};
114			response[evt] = listeners;
115		}
116
117		return response || listeners;
118	};
119
120	/**
121	 * Adds a listener function to the specified event.
122	 * The listener will not be added if it is a duplicate.
123	 * If the listener returns true then it will be removed after it is called.
124	 * If you pass a regular expression as the event name then the listener will be added to all events that match it.
125	 *
126	 * @param {String|RegExp} evt Name of the event to attach the listener to.
127	 * @param {Function} listener Method to be called when the event is emitted. If the function returns true then it will be removed after calling.
128	 * @return {Object} Current instance of EventEmitter for chaining.
129	 */
130	proto.addListener = function (evt, listener) {
131		var listeners = this.getListenersAsObject(evt),
132			key;
133
134		for (key in listeners) {
135			if (listeners.hasOwnProperty(key) &&
136				indexOfListener(listener, listeners[key]) === -1) {
137				listeners[key].push(listener);
138			}
139		}
140
141		// Return the instance of EventEmitter to allow chaining
142		return this;
143	};
144
145	/**
146	 * Alias of addListener
147	 */
148	proto.on = proto.addListener;
149
150	/**
151	 * Defines an event name. This is required if you want to use a regex to add a listener to multiple events at once. If you don't do this then how do you expect it to know what event to add to? Should it just add to every possible match for a regex? No. That is scary and bad.
152	 * You need to tell it what event names should be matched by a regex.
153	 *
154	 * @param {String} evt Name of the event to create.
155	 * @return {Object} Current instance of EventEmitter for chaining.
156	 */
157	proto.defineEvent = function (evt) {
158		this.getListeners(evt);
159		return this;
160	};
161
162	/**
163	 * Uses defineEvent to define multiple events.
164	 *
165	 * @param {String[]} evts An array of event names to define.
166	 * @return {Object} Current instance of EventEmitter for chaining.
167	 */
168	proto.defineEvents = function (evts)
169	{
170		for (var i = 0; i < evts.length; i += 1) {
171			this.defineEvent(evts[i]);
172		}
173		return this;
174	};
175
176	/**
177	 * Removes a listener function from the specified event.
178	 * When passed a regular expression as the event name, it will remove the listener from all events that match it.
179	 *
180	 * @param {String|RegExp} evt Name of the event to remove the listener from.
181	 * @param {Function} listener Method to remove from the event.
182	 * @return {Object} Current instance of EventEmitter for chaining.
183	 */
184	proto.removeListener = function (evt, listener) {
185		var listeners = this.getListenersAsObject(evt),
186			index,
187			key;
188
189		for (key in listeners) {
190			if (listeners.hasOwnProperty(key)) {
191				index = indexOfListener(listener, listeners[key]);
192
193				if (index !== -1) {
194					listeners[key].splice(index, 1);
195				}
196			}
197		}
198
199		// Return the instance of EventEmitter to allow chaining
200		return this;
201	};
202
203	/**
204	 * Alias of removeListener
205	 */
206	proto.off = proto.removeListener;
207
208	/**
209	 * Adds listeners in bulk using the manipulateListeners method.
210	 * If you pass an object as the second argument you can add to multiple events at once. The object should contain key value pairs of events and listeners or listener arrays. You can also pass it an event name and an array of listeners to be added.
211	 * You can also pass it a regular expression to add the array of listeners to all events that match it.
212	 * Yeah, this function does quite a bit. That's probably a bad thing.
213	 *
214	 * @param {String|Object|RegExp} evt An event name if you will pass an array of listeners next. An object if you wish to add to multiple events at once.
215	 * @param {Function[]} [listeners] An optional array of listener functions to add.
216	 * @return {Object} Current instance of EventEmitter for chaining.
217	 */
218	proto.addListeners = function (evt, listeners) {
219		// Pass through to manipulateListeners
220		return this.manipulateListeners(false, evt, listeners);
221	};
222
223	/**
224	 * Removes listeners in bulk using the manipulateListeners method.
225	 * If you pass an object as the second argument you can remove from multiple events at once. The object should contain key value pairs of events and listeners or listener arrays.
226	 * You can also pass it an event name and an array of listeners to be removed.
227	 * You can also pass it a regular expression to remove the listeners from all events that match it.
228	 *
229	 * @param {String|Object|RegExp} evt An event name if you will pass an array of listeners next. An object if you wish to remove from multiple events at once.
230	 * @param {Function[]} [listeners] An optional array of listener functions to remove.
231	 * @return {Object} Current instance of EventEmitter for chaining.
232	 */
233	proto.removeListeners = function (evt, listeners) {
234		// Pass through to manipulateListeners
235		return this.manipulateListeners(true, evt, listeners);
236	};
237
238	/**
239	 * Edits listeners in bulk. The addListeners and removeListeners methods both use this to do their job. You should really use those instead, this is a little lower level.
240	 * The first argument will determine if the listeners are removed (true) or added (false).
241	 * If you pass an object as the second argument you can add/remove from multiple events at once. The object should contain key value pairs of events and listeners or listener arrays.
242	 * You can also pass it an event name and an array of listeners to be added/removed.
243	 * You can also pass it a regular expression to manipulate the listeners of all events that match it.
244	 *
245	 * @param {Boolean} remove True if you want to remove listeners, false if you want to add.
246	 * @param {String|Object|RegExp} evt An event name if you will pass an array of listeners next. An object if you wish to add/remove from multiple events at once.
247	 * @param {Function[]} [listeners] An optional array of listener functions to add/remove.
248	 * @return {Object} Current instance of EventEmitter for chaining.
249	 */
250	proto.manipulateListeners = function (remove, evt, listeners) {
251		// Initialise any required variables
252		var i,
253			value,
254			single = remove ? this.removeListener : this.addListener,
255			multiple = remove ? this.removeListeners : this.addListeners;
256
257		// If evt is an object then pass each of it's properties to this method
258		if (typeof evt === 'object' && !(evt instanceof RegExp)) {
259			for (i in evt) {
260				if (evt.hasOwnProperty(i) && (value = evt[i])) {
261					// Pass the single listener straight through to the singular method
262					if (typeof value === 'function') {
263						single.call(this, i, value);
264					}
265					else {
266						// Otherwise pass back to the multiple function
267						multiple.call(this, i, value);
268					}
269				}
270			}
271		}
272		else {
273			// So evt must be a string
274			// And listeners must be an array of listeners
275			// Loop over it and pass each one to the multiple method
276			i = listeners.length;
277			while (i--) {
278				single.call(this, evt, listeners[i]);
279			}
280		}
281
282		// Return the instance of EventEmitter to allow chaining
283		return this;
284	};
285
286	/**
287	 * Removes all listeners from a specified event.
288	 * If you do not specify an event then all listeners will be removed.
289	 * That means every event will be emptied.
290	 * You can also pass a regex to remove all events that match it.
291	 *
292	 * @param {String|RegExp} [evt] Optional name of the event to remove all listeners for. Will remove from every event if not passed.
293	 * @return {Object} Current instance of EventEmitter for chaining.
294	 */
295	proto.removeEvent = function (evt) {
296		var type = typeof evt,
297			events = this._getEvents(),
298			key;
299
300		// Remove different things depending on the state of evt
301		if (type === 'string') {
302			// Remove all listeners for the specified event
303			delete events[evt];
304		}
305		else if (type === 'object') {
306			// Remove all events matching the regex.
307			for (key in events) {
308				if (events.hasOwnProperty(key) && evt.test(key)) {
309					delete events[key];
310				}
311			}
312		}
313		else {
314			// Remove all listeners in all events
315			delete this._events;
316		}
317
318		// Return the instance of EventEmitter to allow chaining
319		return this;
320	};
321
322	/**
323	 * Emits an event of your choice.
324	 * When emitted, every listener attached to that event will be executed.
325	 * If you pass the optional argument array then those arguments will be passed to every listener upon execution.
326	 * Because it uses `apply`, your array of arguments will be passed as if you wrote them out separately.
327	 * So they will not arrive within the array on the other side, they will be separate.
328	 * You can also pass a regular expression to emit to all events that match it.
329	 *
330	 * @param {String|RegExp} evt Name of the event to emit and execute listeners for.
331	 * @param {Array} [args] Optional array of arguments to be passed to each listener.
332	 * @return {Object} Current instance of EventEmitter for chaining.
333	 */
334	proto.emitEvent = function (evt, args) {
335		var listeners = this.getListenersAsObject(evt),
336			i,
337			key,
338			response;
339
340		for (key in listeners) {
341			if (listeners.hasOwnProperty(key)) {
342				i = listeners[key].length;
343
344				while (i--) {
345					// If the listener returns true then it shall be removed from the event
346					// The function is executed either with a basic call or an apply if there is an args array
347					response = args ? listeners[key][i].apply(null, args) : listeners[key][i]();
348					if (response === true) {
349						this.removeListener(evt, listeners[key][i]);
350					}
351				}
352			}
353		}
354
355		// Return the instance of EventEmitter to allow chaining
356		return this;
357	};
358
359	/**
360	 * Alias of emitEvent
361	 */
362	proto.trigger = proto.emitEvent;
363
364	/**
365	 * Subtly different from emitEvent in that it will pass its arguments on to the listeners, as opposed to taking a single array of arguments to pass on.
366	 * As with emitEvent, you can pass a regex in place of the event name to emit to all events that match it.
367	 *
368	 * @param {String|RegExp} evt Name of the event to emit and execute listeners for.
369	 * @param {...*} Optional additional arguments to be passed to each listener.
370	 * @return {Object} Current instance of EventEmitter for chaining.
371	 */
372	proto.emit = function (evt) {
373		var args = Array.prototype.slice.call(arguments, 1);
374		return this.emitEvent(evt, args);
375	};
376
377	// Expose the class either via AMD or the global object
378	if (typeof define === 'function' && define.amd) {
379		define(function () {
380			return EventEmitter;
381		});
382	}
383	else {
384		exports.EventEmitter = EventEmitter;
385	}
386}(this));
387/*!
388 * eventie v1.0.3
389 * event binding helper
390 *   eventie.bind( elem, 'click', myFn )
391 *   eventie.unbind( elem, 'click', myFn )
392 */
393
394/*jshint browser: true, undef: true, unused: true */
395/*global define: false */
396
397( function( window ) {
398
399'use strict';
400
401var docElem = document.documentElement;
402
403var bind = function() {};
404
405if ( docElem.addEventListener ) {
406  bind = function( obj, type, fn ) {
407    obj.addEventListener( type, fn, false );
408  };
409} else if ( docElem.attachEvent ) {
410  bind = function( obj, type, fn ) {
411    obj[ type + fn ] = fn.handleEvent ?
412      function() {
413        var event = window.event;
414        // add event.target
415        event.target = event.target || event.srcElement;
416        fn.handleEvent.call( fn, event );
417      } :
418      function() {
419        var event = window.event;
420        // add event.target
421        event.target = event.target || event.srcElement;
422        fn.call( obj, event );
423      };
424    obj.attachEvent( "on" + type, obj[ type + fn ] );
425  };
426}
427
428var unbind = function() {};
429
430if ( docElem.removeEventListener ) {
431  unbind = function( obj, type, fn ) {
432    obj.removeEventListener( type, fn, false );
433  };
434} else if ( docElem.detachEvent ) {
435  unbind = function( obj, type, fn ) {
436    obj.detachEvent( "on" + type, obj[ type + fn ] );
437    try {
438      delete obj[ type + fn ];
439    } catch ( err ) {
440      // can't delete window object properties
441      obj[ type + fn ] = undefined;
442    }
443  };
444}
445
446var eventie = {
447  bind: bind,
448  unbind: unbind
449};
450
451// transport
452if ( typeof define === 'function' && define.amd ) {
453  // AMD
454  define( eventie );
455} else {
456  // browser global
457  window.eventie = eventie;
458}
459
460})( this );
461
462/*!
463 * imagesLoaded v3.0.2
464 * JavaScript is all like "You images are done yet or what?"
465 */
466
467( function( window ) {
468
469'use strict';
470
471var $ = window.jQuery;
472var console = window.console;
473var hasConsole = typeof console !== 'undefined';
474
475// -------------------------- helpers -------------------------- //
476
477// extend objects
478function extend( a, b ) {
479  for ( var prop in b ) {
480    a[ prop ] = b[ prop ];
481  }
482  return a;
483}
484
485var objToString = Object.prototype.toString;
486function isArray( obj ) {
487  return objToString.call( obj ) === '[object Array]';
488}
489
490// turn element or nodeList into an array
491function makeArray( obj ) {
492  var ary = [];
493  if ( isArray( obj ) ) {
494    // use object if already an array
495    ary = obj;
496  } else if ( typeof obj.length === 'number' ) {
497    // convert nodeList to array
498    for ( var i=0, len = obj.length; i < len; i++ ) {
499      ary.push( obj[i] );
500    }
501  } else {
502    // array of single index
503    ary.push( obj );
504  }
505  return ary;
506}
507
508// --------------------------  -------------------------- //
509
510function defineImagesLoaded( EventEmitter, eventie ) {
511
512  /**
513   * @param {Array, Element, NodeList, String} elem
514   * @param {Object or Function} options - if function, use as callback
515   * @param {Function} onAlways - callback function
516   */
517  function ImagesLoaded( elem, options, onAlways ) {
518    // coerce ImagesLoaded() without new, to be new ImagesLoaded()
519    if ( !( this instanceof ImagesLoaded ) ) {
520      return new ImagesLoaded( elem, options );
521    }
522    // use elem as selector string
523    if ( typeof elem === 'string' ) {
524      elem = document.querySelectorAll( elem );
525    }
526
527    this.elements = makeArray( elem );
528    this.options = extend( {}, this.options );
529
530    if ( typeof options === 'function' ) {
531      onAlways = options;
532    } else {
533      extend( this.options, options );
534    }
535
536    if ( onAlways ) {
537      this.on( 'always', onAlways );
538    }
539
540    this.getImages();
541
542    if ( $ ) {
543      // add jQuery Deferred object
544      this.jqDeferred = new $.Deferred();
545    }
546
547    // HACK check async to allow time to bind listeners
548    var _this = this;
549    setTimeout( function() {
550      _this.check();
551    });
552  }
553
554  ImagesLoaded.prototype = new EventEmitter();
555
556  ImagesLoaded.prototype.options = {};
557
558  ImagesLoaded.prototype.getImages = function() {
559    this.images = [];
560
561    // filter & find items if we have an item selector
562    for ( var i=0, len = this.elements.length; i < len; i++ ) {
563      var elem = this.elements[i];
564      // filter siblings
565      if ( elem.nodeName === 'IMG' ) {
566        this.addImage( elem );
567      }
568      // find children
569      var childElems = elem.querySelectorAll('img');
570      // concat childElems to filterFound array
571      for ( var j=0, jLen = childElems.length; j < jLen; j++ ) {
572        var img = childElems[j];
573        this.addImage( img );
574      }
575    }
576  };
577
578  /**
579   * @param {Image} img
580   */
581  ImagesLoaded.prototype.addImage = function( img ) {
582    var loadingImage = new LoadingImage( img );
583    this.images.push( loadingImage );
584  };
585
586  ImagesLoaded.prototype.check = function() {
587    var _this = this;
588    var checkedCount = 0;
589    var length = this.images.length;
590    this.hasAnyBroken = false;
591    // complete if no images
592    if ( !length ) {
593      this.complete();
594      return;
595    }
596
597    function onConfirm( image, message ) {
598      if ( _this.options.debug && hasConsole ) {
599        console.log( 'confirm', image, message );
600      }
601
602      _this.progress( image );
603      checkedCount++;
604      if ( checkedCount === length ) {
605        _this.complete();
606      }
607      return true; // bind once
608    }
609
610    for ( var i=0; i < length; i++ ) {
611      var loadingImage = this.images[i];
612      loadingImage.on( 'confirm', onConfirm );
613      loadingImage.check();
614    }
615  };
616
617  ImagesLoaded.prototype.progress = function( image ) {
618    this.hasAnyBroken = this.hasAnyBroken || !image.isLoaded;
619    this.emit( 'progress', this, image );
620    if ( this.jqDeferred ) {
621      this.jqDeferred.notify( this, image );
622    }
623  };
624
625  ImagesLoaded.prototype.complete = function() {
626    var eventName = this.hasAnyBroken ? 'fail' : 'done';
627    this.isComplete = true;
628    this.emit( eventName, this );
629    this.emit( 'always', this );
630    if ( this.jqDeferred ) {
631      var jqMethod = this.hasAnyBroken ? 'reject' : 'resolve';
632      this.jqDeferred[ jqMethod ]( this );
633    }
634  };
635
636  // -------------------------- jquery -------------------------- //
637
638  if ( $ ) {
639    $.fn.imagesLoaded = function( options, callback ) {
640      var instance = new ImagesLoaded( this, options, callback );
641      return instance.jqDeferred.promise( $(this) );
642    };
643  }
644
645
646  // --------------------------  -------------------------- //
647
648  var cache = {};
649
650  function LoadingImage( img ) {
651    this.img = img;
652  }
653
654  LoadingImage.prototype = new EventEmitter();
655
656  LoadingImage.prototype.check = function() {
657    // first check cached any previous images that have same src
658    var cached = cache[ this.img.src ];
659    if ( cached ) {
660      this.useCached( cached );
661      return;
662    }
663    // add this to cache
664    cache[ this.img.src ] = this;
665
666    // If complete is true and browser supports natural sizes,
667    // try to check for image status manually.
668    if ( this.img.complete && this.img.naturalWidth !== undefined ) {
669      // report based on naturalWidth
670      this.confirm( this.img.naturalWidth !== 0, 'naturalWidth' );
671      return;
672    }
673
674    // If none of the checks above matched, simulate loading on detached element.
675    var proxyImage = this.proxyImage = new Image();
676    eventie.bind( proxyImage, 'load', this );
677    eventie.bind( proxyImage, 'error', this );
678    proxyImage.src = this.img.src;
679  };
680
681  LoadingImage.prototype.useCached = function( cached ) {
682    if ( cached.isConfirmed ) {
683      this.confirm( cached.isLoaded, 'cached was confirmed' );
684    } else {
685      var _this = this;
686      cached.on( 'confirm', function( image ) {
687        _this.confirm( image.isLoaded, 'cache emitted confirmed' );
688        return true; // bind once
689      });
690    }
691  };
692
693  LoadingImage.prototype.confirm = function( isLoaded, message ) {
694    this.isConfirmed = true;
695    this.isLoaded = isLoaded;
696    this.emit( 'confirm', this, message );
697  };
698
699  // trigger specified handler for event type
700  LoadingImage.prototype.handleEvent = function( event ) {
701    var method = 'on' + event.type;
702    if ( this[ method ] ) {
703      this[ method ]( event );
704    }
705  };
706
707  LoadingImage.prototype.onload = function() {
708    this.confirm( true, 'onload' );
709    this.unbindProxyEvents();
710  };
711
712  LoadingImage.prototype.onerror = function() {
713    this.confirm( false, 'onerror' );
714    this.unbindProxyEvents();
715  };
716
717  LoadingImage.prototype.unbindProxyEvents = function() {
718    eventie.unbind( this.proxyImage, 'load', this );
719    eventie.unbind( this.proxyImage, 'error', this );
720  };
721
722  // -----  ----- //
723
724  return ImagesLoaded;
725}
726
727// -------------------------- transport -------------------------- //
728
729if ( typeof define === 'function' && define.amd ) {
730  // AMD
731  define( [
732      'eventEmitter',
733      'eventie'
734    ],
735    defineImagesLoaded );
736} else {
737  // browser global
738  window.imagesLoaded = defineImagesLoaded(
739    window.EventEmitter,
740    window.eventie
741  );
742}
743
744})( window );

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.