All Downloads are FREE. Search and download functionalities are using the official Maven repository.

gwt.material.design.addins.client.masonry.resources.js.imageloaded.js Maven / Gradle / Ivy

There is a newer version: 2.8.3
Show newest version
/*!
 * imagesLoaded PACKAGED v4.1.4
 * JavaScript is all like "You images are done yet or what?"
 * MIT License
 */

/**
 * EvEmitter v1.1.0
 * 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 ) {
        // CommonJS - Browserify, Webpack
        module.exports = factory();
    } else {
        // Browser globals
        global.EvEmitter = factory();
    }

}( typeof window != 'undefined' ? window : this, function() {



    function EvEmitter() {}

    var proto = EvEmitter.prototype;

    proto.on = function( eventName, listener ) {
        if ( !eventName || !listener ) {
            return;
        }
        // set events hash
        var events = this._events = this._events || {};
        // set listeners array
        var listeners = events[ eventName ] = events[ eventName ] || [];
        // only add once
        if ( listeners.indexOf( listener ) == -1 ) {
            listeners.push( listener );
        }

        return this;
    };

    proto.once = function( eventName, listener ) {
        if ( !eventName || !listener ) {
            return;
        }
        // add event
        this.on( eventName, listener );
        // set once flag
        // set onceEvents hash
        var onceEvents = this._onceEvents = this._onceEvents || {};
        // set onceListeners object
        var onceListeners = onceEvents[ eventName ] = onceEvents[ eventName ] || {};
        // set flag
        onceListeners[ listener ] = true;

        return this;
    };

    proto.off = function( eventName, listener ) {
        var listeners = this._events && this._events[ eventName ];
        if ( !listeners || !listeners.length ) {
            return;
        }
        var index = listeners.indexOf( listener );
        if ( index != -1 ) {
            listeners.splice( index, 1 );
        }

        return this;
    };

    proto.emitEvent = function( eventName, args ) {
        var listeners = this._events && this._events[ eventName ];
        if ( !listeners || !listeners.length ) {
            return;
        }
        // copy over to avoid interference if .off() in listener
        listeners = listeners.slice(0);
        args = args || [];
        // once stuff
        var onceListeners = this._onceEvents && this._onceEvents[ eventName ];

        for ( var i=0; i < listeners.length; i++ ) {
            var listener = listeners[i]
            var isOnce = onceListeners && onceListeners[ listener ];
            if ( isOnce ) {
                // remove listener
                // remove before trigger to prevent recursion
                this.off( eventName, listener );
                // unset once flag
                delete onceListeners[ listener ];
            }
            // trigger listener
            listener.apply( this, args );
        }

        return this;
    };

    proto.allOff = function() {
        delete this._events;
        delete this._onceEvents;
    };

    return EvEmitter;

}));

/*!
 * imagesLoaded v4.1.4
 * JavaScript is all like "You images are done yet or what?"
 * MIT License
 */

( function( window, factory ) { 'use strict';
    // 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 ) {
        // CommonJS
        module.exports = factory(
            window,
            require('ev-emitter')
        );
    } else {
        // browser global
        window.imagesLoaded = factory(
            window,
            window.EvEmitter
        );
    }

})( typeof window !== 'undefined' ? window : this,

// --------------------------  factory -------------------------- //

    function factory( window, EvEmitter ) {



        var $ = window.jQuery;
        var 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;
            }

            var isArrayLike = typeof obj == 'object' && typeof obj.length == 'number';
            if ( isArrayLike ) {
                // convert nodeList to array
                return arraySlice.call( obj );
            }

            // array of single index
            return [ obj ];
        }

// -------------------------- imagesLoaded -------------------------- //

        /**
         * @param {Array, Element, NodeList, String} elem
         * @param {Object or Function} options - if function, use as callback
         * @param {Function} onAlways - callback function
         */
        function ImagesLoaded( elem, options, onAlways ) {
            // coerce ImagesLoaded() without new, to be new ImagesLoaded()
            if ( !( this instanceof ImagesLoaded ) ) {
                return new ImagesLoaded( elem, options, onAlways );
            }
            // use elem as selector string
            var queryElem = elem;
            if ( typeof elem == 'string' ) {
                queryElem = document.querySelectorAll( elem );
            }
            // bail if bad element
            if ( !queryElem ) {
                console.error( 'Bad element for imagesLoaded ' + ( queryElem || elem ) );
                return;
            }

            this.elements = makeArray( queryElem );
            this.options = extend( {}, this.options );
            // shift arguments if no options set
            if ( typeof options == 'function' ) {
                onAlways = options;
            } else {
                extend( this.options, options );
            }

            if ( onAlways ) {
                this.on( 'always', onAlways );
            }

            this.getImages();

            if ( $ ) {
                // add jQuery Deferred object
                this.jqDeferred = new $.Deferred();
            }

            // HACK check async to allow time to bind listeners
            setTimeout( this.check.bind( this ) );
        }

        ImagesLoaded.prototype = Object.create( EvEmitter.prototype );

        ImagesLoaded.prototype.options = {};

        ImagesLoaded.prototype.getImages = function() {
            this.images = [];

            // filter & find items if we have an item selector
            this.elements.forEach( this.addElementImages, this );
        };

        /**
         * @param {Node} element
         */
        ImagesLoaded.prototype.addElementImages = function( elem ) {
            // filter siblings
            if ( elem.nodeName == 'IMG' ) {
                this.addImage( elem );
            }
            // get background image on element
            if ( this.options.background === true ) {
                this.addElementBackgroundImages( elem );
            }

            // find children
            // no non-element nodes, #143
            var nodeType = elem.nodeType;
            if ( !nodeType || !elementNodeTypes[ nodeType ] ) {
                return;
            }
            var childImgs = elem.querySelectorAll('img');
            // concat childElems to filterFound array
            for ( var i=0; i < childImgs.length; i++ ) {
                var img = childImgs[i];
                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];
                    this.addElementBackgroundImages( child );
                }
            }
        };

        var elementNodeTypes = {
            1: true,
            9: true,
            11: true
        };

        ImagesLoaded.prototype.addElementBackgroundImages = function( elem ) {
            var style = getComputedStyle( elem );
            if ( !style ) {
                // Firefox returns null if in a hidden iframe https://bugzil.la/548397
                return;
            }
            // get url inside url("...")
            var reURL = /url\((['"])?(.*?)\1\)/gi;
            var matches = reURL.exec( style.backgroundImage );
            while ( matches !== null ) {
                var url = matches && matches[2];
                if ( url ) {
                    this.addBackground( url, elem );
                }
                matches = reURL.exec( style.backgroundImage );
            }
        };

        /**
         * @param {Image} img
         */
        ImagesLoaded.prototype.addImage = function( img ) {
            var loadingImage = new LoadingImage( img );
            this.images.push( loadingImage );
        };

        ImagesLoaded.prototype.addBackground = function( url, elem ) {
            var 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
            if ( !this.images.length ) {
                this.complete();
                return;
            }

            function onProgress( image, elem, message ) {
                // HACK - Chrome triggers event before object properties have changed. #83
                setTimeout( function() {
                    _this.progress( image, elem, message );
                });
            }

            this.images.forEach( function( loadingImage ) {
                loadingImage.once( 'progress', onProgress );
                loadingImage.check();
            });
        };

        ImagesLoaded.prototype.progress = function( image, elem, message ) {
            this.progressedCount++;
            this.hasAnyBroken = this.hasAnyBroken || !image.isLoaded;
            // progress event
            this.emitEvent( 'progress', [ this, image, elem ] );
            if ( this.jqDeferred && this.jqDeferred.notify ) {
                this.jqDeferred.notify( this, image );
            }
            // check if completed
            if ( this.progressedCount == this.images.length ) {
                this.complete();
            }

            if ( this.options.debug && console ) {
                console.log( 'progress: ' + message, image, elem );
            }
        };

        ImagesLoaded.prototype.complete = function() {
            var 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';
                this.jqDeferred[ jqMethod ]( this );
            }
        };

// --------------------------  -------------------------- //

        function LoadingImage( img ) {
            this.img = img;
        }

        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();
            if ( isComplete ) {
                // report based on naturalWidth
                this.confirm( this.img.naturalWidth !== 0, 'naturalWidth' );
                return;
            }

            // If none of the checks above matched, simulate loading on detached element.
            this.proxyImage = new Image();
            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;
        };

        LoadingImage.prototype.getIsImageComplete = function() {
            // check for non-zero, non-undefined naturalWidth
            // fixes Safari+InfiniteScroll+Masonry bug infinite-scroll#671
            return this.img.complete && this.img.naturalWidth;
        };

        LoadingImage.prototype.confirm = function( isLoaded, message ) {
            this.isLoaded = isLoaded;
            this.emitEvent( 'progress', [ this, this.img, message ] );
        };

// ----- events ----- //

// trigger specified handler for event type
        LoadingImage.prototype.handleEvent = function( event ) {
            var method = 'on' + event.type;
            if ( this[ method ] ) {
                this[ method ]( event );
            }
        };

        LoadingImage.prototype.onload = function() {
            this.confirm( true, 'onload' );
            this.unbindEvents();
        };

        LoadingImage.prototype.onerror = function() {
            this.confirm( false, 'onerror' );
            this.unbindEvents();
        };

        LoadingImage.prototype.unbindEvents = function() {
            this.proxyImage.removeEventListener( 'load', this );
            this.proxyImage.removeEventListener( 'error', this );
            this.img.removeEventListener( 'load', this );
            this.img.removeEventListener( 'error', this );
        };

// -------------------------- Background -------------------------- //

        function Background( url, element ) {
            this.url = url;
            this.element = element;
            this.img = new Image();
        }

// inherit LoadingImage prototype
        Background.prototype = Object.create( LoadingImage.prototype );

        Background.prototype.check = function() {
            this.img.addEventListener( 'load', this );
            this.img.addEventListener( 'error', this );
            this.img.src = this.url;
            // check if image is already complete
            var isComplete = this.getIsImageComplete();
            if ( isComplete ) {
                this.confirm( this.img.naturalWidth !== 0, 'naturalWidth' );
                this.unbindEvents();
            }
        };

        Background.prototype.unbindEvents = function() {
            this.img.removeEventListener( 'load', this );
            this.img.removeEventListener( 'error', this );
        };

        Background.prototype.confirm = function( isLoaded, message ) {
            this.isLoaded = isLoaded;
            this.emitEvent( 'progress', [ this, this.element, message ] );
        };

// -------------------------- jQuery -------------------------- //

        ImagesLoaded.makeJQueryPlugin = function( jQuery ) {
            jQuery = jQuery || window.jQuery;
            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) );
            };
        };
// try making plugin
        ImagesLoaded.makeJQueryPlugin();

// --------------------------  -------------------------- //

        return ImagesLoaded;

    });





© 2015 - 2024 Weber Informatics LLC | Privacy Policy