Create New Item
×
Item Type
File
Folder
Item Name
×
Search file in folder and subfolders...
File Manager
/
wp-content
/
plugins
/
anywhere-elementor-pro.2.15.5
/
includes
/
assets
/
lib
/
infinite-scroll
Advanced Search
Upload
New Item
Settings
Back
Back Up
Advanced Editor
Save
/*! * Infinite Scroll PACKAGED v3.0.5 * Automatically add next page * * Licensed GPLv3 for open source use * or Infinite Scroll Commercial License for commercial use * * https://infinite-scroll.com * Copyright 2018 Metafizzy */ /** * Bridget makes jQuery widgets * v2.0.1 * MIT license */ /* jshint browser: true, strict: true, undef: true, unused: true */ ( function( window, factory ) { // universal module definition /*jshint strict: false */ /* globals define, module, require */ if ( typeof define == 'function' && define.amd ) { // AMD define( 'jquery-bridget/jquery-bridget',[ 'jquery' ], function( jQuery ) { return factory( window, jQuery ); }); } else if ( typeof module == 'object' && module.exports ) { // CommonJS module.exports = factory( window, require('jquery') ); } else { // browser global window.jQueryBridget = factory( window, window.jQuery ); } }( window, function factory( window, jQuery ) { 'use strict'; // ----- utils ----- // var arraySlice = Array.prototype.slice; // helper function for logging errors // $.error breaks jQuery chaining var console = window.console; var logError = typeof console == 'undefined' ? function() {} : function( message ) { console.error( message ); }; // ----- jQueryBridget ----- // function jQueryBridget( namespace, PluginClass, $ ) { $ = $ || jQuery || window.jQuery; if ( !$ ) { return; } // add option method -> $().plugin('option', {...}) if ( !PluginClass.prototype.option ) { // option setter PluginClass.prototype.option = function( opts ) { // bail out if not an object if ( !$.isPlainObject( opts ) ){ return; } this.options = $.extend( true, this.options, opts ); }; } // make jQuery plugin $.fn[ namespace ] = function( arg0 /*, arg1 */ ) { if ( typeof arg0 == 'string' ) { // method call $().plugin( 'methodName', { options } ) // shift arguments by 1 var args = arraySlice.call( arguments, 1 ); return methodCall( this, arg0, args ); } // just $().plugin({ options }) plainCall( this, arg0 ); return this; }; // $().plugin('methodName') function methodCall( $elems, methodName, args ) { var returnValue; var pluginMethodStr = '$().' + namespace + '("' + methodName + '")'; $elems.each( function( i, elem ) { // get instance var instance = $.data( elem, namespace ); if ( !instance ) { logError( namespace + ' not initialized. Cannot call methods, i.e. ' + pluginMethodStr ); return; } var method = instance[ methodName ]; if ( !method || methodName.charAt(0) == '_' ) { logError( pluginMethodStr + ' is not a valid method' ); return; } // apply method, get return value var value = method.apply( instance, args ); // set return value if value is returned, use only first value returnValue = returnValue === undefined ? value : returnValue; }); return returnValue !== undefined ? returnValue : $elems; } function plainCall( $elems, options ) { $elems.each( function( i, elem ) { var instance = $.data( elem, namespace ); if ( instance ) { // set options & init instance.option( options ); instance._init(); } else { // initialize new instance instance = new PluginClass( elem, options ); $.data( elem, namespace, instance ); } }); } updateJQuery( $ ); } // ----- updateJQuery ----- // // set $.bridget for v1 backwards compatibility function updateJQuery( $ ) { if ( !$ || ( $ && $.bridget ) ) { return; } $.bridget = jQueryBridget; } updateJQuery( jQuery || window.jQuery ); // ----- ----- // return jQueryBridget; })); /** * 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; })); /** * matchesSelector v2.0.2 * matchesSelector( element, '.selector' ) * MIT license */ /*jshint browser: true, strict: true, undef: true, unused: true */ ( function( window, factory ) { /*global define: false, module: false */ 'use strict'; // universal module definition if ( typeof define == 'function' && define.amd ) { // AMD define( 'desandro-matches-selector/matches-selector',factory ); } else if ( typeof module == 'object' && module.exports ) { // CommonJS module.exports = factory(); } else { // browser global window.matchesSelector = factory(); } }( window, function factory() { 'use strict'; var matchesMethod = ( function() { var ElemProto = window.Element.prototype; // check for the standard method name first if ( ElemProto.matches ) { return 'matches'; } // check un-prefixed if ( ElemProto.matchesSelector ) { return 'matchesSelector'; } // check vendor prefixes var prefixes = [ 'webkit', 'moz', 'ms', 'o' ]; for ( var i=0; i < prefixes.length; i++ ) { var prefix = prefixes[i]; var method = prefix + 'MatchesSelector'; if ( ElemProto[ method ] ) { return method; } } })(); return function matchesSelector( elem, selector ) { return elem[ matchesMethod ]( selector ); }; })); /** * Fizzy UI utils v2.0.7 * MIT license */ /*jshint browser: true, undef: true, unused: true, strict: true */ ( function( window, factory ) { // universal module definition /*jshint strict: false */ /*globals define, module, require */ if ( typeof define == 'function' && define.amd ) { // AMD define( 'fizzy-ui-utils/utils',[ 'desandro-matches-selector/matches-selector' ], function( matchesSelector ) { return factory( window, matchesSelector ); }); } else if ( typeof module == 'object' && module.exports ) { // CommonJS module.exports = factory( window, require('desandro-matches-selector') ); } else { // browser global window.fizzyUIUtils = factory( window, window.matchesSelector ); } }( window, function factory( window, matchesSelector ) { var utils = {}; // ----- extend ----- // // extends objects utils.extend = function( a, b ) { for ( var prop in b ) { a[ prop ] = b[ prop ]; } return a; }; // ----- modulo ----- // utils.modulo = function( num, div ) { return ( ( num % div ) + div ) % div; }; // ----- makeArray ----- // var arraySlice = Array.prototype.slice; // turn element or nodeList into an array utils.makeArray = function( obj ) { if ( Array.isArray( obj ) ) { // use object if already an array return obj; } // return empty array if undefined or null. #6 if ( obj === null || obj === undefined ) { return []; } 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 ]; }; // ----- removeFrom ----- // utils.removeFrom = function( ary, obj ) { var index = ary.indexOf( obj ); if ( index != -1 ) { ary.splice( index, 1 ); } }; // ----- getParent ----- // utils.getParent = function( elem, selector ) { while ( elem.parentNode && elem != document.body ) { elem = elem.parentNode; if ( matchesSelector( elem, selector ) ) { return elem; } } }; // ----- getQueryElement ----- // // use element as selector string utils.getQueryElement = function( elem ) { if ( typeof elem == 'string' ) { return document.querySelector( elem ); } return elem; }; // ----- handleEvent ----- // // enable .ontype to trigger from .addEventListener( elem, 'type' ) utils.handleEvent = function( event ) { var method = 'on' + event.type; if ( this[ method ] ) { this[ method ]( event ); } }; // ----- filterFindElements ----- // utils.filterFindElements = function( elems, selector ) { // make array of elems elems = utils.makeArray( elems ); var ffElems = []; elems.forEach( function( elem ) { // check that elem is an actual element if ( !( elem instanceof HTMLElement ) ) { return; } // add elem if no selector if ( !selector ) { ffElems.push( elem ); return; } // filter & find items if we have a selector // filter if ( matchesSelector( elem, selector ) ) { ffElems.push( elem ); } // find children var childElems = elem.querySelectorAll( selector ); // concat childElems to filterFound array for ( var i=0; i < childElems.length; i++ ) { ffElems.push( childElems[i] ); } }); return ffElems; }; // ----- debounceMethod ----- // utils.debounceMethod = function( _class, methodName, threshold ) { threshold = threshold || 100; // original method var method = _class.prototype[ methodName ]; var timeoutName = methodName + 'Timeout'; _class.prototype[ methodName ] = function() { var timeout = this[ timeoutName ]; clearTimeout( timeout ); var args = arguments; var _this = this; this[ timeoutName ] = setTimeout( function() { method.apply( _this, args ); delete _this[ timeoutName ]; }, threshold ); }; }; // ----- docReady ----- // utils.docReady = function( callback ) { var readyState = document.readyState; if ( readyState == 'complete' || readyState == 'interactive' ) { // do async to allow for other scripts to run. metafizzy/flickity#441 setTimeout( callback ); } else { document.addEventListener( 'DOMContentLoaded', callback ); } }; // ----- htmlInit ----- // // http://jamesroberts.name/blog/2010/02/22/string-functions-for-javascript-trim-to-camel-case-to-dashed-and-to-underscore/ utils.toDashed = function( str ) { return str.replace( /(.)([A-Z])/g, function( match, $1, $2 ) { return $1 + '-' + $2; }).toLowerCase(); }; var console = window.console; /** * allow user to initialize classes via [data-namespace] or .js-namespace class * htmlInit( Widget, 'widgetName' ) * options are parsed from data-namespace-options */ utils.htmlInit = function( WidgetClass, namespace ) { utils.docReady( function() { var dashedNamespace = utils.toDashed( namespace ); var dataAttr = 'data-' + dashedNamespace; var dataAttrElems = document.querySelectorAll( '[' + dataAttr + ']' ); var jsDashElems = document.querySelectorAll( '.js-' + dashedNamespace ); var elems = utils.makeArray( dataAttrElems ) .concat( utils.makeArray( jsDashElems ) ); var dataOptionsAttr = dataAttr + '-options'; var jQuery = window.jQuery; elems.forEach( function( elem ) { var attr = elem.getAttribute( dataAttr ) || elem.getAttribute( dataOptionsAttr ); var options; try { options = attr && JSON.parse( attr ); } catch ( error ) { // log error, do not initialize if ( console ) { console.error( 'Error parsing ' + dataAttr + ' on ' + elem.className + ': ' + error ); } return; } // initialize var instance = new WidgetClass( elem, options ); // make available via $().data('namespace') if ( jQuery ) { jQuery.data( elem, namespace, instance ); } }); }); }; // ----- ----- // return utils; })); // core ( function( window, factory ) { // universal module definition /* globals define, module, require */ if ( typeof define == 'function' && define.amd ) { // AMD define( 'infinite-scroll/js/core',[ 'ev-emitter/ev-emitter', 'fizzy-ui-utils/utils', ], function( EvEmitter, utils) { return factory( window, EvEmitter, utils ); }); } else if ( typeof module == 'object' && module.exports ) { // CommonJS module.exports = factory( window, require('ev-emitter'), require('fizzy-ui-utils') ); } else { // browser global window.InfiniteScroll = factory( window, window.EvEmitter, window.fizzyUIUtils ); } }( window, function factory( window, EvEmitter, utils ) { var jQuery = window.jQuery; // internal store of all InfiniteScroll intances var instances = {}; function InfiniteScroll( element, options ) { var queryElem = utils.getQueryElement( element ); if ( !queryElem ) { console.error( 'Bad element for InfiniteScroll: ' + ( queryElem || element ) ); return; } element = queryElem; // do not initialize twice on same element if ( element.infiniteScrollGUID ) { var instance = instances[ element.infiniteScrollGUID ]; instance.option( options ); return instance; } this.element = element; // options this.options = utils.extend( {}, InfiniteScroll.defaults ); this.option( options ); // add jQuery if ( jQuery ) { this.$element = jQuery( this.element ); } this.create(); } // defaults InfiniteScroll.defaults = { // path: null, // hideNav: null, // debug: false, }; // create & destroy methods InfiniteScroll.create = {}; InfiniteScroll.destroy = {}; var proto = InfiniteScroll.prototype; // inherit EvEmitter utils.extend( proto, EvEmitter.prototype ); // -------------------------- -------------------------- // // globally unique identifiers var GUID = 0; proto.create = function() { // create core // add id for InfiniteScroll.data var id = this.guid = ++GUID; this.element.infiniteScrollGUID = id; // expando instances[ id ] = this; // associate via id // properties this.pageIndex = 1; // default to first page this.loadCount = 0; this.updateGetPath(); // bail if getPath not set, or returns falsey #776 var hasPath = this.getPath && this.getPath(); if ( !hasPath ) { console.error('Disabling InfiniteScroll'); return; } this.updateGetAbsolutePath(); this.log( 'initialized', [ this.element.className ] ); this.callOnInit(); // create features for ( var method in InfiniteScroll.create ) { InfiniteScroll.create[ method ].call( this ); } }; proto.option = function( opts ) { utils.extend( this.options, opts ); }; // call onInit option, used for binding events on init proto.callOnInit = function() { var onInit = this.options.onInit; if ( onInit ) { onInit.call( this, this ); } }; // ----- events ----- // proto.dispatchEvent = function( type, event, args ) { this.log( type, args ); var emitArgs = event ? [ event ].concat( args ) : args; this.emitEvent( type, emitArgs ); // trigger jQuery event if ( !jQuery || !this.$element ) { return; } // namespace jQuery event type += '.infiniteScroll'; var $event = type; if ( event ) { // create jQuery event var jQEvent = jQuery.Event( event ); jQEvent.type = type; $event = jQEvent; } this.$element.trigger( $event, args ); }; var loggers = { initialized: function( className ) { return 'on ' + className; }, request: function( path ) { return 'URL: ' + path; }, load: function( response, path ) { return ( response.title || '' ) + '. URL: ' + path; }, error: function( error, path ) { return error + '. URL: ' + path; }, append: function( response, path, items ) { return items.length + ' items. URL: ' + path; }, last: function( response, path ) { return 'URL: ' + path; }, history: function( title, path ) { return 'URL: ' + path; }, pageIndex: function( index, origin ) { return 'current page determined to be: ' + index + ' from ' + origin; }, }; // log events proto.log = function( type, args ) { if ( !this.options.debug ) { return; } var message = '[InfiniteScroll] ' + type; var logger = loggers[ type ]; if ( logger ) { message += '. ' + logger.apply( this, args ); } console.log( message ); }; // -------------------------- methods used amoung features -------------------------- // proto.updateMeasurements = function() { this.windowHeight = window.innerHeight; var rect = this.element.getBoundingClientRect(); this.top = rect.top + window.pageYOffset; }; proto.updateScroller = function() { var elementScroll = this.options.elementScroll; if ( !elementScroll ) { // default, use window this.scroller = window; return; } // if true, set to element, otherwise use option this.scroller = elementScroll === true ? this.element : utils.getQueryElement( elementScroll ); if ( !this.scroller ) { throw 'Unable to find elementScroll: ' + elementScroll; } }; // -------------------------- page path -------------------------- // proto.updateGetPath = function() { var optPath = this.options.path; if ( !optPath ) { console.error( 'InfiniteScroll path option required. Set as: ' + optPath ); return; } // function var type = typeof optPath; if ( type == 'function' ) { this.getPath = optPath; return; } // template string: '/pages/{{#}}.html' var templateMatch = type == 'string' && optPath.match('{{#}}'); if ( templateMatch ) { this.updateGetPathTemplate( optPath ); return; } // selector: '.next-page-selector' this.updateGetPathSelector( optPath ); }; proto.updateGetPathTemplate = function( optPath ) { // set getPath with template string this.getPath = function() { var nextIndex = this.pageIndex + 1; return optPath.replace( '{{#}}', nextIndex ); }.bind( this ); // get pageIndex from location // convert path option into regex to look for pattern in location var regexString = optPath.replace( '{{#}}', '(\\d\\d?\\d?)' ); var templateRe = new RegExp( regexString ); var match = location.href.match( templateRe ); if ( match ) { this.pageIndex = parseInt( match[1], 10 ); this.log( 'pageIndex', [ this.pageIndex, 'template string' ] ); } }; var pathRegexes = [ // WordPress & Tumblr - example.com/page/2 // Jekyll - example.com/page2 /^(.*?\/?page\/?)(\d\d?\d?)(.*?$)/, // Drupal - example.com/?page=1 /^(.*?\/?\?page=)(\d\d?\d?)(.*?$)/, // catch all, last occurence of a number /(.*?)(\d\d?\d?)(?!.*\d)(.*?$)/, ]; proto.updateGetPathSelector = function( optPath ) { // parse href of link: '.next-page-link' var hrefElem = document.querySelector( optPath ); if ( !hrefElem ) { console.error( 'Bad InfiniteScroll path option. Next link not found: ' + optPath ); return; } var href = hrefElem.getAttribute('href'); // try matching href to pathRegexes patterns var pathParts, regex; for ( var i=0; href && i < pathRegexes.length; i++ ) { regex = pathRegexes[i]; var match = href.match( regex ); if ( match ) { pathParts = match.slice(1); // remove first part break; } } if ( !pathParts ) { console.error( 'InfiniteScroll unable to parse next link href: ' + href ); return; } this.isPathSelector = true; // flag for checkLastPage() this.getPath = function() { var nextIndex = this.pageIndex + 1; return pathParts[0] + nextIndex + pathParts[2]; }.bind( this ); // get pageIndex from href this.pageIndex = parseInt( pathParts[1], 10 ) - 1; this.log( 'pageIndex', [ this.pageIndex, 'next link' ] ); }; proto.updateGetAbsolutePath = function() { var path = this.getPath(); // path doesn't start with http or / var isAbsolute = path.match( /^http/ ) || path.match( /^\// ); if ( isAbsolute ) { this.getAbsolutePath = this.getPath; return; } var pathname = location.pathname; // /foo/bar/index.html => /foo/bar var directory = pathname.substring( 0, pathname.lastIndexOf('/') ); this.getAbsolutePath = function() { return directory + '/' + this.getPath(); }; }; // -------------------------- nav -------------------------- // // hide navigation InfiniteScroll.create.hideNav = function() { var nav = utils.getQueryElement( this.options.hideNav ); if ( !nav ) { return; } nav.style.display = 'none'; this.nav = nav; }; InfiniteScroll.destroy.hideNav = function() { if ( this.nav ) { this.nav.style.display = ''; } }; // -------------------------- destroy -------------------------- // proto.destroy = function() { this.allOff(); // remove all event listeners // call destroy methods for ( var method in InfiniteScroll.destroy ) { InfiniteScroll.destroy[ method ].call( this ); } delete this.element.infiniteScrollGUID; delete instances[ this.guid ]; // remove jQuery data. #807 if ( jQuery && this.$element ) { jQuery.removeData( this.element, 'infiniteScroll' ); } }; // -------------------------- utilities -------------------------- // // https://remysharp.com/2010/07/21/throttling-function-calls InfiniteScroll.throttle = function( fn, threshold ) { threshold = threshold || 200; var last, timeout; return function() { var now = +new Date(); var args = arguments; var trigger = function() { last = now; fn.apply( this, args ); }.bind( this ); if ( last && now < last + threshold ) { // hold on to it clearTimeout( timeout ); timeout = setTimeout( trigger, threshold ); } else { trigger(); } }; }; InfiniteScroll.data = function( elem ) { elem = utils.getQueryElement( elem ); var id = elem && elem.infiniteScrollGUID; return id && instances[ id ]; }; // set internal jQuery, for Webpack + jQuery v3 InfiniteScroll.setJQuery = function( $ ) { jQuery = $; }; // -------------------------- setup -------------------------- // utils.htmlInit( InfiniteScroll, 'infinite-scroll' ); // add noop _init method for jQuery Bridget. #768 proto._init = function() {}; if ( jQuery && jQuery.bridget ) { jQuery.bridget( 'infiniteScroll', InfiniteScroll ); } // -------------------------- -------------------------- // return InfiniteScroll; })); // page-load ( function( window, factory ) { // universal module definition /* globals define, module, require */ if ( typeof define == 'function' && define.amd ) { // AMD define( 'infinite-scroll/js/page-load',[ './core', ], function( InfiniteScroll ) { return factory( window, InfiniteScroll ); }); } else if ( typeof module == 'object' && module.exports ) { // CommonJS module.exports = factory( window, require('./core') ); } else { // browser global factory( window, window.InfiniteScroll ); } }( window, function factory( window, InfiniteScroll ) { var proto = InfiniteScroll.prototype; // InfiniteScroll.defaults.append = false; InfiniteScroll.defaults.loadOnScroll = true; InfiniteScroll.defaults.checkLastPage = true; InfiniteScroll.defaults.responseType = 'document'; // InfiniteScroll.defaults.prefill = false; // InfiniteScroll.defaults.outlayer = null; InfiniteScroll.create.pageLoad = function() { this.canLoad = true; this.on( 'scrollThreshold', this.onScrollThresholdLoad ); this.on( 'load', this.checkLastPage ); if ( this.options.outlayer ) { this.on( 'append', this.onAppendOutlayer ); } }; proto.onScrollThresholdLoad = function() { if ( this.options.loadOnScroll ) { this.loadNextPage(); } }; proto.loadNextPage = function() { if ( this.isLoading || !this.canLoad ) { return; } var path = this.getAbsolutePath(); this.isLoading = true; var onLoad = function( response ) { this.onPageLoad( response, path ); }.bind( this ); var onError = function( error ) { this.onPageError( error, path ); }.bind( this ); request( path, this.options.responseType, onLoad, onError ); this.dispatchEvent( 'request', null, [ path ] ); }; proto.onPageLoad = function( response, path ) { // done loading if not appending if ( !this.options.append ) { this.isLoading = false; } this.pageIndex++; this.loadCount++; this.dispatchEvent( 'load', null, [ response, path ] ); this.appendNextPage( response, path ); return response; }; proto.appendNextPage = function( response, path ) { var optAppend = this.options.append; // do not append json var isDocument = this.options.responseType == 'document'; if ( !isDocument || !optAppend ) { return; } var items = response.querySelectorAll( optAppend ); var fragment = getItemsFragment( items ); var appendReady = function () { this.appendItems( items, fragment ); this.isLoading = false; this.dispatchEvent( 'append', null, [ response, path, items ] ); }.bind( this ); // TODO add hook for option to trigger appendReady if ( this.options.outlayer ) { this.appendOutlayerItems( fragment, appendReady ); } else { appendReady(); } }; proto.appendItems = function( items, fragment ) { if ( !items || !items.length ) { return; } // get fragment if not provided fragment = fragment || getItemsFragment( items ); refreshScripts( fragment ); this.element.appendChild( fragment ); }; function getItemsFragment( items ) { // add items to fragment var fragment = document.createDocumentFragment(); for ( var i=0; items && i < items.length; i++ ) { fragment.appendChild( items[i] ); } return fragment; } // replace <script>s with copies so they load // <script>s added by InfiniteScroll will not load // similar to https://stackoverflow.com/questions/610995 function refreshScripts( fragment ) { var scripts = fragment.querySelectorAll('script'); for ( var i=0; i < scripts.length; i++ ) { var script = scripts[i]; var freshScript = document.createElement('script'); copyAttributes( script, freshScript ); // copy inner script code. #718, #782 freshScript.innerHTML = script.innerHTML; script.parentNode.replaceChild( freshScript, script ); } } function copyAttributes( fromNode, toNode ) { var attrs = fromNode.attributes; for ( var i=0; i < attrs.length; i++ ) { var attr = attrs[i]; toNode.setAttribute( attr.name, attr.value ); } } // ----- outlayer ----- // proto.appendOutlayerItems = function( fragment, appendReady ) { var imagesLoaded = InfiniteScroll.imagesLoaded || window.imagesLoaded; if ( !imagesLoaded ) { console.error('[InfiniteScroll] imagesLoaded required for outlayer option'); this.isLoading = false; return; } // append once images loaded imagesLoaded( fragment, appendReady ); }; proto.onAppendOutlayer = function( response, path, items ) { this.options.outlayer.appended( items ); }; // ----- checkLastPage ----- // // check response for next element proto.checkLastPage = function( response, path ) { var checkLastPage = this.options.checkLastPage; if ( !checkLastPage ) { return; } var pathOpt = this.options.path; // if path is function, check if next path is truthy if ( typeof pathOpt == 'function' ) { var nextPath = this.getPath(); if ( !nextPath ) { this.lastPageReached( response, path ); return; } } // get selector from checkLastPage or path option var selector; if ( typeof checkLastPage == 'string' ) { selector = checkLastPage; } else if ( this.isPathSelector ) { // path option is selector string selector = pathOpt; } // check last page for selector // bail if no selector or not document response if ( !selector || !response.querySelector ) { return; } // check if response has selector var nextElem = response.querySelector( selector ); if ( !nextElem ) { this.lastPageReached( response, path ); } }; proto.lastPageReached = function( response, path ) { this.canLoad = false; this.dispatchEvent( 'last', null, [ response, path ] ); }; // ----- error ----- // proto.onPageError = function( error, path ) { this.isLoading = false; this.canLoad = false; this.dispatchEvent( 'error', null, [ error, path ] ); return error; }; // -------------------------- prefill -------------------------- // InfiniteScroll.create.prefill = function() { if ( !this.options.prefill ) { return; } var append = this.options.append; if ( !append ) { console.error( 'append option required for prefill. Set as :' + append ); return; } this.updateMeasurements(); this.updateScroller(); this.isPrefilling = true; this.on( 'append', this.prefill ); this.once( 'error', this.stopPrefill ); this.once( 'last', this.stopPrefill ); this.prefill(); }; proto.prefill = function() { var distance = this.getPrefillDistance(); this.isPrefilling = distance >= 0; if ( this.isPrefilling ) { this.log('prefill'); this.loadNextPage(); } else { this.stopPrefill(); } }; proto.getPrefillDistance = function() { // element scroll if ( this.options.elementScroll ) { return this.scroller.clientHeight - this.scroller.scrollHeight; } // window return this.windowHeight - this.element.clientHeight; }; proto.stopPrefill = function() { this.log('stopPrefill'); this.off( 'append', this.prefill ); }; // -------------------------- request -------------------------- // function request( url, responseType, onLoad, onError ) { var req = new XMLHttpRequest(); req.open( 'GET', url, true ); // set responseType document to return DOM req.responseType = responseType || ''; // set X-Requested-With header to check that is ajax request req.setRequestHeader('X-Requested-With', 'XMLHttpRequest'); req.onload = function() { if ( req.status == 200 ) { onLoad( req.response ); } else { // not 200 OK, error var error = new Error( req.statusText ); onError( error ); } }; // Handle network errors req.onerror = function() { var error = new Error( 'Network error requesting ' + url ); onError( error ); }; req.send(); } // -------------------------- -------------------------- // return InfiniteScroll; })); // scroll-watch ( function( window, factory ) { // universal module definition /* globals define, module, require */ if ( typeof define == 'function' && define.amd ) { // AMD define( 'infinite-scroll/js/scroll-watch',[ './core', 'fizzy-ui-utils/utils', ], function( InfiniteScroll, utils ) { return factory( window, InfiniteScroll, utils ); }); } else if ( typeof module == 'object' && module.exports ) { // CommonJS module.exports = factory( window, require('./core'), require('fizzy-ui-utils') ); } else { // browser global factory( window, window.InfiniteScroll, window.fizzyUIUtils ); } }( window, function factory( window, InfiniteScroll, utils ) { var proto = InfiniteScroll.prototype; // default options InfiniteScroll.defaults.scrollThreshold = 400; // InfiniteScroll.defaults.elementScroll = null; InfiniteScroll.create.scrollWatch = function() { // events this.pageScrollHandler = this.onPageScroll.bind( this ); this.resizeHandler = this.onResize.bind( this ); var scrollThreshold = this.options.scrollThreshold; var isEnable = scrollThreshold || scrollThreshold === 0; if ( isEnable ) { this.enableScrollWatch(); } }; InfiniteScroll.destroy.scrollWatch = function() { this.disableScrollWatch(); }; proto.enableScrollWatch = function() { if ( this.isScrollWatching ) { return; } this.isScrollWatching = true; this.updateMeasurements(); this.updateScroller(); // TODO disable after error? this.on( 'last', this.disableScrollWatch ); this.bindScrollWatchEvents( true ); }; proto.disableScrollWatch = function() { if ( !this.isScrollWatching ) { return; } this.bindScrollWatchEvents( false ); delete this.isScrollWatching; }; proto.bindScrollWatchEvents = function( isBind ) { var addRemove = isBind ? 'addEventListener' : 'removeEventListener'; this.scroller[ addRemove ]( 'scroll', this.pageScrollHandler ); window[ addRemove ]( 'resize', this.resizeHandler ); }; proto.onPageScroll = InfiniteScroll.throttle( function() { var distance = this.getBottomDistance(); if ( distance <= this.options.scrollThreshold ) { this.dispatchEvent('scrollThreshold'); } }); proto.getBottomDistance = function() { if ( this.options.elementScroll ) { return this.getElementBottomDistance(); } else { return this.getWindowBottomDistance(); } }; proto.getWindowBottomDistance = function() { var bottom = this.top + this.element.clientHeight; var scrollY = window.pageYOffset + this.windowHeight; return bottom - scrollY; }; proto.getElementBottomDistance = function() { var bottom = this.scroller.scrollHeight; var scrollY = this.scroller.scrollTop + this.scroller.clientHeight; return bottom - scrollY; }; proto.onResize = function() { this.updateMeasurements(); }; utils.debounceMethod( InfiniteScroll, 'onResize', 150 ); // -------------------------- -------------------------- // return InfiniteScroll; })); // history ( function( window, factory ) { // universal module definition /* globals define, module, require */ if ( typeof define == 'function' && define.amd ) { // AMD define( 'infinite-scroll/js/history',[ './core', 'fizzy-ui-utils/utils', ], function( InfiniteScroll, utils ) { return factory( window, InfiniteScroll, utils ); }); } else if ( typeof module == 'object' && module.exports ) { // CommonJS module.exports = factory( window, require('./core'), require('fizzy-ui-utils') ); } else { // browser global factory( window, window.InfiniteScroll, window.fizzyUIUtils ); } }( window, function factory( window, InfiniteScroll, utils ) { var proto = InfiniteScroll.prototype; InfiniteScroll.defaults.history = 'replace'; // InfiniteScroll.defaults.historyTitle = false; var link = document.createElement('a'); // ----- create/destroy ----- // InfiniteScroll.create.history = function() { if ( !this.options.history ) { return; } // check for same origin link.href = this.getAbsolutePath(); // MS Edge does not have origin on link https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/12236493/ var linkOrigin = link.origin || link.protocol + '//' + link.host; var isSameOrigin = linkOrigin == location.origin; if ( !isSameOrigin ) { console.error( '[InfiniteScroll] cannot set history with different origin: ' + link.origin + ' on ' + location.origin + ' . History behavior disabled.' ); return; } // two ways to handle changing history if ( this.options.append ) { this.createHistoryAppend(); } else { this.createHistoryPageLoad(); } }; proto.createHistoryAppend = function() { this.updateMeasurements(); this.updateScroller(); // array of scroll positions of appended pages this.scrollPages = [ { // first page top: 0, path: location.href, title: document.title, } ]; this.scrollPageIndex = 0; // events this.scrollHistoryHandler = this.onScrollHistory.bind( this ); this.unloadHandler = this.onUnload.bind( this ); this.scroller.addEventListener( 'scroll', this.scrollHistoryHandler ); this.on( 'append', this.onAppendHistory ); this.bindHistoryAppendEvents( true ); }; proto.bindHistoryAppendEvents = function( isBind ) { var addRemove = isBind ? 'addEventListener' : 'removeEventListener'; this.scroller[ addRemove ]( 'scroll', this.scrollHistoryHandler ); window[ addRemove ]( 'unload', this.unloadHandler ); }; proto.createHistoryPageLoad = function() { this.on( 'load', this.onPageLoadHistory ); }; InfiniteScroll.destroy.history = proto.destroyHistory = function() { var isHistoryAppend = this.options.history && this.options.append; if ( isHistoryAppend ) { this.bindHistoryAppendEvents( false ); } }; // ----- append history ----- // proto.onAppendHistory = function( response, path, items ) { // do not proceed if no items. #779 if ( !items || !items.length ) { return; } var firstItem = items[0]; var elemScrollY = this.getElementScrollY( firstItem ); // resolve path link.href = path; // add page data to hash this.scrollPages.push({ top: elemScrollY, path: link.href, title: response.title, }); }; proto.getElementScrollY = function( elem ) { if ( this.options.elementScroll ) { return this.getElementElementScrollY( elem ); } else { return this.getElementWindowScrollY( elem ); } }; proto.getElementWindowScrollY = function( elem ) { var rect = elem.getBoundingClientRect(); return rect.top + window.pageYOffset; }; // wow, stupid name proto.getElementElementScrollY = function( elem ) { return elem.offsetTop - this.top; }; proto.onScrollHistory = function() { // cycle through positions, find biggest without going over var scrollViewY = this.getScrollViewY(); var pageIndex, page; for ( var i=0; i < this.scrollPages.length; i++ ) { var scrollPage = this.scrollPages[i]; if ( scrollPage.top >= scrollViewY ) { break; } pageIndex = i; page = scrollPage; } // set history if changed if ( pageIndex != this.scrollPageIndex ) { this.scrollPageIndex = pageIndex; this.setHistory( page.title, page.path ); } }; utils.debounceMethod( InfiniteScroll, 'onScrollHistory', 150 ); proto.getScrollViewY = function() { if ( this.options.elementScroll ) { return this.scroller.scrollTop + this.scroller.clientHeight/2; } else { return window.pageYOffset + this.windowHeight/2; } }; proto.setHistory = function( title, path ) { var optHistory = this.options.history; var historyMethod = optHistory && history[ optHistory + 'State' ]; if ( !historyMethod ) { return; } history[ optHistory + 'State' ]( null, title, path ); if ( this.options.historyTitle ) { document.title = title; } this.dispatchEvent( 'history', null, [ title, path ] ); }; // scroll to top to prevent initial scroll-reset after page refresh // https://stackoverflow.com/a/18633915/182183 proto.onUnload = function() { var pageIndex = this.scrollPageIndex; if ( pageIndex === 0 ) { return; } // calculate where scroll position would be on refresh var scrollPage = this.scrollPages[ pageIndex ]; var scrollY = window.pageYOffset - scrollPage.top + this.top; // disable scroll event before setting scroll #679 this.destroyHistory(); scrollTo( 0, scrollY ); }; // ----- load history ----- // // update URL proto.onPageLoadHistory = function( response, path ) { this.setHistory( response.title, path ); }; // -------------------------- -------------------------- // return InfiniteScroll; })); // button ( function( window, factory ) { // universal module definition /* globals define, module, require */ if ( typeof define == 'function' && define.amd ) { // AMD define( 'infinite-scroll/js/button',[ './core', 'fizzy-ui-utils/utils', ], function( InfiniteScroll, utils ) { return factory( window, InfiniteScroll, utils ); }); } else if ( typeof module == 'object' && module.exports ) { // CommonJS module.exports = factory( window, require('./core'), require('fizzy-ui-utils') ); } else { // browser global factory( window, window.InfiniteScroll, window.fizzyUIUtils ); } }( window, function factory( window, InfiniteScroll, utils ) { // InfiniteScroll.defaults.button = null; InfiniteScroll.create.button = function() { var buttonElem = utils.getQueryElement( this.options.button ); if ( buttonElem ) { this.button = new InfiniteScrollButton( buttonElem, this ); return; } }; InfiniteScroll.destroy.button = function() { if ( this.button ) { this.button.destroy(); } }; // -------------------------- InfiniteScrollButton -------------------------- // function InfiniteScrollButton( element, infScroll ) { this.element = element; this.infScroll = infScroll; // events this.clickHandler = this.onClick.bind( this ); this.element.addEventListener( 'click', this.clickHandler ); infScroll.on( 'request', this.disable.bind( this ) ); infScroll.on( 'load', this.enable.bind( this ) ); infScroll.on( 'error', this.hide.bind( this ) ); infScroll.on( 'last', this.hide.bind( this ) ); } InfiniteScrollButton.prototype.onClick = function( event ) { event.preventDefault(); this.infScroll.loadNextPage(); }; InfiniteScrollButton.prototype.enable = function() { this.element.removeAttribute('disabled'); }; InfiniteScrollButton.prototype.disable = function() { this.element.disabled = 'disabled'; }; InfiniteScrollButton.prototype.hide = function() { this.element.style.display = 'none'; }; InfiniteScrollButton.prototype.destroy = function() { this.element.removeEventListener( 'click', this.clickHandler ); }; // -------------------------- -------------------------- // InfiniteScroll.Button = InfiniteScrollButton; return InfiniteScroll; })); // status ( function( window, factory ) { // universal module definition /* globals define, module, require */ if ( typeof define == 'function' && define.amd ) { // AMD define( 'infinite-scroll/js/status',[ './core', 'fizzy-ui-utils/utils', ], function( InfiniteScroll, utils ) { return factory( window, InfiniteScroll, utils ); }); } else if ( typeof module == 'object' && module.exports ) { // CommonJS module.exports = factory( window, require('./core'), require('fizzy-ui-utils') ); } else { // browser global factory( window, window.InfiniteScroll, window.fizzyUIUtils ); } }( window, function factory( window, InfiniteScroll, utils ) { var proto = InfiniteScroll.prototype; // InfiniteScroll.defaults.status = null; InfiniteScroll.create.status = function() { var statusElem = utils.getQueryElement( this.options.status ); if ( !statusElem ) { return; } // elements this.statusElement = statusElem; this.statusEventElements = { request: statusElem.querySelector('.infinite-scroll-request'), error: statusElem.querySelector('.infinite-scroll-error'), last: statusElem.querySelector('.infinite-scroll-last'), }; // events this.on( 'request', this.showRequestStatus ); this.on( 'error', this.showErrorStatus ); this.on( 'last', this.showLastStatus ); this.bindHideStatus('on'); }; proto.bindHideStatus = function( bindMethod ) { var hideEvent = this.options.append ? 'append' : 'load'; this[ bindMethod ]( hideEvent, this.hideAllStatus ); }; proto.showRequestStatus = function() { this.showStatus('request'); }; proto.showErrorStatus = function() { this.showStatus('error'); }; proto.showLastStatus = function() { this.showStatus('last'); // prevent last then append event race condition from showing last status #706 this.bindHideStatus('off'); }; proto.showStatus = function( eventName ) { show( this.statusElement ); this.hideStatusEventElements(); var eventElem = this.statusEventElements[ eventName ]; show( eventElem ); }; proto.hideAllStatus = function() { hide( this.statusElement ); this.hideStatusEventElements(); }; proto.hideStatusEventElements = function() { for ( var type in this.statusEventElements ) { var eventElem = this.statusEventElements[ type ]; hide( eventElem ); } }; // -------------------------- -------------------------- // function hide( elem ) { setDisplay( elem, 'none' ); } function show( elem ) { setDisplay( elem, 'block' ); } function setDisplay( elem, value ) { if ( elem ) { elem.style.display = value; } } // -------------------------- -------------------------- // return InfiniteScroll; })); /*! * Infinite Scroll v3.0.5 * Automatically add next page * * Licensed GPLv3 for open source use * or Infinite Scroll Commercial License for commercial use * * https://infinite-scroll.com * Copyright 2018 Metafizzy */ ( function( window, factory ) { // universal module definition /* globals define, module, require */ if ( typeof define == 'function' && define.amd ) { // AMD define( [ 'infinite-scroll/js/core', 'infinite-scroll/js/page-load', 'infinite-scroll/js/scroll-watch', 'infinite-scroll/js/history', 'infinite-scroll/js/button', 'infinite-scroll/js/status', ], factory ); } else if ( typeof module == 'object' && module.exports ) { // CommonJS module.exports = factory( require('./core'), require('./page-load'), require('./scroll-watch'), require('./history'), require('./button'), require('./status') ); } })( window, function factory( InfiniteScroll ) { return InfiniteScroll; }); /*! * 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( 'imagesloaded/imagesloaded',[ '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; });