# photonic/2.19/include/scripts/third-party/jquery.waitForImages.js

Photonic Gallery &amp; Lightbox for Flickr, SmugMug &amp; Others, version 2.19. 224 lines.

- Page: https://pluginprobe.com/plugins/photonic/2.19/code/include/scripts/third-party/jquery.waitForImages.js
- Raw: https://pluginprobe.com/plugins/photonic/2.19/raw/include/scripts/third-party/jquery.waitForImages.js
- Modified: 2018-11-27T00:03:42+00:00

Line numbers below start at 1. Link to a line or a range by appending a fragment to the
page URL, for example `https://pluginprobe.com/plugins/photonic/2.19/code/include/scripts/third-party/jquery.waitForImages.js#L10-L20`.

```javascript
/*! waitForImages jQuery Plugin - v2.0.2 - 2015-06-02
 * https://github.com/alexanderdickson/waitForImages
 * Copyright (c) 2015 Alex Dickson; Licensed MIT */

;(function (factory) {
	if (typeof define === 'function' && define.amd) {
		// AMD. Register as an anonymous module.
		define(['jquery'], factory);
	} else if (typeof exports === 'object') {
		// CommonJS / nodejs module
		module.exports = factory(require('jquery'));
	} else {
		// Browser globals
		factory(jQuery);
	}
}(function ($) {
	// Namespace all events.
	var eventNamespace = 'waitForImages';

	// CSS properties which contain references to images.
	$.waitForImages = {
		hasImageProperties: [
			'backgroundImage',
			'listStyleImage',
			'borderImage',
			'borderCornerImage',
			'cursor'
		],
		hasImageAttributes: ['srcset']
	};

	// Custom selector to find all `img` elements with a valid `src` attribute.
	$.expr[':']['has-src'] = function (obj) {
		// Ensure we are dealing with an `img` element with a valid
		// `src` attribute.
		return $(obj).is('img[src][src!=""]');
	};

	// Custom selector to find images which are not already cached by the
	// browser.
	$.expr[':'].uncached = function (obj) {
		// Ensure we are dealing with an `img` element with a valid
		// `src` attribute.
		if (!$(obj).is(':has-src')) {
			return false;
		}

		return !obj.complete;
	};

	$.fn.waitForImages = function () {

		var allImgsLength = 0;
		var allImgsLoaded = 0;
		var deferred = $.Deferred();

		var finishedCallback;
		var eachCallback;
		var waitForAll;

		// Handle options object (if passed).
		if ($.isPlainObject(arguments[0])) {

			waitForAll = arguments[0].waitForAll;
			eachCallback = arguments[0].each;
			finishedCallback = arguments[0].finished;

		} else {

			// Handle if using deferred object and only one param was passed in.
			if (arguments.length === 1 && $.type(arguments[0]) === 'boolean') {
				waitForAll = arguments[0];
			} else {
				finishedCallback = arguments[0];
				eachCallback = arguments[1];
				waitForAll = arguments[2];
			}

		}

		// Handle missing callbacks.
		finishedCallback = finishedCallback || $.noop;
		eachCallback = eachCallback || $.noop;

		// Convert waitForAll to Boolean
		waitForAll = !! waitForAll;

		// Ensure callbacks are functions.
		if (!$.isFunction(finishedCallback) || !$.isFunction(eachCallback)) {
			throw new TypeError('An invalid callback was supplied.');
		}

		this.each(function () {
			// Build a list of all imgs, dependent on what images will
			// be considered.
			var obj = $(this);
			var allImgs = [];
			// CSS properties which may contain an image.
			var hasImgProperties = $.waitForImages.hasImageProperties || [];
			// Element attributes which may contain an image.
			var hasImageAttributes = $.waitForImages.hasImageAttributes || [];
			// To match `url()` references.
			// Spec: http://www.w3.org/TR/CSS2/syndata.html#value-def-uri
			var matchUrl = /url\(\s*(['"]?)(.*?)\1\s*\)/g;

			if (waitForAll) {

				// Get all elements (including the original), as any one of
				// them could have a background image.
				obj.find('*').addBack().each(function () {
					var element = $(this);

					// If an `img` element, add it. But keep iterating in
					// case it has a background image too.
					if (element.is('img:has-src')) {
						allImgs.push({
							src: element.attr('src'),
							element: element[0]
						});
					}

					$.each(hasImgProperties, function (i, property) {
						var propertyValue = element.css(property);
						var match;

						// If it doesn't contain this property, skip.
						if (!propertyValue) {
							return true;
						}

						// Get all url() of this element.
						while (match = matchUrl.exec(propertyValue)) {
							allImgs.push({
								src: match[2],
								element: element[0]
							});
						}
					});

					$.each(hasImageAttributes, function (i, attribute) {
						var attributeValue = element.attr(attribute);
						var attributeValues;

						// If it doesn't contain this property, skip.
						if (!attributeValue) {
							return true;
						}

						// Check for multiple comma separated images
						attributeValues = attributeValue.split(',');

						$.each(attributeValues, function(i, value) {
							// Trim value and get string before first
							// whitespace (for use with srcset).
							value = $.trim(value).split(' ')[0];
							allImgs.push({
								src: value,
								element: element[0]
							});
						});
					});
				});
			} else {
				// For images only, the task is simpler.
				obj.find('img:has-src')
					.each(function () {
						allImgs.push({
							src: this.src,
							element: this
						});
					});
			}

			allImgsLength = allImgs.length;
			allImgsLoaded = 0;

			// If no images found, don't bother.
			if (allImgsLength === 0) {
				finishedCallback.call(obj[0]);
				deferred.resolveWith(obj[0]);
			}

			$.each(allImgs, function (i, img) {

				var image = new Image();
				var events =
					'load.' + eventNamespace + ' error.' + eventNamespace;

				// Handle the image loading and error with the same callback.
				$(image).one(events, function me (event) {
					// If an error occurred with loading the image, set the
					// third argument accordingly.
					var eachArguments = [
						allImgsLoaded,
						allImgsLength,
						event.type == 'load'
					];
					allImgsLoaded++;

					eachCallback.apply(img.element, eachArguments);
					deferred.notifyWith(img.element, eachArguments);

					// Unbind the event listeners. I use this in addition to
					// `one` as one of those events won't be called (either
					// 'load' or 'error' will be called).
					$(this).off(events, me);

					if (allImgsLoaded == allImgsLength) {
						finishedCallback.call(obj[0]);
						deferred.resolveWith(obj[0]);
						return false;
					}

				});

				image.src = img.src;
			});
		});

		return deferred.promise();
	};
}));


```
