PageSourceSearch

https://www.demetzoslab.gr/js/imagesloaded.js

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