MDL-9137 Fixing errors in the overview report
[moodle-pu.git] / lib / yui / imageloader / imageloader-experimental-debug.js
blob55b85c5efd6ee3e9042338b1298d700382c42f88
1 /*
2 Copyright (c) 2007, Yahoo! Inc. All rights reserved.
3 Code licensed under the BSD License:
4 http://developer.yahoo.net/yui/license.txt
5 version: 2.3.0
6 */
7 /**
8  * The image loader is a framework to dynamically load images
9  * according to certain triggers, enabling faster load times
10  * and a more responsive UI.
11  *
12  * @module imageloader
13  * @namespace YAHOO.util
14  * @experimental
15  */
17 if (typeof(YAHOO.util.ImageLoader) == 'undefined') {
18         YAHOO.util.ImageLoader = {};
21 /**
22  * A group for images. A group can have one time limit and a series of triggers. Thus the images belonging to this group must share these constraints.
23  * @class YAHOO.util.ImageLoader.group
24  * @requires YAHOO.util.Dom
25  * @requires YAHOO.util.Event
26  * @constructor
27  * @param {String|HTMLElement}  trigEl  The HTML element id or reference to assign the trigger event to. Can be null for no trigger
28  * @param {String}      trigAct The type of event to assign to trigEl. Can be null for no trigger
29  * @param {Number}      timeout Timeout (time limit) length, in seconds. Can be undefined, or <= 0, for no time limit
30  */
31 YAHOO.util.ImageLoader.group = function(trigEl, trigAct, timeout) {
32         /**
33          * Name for the group. Only used to identify the group in logging statements
34          * @property name
35          * @type String
36          */
37         this.name = 'unnamed';
38         
39         /**
40          * Collection of images registered with this group
41          * @property _imgObjs
42          * @private
43          * @type Object
44          */
45         this._imgObjs = {};
46         
47         /**
48          * Timeout (time limit) length, in seconds
49          * @property timeoutLen
50          * @type Number
51          */
52         this.timeoutLen = timeout;
53         
54         /**
55          * Timeout object to keep a handle on the time limit
56          * @property _timeout
57          * @private
58          * @type Object
59          */
60         this._timeout = null;
61         
62         /**
63          * Collection of triggers for this group.
64          * Keeps track of each trigger's element, event, and event-listener-callback "fetch" function
65          * @property _triggers
66          * @private
67          * @type Array
68          */
69         this._triggers = [];
71         /**
72          * Flag to check if images are above the fold. If foldConditional is true, the group will check each of its image locations at page load. If any part of the image is within the client viewport, the image is displayed immediately
73          * @property foldConditional
74          * @type Boolean
75          */
76         this.foldConditional = false;
78         /**
79          * Class name that will identify images belonging to the group. This class name will be removed from each element in order to fetch images.
80          * This class should have, in its CSS style definition, "background:none !important;"
81          * @property className
82          * @type String
83          */
84         this.className = null;
86         /**
87          * HTML elements having the class name that is associated with this group
88          * Elements are stored during the _foldCheck function and reused later during the fetch function. Gives a slight performance improvement when className and foldConditional are both used
89          * @property _classImageEls
90          * @private
91          * @type Array
92          */
93         this._classImageEls = null;
95         // add a listener to set the time limit in the onload
96         YAHOO.util.Event.addListener(window, 'load', this._onloadTasks, this, true);
97         // add the trigger
98         this.addTrigger(trigEl, trigAct);
103  * Adds a trigger to the group. Call this with the same style as YAHOO.util.Event.addListener
104  * @method addTrigger
105  * @param {String|HTMLElement} trigEl  The HTML element id or reference to assign the trigger event to
106  * @param {String} trigAct The type of event to assign to trigEl
107  */
108 YAHOO.util.ImageLoader.group.prototype.addTrigger = function(trigEl, trigAct) {
109         if (! trigEl || ! trigAct) {
110                 return;
111         }
112         /* Need to wrap the fetch function. Event Util can't distinguish prototyped functions of different instantiations
113          *   Leads to this scenario: groupA and groupZ both have window-scroll triggers. groupZ also has a 2-sec timeout (groupA has no timeout).
114          *   groupZ's timeout fires; we remove the triggers. The removeListener call finds the first window-scroll event with Y.u.IL.p.fetch, which is groupA's. 
115          *   groupA's trigger is removed and never fires, leaving images unfetched
116          */
117         var wrappedFetch = function() {
118                 this.fetch();
119         };
120         this._triggers.push([trigEl, trigAct, wrappedFetch]);
121         YAHOO.util.Event.addListener(trigEl, trigAct, wrappedFetch, this, true);
125  * Setup to do in the window's onload
126  * Initiates time limit for group; executes the fold check for the images
127  * @method _onloadTasks
128  * @private
129  */
130 YAHOO.util.ImageLoader.group.prototype._onloadTasks = function() {
131         if (this.timeoutLen && typeof(this.timeoutLen) == 'number' && this.timeoutLen > 0) {
132                 this._timeout = setTimeout(this._getFetchTimeout(), this.timeoutLen * 1000);
133         }
135         if (this.foldConditional) {
136                 this._foldCheck();
137         }
141  * Returns the group's fetch method, with the proper closure, for use with setTimeout
142  * @method _getFetchTimeout
143  * @return {Function}  group's fetch method
144  * @private
145  */
146 YAHOO.util.ImageLoader.group.prototype._getFetchTimeout = function() {
147         var self = this;
148         return function() { self.fetch(); };
152  * Registers a background image with the group
153  * @method registerBgImage
154  * @param {String}      domId   HTML DOM id of the image element
155  * @param {String}      url     URL for the image
156  * @return {Object}     bgImgObj that was registered, for modifying any attributes in the object
157  */
158 YAHOO.util.ImageLoader.group.prototype.registerBgImage = function(domId, url) {
159         this._imgObjs[domId] = new YAHOO.util.ImageLoader.bgImgObj(domId, url);
160         return this._imgObjs[domId];
163  * Registers a src image with the group
164  * @method registerSrcImage
165  * @param {String}      domId   HTML DOM id of the image element
166  * @param {String}      url     URL for the image
167  * @param {Int} width   pixel width of the image - defaults to image's natural size
168  * @param {Int} height  pixel height of the image - defaults to image's natural size
169  * @return {Object}     srcImgObj that was registered, for modifying any attributes in the object
170  */
171 YAHOO.util.ImageLoader.group.prototype.registerSrcImage = function(domId, url, width, height) {
172         this._imgObjs[domId] = new YAHOO.util.ImageLoader.srcImgObj(domId, url, width, height);
173         return this._imgObjs[domId];
176  * Registers an alpha-channel-type png background image with the group
177  * @method registerPngBgImage
178  * @param {String}      domId   HTML DOM id of the image element
179  * @param {String}      url     URL for the image
180  * @return {Object}     pngBgImgObj that was registered, for modifying any attributes in the object
181  */
182 YAHOO.util.ImageLoader.group.prototype.registerPngBgImage = function(domId, url) {
183         this._imgObjs[domId] = new YAHOO.util.ImageLoader.pngBgImgObj(domId, url);
184         return this._imgObjs[domId];
188  * Displays the images in the group
189  * @method fetch
190  */
191 YAHOO.util.ImageLoader.group.prototype.fetch = function() {
192         YAHOO.log('Fetching images in group: "' + this.name + '".', 'info', 'imageloader');
194         clearTimeout(this._timeout);
195         // remove all listeners
196         for (var i=0; i < this._triggers.length; i++) {
197                 YAHOO.util.Event.removeListener(this._triggers[i][0], this._triggers[i][1], this._triggers[i][2]);
198         }
200         // fetch whatever we need to by className
201         this._fetchByClass();
203         // fetch registered images
204         for (var id in this._imgObjs) {
205                 if (YAHOO.lang.hasOwnProperty(this._imgObjs, id)) {
206                         this._imgObjs[id].fetch();
207                 }
208         }
212  * Checks the position of each image in the group. If any part of the image is within the client viewport, shows the image immediately.
213  * @method _foldCheck
214  * @private
215  */
216 YAHOO.util.ImageLoader.group.prototype._foldCheck = function() {
217         YAHOO.log('Checking for images above the fold in group: "' + this.name + '"', 'info', 'imageloader');
218         var scrollTop = (document.compatMode != 'CSS1Compat') ? document.body.scrollTop : document.documentElement.scrollTop;
219         var viewHeight = YAHOO.util.Dom.getViewportHeight();
220         var hLimit = scrollTop + viewHeight;
221         var scrollLeft = (document.compatMode != 'CSS1Compat') ? document.body.scrollLeft : document.documentElement.scrollLeft;
222         var viewWidth = YAHOO.util.Dom.getViewportWidth();
223         var wLimit = scrollLeft + viewWidth;
224         for (var id in this._imgObjs) {
225                 if (YAHOO.lang.hasOwnProperty(this._imgObjs, id)) {
226                         var elPos = YAHOO.util.Dom.getXY(this._imgObjs[id].domId);
227                         if (elPos[1] < hLimit && elPos[0] < wLimit) {
228                                 YAHOO.log('Image with id "' + this._imgObjs[id].domId + '" is above the fold. Fetching image.', 'info', 'imageloader');
229                                 this._imgObjs[id].fetch();
230                         }
231                 }
232         }
233         // and by class
234         if (this.className) {
235                 this._classImageEls = YAHOO.util.Dom.getElementsByClassName(this.className);
236                 for (var i=0; i < this._classImageEls.length; i++) {
237                         var elPos = YAHOO.util.Dom.getXY(this._classImageEls[i]);
238                         if (elPos[1] < hLimit && elPos[0] < wLimit) {
239                                 YAHOO.log('Image with id "' + this._classImageEls[i].id + '" is above the fold. Fetching image. (Image registered by class name with the group - may not have an id.)', 'info', 'imageloader');
240                                 YAHOO.util.Dom.removeClass(this._classImageEls[i], this.className);
241                         }
242                 }
243         }
247  * Finds all elements in the Dom with the class name specified in the group. Removes the class from the element in order to let the style definitions trigger the image fetching
248  * @method _fetchByClass
249  * @private
250  */
251 YAHOO.util.ImageLoader.group.prototype._fetchByClass = function() {
252         if (! this.className) {
253                 return;
254         }
256         YAHOO.log('Fetching all images with class "' + this.className + '" in group "' + this.name + '".', 'info', 'imageloader');
257         // this._classImageEls may have been set during _foldCheck
258         if (this._classImageEls === null) {
259                 this._classImageEls = YAHOO.util.Dom.getElementsByClassName(this.className);
260         }
261         YAHOO.util.Dom.removeClass(this._classImageEls, this.className);
266  * Base class for image objects to be registered with the groups
267  * @class YAHOO.util.ImageLoader.imgObj
268  * @constructor
269  * @param {String}      domId   HTML DOM id of the image element
270  * @param {String}      url     URL for the image
271  */
272 YAHOO.util.ImageLoader.imgObj = function(domId, url) {
273         /**
274          * HTML DOM id of the image element
275          * @property domId
276          * @type String
277          */
278         this.domId = domId;
280         /**
281          * URL for the image
282          * @property url
283          * @type String
284          */
285         this.url = url;
287         /**
288          * Pixel width of the image. Will be set as a "width" attribute after the image is fetched.
289          * Detaults to the natural width of the image.
290          * Only appropriate with src images
291          * @property width
292          * @type Int
293          */
294         this.width = null;
296         /**
297          * Pixel height of the image. Will be set as a "height" attribute after the image is fetched.
298          * Detaults to the natural height of the image.
299          * Only appropriate with src images
300          * @property height
301          * @type Int
302          */
303         this.height = null;
305         /**
306          * Whether the style.visibility should be set to "visible" after the image is fetched.
307          * Used when setting src images as visibility:hidden prior to image fetching
308          * @property setVisible
309          * @type Boolean
310          */
311         this.setVisible = false;
313         /**
314          * Whether the image has already been fetched. In the case of a foldCondional group, keeps track for when the trigger is fired so images aren't fetched twice
315          * @property _fetched
316          * @type Boolean
317          * @private
318          */
319         this._fetched = false;
323  * Displays the image; puts the URL into the DOM
324  * @method fetch
325  */
326 YAHOO.util.ImageLoader.imgObj.prototype.fetch = function() {
327         if (this._fetched) {
328                 return;
329         }
330         var el = document.getElementById(this.domId);
331         if (! el) {
332                 return;
333         }
334         YAHOO.log('Fetching image with id "' + this.domId + '".', 'info', 'imageloader');
335         this._applyUrl(el);
337         if (this.setVisible) {
338                 el.style.visibility = 'visible';
339         }
340         if (this.width) {
341                 el.width = this.width;
342         }
343         if (this.height) {
344                 el.height = this.height;
345         }
346         this._fetched = true;
350  * Inserts the image URL into the DOM so that the image is displayed.
351  * Must be overridden by child class
352  * @method _applyUrl
353  * @param {Object}      el      HTML DOM element
354  * @private
355  */
356 YAHOO.util.ImageLoader.imgObj.prototype._applyUrl = function(el) {
360  * Background image object. A background image is one whose URL is specified by "background-image" in the element's style
361  * @class YAHOO.util.ImageLoader.bgImgObj
362  * @constructor
363  * @extends YAHOO.util.ImageLoader.imgObj
364  * @param {String}      domId   HTML DOM id of the image element
365  * @param {String}      url     URL for the image
366  */
367 YAHOO.util.ImageLoader.bgImgObj = function(domId, url) {
368         YAHOO.util.ImageLoader.bgImgObj.superclass.constructor.call(this, domId, url);
371 YAHOO.lang.extend(YAHOO.util.ImageLoader.bgImgObj, YAHOO.util.ImageLoader.imgObj);
374  * Inserts the image URL into the DOM so that the image is displayed.
375  * Sets style.backgroundImage
376  * @method _applyUrl
377  * @param {Object}      el      HTML DOM element
378  * @private
379  */
380 YAHOO.util.ImageLoader.bgImgObj.prototype._applyUrl = function(el) {
381         el.style.backgroundImage = "url('" + this.url + "')";
385  * Source image object. A source image is one whose URL is specified by a src attribute in the DOM element
386  * @class YAHOO.util.ImageLoader.srcImgObj
387  * @constructor
388  * @extends YAHOO.util.ImageLoader.imgObj
389  * @param {String}      domId   HTML DOM id of the image element
390  * @param {String}      url     URL for the image
391  * @param {Int} width   pixel width of the image - defaults to image's natural size
392  * @param {Int} height  pixel height of the image - defaults to image's natural size
393  */
394 YAHOO.util.ImageLoader.srcImgObj = function(domId, url, width, height) {
395         YAHOO.util.ImageLoader.srcImgObj.superclass.constructor.call(this, domId, url);
396         this.width = width;
397         this.height = height;
400 YAHOO.lang.extend(YAHOO.util.ImageLoader.srcImgObj, YAHOO.util.ImageLoader.imgObj);
403  * Inserts the image URL into the DOM so that the image is displayed.
404  * Sets src
405  * @method _applyUrl
406  * @param {Object}      el      HTML DOM element
407  * @private
408  */
409 YAHOO.util.ImageLoader.srcImgObj.prototype._applyUrl = function(el) {
410         el.src = this.url;
414  * PNG background image object. A PNG background image is one whose URL is specified through AlphaImageLoader or by "background-image" in the element's style
415  * @class YAHOO.util.ImageLoader.pngBgImgObj
416  * @constructor
417  * @extends YAHOO.util.ImageLoader.imgObj
418  * @param {String}      domId   HTML DOM id of the image element
419  * @param {String}      url     URL for the image
420  */
421 YAHOO.util.ImageLoader.pngBgImgObj = function(domId, url) {
422         YAHOO.util.ImageLoader.pngBgImgObj.superclass.constructor.call(this, domId, url);
425 YAHOO.lang.extend(YAHOO.util.ImageLoader.pngBgImgObj, YAHOO.util.ImageLoader.imgObj);
428  * Inserts the image URL into the DOM so that the image is displayed.
429  * If the browser is determined to be IE6 (or older), sets the AlphaImageLoader src; otherwise sets style.backgroundImage
430  * @method _applyUrl
431  * @param {Object}      el      HTML DOM element
432  * @private
433  */
434 YAHOO.util.ImageLoader.pngBgImgObj.prototype._applyUrl = function(el) {
435         if (YAHOO.env.ua.ie && YAHOO.env.ua.ie <= 6) {
436                 el.style.filter = 'progid:DXImageTransform.Microsoft.AlphaImageLoader(src="' + this.url + '", sizingMethod="scale")';
437         }
438         else {
439                 el.style.backgroundImage = "url('" + this.url + "')";
440         }
442 YAHOO.register("imageloader", YAHOO.util.ImageLoader, {version: "2.3.0", build: "442"});