1;(function ($) { 2 // Namespace all events. 3 var eventNamespace = 'waitForImages'; 4 5 // CSS properties which contain references to images. 6 $.waitForImages = { 7 hasImageProperties: ['backgroundImage', 'listStyleImage', 'borderImage', 'borderCornerImage', 'cursor'] 8 }; 9 10 // Custom selector to find `img` elements that have a valid `src` attribute and have not already loaded. 11 $.expr[':'].uncached = function (obj) { 12 // Ensure we are dealing with an `img` element with a valid `src` attribute. 13 if (!$(obj).is('img[src!=""]')) { 14 return false; 15 } 16 17 // Firefox's `complete` property will always be `true` even if the image has not been downloaded. 18 // Doing it this way works in Firefox. 19 var img = new Image(); 20 img.src = obj.src; 21 return !img.complete; 22 }; 23 24 $.fn.waitForImages = function (finishedCallback, eachCallback, waitForAll) { 25 26 var allImgsLength = 0; 27 var allImgsLoaded = 0; 28 29 // Handle options object. 30 if ($.isPlainObject(arguments[0])) { 31 waitForAll = arguments[0].waitForAll; 32 eachCallback = arguments[0].each; 33 // This must be last as arguments[0] 34 // is aliased with finishedCallback. 35 finishedCallback = arguments[0].finished; 36 } 37 38 // Handle missing callbacks. 39 finishedCallback = finishedCallback || $.noop; 40 eachCallback = eachCallback || $.noop; 41 42 // Convert waitForAll to Boolean 43 waitForAll = !! waitForAll; 44 45 // Ensure callbacks are functions. 46 if (!$.isFunction(finishedCallback) || !$.isFunction(eachCallback)) { 47 throw new TypeError('An invalid callback was supplied.'); 48 } 49 50 return this.each(function () { 51 // Build a list of all imgs, dependent on what images will be considered. 52 var obj = $(this); 53 var allImgs = []; 54 // CSS properties which may contain an image. 55 var hasImgProperties = $.waitForImages.hasImageProperties || []; 56 // To match `url()` references. 57 // Spec: http://www.w3.org/TR/CSS2/syndata.html#value-def-uri 58 var matchUrl = /url\(\s*(['"]?)(.*?)\1\s*\)/g; 59 60 if (waitForAll) { 61 62 // Get all elements (including the original), as any one of them could have a background image. 63 obj.find('*').addBack().each(function () { 64 var element = $(this); 65 66 // If an `img` element, add it. But keep iterating in case it has a background image too. 67 if (element.is('img:uncached')) { 68 allImgs.push({ 69 src: element.attr('src'), 70 element: element[0] 71 }); 72 } 73 74 $.each(hasImgProperties, function (i, property) { 75 var propertyValue = element.css(property); 76 var match; 77 78 // If it doesn't contain this property, skip. 79 if (!propertyValue) { 80 return true; 81 } 82 83 // Get all url() of this element. 84 while (match = matchUrl.exec(propertyValue)) { 85 allImgs.push({ 86 src: match[2], 87 element: element[0] 88 }); 89 } 90 }); 91 }); 92 } else { 93 // For images only, the task is simpler. 94 obj.find('img:uncached') 95 .each(function () { 96 allImgs.push({ 97 src: this.src, 98 element: this 99 }); 100 }); 101 } 102 103 allImgsLength = allImgs.length; 104 allImgsLoaded = 0; 105 106 // If no images found, don't bother. 107 if (allImgsLength === 0) { 108 finishedCallback.call(obj[0]); 109 } 110 111 $.each(allImgs, function (i, img) { 112 113 var image = new Image(); 114 115 // Handle the image loading and error with the same callback. 116 $(image).on('load.' + eventNamespace + ' error.' + eventNamespace, function (event) { 117 allImgsLoaded++; 118 119 // If an error occurred with loading the image, set the third argument accordingly. 120 eachCallback.call(img.element, allImgsLoaded, allImgsLength, event.type == 'load'); 121 122 if (allImgsLoaded == allImgsLength) { 123 finishedCallback.call(obj[0]); 124 return false; 125 } 126 127 }); 128 129 image.src = img.src; 130 }); 131 }); 132 }; 133}(jQuery));
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.