Full Code of desandro/imagesloaded for AI

master 92de29b5a9a4 cached
32 files
60.0 KB
18.5k tokens
17 symbols
1 requests
Download .txt
Repository: desandro/imagesloaded
Branch: master
Commit: 92de29b5a9a4
Files: 32
Total size: 60.0 KB

Directory structure:
gitextract_8bkypk_n/

├── .eslintrc.js
├── .gitignore
├── .nvmrc
├── LICENSE.md
├── README.md
├── bower.json
├── contributing.md
├── imagesloaded.js
├── imagesloaded.pkgd.js
├── package.json
├── sandbox/
│   ├── background/
│   │   ├── css/
│   │   │   └── background.css
│   │   └── index.html
│   ├── picture.html
│   └── progress/
│       ├── index.html
│       └── progress.js
├── tasks/
│   ├── dist.js
│   └── version.js
└── test/
    ├── css/
    │   └── tests.css
    ├── index.html
    └── unit/
        ├── append.js
        ├── background.js
        ├── basics.js
        ├── data-uri.js
        ├── jquery-fail.js
        ├── jquery-success.js
        ├── local-files.js
        ├── no-images.js
        ├── non-element.js
        ├── picture.js
        ├── selector-string.js
        ├── single-element.js
        └── srcset.js

================================================
FILE CONTENTS
================================================

================================================
FILE: .eslintrc.js
================================================
/* eslint-env node */

module.exports = {
  plugins: [ 'metafizzy' ],
  extends: 'plugin:metafizzy/browser',
  env: {
    browser: true,
    commonjs: true,
  },
  parserOptions: {
    ecmaVersion: 2018,
  },
  globals: {
    imagesLoaded: 'readonly',
    QUnit: 'readonly',
  },
  rules: {
    eqeqeq: [ 'error', 'smart' ],
    'id-length': [ 'error', {
      min: 2,
      max: 30,
      exceptions: [ 'x', 'y', 'z', 'i', 'j', 'a', 'b', 't', '$' ],
    } ],
    'new-cap': 'off',
  },
  ignorePatterns: [ '*pkgd*.js' ],
};


================================================
FILE: .gitignore
================================================
bower_components/
node_modules/
build/index.html
build/*.woff*
build/imagesloaded*.js
.netlify


================================================
FILE: .nvmrc
================================================
16

================================================
FILE: LICENSE.md
================================================
Copyright (c) 2011-2022 [David DeSandro](https://desandro.com) and [contributors](https://github.com/desandro/imagesloaded/graphs/contributors)

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.


================================================
FILE: README.md
================================================
# imagesLoaded

<p class="tagline">JavaScript is all like "You images done yet or what?"</p>

[imagesloaded.desandro.com](https://imagesloaded.desandro.com)

Detect when images have been loaded.

## Install

### Download

+ [imagesloaded.pkgd.min.js](https://unpkg.com/imagesloaded@5/imagesloaded.pkgd.min.js) minified
+ [imagesloaded.pkgd.js](https://unpkg.com/imagesloaded@5/imagesloaded.pkgd.js) un-minified

### CDN

``` html
<script src="https://unpkg.com/imagesloaded@5/imagesloaded.pkgd.min.js"></script>
<!-- or -->
<script src="https://unpkg.com/imagesloaded@5/imagesloaded.pkgd.js"></script>
```

### Package managers

Install via npm: `npm install imagesloaded`

Install via Yarn: `yarn add imagesloaded`

## jQuery

You can use imagesLoaded as a jQuery Plugin.

``` js
$('#container').imagesLoaded( function() {
  // images have loaded
});

// options
$('#container').imagesLoaded( {
  // options...
  },
  function() {
    // images have loaded
  }
);
```

`.imagesLoaded()` returns a [jQuery Deferred object](https://api.jquery.com/category/deferred-object/). This allows you to use `.always()`, `.done()`, `.fail()` and `.progress()`.

``` js
$('#container').imagesLoaded()
  .always( function( instance ) {
    console.log('all images loaded');
  })
  .done( function( instance ) {
    console.log('all images successfully loaded');
  })
  .fail( function() {
    console.log('all images loaded, at least one is broken');
  })
  .progress( function( instance, image ) {
    var result = image.isLoaded ? 'loaded' : 'broken';
    console.log( 'image is ' + result + ' for ' + image.img.src );
  });
```

## Vanilla JavaScript

You can use imagesLoaded with vanilla JS.

``` js
imagesLoaded( elem, callback )
// options
imagesLoaded( elem, options, callback )
// you can use `new` if you like
new imagesLoaded( elem, callback )
```

+ `elem` _Element, NodeList, Array, or Selector String_
+ `options` _Object_
+ `callback` _Function_ - function triggered after all images have been loaded

Using a callback function is the same as binding it to the `always` event (see below).

``` js
// element
imagesLoaded( document.querySelector('#container'), function( instance ) {
  console.log('all images are loaded');
});
// selector string
imagesLoaded( '#container', function() {...});
// multiple elements
var posts = document.querySelectorAll('.post');
imagesLoaded( posts, function() {...});
```

Bind events with vanilla JS with .on(), .off(), and .once() methods.

``` js
var imgLoad = imagesLoaded( elem );
function onAlways( instance ) {
  console.log('all images are loaded');
}
// bind with .on()
imgLoad.on( 'always', onAlways );
// unbind with .off()
imgLoad.off( 'always', onAlways );
```

## Background

Detect when background images have loaded, in addition to `<img>`s.

Set `{ background: true }` to detect when the element's background image has loaded.

``` js
// jQuery
$('#container').imagesLoaded( { background: true }, function() {
  console.log('#container background image loaded');
});

// vanilla JS
imagesLoaded( '#container', { background: true }, function() {
  console.log('#container background image loaded');
});
```

[See jQuery demo](https://codepen.io/desandro/pen/pjVMPB) or [vanilla JS demo](https://codepen.io/desandro/pen/avKooW) on CodePen.

Set to a selector string like `{ background: '.item' }` to detect when the background images of child elements have loaded.

``` js
// jQuery
$('#container').imagesLoaded( { background: '.item' }, function() {
  console.log('all .item background images loaded');
});

// vanilla JS
imagesLoaded( '#container', { background: '.item' }, function() {
  console.log('all .item background images loaded');
});
```

[See jQuery demo](https://codepen.io/desandro/pen/avKoZL) or [vanilla JS demo](https://codepen.io/desandro/pen/vNrBGz) on CodePen.

## Events

### always

``` js
// jQuery
$('#container').imagesLoaded().always( function( instance ) {
  console.log('ALWAYS - all images have been loaded');
});

// vanilla JS
imgLoad.on( 'always', function( instance ) {
  console.log('ALWAYS - all images have been loaded');
});
```

Triggered after all images have been either loaded or confirmed broken.

+ `instance` _imagesLoaded_ - the imagesLoaded instance

### done

``` js
// jQuery
$('#container').imagesLoaded().done( function( instance ) {
  console.log('DONE  - all images have been successfully loaded');
});

// vanilla JS
imgLoad.on( 'done', function( instance ) {
  console.log('DONE  - all images have been successfully loaded');
});
```

Triggered after all images have successfully loaded without any broken images.

### fail

``` js
$('#container').imagesLoaded().fail( function( instance ) {
  console.log('FAIL - all images loaded, at least one is broken');
});

// vanilla JS
imgLoad.on( 'fail', function( instance ) {
  console.log('FAIL - all images loaded, at least one is broken');
});
```

Triggered after all images have been loaded with at least one broken image.

### progress

``` js
imgLoad.on( 'progress', function( instance, image ) {
  var result = image.isLoaded ? 'loaded' : 'broken';
  console.log( 'image is ' + result + ' for ' + image.img.src );
});
```

Triggered after each image has been loaded.

+ `instance` _imagesLoaded_ - the imagesLoaded instance
+ `image` _LoadingImage_ - the LoadingImage instance of the loaded image

<!-- sponsored -->

## Properties

### LoadingImage.img

_Image_ - The `img` element

### LoadingImage.isLoaded

_Boolean_ - `true` when the image has successfully loaded

### imagesLoaded.images

Array of _LoadingImage_ instances for each image detected

``` js
var imgLoad = imagesLoaded('#container');
imgLoad.on( 'always', function() {
  console.log( imgLoad.images.length + ' images loaded' );
  // detect which image is broken
  for ( var i = 0, len = imgLoad.images.length; i < len; i++ ) {
    var image = imgLoad.images[i];
    var result = image.isLoaded ? 'loaded' : 'broken';
    console.log( 'image is ' + result + ' for ' + image.img.src );
  }
});
```

## Webpack

Install imagesLoaded with npm.

``` bash
npm install imagesloaded
```

You can then `require('imagesloaded')`.

``` js
// main.js
var imagesLoaded = require('imagesloaded');

imagesLoaded( '#container', function() {
  // images have loaded
});
```

Use `.makeJQueryPlugin` to make `.imagesLoaded()` jQuery plugin.

``` js
// main.js
var imagesLoaded = require('imagesloaded');
var $ = require('jquery');

// provide jQuery argument
imagesLoaded.makeJQueryPlugin( $ );
// now use .imagesLoaded() jQuery plugin
$('#container').imagesLoaded( function() {...});
```

Run webpack.

``` bash
webpack main.js bundle.js
```

## Browserify

imagesLoaded works with [Browserify](https://browserify.org/).

``` bash
npm install imagesloaded --save
```

``` js
var imagesLoaded = require('imagesloaded');

imagesLoaded( elem, function() {...} );
```

Use `.makeJQueryPlugin` to make to use `.imagesLoaded()` jQuery plugin.

``` js
var $ = require('jquery');
var imagesLoaded = require('imagesloaded');

// provide jQuery argument
imagesLoaded.makeJQueryPlugin( $ );
// now use .imagesLoaded() jQuery plugin
$('#container').imagesLoaded( function() {...});
```


## Browser support

+ Chrome 49+
+ Firefox 41+
+ Edge 14+
+ iOS Safari 8+

Use [imagesLoaded v4](https://github.com/desandro/imagesloaded/tree/v4.1.4) for Internet Explorer and other older browser support.

## Development

Development uses Node.js v16 with npm v8

``` bash
nvm use
```

## MIT License

imagesLoaded is released under the [MIT License](https://desandro.mit-license.org/). Have at it.


================================================
FILE: bower.json
================================================
{
  "name": "imagesloaded",
  "description": "JavaScript is all like _You images done yet or what?_",
  "main": "imagesloaded.js",
  "dependencies": {
    "ev-emitter": "^2.1.2"
  },
  "devDependencies": {
  },
  "ignore": [
    "**/.*",
    "test",
    "package.json",
    "composer.json",
    "node_modules",
    "bower_components",
    "tests",
    "sandbox/",
    "gulpfile.js",
    "contributing.md"
  ],
  "homepage": "https://imagesloaded.desandro.com",
  "authors": [
    "David DeSandro"
  ],
  "moduleType": [
    "amd",
    "globals",
    "node"
  ],
  "keywords": [
    "images"
  ],
  "license": "MIT"
}


================================================
FILE: contributing.md
================================================
## Submitting issues

### Reduced test case required

All bug reports and problem issues require a [**reduced test case**](https://css-tricks.com/reduced-test-cases/).

+ A reduced test case clearly demonstrates the bug or issue.
+ It contains the bare minimum HTML, CSS, and JavaScript required to demonstrate the bug.
+ A link to your production site is **not** a reduced test case.

Create a test case by forking a [CodePen demos](https://codepen.io/collection/xKRgYx).

+ [progress with jQuery](https://codepen.io/desandro/pen/podVjYW)
+ [progress with vanilla JS](https://codepen.io/desandro/pen/XWzqXrP)
+ [`{ background: true }` with jQuery](https://codepen.io/desandro/pen/QWOrNNY)
+ [`{ background: true }` with vanilla JS](https://codepen.io/desandro/pen/oNodxYW)
+ [`{ background: '.selector' }` with jQuery](https://codepen.io/desandro/pen/YzELWdo)
+ [`{ background: '.selector' }` with vanilla JS](https://codepen.io/desandro/pen/KKyRMEv)

Providing a reduced test case is the best way to get your issue addressed. They help you point out the problem. They help me verify and debug the problem. They help others understand the problem. Without a reduced test case, your issue may be closed.


================================================
FILE: imagesloaded.js
================================================
/*!
 * imagesLoaded v5.0.0
 * JavaScript is all like "You images are done yet or what?"
 * MIT License
 */

( function( window, factory ) {
  // universal module definition
  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,
    function factory( window, EvEmitter ) {

let $ = window.jQuery;
let console = window.console;

// -------------------------- helpers -------------------------- //

// turn element or nodeList into an array
function makeArray( obj ) {
  // use object if already an array
  if ( Array.isArray( obj ) ) return obj;

  let isArrayLike = typeof obj == 'object' && typeof obj.length == 'number';
  // convert nodeList to array
  if ( isArrayLike ) return [ ...obj ];

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

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

/**
 * @param {[Array, Element, NodeList, String]} elem
 * @param {[Object, Function]} options - if function, use as callback
 * @param {Function} onAlways - callback function
 * @returns {ImagesLoaded}
 */
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
  let 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 = {};
  // shift arguments if no options set
  if ( typeof options == 'function' ) {
    onAlways = options;
  } else {
    Object.assign( this.options, options );
  }

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

  this.getImages();
  // add jQuery Deferred object
  if ( $ ) 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.getImages = function() {
  this.images = [];

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

const elementNodeTypes = [ 1, 9, 11 ];

/**
 * @param {Node} elem
 */
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
  let { nodeType } = elem;
  if ( !nodeType || !elementNodeTypes.includes( nodeType ) ) return;

  let childImgs = elem.querySelectorAll('img');
  // concat childElems to filterFound array
  for ( let img of childImgs ) {
    this.addImage( img );
  }

  // get child background images
  if ( typeof this.options.background == 'string' ) {
    let children = elem.querySelectorAll( this.options.background );
    for ( let child of children ) {
      this.addElementBackgroundImages( child );
    }
  }
};

const reURL = /url\((['"])?(.*?)\1\)/gi;

ImagesLoaded.prototype.addElementBackgroundImages = function( elem ) {
  let style = getComputedStyle( elem );
  // Firefox returns null if in a hidden iframe https://bugzil.la/548397
  if ( !style ) return;

  // get url inside url("...")
  let matches = reURL.exec( style.backgroundImage );
  while ( matches !== null ) {
    let url = matches && matches[2];
    if ( url ) {
      this.addBackground( url, elem );
    }
    matches = reURL.exec( style.backgroundImage );
  }
};

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

ImagesLoaded.prototype.addBackground = function( url, elem ) {
  let background = new Background( url, elem );
  this.images.push( background );
};

ImagesLoaded.prototype.check = function() {
  this.progressedCount = 0;
  this.hasAnyBroken = false;
  // complete if no images
  if ( !this.images.length ) {
    this.complete();
    return;
  }

  /* eslint-disable-next-line func-style */
  let onProgress = ( image, elem, message ) => {
    // HACK - Chrome triggers event before object properties have changed. #83
    setTimeout( () => {
      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() {
  let eventName = this.hasAnyBroken ? 'fail' : 'done';
  this.isComplete = true;
  this.emitEvent( eventName, [ this ] );
  this.emitEvent( 'always', [ this ] );
  if ( this.jqDeferred ) {
    let 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.
  let 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();
  // add crossOrigin attribute. #204
  if ( this.img.crossOrigin ) {
    this.proxyImage.crossOrigin = this.img.crossOrigin;
  }
  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.currentSrc || 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;
  let { parentNode } = this.img;
  // emit progress with parent <picture> or self <img>
  let elem = parentNode.nodeName === 'PICTURE' ? parentNode : this.img;
  this.emitEvent( 'progress', [ this, elem, message ] );
};

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

// trigger specified handler for event type
LoadingImage.prototype.handleEvent = function( event ) {
  let 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
  let 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, onAlways ) {
    let instance = new ImagesLoaded( this, options, onAlways );
    return instance.jqDeferred.promise( $( this ) );
  };
};
// try making plugin
ImagesLoaded.makeJQueryPlugin();

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

return ImagesLoaded;

} );


================================================
FILE: imagesloaded.pkgd.js
================================================
/*!
 * imagesLoaded PACKAGED v5.0.0
 * JavaScript is all like "You images are done yet or what?"
 * MIT License
 */

/**
 * EvEmitter v2.1.1
 * Lil' event emitter
 * MIT License
 */

( function( global, factory ) {
  // universal module definition
  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() {}

let proto = EvEmitter.prototype;

proto.on = function( eventName, listener ) {
  if ( !eventName || !listener ) return this;

  // set events hash
  let events = this._events = this._events || {};
  // set listeners array
  let listeners = events[ eventName ] = events[ eventName ] || [];
  // only add once
  if ( !listeners.includes( listener ) ) {
    listeners.push( listener );
  }

  return this;
};

proto.once = function( eventName, listener ) {
  if ( !eventName || !listener ) return this;

  // add event
  this.on( eventName, listener );
  // set once flag
  // set onceEvents hash
  let onceEvents = this._onceEvents = this._onceEvents || {};
  // set onceListeners object
  let onceListeners = onceEvents[ eventName ] = onceEvents[ eventName ] || {};
  // set flag
  onceListeners[ listener ] = true;

  return this;
};

proto.off = function( eventName, listener ) {
  let listeners = this._events && this._events[ eventName ];
  if ( !listeners || !listeners.length ) return this;

  let index = listeners.indexOf( listener );
  if ( index != -1 ) {
    listeners.splice( index, 1 );
  }

  return this;
};

proto.emitEvent = function( eventName, args ) {
  let listeners = this._events && this._events[ eventName ];
  if ( !listeners || !listeners.length ) return this;

  // copy over to avoid interference if .off() in listener
  listeners = listeners.slice( 0 );
  args = args || [];
  // once stuff
  let onceListeners = this._onceEvents && this._onceEvents[ eventName ];

  for ( let listener of listeners ) {
    let 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 this;
};

return EvEmitter;

} ) );
/*!
 * imagesLoaded v5.0.0
 * JavaScript is all like "You images are done yet or what?"
 * MIT License
 */

( function( window, factory ) {
  // universal module definition
  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,
    function factory( window, EvEmitter ) {

let $ = window.jQuery;
let console = window.console;

// -------------------------- helpers -------------------------- //

// turn element or nodeList into an array
function makeArray( obj ) {
  // use object if already an array
  if ( Array.isArray( obj ) ) return obj;

  let isArrayLike = typeof obj == 'object' && typeof obj.length == 'number';
  // convert nodeList to array
  if ( isArrayLike ) return [ ...obj ];

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

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

/**
 * @param {[Array, Element, NodeList, String]} elem
 * @param {[Object, Function]} options - if function, use as callback
 * @param {Function} onAlways - callback function
 * @returns {ImagesLoaded}
 */
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
  let 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 = {};
  // shift arguments if no options set
  if ( typeof options == 'function' ) {
    onAlways = options;
  } else {
    Object.assign( this.options, options );
  }

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

  this.getImages();
  // add jQuery Deferred object
  if ( $ ) 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.getImages = function() {
  this.images = [];

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

const elementNodeTypes = [ 1, 9, 11 ];

/**
 * @param {Node} elem
 */
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
  let { nodeType } = elem;
  if ( !nodeType || !elementNodeTypes.includes( nodeType ) ) return;

  let childImgs = elem.querySelectorAll('img');
  // concat childElems to filterFound array
  for ( let img of childImgs ) {
    this.addImage( img );
  }

  // get child background images
  if ( typeof this.options.background == 'string' ) {
    let children = elem.querySelectorAll( this.options.background );
    for ( let child of children ) {
      this.addElementBackgroundImages( child );
    }
  }
};

const reURL = /url\((['"])?(.*?)\1\)/gi;

ImagesLoaded.prototype.addElementBackgroundImages = function( elem ) {
  let style = getComputedStyle( elem );
  // Firefox returns null if in a hidden iframe https://bugzil.la/548397
  if ( !style ) return;

  // get url inside url("...")
  let matches = reURL.exec( style.backgroundImage );
  while ( matches !== null ) {
    let url = matches && matches[2];
    if ( url ) {
      this.addBackground( url, elem );
    }
    matches = reURL.exec( style.backgroundImage );
  }
};

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

ImagesLoaded.prototype.addBackground = function( url, elem ) {
  let background = new Background( url, elem );
  this.images.push( background );
};

ImagesLoaded.prototype.check = function() {
  this.progressedCount = 0;
  this.hasAnyBroken = false;
  // complete if no images
  if ( !this.images.length ) {
    this.complete();
    return;
  }

  /* eslint-disable-next-line func-style */
  let onProgress = ( image, elem, message ) => {
    // HACK - Chrome triggers event before object properties have changed. #83
    setTimeout( () => {
      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() {
  let eventName = this.hasAnyBroken ? 'fail' : 'done';
  this.isComplete = true;
  this.emitEvent( eventName, [ this ] );
  this.emitEvent( 'always', [ this ] );
  if ( this.jqDeferred ) {
    let 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.
  let 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();
  // add crossOrigin attribute. #204
  if ( this.img.crossOrigin ) {
    this.proxyImage.crossOrigin = this.img.crossOrigin;
  }
  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.currentSrc || 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;
  let { parentNode } = this.img;
  // emit progress with parent <picture> or self <img>
  let elem = parentNode.nodeName === 'PICTURE' ? parentNode : this.img;
  this.emitEvent( 'progress', [ this, elem, message ] );
};

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

// trigger specified handler for event type
LoadingImage.prototype.handleEvent = function( event ) {
  let 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
  let 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, onAlways ) {
    let instance = new ImagesLoaded( this, options, onAlways );
    return instance.jqDeferred.promise( $( this ) );
  };
};
// try making plugin
ImagesLoaded.makeJQueryPlugin();

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

return ImagesLoaded;

} );


================================================
FILE: package.json
================================================
{
  "name": "imagesloaded",
  "version": "5.0.0",
  "description": "JavaScript is all like _You images done yet or what?_",
  "main": "imagesloaded.js",
  "files": [
    "imagesloaded*.js"
  ],
  "dependencies": {
    "ev-emitter": "^2.1.2"
  },
  "devDependencies": {
    "eslint": "^7.32.0",
    "eslint-plugin-metafizzy": "^1.2.1",
    "jquery": "^3.6.0",
    "qunit": "^2.17.2",
    "terser": "^5.10.0"
  },
  "scripts": {
    "test": "npm run lint",
    "lint": "npx eslint .",
    "dist": "node tasks/dist.js",
    "version": "node tasks/version.js && npm run dist && git add -A ."
  },
  "repository": {
    "type": "git",
    "url": "git://github.com/desandro/imagesloaded.git"
  },
  "keywords": [
    "images",
    "loaded",
    "ui",
    "dom",
    "jquery-plugin"
  ],
  "license": "MIT",
  "bugs": {
    "url": "https://github.com/desandro/imagesloaded/issues"
  },
  "homepage": "https://github.com/desandro/imagesloaded",
  "directories": {
    "test": "test"
  },
  "author": "David DeSandro"
}


================================================
FILE: sandbox/background/css/background.css
================================================
.box {
  width: 300px;
  height: 300px;
  margin: 0 20px 20px 0;
  border: 1px solid;
  display: inline-block;
}

.orange-tree {
  background: url('https://i.imgur.com/bwy74ok.jpg');
  background-size: cover;
}

.thunder-cloud {
  background: url('../../../test/img/thunder-cloud.jpg');
  background-size: contain;
}

.multi1 {
  background:
    url("https://i.imgur.com/ZAVN3.png"),
    url('https://i.imgur.com/6UdOxeB.png') bottom right,
    url(https://i.imgur.com/LkmcILl.jpg);
  background-size: cover;
}

.blue {
  background: #09F;
}

================================================
FILE: sandbox/background/index.html
================================================
<!doctype html>
<html>
<head>
  <meta charset="utf-8" />
  <meta name="viewport" content="width=device-width" />

  <title>background</title>

  <!-- put in separate folder so JS path is different from CSS path -->
  <link rel="stylesheet" href="css/background.css" >

</head>
<body>

  <h1>background</h1>

<div class="box orange-tree"></div>

<div class="box thunder-cloud"></div>

<div class="box multi1"></div>

<div class="box blue"></div>

<script src="../../node_modules/ev-emitter/ev-emitter.js"></script>
<script src="../../imagesloaded.js"></script>
<script>

var imgLoad0 = imagesLoaded( '.orange-tree', { background: true }, function() {
  console.log('orange tree bg images loaded', imgLoad0.images.length );
});

var imgLoad1 = imagesLoaded( '.thunder-cloud', { background: true }, function() {
  console.log('thunder cloud bg images loaded', imgLoad1.images.length);
});

var imgLoad2 = imagesLoaded( '.multi1', { background: true }, function() {
  console.log('multi1 bg images loaded', imgLoad2.images.length);
});

var imgLoad3 = imagesLoaded( '.box', { background: true }, function() {
  console.log('.box bg images loaded', imgLoad3.images.length);
});
imgLoad3.on('progress', function( instance, image, element ) {
  console.log( 'progress on .box', image.img.src, element.className );
});

</script>

</body>
</html>


================================================
FILE: sandbox/picture.html
================================================
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">

  <title>picture</title>

</head>
<body>

    <picture>
      <source srcset="https://picsum.photos/id/103/1200/900" media="(min-width: 1200px)">
      <source srcset="https://picsum.photos/id/103/800/600" media="(min-width: 800px)">
      <img src="https://picsum.photos/id/103/400/300">
    </picture>
  
</body>
</html>


================================================
FILE: sandbox/progress/index.html
================================================
<!doctype html>
<html>
<head>
  <meta charset="utf-8" />
  <meta name="viewport" content="width=device-width" />

  <title>progress</title>

  <style>
  #image-container img {
    max-height: 140px;
  }

  li {
    height: 140px;
    min-width: 100px;
    display: block;
    float: left;
    list-style: none;
    margin: 0 5px 5px 0;
    background-color: black;
    background-position: center center;
    background-repeat: no-repeat;
  }

  li img,
  #status {
    -webkit-transition: opacity 0.4s;
       -moz-transition: opacity 0.4s;
        -ms-transition: opacity 0.4s;
            transition: opacity 0.4s;
  }

  li.is-loading {
    background-color: black;
    background-image: url('https://desandro.github.io/imagesloaded/assets/loading.gif');
  }

  li.is-broken {
    background-image: url('https://desandro.github.io/imagesloaded/assets/broken.png');
    background-color: #be3730;
    width: 120px;
  }

  li.is-loading img,
  li.is-broken img {
    opacity: 0;
  }

  .buttons { margin-bottom: 1.0em; }

  button {
    font-size: 18px;
    padding: 0.4em 0.8em;
    font-family: sans-serif;
  }

  #status {
    opacity: 0;
    position: fixed;
    right: 20px;
    top: 20px;
    background: hsla( 0, 0%, 0%, 0.8);
    padding: 20px;
    border-radius: 10px;
    z-index: 2; /* over other stuff */
  }
  </style>
  
</head>
<body>

  <h1>progress</h1>

  <div class="buttons">
    <button id="add">Add images</button>
    <button id="reset">Reset</button>
  </div>
  <div id="status">
    <progress max="7" value="0"></progress>
  </div>
  <div id="image-container"></div>

<script src="../../node_modules/ev-emitter/ev-emitter.js"></script>
<script src="../../imagesloaded.js"></script>
<script src="progress.js"></script>

</body>
</html>


================================================
FILE: sandbox/progress/progress.js
================================================
let progressElem, statusElem,
        supportsProgress,
        loadedImageCount, imageCount;

let container = document.querySelector('#image-container');
statusElem = document.querySelector('#status');
progressElem = document.querySelector('progress');

supportsProgress = progressElem &&
  // IE does not support progress
  progressElem.toString().indexOf('Unknown') === -1;

document.querySelector('#add').onclick = function() {
  // add new images
  let fragment = getItemsFragment();
  container.insertBefore( fragment, container.firstChild );
  // use ImagesLoaded
  let imgLoad = imagesLoaded( container );
  imgLoad.on( 'progress', onProgress );
  imgLoad.on( 'always', onAlways );
  // reset progress counter
  imageCount = imgLoad.images.length;
  resetProgress();
  updateProgress( 0 );
};

// reset container
document.querySelector('#reset').onclick = function() {
  empty( container );
};

// ----- set text helper ----- //

let docElem = document.documentElement;
let textSetter = docElem.textContent !== undefined ? 'textContent' : 'innerText';

function setText( elem, value ) {
  elem[ textSetter ] = value;
}

function empty( elem ) {
  while ( elem.firstChild ) {
    elem.removeChild( elem.firstChild );
  }
}

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

// return doc fragment with
function getItemsFragment() {
  let fragment = document.createDocumentFragment();
  for ( let i = 0; i < 7; i++ ) {
    let item = getImageItem();
    fragment.appendChild( item );
  }
  return fragment;
}

// return an <li> with a <img> in it
function getImageItem() {
  let item = document.createElement('li');
  item.className = 'is-loading';
  let img = document.createElement('img');
  let size = Math.random() * 3 + 1;
  let width = Math.random() * 110 + 100;
  width = Math.round( width * size );
  let height = Math.round( 140 * size );
  let rando = Math.ceil( Math.random() * 1000 );
  // 10% chance of broken image src
  // random parameter to prevent cached images
  img.src = rando < 100 ? `//foo/broken-${rando}.jpg` :
    // use picsum for great random images
    `https://picsum.photos/${width}/${height}/?random`;
  item.appendChild( img );
  return item;
}

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

function resetProgress() {
  statusElem.style.opacity = 1;
  loadedImageCount = 0;
  if ( supportsProgress ) {
    progressElem.setAttribute( 'max', imageCount );
  }
}

function updateProgress( value ) {
  if ( supportsProgress ) {
    progressElem.setAttribute( 'value', value );
  } else {
    // if you don't support progress elem
    setText( statusElem, value + ' / ' + imageCount );
  }
}

// triggered after each item is loaded
function onProgress( imgLoad, image ) {
  // change class if the image is loaded or broken
  image.img.parentNode.className = image.isLoaded ? '' : 'is-broken';
  // update progress element
  loadedImageCount++;
  updateProgress( loadedImageCount );
}

// hide status when done
function onAlways() {
  statusElem.style.opacity = 0;
}


================================================
FILE: tasks/dist.js
================================================
const fs = require('fs');
const { execSync } = require('child_process');
const { minify } = require('terser');

const indexPath = 'imagesloaded.js';
const distPath = 'imagesloaded.pkgd.js';
const distMinPath = 'imagesloaded.pkgd.min.js';

let indexContent = fs.readFileSync( `./${indexPath}`, 'utf8' );

let paths = [
  'node_modules/ev-emitter/ev-emitter.js',
  'imagesloaded.js',
];

// concatenate files
execSync(`cat ${paths.join(' ')} > ${distPath}`);

// add banner
let banner = indexContent.split(' */')[0] + ' */\n\n';
banner = banner.replace( 'imagesLoaded', 'imagesLoaded PACKAGED' );
let distJsContent = fs.readFileSync( distPath, 'utf8' );
distJsContent = banner + distJsContent;
fs.writeFileSync( distPath, distJsContent );

// minify
( async function() {
  let { code } = await minify( distJsContent, { mangle: true } );
  fs.writeFileSync( distMinPath, code );
} )();


================================================
FILE: tasks/version.js
================================================
const fs = require('fs');
const version = require('../package.json').version;

const file = 'imagesloaded.js';

let src = fs.readFileSync( file, 'utf8' );
src = src.replace( /imagesLoaded v\d+\.\d+\.\d+/, `imagesLoaded v${version}` );
fs.writeFileSync( file, src, 'utf8' );


================================================
FILE: test/css/tests.css
================================================
body {
  font-family: sans-serif;
}

img {
  display: inline-block;
  max-width: 240px;
}

#qunit {
  max-width: 600px;
  right: 0;
  left: auto;
}

/* ---- backgrounds ---- */

.bg-box {
  width: 240px;
  height: 240px;
  margin: 0 20px 20px 0;
  border: 1px solid;
  display: inline-block;
}

.bg-box.tulip {
  background: url('https://i.imgur.com/9xYjgCk.jpg');
  background-size: cover;
}

.bg-box.thunder-cloud {
  background: url('../img/thunder-cloud.jpg');
  background-size: contain;
}

.bg-box.multi {
  background:
    url("https://i.imgur.com/ZAVN3.png"),
    url('https://i.imgur.com/6UdOxeB.png') bottom right,
    url(https://picsum.photos/601/401/?random);
  background-size: cover;
}

.bg-box.blue {
  background: #09F;
}

.bg-box.gulls {
  background-image: url('https://i.imgur.com/qKhkOKC.jpg');
  background-size: cover;
}


================================================
FILE: test/index.html
================================================
<!doctype html>
<html>
<head>
  <meta charset="utf-8">

  <title>imagesLoaded tests</title>

  <link rel="stylesheet" href="../node_modules/qunit/qunit/qunit.css" />
  <link rel="stylesheet" href="css/tests.css" />

  <script src="../node_modules/ev-emitter/ev-emitter.js"></script>
  <script src="../node_modules/qunit/qunit/qunit.js"></script>
  <script src="../node_modules/jquery/dist/jquery.js"></script>

  <script src="../imagesloaded.js"></script>

  <script src="unit/basics.js"></script>
  <script src="unit/selector-string.js"></script>
  <script src="unit/single-element.js"></script>
  <script src="unit/local-files.js"></script>
  <script src="unit/data-uri.js"></script>
  <script src="unit/append.js"></script>
  <script src="unit/no-images.js"></script>
  <script src="unit/jquery-success.js"></script>
  <script src="unit/jquery-fail.js"></script>
  <script src="unit/non-element.js"></script>
  <script src="unit/background.js"></script>
  <script src="unit/picture.js"></script>
  <script src="unit/srcset.js"></script>

</head>
<body>

  <h1>imagesLoaded tests</h1>

  <div id="qunit"></div>

  <h2>Basics</h2>

  <div id="basics">
    <img src="https://i.imgur.com/xrQHn.jpg" />
    <img src="https://i.imgur.com/b3fBJ.jpg" />
    <img src="https://i.imgur.com/xmSh2.jpg" />
    <img src="https://i.imgur.com/iIpJm.jpg" />
    <img src="https://i.imgur.com/cvZZl10.gif" />
  </div>

  <img id="mario-with-shell" src="https://i.imgur.com/ZAVN3.png" >

  <h2>Locals</h2>

  <div id="locals">
    <img src="img/blue-shell.jpg" />
    <img src="img/bowser-jr.jpg" />
    <!-- thunder cloud has bad permissions, should 403 -->
    <img src="img/not-there.jpg" />
  </div>

  <h2>Data URI</h2>

  <div id="data-uri">
    <img src="data:image/jpeg;base64,/9j/4AAQSkZJRgABAgAAZABkAAD/7AARRHVja3kAAQAEAAAARgAA/+4ADkFkb2JlAGTAAAAAAf/bAIQABAMDAwMDBAMDBAYEAwQGBwUEBAUHCAYGBwYGCAoICQkJCQgKCgwMDAwMCgwMDQ0MDBERERERFBQUFBQUFBQUFAEEBQUIBwgPCgoPFA4ODhQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQU/8AAEQgAMAAwAwERAAIRAQMRAf/EAJMAAAEFAQEBAAAAAAAAAAAAAAYAAwQHCAUBAgEAAgIDAQEAAAAAAAAAAAAAAAUEBgECAwcIEAABAwMDAgQFAwUAAAAAAAACAQMEEQUGACESMQdBUSIyYUJiExRSIwihgiQVFhEAAQMCBQEFBgcAAAAAAAAAAQARAgMEITFBEgVRYYGRIgZxocHRchPw4TJCIxQH/9oADAMBAAIRAxEAPwDf2hCWhC42R5JBxuF+RJq7JcqMWIC/uOmngnkKfMXh/TSTmOZt+MoGrVP0x1kez4nTwCl21rOvPbHvPRRMHuFzutmcuF2NClPyn1ERSjYNiXEQD4DTx389RvTl/VvrKNxUzqGRA6B2AHgt72lGlVMI/tbxRJqyKCloQloQm31eRlxY4iT6CqtCaqIqVNkVURaJXWk9207W3Ng+T9qyGfFUtPutrbyFIuazTtWRyy+1FbuIKyw9v6QiO7tODVdhEuXmldfM/qbi+arXMql2A2hDmAHQM7D29+Kt9tc04w20Rh7+9FkKZIx1VFhf8bkv3I5biqqu6p5Kvw0u9N+sL3iav9eX8tJ22dPoOnsy7FwrW8bnzZS6/NHkZ4pEdt42yZIxQlaP3DXwXX1LQqmrTjMxMNwfbLMdh7VWJBiQ7p3Xdapt99mMy5JkOC1HZEnHXTVBEQBKkSqvRERN9CFSFx7q5PkqOz8TfZs2ON8lizJDIvyZLadHlFxeLYF1BOKlTdadNWy34emIg1XMjoNElr35EmgEORO4uaXWUNnya2QMpxZ50FemSWBhuxXBJFB9tKGDn219ftAtvStdJvUnEQHHXEqQJIpTaP6jI7SwGrk5KVZ3z1IieDkfgqDkOf8AcEsmQ7FGbs+LspRm7SowzJkh2u7iNGvFhpE9iqJGXVeOvPfQX+Yw4+Iu+Q89zIOIPhSfqdanXSOQxxU6+5oSBhROA9/5Isgd08vxltq5ZQ+zfccNUKZIYZFiUwz4ugjXocEfcQ8UKnRa7a9cuOHpyiftOJDQ6pPR5AmTTCvONJYmR2ZcVwXosgBdYeBeQG2aIQkKp1RUWqaqZDJ0qL7p5U9nz1w7cY887FtMSQLGR3JteKyVb9TkJrxQK0F4/HcE8V1ZONsAwrVMtB8Uru7v7flGaGZlqdt8AGnXUOMwQqTYogjTolUTy1Z4yEkid1DwPIrzLzLKbNdba7GsFo+wlruDraCxL/IqQ/jkgopIAJ+9Ui9dKcemlUjWlUkCPKGbwXWpCAhEjMu697gZHfYmW4pabRbnZVjuzjwXa4NAJsRRZ4kX5JKKqCE2pfaUVH1pvXprANaE4iIwLv4IpxgYSJzGSnwLQ7cbe4DLyNx3iJRbVEIadFoi+emkpiJXEll2O1uXu9u5cLt1fnXZVinS1ZsFwMuSwjfWoRHK7q0p1RkvkqgL6aKlc5Pj3BrQ7x8fmn1pd7/Kc1W9zukjtr3AvuMX0VjPSpsm5WqQ5sEyFMeJ4XGyXYlFSVtxE3Eh36ppnYV4VKMRqAyj3luTJwuxIvzV6bKG2+ipJFRJQXdBXqqeVNMwAEs2mKYKZc7MItPG3NbH2PI4jLnH6gL01+IrocrIAllgkk26XgSaYJuG2XueJxHnOPjxAdq+XJaaHKCBHPFSYeQt2JoYDj9Ejigipruop4rrBiDmsGBlih+DOkdzc8s2K2BFkPtTI1wukltOTcOFDeB43XFTZFLigNoq1Ii26Lpdf3EKdEjUhgmdpbyEnK1plWF4pm8BLZltoi3eEKqTYSm0MmyXqTZ7EBbdQVF1R4VJQLxLJ2Q6zdlX8asvxO5O3TtPLbulofLktiukhWpbH0syTRRcBPAXaEn6i0+teV24T8VFq24mEMOdve/F3f8Awf8AjljPJRClS5sQIqeFeYOGS0+kFXTGXLUgMCosbJl9tdu+/FoeWEuHpKc3QZUSdFKMXxQnHGyT+4E0R5aiRiidk6IsX/jVmOW3Jq5d15bdqsrBcksdrfV2Y/T5XZIIgttr8yNciX9Q6X3XK7g0PFSqVuILSmLYbiuE2/8A1eJ2iLaIKrycbitoCuElfU4XuMt+pqq6QTqSmXkXUoBl/9k=" />
    <img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACsAAAAwCAMAAAC/knOqAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAMBQTFRFkF0QF27/Bgsp/fQF+fr6jqvpDEG2zp4CCx9Ys4IFo5JU8MqQXJH2Ulxj89QDC0bIsrKxIHn//fxztcv2iYqG5ebmCjCHzNjxAzTYRmih2drcCzijMof+OB8U/Pg59PHXE2D9xMK9eUMDAVf8kXNP/fvr2eP0p6WgOUtnAkX7Eljwa3WB5er2UXjVC0jZAh9/EFHa8PHyl5mZJVKt6NM34dzNz87NASGpsbzZDlDytq4tLWfs4bQFyLNp////+/v7DjziEwAAAEB0Uk5T////////////////////////////////////////////////////////////////////////////////////AMJ7sUQAAAPaSURBVHjadNWLdqo6EAZgQKGRA0YUYzRQY1ELqFykiojV93+rM0FQbLt/VlcvfpmVhGQq3V6TjgyjLOWyNIzR9sdn0stvE0MuQrmOZxmjf9pRybln+sJZspWZiSU7o7+twTmXtcU3BmhZ4f6/zLJk2ej+ttsyDIXVN4klsGzqmQP1ZXn9044TQbmcuS5Yx3Ic380cy2rj2qZJktzrui7MFqiDKlutcv1ip0mNseuGFbaedeVd235qGOMkAo4VJYB4AVcUbHG5erjxtN1ME8kwpgHybV0/63vbRF5QrUFk+7ADwpgGD82nva9+p4m+CQKYWFjwUH3YKYNkjPrnCr6/D4fz93f46WsKuIDqu8amPmGE5bnZr2u+fw2Hwwr3N4FYRZKsazshBLCggPv9S79K56saV+NRbU8McO6+ifSavL1dLtVQk2LYT7VtY/hcgnw8HgkGAL9Q2E78tDGJfWBV3CbiFwnqmzlsfmPXUDd2pTtUFAVVj6IIDtVNqmGtmW+aEYJQDZ9puM/gPTX7cNtBYeS7r+z+hVyfAp0+3gUsDsXKP5IXGLPne7uVUJf8TRFPEi1Ln1YVq/sbazzBbN8+v2LGjCguzNBtllVRwovoPtvnvcgYihlpLaueQeFRjY1f79vWhxfCGKpz54gVRYTZ7Nedn8JeiPNG7lhBGS2KIKdZ99edT6cKQjEiBGMf+UhhZRFQSnG02/60J9i0qmCMcsbimPGABkXIRYdQX+2EaaEcinOc57GWlWXpeR7cYqsUPWj0YksKN73QNEpLdZJer9d0rToeVC2LEG5+2rIqLjjXKKPJ6PrMxPJkK6DcsdSn3dIo5DnK8113de22tOHJWhyUDp88rBFFPEJxvruu0jYVOEE0tCyjsSMchQVBOZ3Px+MfeOehmHJLbs76LioKpuT5QND0hV4nnqZoGPrb3Z6iKNIUJc6Os5nA3ZfKTgCvGtq3Kuw2BIpMP5/O/8JGQEzC4N/BGuyuwAyZKYvtw/GOYc7A4RHf1ICNbUIi2blJqocJWt5Skm8OiyPo8aGufX/UQJvd9sSPZFUqKfGPcHRYPF0MBovT8VhXh3TT1cqgFM7kzESslEbqUezdyszJ4HvwKfhi8eCra0incwFm+1N9Hub9ztnffOqf+0/IY8BhpWbnTmfePjurs2iJZ922dXsPqQcMFouqWfbnLfst+ii05t7Stjd2lb0Y1Lt0hkA73y3bexNddzjs93S7yd5e9i4XaPFQ5tLqD5LohxfouG+S5G/u8T8+7l34Al25+7SHpVRlKS312fo4OA0Ws7Fe/1FaLg+V+l+AAQAurhhy+upm/wAAAABJRU5ErkJggg==" />
  </div>

  <h2>append</h2>

  <div id="append"></div>

  <h2>no images</h2>

  <div id="no-images"></div>

  <h2>jQuery success</h2>

  <div id="jquery-success">
    <img src="https://i.imgur.com/YbYCPFF.png" />
    <img src="https://i.imgur.com/6UdOxeB.png" />
    <img src="https://i.imgur.com/qd8G15D.png" />
  </div>

  <h2>jQuery fail</h2>

  <div id="jquery-fail">
    <img src="https://i.imgur.com/xmSh2.jpg" />
    <img src="img/bowser-jr.jpg" />
    <img src="https://i.imgur.com/ZAVN3.png">
    <img src="img/not-there.jpg" />
    <img src="foobar.jpg" />
  </div>

  <h2>background</h2>

  <div id="background">
    <div class="bg-box tulip"></div>
    <div class="bg-box thunder-cloud"></div>
    <div class="bg-box multi"></div>
    <div class="bg-box blue"></div>
    <div class="bg-box gulls">
      <img src="https://picsum.photos/400/300/?random" />
      <img src="https://picsum.photos/800/600/?random" />
    </div>
  </div>

  <h2>picture</h2>

  <div id="picture-list">
    <picture>
      <source srcset="https://picsum.photos/id/1036/1200/900" media="(min-width: 1200px)">
      <source srcset="https://picsum.photos/id/1036/800/600" media="(min-width: 800px)">
      <img src="https://picsum.photos/id/1036/400/300">
    </picture>
    <picture>
      <source srcset="https://picsum.photos/id/103/1200/900" media="(min-width: 1200px)">
      <source srcset="https://picsum.photos/id/103/800/600" media="(min-width: 800px)">
      <img src="https://picsum.photos/id/103/400/300">
    </picture>
    <picture>
      <source srcset="https://picsum.photos/id/1080/900/1200" media="(min-width: 1200px)">
      <source srcset="https://picsum.photos/id/1080/600/800" media="(min-width: 800px)">
      <img src="https://picsum.photos/id/1080/300/400">
    </picture>
  </div>

  <h2>srcset</h2>

  <div id="srcset">
    <img
      srcset="
        https://picsum.photos/id/1074/1200/900 1200w,
        https://picsum.photos/id/1074/800/600 800w,
        https://picsum.photos/id/1074/400/300 400w
      "
      sizes="
        (min-width: 1200px) 240px,
        (min-width: 800px) 240px,
        240px,
      "
    >
    <img
      srcset="
        https://picsum.photos/id/159/900/1200 900w,
        https://picsum.photos/id/159/600/800 600w,
        https://picsum.photos/id/159/300/400 300w
      "
      sizes="
        (min-width: 1200px) 240px,
        (min-width: 800px) 240px,
        240px,
      "
    >
    <img
      srcset="
        https://picsum.photos/id/133/1200/900 1200w,
        https://picsum.photos/id/133/800/600 800w,
        https://picsum.photos/id/133/400/300 400w
      "
      sizes="
        (min-width: 1200px) 240px,
        (min-width: 800px) 240px,
        240px,
      "
    >
  </div>


</body>
</html>


================================================
FILE: test/unit/append.js
================================================
QUnit.test( 'append', function( assert ) {
  let imgUrls = [
    'https://i.imgur.com/bwy74ok.jpg',
    'https://i.imgur.com/bAZWoqx.jpg',
    'https://i.imgur.com/PgmEBSB.jpg',
    'https://i.imgur.com/aboaFoB.jpg',
    'https://i.imgur.com/LkmcILl.jpg',
    'https://i.imgur.com/q9zO6tw.jpg',
  ];

  // create images
  let fragment = document.createDocumentFragment();
  for ( let i = 0, len = imgUrls.length; i < len; i++ ) {
    let img = document.createElement('img');
    img.src = imgUrls[i];
    fragment.appendChild( img );
  }

  let elem = document.querySelector('#append');
  elem.appendChild( fragment );
  let done = assert.async();

  imagesLoaded( elem, { debug: false } ).on( 'always', function() {
    assert.ok('appended images loaded');
    done();
  } );

} );


================================================
FILE: test/unit/background.js
================================================
QUnit.test( 'background', function( assert ) {
  // from Modernizr
  let supportsMultiBGs = ( function() {
    let style = document.createElement('a').style;
    style.cssText = 'background:url(https://),url(https://),red url(https://)';
    return ( /(url\s*\(.*?){3}/ ).test( style.background );
  } )();

  let multiBGCount = supportsMultiBGs ? 3 : 0;
  let done = assert.async( 14 + multiBGCount );

  let imgLoad0 = imagesLoaded( '#background .tulip', { background: true }, function() {
    assert.ok( true, 'callback triggered on .orange-tree' );
    done();
  } );
  assert.equal( imgLoad0.images.length, 1, '1 image on .images' );

  imgLoad0.on( 'progress', function( instance, image, element ) {
    assert.ok( element.nodeName === 'DIV', 'progress; element is div' );
    assert.ok( image.isLoaded, 'progress; image.isLoaded' );
    done();
  } );

  let imgLoad1 = imagesLoaded( '#background .thunder-cloud', { background: true },
      function() {
      assert.ok( true, 'callback triggered on .thunder-cloud' );
      done();
    } );
  assert.equal( imgLoad1.images.length, 1, '1 image on .images' );

  // multiple backgrounds
  let imgLoad2 = imagesLoaded( '#background .multi', { background: true }, function() {
    assert.ok( true, 'callback triggered on .multi' );
    done();
  } );
  assert.equal( imgLoad2.images.length, multiBGCount,
      'correct multiple BG count on .images' );

  // multiple elements
  let imgLoad3 = imagesLoaded( '#background .bg-box', { background: true }, function() {
    assert.ok( true, 'callback triggered on .bg-box' );
    let count = 5 + multiBGCount;
    assert.equal( imgLoad3.images.length, count, count + ' images on .bg-box' );
    done();
  } );

  imgLoad3.on( 'progress', function( instance, image /* , element */) {
    assert.ok( true, 'progress on .bg-box; ' + image.img.src );
    assert.equal( image.isLoaded, true, 'image.isLoaded == true' );
    done();
  } );

  // background and <img> children
  let imgLoad4 = imagesLoaded( '#background .gulls', { background: true } );
  assert.equal( imgLoad4.images.length, 3, '3 images: 1 background and 2 <img>' );

  imgLoad4.on( 'progress', function( instance, image ) {
    assert.equal( image.isLoaded, true, 'image is loaded' );
    done();
  } );

  // child background selector
  let imgLoad5 = imagesLoaded( '#background', { background: '.bg-box' }, function() {
    let count = 5 + multiBGCount;
    assert.equal( imgLoad5.images.length, count,
        count + ' images on .bg-box, with {background: .bg-box}' );
    done();
  } );

} );


================================================
FILE: test/unit/basics.js
================================================
QUnit.test( 'basics', function( assert ) {
  let elem = document.querySelector('#basics');
  let images = elem.querySelectorAll('img');
  let done = assert.async( 3 + images.length );

  let imgLoader = new imagesLoaded( elem, function( obj ) {
    assert.ok( true, 'callback function triggered' );
    assert.equal( imgLoader, obj, 'callback argument and instance match' );
    done();
  } );
  imgLoader.on( 'done', function() {
    assert.ok( true, 'done event triggered' );
    done();
  } );
  imgLoader.on( 'always', function() {
    assert.ok( true, 'always event triggered' );
    done();
  } );

  imgLoader.on( 'progress', function( loader, image ) {
    assert.ok( image.isLoaded, 'image is loaded' );
    done();
  } );

} );


================================================
FILE: test/unit/data-uri.js
================================================
QUnit.test( 'data-uri', function( assert ) {
  let done = assert.async();
  imagesLoaded( '#data-uri', { debug: false } ).on( 'done', function( obj ) {
    assert.ok( true, 'data-uri images loaded' );
    assert.equal( obj.images.length, 2, 'instance has 2 images' );
    done();
  } );
} );


================================================
FILE: test/unit/jquery-fail.js
================================================
QUnit.test( 'jquery fail', function( assert ) {
  let $ = window.jQuery;
  let $images = $('#jquery-fail img');
  let done = assert.async( 3 + $images.length );

  $('#jquery-fail').imagesLoaded( function( instance ) {
      assert.ok( true, 'callback triggered' );
      assert.ok( instance instanceof imagesLoaded, 'instance instanceof imagesLoaded' );
      done();
    } )
    .fail( function( instance ) {
      assert.ok( true, 'fail triggered' );
      assert.ok( instance instanceof imagesLoaded, 'instance instanceof imagesLoaded' );
      done();
    } )
    .always( function( instance ) {
      assert.ok( true, 'always triggered' );
      assert.ok( instance instanceof imagesLoaded, 'instance instanceof imagesLoaded' );
      done();
    } )
    .progress( function( /* instance, image */) {
      assert.ok( true, 'progress trigged' );
      done();
    } );

  } );


================================================
FILE: test/unit/jquery-success.js
================================================
QUnit.test( 'jquery success', function( assert ) {
  let $ = window.jQuery;
  let done = assert.async( 6 );

  $('#jquery-success').imagesLoaded( function( instance ) {
      assert.ok( true, 'callback triggered' );
      assert.ok( instance instanceof imagesLoaded, 'instance instanceof imagesLoaded' );
      done();
    } )
    .done( function( instance ) {
      assert.ok( true, 'done triggered' );
      assert.ok( instance instanceof imagesLoaded, 'instance instanceof imagesLoaded' );
      done();
    } )
    .always( function( instance ) {
      assert.ok( true, 'always triggered' );
      assert.ok( instance instanceof imagesLoaded, 'instance instanceof imagesLoaded' );
      done();
    } )
    .progress( function( instance, image ) {
      assert.ok( image.isLoaded, 'progress trigged, image is loaded' );
      done();
    } );

} );


================================================
FILE: test/unit/local-files.js
================================================
QUnit.test( 'local files', function( assert ) {
  let elem = document.querySelector('#locals');
  let done = assert.async( 6 );

  let imgLoader = new imagesLoaded( elem, function( obj ) {
    assert.ok( true, 'callback function triggered' );
    assert.equal( imgLoader, obj, 'callback argument and instance match' );
    done();
  } );
  imgLoader.on( 'fail', function() {
    assert.ok( true, 'fail event triggered' );
    done();
  } );
  imgLoader.on( 'always', function() {
    assert.ok( true, 'always event triggered' );
    done();
  } );

  imgLoader.on( 'progress', function( loader, image ) {
    assert.ok( true, 'image progressed' );
    if ( image.img.src.indexOf('img/not-there.jpg') !== -1 ) {
      assert.ok( !image.isLoaded, 'thunder cloud is not loaded' );
    } else {
      assert.ok( image.isLoaded, 'image is loaded' );
    }
    done();
  } );

} );


================================================
FILE: test/unit/no-images.js
================================================
QUnit.test( 'no images', function( assert ) {
  let elem = document.querySelector('#no-images');
  let done = assert.async();
  imagesLoaded( elem, function() {
    assert.ok( true, 'triggered with no images' );
    done();
  } );

} );


================================================
FILE: test/unit/non-element.js
================================================
QUnit.test( 'dismiss non-element nodes', function( assert ) {
  let $ = window.jQuery;
  let done = assert.async( 2 );

  $( '<img src="https://picsum.photos/401/301/?random" />' +
  '<img src="https://picsum.photos/402/302/?random" /> ' )
    .imagesLoaded( function() {
      assert.ok( true, 'elements from jQuery string ok' );
      done();
    } );

  // test fragment
  let frag = document.createDocumentFragment();
  let img = new Image();
  img.src = 'https://picsum.photos/403/303/?random';
  frag.appendChild( img );
  let imgLoad = imagesLoaded( frag, function() {
    assert.ok( true, 'document fragment ok' );
    assert.equal( imgLoad.images.length, 1, '1 image found' );
    done();
  } );

} );


================================================
FILE: test/unit/picture.js
================================================
QUnit.test( 'picture', function( assert ) {

  let done = assert.async( 4 );

  let imgLoad0 = imagesLoaded( '#picture-list', function() {
    assert.ok( true, 'callback triggered on #picture-list' );
    done();
  } );
  assert.equal( imgLoad0.images.length, 3, '3 images on #picture-list' );

  imgLoad0.on( 'progress', function( instance, image, element ) {
    assert.ok( element.nodeName === 'PICTURE', 'progress; element is picture' );
    assert.ok( image.isLoaded, 'progress; image.isLoaded' );
    done();
  } );

} );


================================================
FILE: test/unit/selector-string.js
================================================
QUnit.test( 'selector string', function( assert ) {
  let images = document.querySelectorAll('#basics img');
  let done = assert.async();
  let imgLoad = imagesLoaded( '#basics', { debug: true } )
    .on( 'done', function( obj ) {
      assert.ok( true, 'selector string worked' );
      assert.ok( obj.images, 'argument has images' );
      assert.equal( obj.images.length, images.length, 'images.length matches' );
      done();
    } );
  assert.ok( imgLoad.options.debug, 'debug option set' );
} );


================================================
FILE: test/unit/single-element.js
================================================
QUnit.test( 'single element', function( assert ) {
  let elem = document.querySelector('#mario-with-shell');
  let done = assert.async();
  imagesLoaded( elem ).on( 'done', function( obj ) {
    assert.ok( true, 'single element worked' );
    assert.ok( obj.images, 'argument has images' );
    assert.equal( obj.images.length, 1, 'images.length = 1' );
    done();
  } );
} );


================================================
FILE: test/unit/srcset.js
================================================
QUnit.test( 'srcset', function( assert ) {

  let done = assert.async( 4 );

  let imgLoad0 = imagesLoaded( '#srcset', function() {
    assert.ok( true, 'callback triggered on #srcset' );
    done();
  } );
  assert.equal( imgLoad0.images.length, 3, '3 images on #srcset' );

  imgLoad0.on( 'progress', function( instance, image, element ) {
    assert.ok( element.nodeName === 'IMG', 'progress; element is img' );
    assert.ok( image.isLoaded, 'progress; image.isLoaded' );
    done();
  } );

} );
Download .txt
gitextract_8bkypk_n/

├── .eslintrc.js
├── .gitignore
├── .nvmrc
├── LICENSE.md
├── README.md
├── bower.json
├── contributing.md
├── imagesloaded.js
├── imagesloaded.pkgd.js
├── package.json
├── sandbox/
│   ├── background/
│   │   ├── css/
│   │   │   └── background.css
│   │   └── index.html
│   ├── picture.html
│   └── progress/
│       ├── index.html
│       └── progress.js
├── tasks/
│   ├── dist.js
│   └── version.js
└── test/
    ├── css/
    │   └── tests.css
    ├── index.html
    └── unit/
        ├── append.js
        ├── background.js
        ├── basics.js
        ├── data-uri.js
        ├── jquery-fail.js
        ├── jquery-success.js
        ├── local-files.js
        ├── no-images.js
        ├── non-element.js
        ├── picture.js
        ├── selector-string.js
        ├── single-element.js
        └── srcset.js
Download .txt
SYMBOL INDEX (17 symbols across 3 files)

FILE: imagesloaded.js
  function makeArray (line 26) | function makeArray( obj ) {
  function ImagesLoaded (line 46) | function ImagesLoaded( elem, options, onAlways ) {
  function LoadingImage (line 210) | function LoadingImage( img ) {
  function Background (line 283) | function Background( url, element ) {

FILE: imagesloaded.pkgd.js
  function EvEmitter (line 25) | function EvEmitter() {}
  function makeArray (line 132) | function makeArray( obj ) {
  function ImagesLoaded (line 152) | function ImagesLoaded( elem, options, onAlways ) {
  function LoadingImage (line 316) | function LoadingImage( img ) {
  function Background (line 389) | function Background( url, element ) {

FILE: sandbox/progress/progress.js
  function setText (line 37) | function setText( elem, value ) {
  function empty (line 41) | function empty( elem ) {
  function getItemsFragment (line 50) | function getItemsFragment() {
  function getImageItem (line 60) | function getImageItem() {
  function resetProgress (line 80) | function resetProgress() {
  function updateProgress (line 88) | function updateProgress( value ) {
  function onProgress (line 98) | function onProgress( imgLoad, image ) {
  function onAlways (line 107) | function onAlways() {
Condensed preview — 32 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (66K chars).
[
  {
    "path": ".eslintrc.js",
    "chars": 525,
    "preview": "/* eslint-env node */\n\nmodule.exports = {\n  plugins: [ 'metafizzy' ],\n  extends: 'plugin:metafizzy/browser',\n  env: {\n  "
  },
  {
    "path": ".gitignore",
    "chars": 95,
    "preview": "bower_components/\nnode_modules/\nbuild/index.html\nbuild/*.woff*\nbuild/imagesloaded*.js\n.netlify\n"
  },
  {
    "path": ".nvmrc",
    "chars": 2,
    "preview": "16"
  },
  {
    "path": "LICENSE.md",
    "chars": 1168,
    "preview": "Copyright (c) 2011-2022 [David DeSandro](https://desandro.com) and [contributors](https://github.com/desandro/imagesload"
  },
  {
    "path": "README.md",
    "chars": 7587,
    "preview": "# imagesLoaded\n\n<p class=\"tagline\">JavaScript is all like \"You images done yet or what?\"</p>\n\n[imagesloaded.desandro.com"
  },
  {
    "path": "bower.json",
    "chars": 617,
    "preview": "{\n  \"name\": \"imagesloaded\",\n  \"description\": \"JavaScript is all like _You images done yet or what?_\",\n  \"main\": \"imagesl"
  },
  {
    "path": "contributing.md",
    "chars": 1204,
    "preview": "## Submitting issues\n\n### Reduced test case required\n\nAll bug reports and problem issues require a [**reduced test case*"
  },
  {
    "path": "imagesloaded.js",
    "chars": 9537,
    "preview": "/*!\n * imagesLoaded v5.0.0\n * JavaScript is all like \"You images are done yet or what?\"\n * MIT License\n */\n\n( function( "
  },
  {
    "path": "imagesloaded.pkgd.js",
    "chars": 12075,
    "preview": "/*!\n * imagesLoaded PACKAGED v5.0.0\n * JavaScript is all like \"You images are done yet or what?\"\n * MIT License\n */\n\n/**"
  },
  {
    "path": "package.json",
    "chars": 1011,
    "preview": "{\n  \"name\": \"imagesloaded\",\n  \"version\": \"5.0.0\",\n  \"description\": \"JavaScript is all like _You images done yet or what?"
  },
  {
    "path": "sandbox/background/css/background.css",
    "chars": 541,
    "preview": ".box {\n  width: 300px;\n  height: 300px;\n  margin: 0 20px 20px 0;\n  border: 1px solid;\n  display: inline-block;\n}\n\n.orang"
  },
  {
    "path": "sandbox/background/index.html",
    "chars": 1339,
    "preview": "<!doctype html>\n<html>\n<head>\n  <meta charset=\"utf-8\" />\n  <meta name=\"viewport\" content=\"width=device-width\" />\n\n  <tit"
  },
  {
    "path": "sandbox/picture.html",
    "chars": 460,
    "preview": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n  <meta charset=\"utf-8\">\n  <meta name=\"viewport\" content=\"width=device-width, in"
  },
  {
    "path": "sandbox/progress/index.html",
    "chars": 1762,
    "preview": "<!doctype html>\n<html>\n<head>\n  <meta charset=\"utf-8\" />\n  <meta name=\"viewport\" content=\"width=device-width\" />\n\n  <tit"
  },
  {
    "path": "sandbox/progress/progress.js",
    "chars": 2945,
    "preview": "let progressElem, statusElem,\n        supportsProgress,\n        loadedImageCount, imageCount;\n\nlet container = document."
  },
  {
    "path": "tasks/dist.js",
    "chars": 883,
    "preview": "const fs = require('fs');\nconst { execSync } = require('child_process');\nconst { minify } = require('terser');\n\nconst in"
  },
  {
    "path": "tasks/version.js",
    "chars": 274,
    "preview": "const fs = require('fs');\nconst version = require('../package.json').version;\n\nconst file = 'imagesloaded.js';\n\nlet src "
  },
  {
    "path": "test/css/tests.css",
    "chars": 844,
    "preview": "body {\n  font-family: sans-serif;\n}\n\nimg {\n  display: inline-block;\n  max-width: 240px;\n}\n\n#qunit {\n  max-width: 600px;\n"
  },
  {
    "path": "test/index.html",
    "chars": 8745,
    "preview": "<!doctype html>\n<html>\n<head>\n  <meta charset=\"utf-8\">\n\n  <title>imagesLoaded tests</title>\n\n  <link rel=\"stylesheet\" hr"
  },
  {
    "path": "test/unit/append.js",
    "chars": 783,
    "preview": "QUnit.test( 'append', function( assert ) {\n  let imgUrls = [\n    'https://i.imgur.com/bwy74ok.jpg',\n    'https://i.imgur"
  },
  {
    "path": "test/unit/background.js",
    "chars": 2563,
    "preview": "QUnit.test( 'background', function( assert ) {\n  // from Modernizr\n  let supportsMultiBGs = ( function() {\n    let style"
  },
  {
    "path": "test/unit/basics.js",
    "chars": 738,
    "preview": "QUnit.test( 'basics', function( assert ) {\n  let elem = document.querySelector('#basics');\n  let images = elem.querySele"
  },
  {
    "path": "test/unit/data-uri.js",
    "chars": 292,
    "preview": "QUnit.test( 'data-uri', function( assert ) {\n  let done = assert.async();\n  imagesLoaded( '#data-uri', { debug: false } "
  },
  {
    "path": "test/unit/jquery-fail.js",
    "chars": 883,
    "preview": "QUnit.test( 'jquery fail', function( assert ) {\n  let $ = window.jQuery;\n  let $images = $('#jquery-fail img');\n  let do"
  },
  {
    "path": "test/unit/jquery-success.js",
    "chars": 853,
    "preview": "QUnit.test( 'jquery success', function( assert ) {\n  let $ = window.jQuery;\n  let done = assert.async( 6 );\n\n  $('#jquer"
  },
  {
    "path": "test/unit/local-files.js",
    "chars": 876,
    "preview": "QUnit.test( 'local files', function( assert ) {\n  let elem = document.querySelector('#locals');\n  let done = assert.asyn"
  },
  {
    "path": "test/unit/no-images.js",
    "chars": 237,
    "preview": "QUnit.test( 'no images', function( assert ) {\n  let elem = document.querySelector('#no-images');\n  let done = assert.asy"
  },
  {
    "path": "test/unit/non-element.js",
    "chars": 711,
    "preview": "QUnit.test( 'dismiss non-element nodes', function( assert ) {\n  let $ = window.jQuery;\n  let done = assert.async( 2 );\n\n"
  },
  {
    "path": "test/unit/picture.js",
    "chars": 528,
    "preview": "QUnit.test( 'picture', function( assert ) {\n\n  let done = assert.async( 4 );\n\n  let imgLoad0 = imagesLoaded( '#picture-l"
  },
  {
    "path": "test/unit/selector-string.js",
    "chars": 504,
    "preview": "QUnit.test( 'selector string', function( assert ) {\n  let images = document.querySelectorAll('#basics img');\n  let done "
  },
  {
    "path": "test/unit/single-element.js",
    "chars": 378,
    "preview": "QUnit.test( 'single element', function( assert ) {\n  let elem = document.querySelector('#mario-with-shell');\n  let done "
  },
  {
    "path": "test/unit/srcset.js",
    "chars": 501,
    "preview": "QUnit.test( 'srcset', function( assert ) {\n\n  let done = assert.async( 4 );\n\n  let imgLoad0 = imagesLoaded( '#srcset', f"
  }
]

About this extraction

This page contains the full source code of the desandro/imagesloaded GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 32 files (60.0 KB), approximately 18.5k tokens, and a symbol index with 17 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!