PluginProbe
Photonic Gallery & Lightbox for Flickr, SmugMug & Others / 2.29
Photonic Gallery & Lightbox for Flickr, SmugMug & Others v2.29
3.36 3.35 3.34 3.33 2.19 2.20 2.21 2.22 2.23 2.24 2.25 2.26 2.27 2.28 2.29 2.30 2.31 2.32 2.33 2.34 2.40 2.41 2.42 2.43 2.44 All 141 releases
photonic / include / scripts / third-party / jquery.waitForImages.js

jquery.waitForImages.js in Photonic Gallery & Lightbox for Flickr, SmugMug & Others 2.29, at include/scripts/third-party/jquery.waitForImages.js

224 lines 6.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 /*! waitForImages jQuery Plugin - v2.0.2 - 2015-06-02
2 * https://github.com/alexanderdickson/waitForImages
3 * Copyright (c) 2015 Alex Dickson; Licensed MIT */
4
5 ;(function (factory) {
6 if (typeof define === 'function' && define.amd) {
7 // AMD. Register as an anonymous module.
8 define(['jquery'], factory);
9 } else if (typeof exports === 'object') {
10 // CommonJS / nodejs module
11 module.exports = factory(require('jquery'));
12 } else {
13 // Browser globals
14 factory(jQuery);
15 }
16 }(function ($) {
17 // Namespace all events.
18 var eventNamespace = 'waitForImages';
19
20 // CSS properties which contain references to images.
21 $.waitForImages = {
22 hasImageProperties: [
23 'backgroundImage',
24 'listStyleImage',
25 'borderImage',
26 'borderCornerImage',
27 'cursor'
28 ],
29 hasImageAttributes: ['srcset']
30 };
31
32 // Custom selector to find all `img` elements with a valid `src` attribute.
33 $.expr[':']['has-src'] = function (obj) {
34 // Ensure we are dealing with an `img` element with a valid
35 // `src` attribute.
36 return $(obj).is('img[src][src!=""]');
37 };
38
39 // Custom selector to find images which are not already cached by the
40 // browser.
41 $.expr[':'].uncached = function (obj) {
42 // Ensure we are dealing with an `img` element with a valid
43 // `src` attribute.
44 if (!$(obj).is(':has-src')) {
45 return false;
46 }
47
48 return !obj.complete;
49 };
50
51 $.fn.waitForImages = function () {
52
53 var allImgsLength = 0;
54 var allImgsLoaded = 0;
55 var deferred = $.Deferred();
56
57 var finishedCallback;
58 var eachCallback;
59 var waitForAll;
60
61 // Handle options object (if passed).
62 if ($.isPlainObject(arguments[0])) {
63
64 waitForAll = arguments[0].waitForAll;
65 eachCallback = arguments[0].each;
66 finishedCallback = arguments[0].finished;
67
68 } else {
69
70 // Handle if using deferred object and only one param was passed in.
71 if (arguments.length === 1 && $.type(arguments[0]) === 'boolean') {
72 waitForAll = arguments[0];
73 } else {
74 finishedCallback = arguments[0];
75 eachCallback = arguments[1];
76 waitForAll = arguments[2];
77 }
78
79 }
80
81 // Handle missing callbacks.
82 finishedCallback = finishedCallback || $.noop;
83 eachCallback = eachCallback || $.noop;
84
85 // Convert waitForAll to Boolean
86 waitForAll = !! waitForAll;
87
88 // Ensure callbacks are functions.
89 if (!$.isFunction(finishedCallback) || !$.isFunction(eachCallback)) {
90 throw new TypeError('An invalid callback was supplied.');
91 }
92
93 this.each(function () {
94 // Build a list of all imgs, dependent on what images will
95 // be considered.
96 var obj = $(this);
97 var allImgs = [];
98 // CSS properties which may contain an image.
99 var hasImgProperties = $.waitForImages.hasImageProperties || [];
100 // Element attributes which may contain an image.
101 var hasImageAttributes = $.waitForImages.hasImageAttributes || [];
102 // To match `url()` references.
103 // Spec: http://www.w3.org/TR/CSS2/syndata.html#value-def-uri
104 var matchUrl = /url\(\s*(['"]?)(.*?)\1\s*\)/g;
105
106 if (waitForAll) {
107
108 // Get all elements (including the original), as any one of
109 // them could have a background image.
110 obj.find('*').addBack().each(function () {
111 var element = $(this);
112
113 // If an `img` element, add it. But keep iterating in
114 // case it has a background image too.
115 if (element.is('img:has-src')) {
116 allImgs.push({
117 src: element.attr('src'),
118 element: element[0]
119 });
120 }
121
122 $.each(hasImgProperties, function (i, property) {
123 var propertyValue = element.css(property);
124 var match;
125
126 // If it doesn't contain this property, skip.
127 if (!propertyValue) {
128 return true;
129 }
130
131 // Get all url() of this element.
132 while (match = matchUrl.exec(propertyValue)) {
133 allImgs.push({
134 src: match[2],
135 element: element[0]
136 });
137 }
138 });
139
140 $.each(hasImageAttributes, function (i, attribute) {
141 var attributeValue = element.attr(attribute);
142 var attributeValues;
143
144 // If it doesn't contain this property, skip.
145 if (!attributeValue) {
146 return true;
147 }
148
149 // Check for multiple comma separated images
150 attributeValues = attributeValue.split(',');
151
152 $.each(attributeValues, function(i, value) {
153 // Trim value and get string before first
154 // whitespace (for use with srcset).
155 value = $.trim(value).split(' ')[0];
156 allImgs.push({
157 src: value,
158 element: element[0]
159 });
160 });
161 });
162 });
163 } else {
164 // For images only, the task is simpler.
165 obj.find('img:has-src')
166 .each(function () {
167 allImgs.push({
168 src: this.src,
169 element: this
170 });
171 });
172 }
173
174 allImgsLength = allImgs.length;
175 allImgsLoaded = 0;
176
177 // If no images found, don't bother.
178 if (allImgsLength === 0) {
179 finishedCallback.call(obj[0]);
180 deferred.resolveWith(obj[0]);
181 }
182
183 $.each(allImgs, function (i, img) {
184
185 var image = new Image();
186 var events =
187 'load.' + eventNamespace + ' error.' + eventNamespace;
188
189 // Handle the image loading and error with the same callback.
190 $(image).one(events, function me (event) {
191 // If an error occurred with loading the image, set the
192 // third argument accordingly.
193 var eachArguments = [
194 allImgsLoaded,
195 allImgsLength,
196 event.type == 'load'
197 ];
198 allImgsLoaded++;
199
200 eachCallback.apply(img.element, eachArguments);
201 deferred.notifyWith(img.element, eachArguments);
202
203 // Unbind the event listeners. I use this in addition to
204 // `one` as one of those events won't be called (either
205 // 'load' or 'error' will be called).
206 $(this).off(events, me);
207
208 if (allImgsLoaded == allImgsLength) {
209 finishedCallback.call(obj[0]);
210 deferred.resolveWith(obj[0]);
211 return false;
212 }
213
214 });
215
216 image.src = img.src;
217 });
218 });
219
220 return deferred.promise();
221 };
222 }));
223
224