comparison pylons_app/public/js/yui/imageloader/imageloader-debug.js @ 0:564e40829f80

initial commit.
author Marcin Kuzminski
date Thu, 18 Feb 2010 13:01:57 +0100
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:564e40829f80
1 /*
2 Copyright (c) 2009, Yahoo! Inc. All rights reserved.
3 Code licensed under the BSD License:
4 http://developer.yahoo.net/yui/license.txt
5 version: 2.8.0r4
6 */
7 /**
8 * The ImageLoader Utility is a framework to dynamically load images according to certain triggers,
9 * enabling faster load times and a more responsive UI.
10 *
11 * @module imageloader
12 * @namespace YAHOO.util
13 * @requires yahoo, dom, event
14 */
15
16 if (typeof(YAHOO.util.ImageLoader) == 'undefined') {
17 YAHOO.util.ImageLoader = {};
18 }
19
20 /**
21 * 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.
22 * @class YAHOO.util.ImageLoader.group
23 * @requires YAHOO.util.Dom
24 * @requires YAHOO.util.Event
25 * @constructor
26 * @param {String|HTMLElement} trigEl The HTML element id or reference to assign the trigger event to. Can be null for no trigger
27 * @param {String} trigAct The type of event to assign to trigEl. Can be null for no trigger
28 * @param {Number} timeout Timeout (time limit) length, in seconds. Can be undefined, or <= 0, for no time limit
29 */
30 YAHOO.util.ImageLoader.group = function(trigEl, trigAct, timeout) {
31 /**
32 * Name for the group. Only used to identify the group in logging statements
33 * @property name
34 * @type String
35 */
36 this.name = 'unnamed';
37
38 /**
39 * Collection of images registered with this group
40 * @property _imgObjs
41 * @private
42 * @type Object
43 */
44 this._imgObjs = {};
45
46 /**
47 * Timeout (time limit) length, in seconds
48 * @property timeoutLen
49 * @type Number
50 */
51 this.timeoutLen = timeout;
52
53 /**
54 * Timeout object to keep a handle on the time limit
55 * @property _timeout
56 * @private
57 * @type Object
58 */
59 this._timeout = null;
60
61 /**
62 * Collection of triggers for this group.
63 * Keeps track of each trigger's element, event, and event-listener-callback "fetch" function
64 * @property _triggers
65 * @private
66 * @type Array
67 */
68 this._triggers = [];
69
70 /**
71 * Collection of custom-event triggers for this group.
72 * Keeps track of each trigger's event object and event-listener-callback "fetch" function
73 * @property _customTriggers
74 * @private
75 * @type Array
76 */
77 this._customTriggers = [];
78
79 /**
80 * 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
81 * @property foldConditional
82 * @type Boolean
83 */
84 this.foldConditional = false;
85
86 /**
87 * Class name that will identify images belonging to the group. This class name will be removed from each element in order to fetch images.
88 * This class should have, in its CSS style definition, "background:none !important;"
89 * @property className
90 * @type String
91 */
92 this.className = null;
93
94 /**
95 * HTML elements having the class name that is associated with this group
96 * 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
97 * @property _classImageEls
98 * @private
99 * @type Array
100 */
101 this._classImageEls = null;
102
103 // add a listener to set the time limit in the onload
104 YAHOO.util.Event.addListener(window, 'load', this._onloadTasks, this, true);
105 // add the trigger
106 this.addTrigger(trigEl, trigAct);
107
108 };
109
110 /**
111 * Adds a trigger to the group. Call this with the same style as YAHOO.util.Event.addListener
112 * @method addTrigger
113 * @param {String|HTMLElement} trigEl The HTML element id or reference to assign the trigger event to
114 * @param {String} trigAct The type of event to assign to trigEl
115 */
116 YAHOO.util.ImageLoader.group.prototype.addTrigger = function(trigEl, trigAct) {
117 if (! trigEl || ! trigAct) {
118 return;
119 }
120 /* Need to wrap the fetch function. Event Util can't distinguish prototyped functions of different instantiations
121 * Leads to this scenario: groupA and groupZ both have window-scroll triggers. groupZ also has a 2-sec timeout (groupA has no timeout).
122 * 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.
123 * groupA's trigger is removed and never fires, leaving images unfetched
124 */
125 var wrappedFetch = function() {
126 this.fetch();
127 };
128 this._triggers.push([trigEl, trigAct, wrappedFetch]);
129 YAHOO.util.Event.addListener(trigEl, trigAct, wrappedFetch, this, true);
130 };
131
132 /**
133 * Adds a custom event trigger to the group.
134 * @method addCustomTrigger
135 * @param {Object} event A YAHOO.util.CustomEvent object
136 */
137 YAHOO.util.ImageLoader.group.prototype.addCustomTrigger = function(event) {
138 // make sure we're dealing with a CustomEvent object
139 if (! event || ! event instanceof YAHOO.util.CustomEvent) {
140 return;
141 }
142
143 // see comment in addTrigger()
144 var wrappedFetch = function() {
145 this.fetch();
146 };
147 this._customTriggers.push([event, wrappedFetch]);
148 event.subscribe(wrappedFetch, this, true);
149 };
150
151 /**
152 * Setup to do in the window's onload
153 * Initiates time limit for group; executes the fold check for the images
154 * @method _onloadTasks
155 * @private
156 */
157 YAHOO.util.ImageLoader.group.prototype._onloadTasks = function() {
158 if (this.timeoutLen && typeof(this.timeoutLen) == 'number' && this.timeoutLen > 0) {
159 this._timeout = setTimeout(this._getFetchTimeout(), this.timeoutLen * 1000);
160 }
161
162 if (this.foldConditional) {
163 this._foldCheck();
164 }
165 };
166
167 /**
168 * Returns the group's fetch method, with the proper closure, for use with setTimeout
169 * @method _getFetchTimeout
170 * @return {Function} group's fetch method
171 * @private
172 */
173 YAHOO.util.ImageLoader.group.prototype._getFetchTimeout = function() {
174 var self = this;
175 return function() { self.fetch(); };
176 };
177
178 /**
179 * Registers a background image with the group
180 * @method registerBgImage
181 * @param {String} domId HTML DOM id of the image element
182 * @param {String} url URL for the image
183 * @return {Object} bgImgObj that was registered, for modifying any attributes in the object
184 */
185 YAHOO.util.ImageLoader.group.prototype.registerBgImage = function(domId, url) {
186 this._imgObjs[domId] = new YAHOO.util.ImageLoader.bgImgObj(domId, url);
187 return this._imgObjs[domId];
188 };
189 /**
190 * Registers a src image with the group
191 * @method registerSrcImage
192 * @param {String} domId HTML DOM id of the image element
193 * @param {String} url URL for the image
194 * @param {Int} width pixel width of the image - defaults to image's natural size
195 * @param {Int} height pixel height of the image - defaults to image's natural size
196 * @return {Object} srcImgObj that was registered, for modifying any attributes in the object
197 */
198 YAHOO.util.ImageLoader.group.prototype.registerSrcImage = function(domId, url, width, height) {
199 this._imgObjs[domId] = new YAHOO.util.ImageLoader.srcImgObj(domId, url, width, height);
200 return this._imgObjs[domId];
201 };
202 /**
203 * Registers an alpha-channel-type png background image with the group
204 * @method registerPngBgImage
205 * @param {String} domId HTML DOM id of the image element
206 * @param {String} url URL for the image
207 * @param {Object} ailProps The AlphaImageLoader properties to be set for the image
208 * Valid properties are 'sizingMethod' and 'enabled'
209 * @return {Object} pngBgImgObj that was registered, for modifying any attributes in the object
210 */
211 YAHOO.util.ImageLoader.group.prototype.registerPngBgImage = function(domId, url, ailProps) {
212 this._imgObjs[domId] = new YAHOO.util.ImageLoader.pngBgImgObj(domId, url, ailProps);
213 return this._imgObjs[domId];
214 };
215
216 /**
217 * Displays the images in the group
218 * @method fetch
219 */
220 YAHOO.util.ImageLoader.group.prototype.fetch = function() {
221 YAHOO.log('Fetching images in group: "' + this.name + '".', 'info', 'imageloader');
222
223 clearTimeout(this._timeout);
224 // remove all listeners
225 for (var i=0, len = this._triggers.length; i < len; i++) {
226 YAHOO.util.Event.removeListener(this._triggers[i][0], this._triggers[i][1], this._triggers[i][2]);
227 }
228 // remove custom event subscriptions
229 for (var i=0, len = this._customTriggers.length; i < len; i++) {
230 this._customTriggers[i][0].unsubscribe(this._customTriggers[i][1], this);
231 }
232
233 // fetch whatever we need to by className
234 this._fetchByClass();
235
236 // fetch registered images
237 for (var id in this._imgObjs) {
238 if (YAHOO.lang.hasOwnProperty(this._imgObjs, id)) {
239 this._imgObjs[id].fetch();
240 }
241 }
242 };
243
244 /**
245 * Checks the position of each image in the group. If any part of the image is within the client viewport, shows the image immediately.
246 * @method _foldCheck
247 * @private
248 */
249 YAHOO.util.ImageLoader.group.prototype._foldCheck = function() {
250 YAHOO.log('Checking for images above the fold in group: "' + this.name + '"', 'info', 'imageloader');
251 var scrollTop = (document.compatMode != 'CSS1Compat') ? document.body.scrollTop : document.documentElement.scrollTop;
252 var viewHeight = YAHOO.util.Dom.getViewportHeight();
253 var hLimit = scrollTop + viewHeight;
254 var scrollLeft = (document.compatMode != 'CSS1Compat') ? document.body.scrollLeft : document.documentElement.scrollLeft;
255 var viewWidth = YAHOO.util.Dom.getViewportWidth();
256 var wLimit = scrollLeft + viewWidth;
257 for (var id in this._imgObjs) {
258 if (YAHOO.lang.hasOwnProperty(this._imgObjs, id)) {
259 var elPos = YAHOO.util.Dom.getXY(this._imgObjs[id].domId);
260 if (elPos[1] < hLimit && elPos[0] < wLimit) {
261 YAHOO.log('Image with id "' + this._imgObjs[id].domId + '" is above the fold. Fetching image.', 'info', 'imageloader');
262 this._imgObjs[id].fetch();
263 }
264 }
265 }
266 // and by class
267 if (this.className) {
268 this._classImageEls = YAHOO.util.Dom.getElementsByClassName(this.className);
269 for (var i=0, len = this._classImageEls.length; i < len; i++) {
270 var elPos = YAHOO.util.Dom.getXY(this._classImageEls[i]);
271 if (elPos[1] < hLimit && elPos[0] < wLimit) {
272 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');
273 YAHOO.util.Dom.removeClass(this._classImageEls[i], this.className);
274 }
275 }
276 }
277 };
278
279 /**
280 * 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
281 * @method _fetchByClass
282 * @private
283 */
284 YAHOO.util.ImageLoader.group.prototype._fetchByClass = function() {
285 if (! this.className) {
286 return;
287 }
288
289 YAHOO.log('Fetching all images with class "' + this.className + '" in group "' + this.name + '".', 'info', 'imageloader');
290 // this._classImageEls may have been set during _foldCheck
291 if (this._classImageEls === null) {
292 this._classImageEls = YAHOO.util.Dom.getElementsByClassName(this.className);
293 }
294 YAHOO.util.Dom.removeClass(this._classImageEls, this.className);
295 };
296
297
298 /**
299 * Base class for image objects to be registered with the groups
300 * @class YAHOO.util.ImageLoader.imgObj
301 * @constructor
302 * @param {String} domId HTML DOM id of the image element
303 * @param {String} url URL for the image
304 */
305 YAHOO.util.ImageLoader.imgObj = function(domId, url) {
306 /**
307 * HTML DOM id of the image element
308 * @property domId
309 * @type String
310 */
311 this.domId = domId;
312
313 /**
314 * URL for the image
315 * @property url
316 * @type String
317 */
318 this.url = url;
319
320 /**
321 * Pixel width of the image. Will be set as a "width" attribute after the image is fetched.
322 * Detaults to the natural width of the image.
323 * Only appropriate with src images
324 * @property width
325 * @type Int
326 */
327 this.width = null;
328
329 /**
330 * Pixel height of the image. Will be set as a "height" attribute after the image is fetched.
331 * Detaults to the natural height of the image.
332 * Only appropriate with src images
333 * @property height
334 * @type Int
335 */
336 this.height = null;
337
338 /**
339 * Whether the style.visibility should be set to "visible" after the image is fetched.
340 * Used when setting src images as visibility:hidden prior to image fetching
341 * @property setVisible
342 * @type Boolean
343 */
344 this.setVisible = false;
345
346 /**
347 * 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
348 * @property _fetched
349 * @type Boolean
350 * @private
351 */
352 this._fetched = false;
353 };
354
355 /**
356 * Displays the image; puts the URL into the DOM
357 * @method fetch
358 */
359 YAHOO.util.ImageLoader.imgObj.prototype.fetch = function() {
360 if (this._fetched) {
361 return;
362 }
363 var el = document.getElementById(this.domId);
364 if (! el) {
365 return;
366 }
367 YAHOO.log('Fetching image with id "' + this.domId + '".', 'info', 'imageloader');
368 this._applyUrl(el);
369
370 if (this.setVisible) {
371 el.style.visibility = 'visible';
372 }
373 if (this.width) {
374 el.width = this.width;
375 }
376 if (this.height) {
377 el.height = this.height;
378 }
379 this._fetched = true;
380 };
381
382 /**
383 * Inserts the image URL into the DOM so that the image is displayed.
384 * Must be overridden by child class
385 * @method _applyUrl
386 * @param {Object} el HTML DOM element
387 * @private
388 */
389 YAHOO.util.ImageLoader.imgObj.prototype._applyUrl = function(el) {
390 };
391
392 /**
393 * Background image object. A background image is one whose URL is specified by "background-image" in the element's style
394 * @class YAHOO.util.ImageLoader.bgImgObj
395 * @constructor
396 * @extends YAHOO.util.ImageLoader.imgObj
397 * @param {String} domId HTML DOM id of the image element
398 * @param {String} url URL for the image
399 */
400 YAHOO.util.ImageLoader.bgImgObj = function(domId, url) {
401 YAHOO.util.ImageLoader.bgImgObj.superclass.constructor.call(this, domId, url);
402 };
403
404 YAHOO.lang.extend(YAHOO.util.ImageLoader.bgImgObj, YAHOO.util.ImageLoader.imgObj);
405
406 /**
407 * Inserts the image URL into the DOM so that the image is displayed.
408 * Sets style.backgroundImage
409 * @method _applyUrl
410 * @param {Object} el HTML DOM element
411 * @private
412 */
413 YAHOO.util.ImageLoader.bgImgObj.prototype._applyUrl = function(el) {
414 el.style.backgroundImage = "url('" + this.url + "')";
415 };
416
417 /**
418 * Source image object. A source image is one whose URL is specified by a src attribute in the DOM element
419 * @class YAHOO.util.ImageLoader.srcImgObj
420 * @constructor
421 * @extends YAHOO.util.ImageLoader.imgObj
422 * @param {String} domId HTML DOM id of the image element
423 * @param {String} url URL for the image
424 * @param {Int} width pixel width of the image - defaults to image's natural size
425 * @param {Int} height pixel height of the image - defaults to image's natural size
426 */
427 YAHOO.util.ImageLoader.srcImgObj = function(domId, url, width, height) {
428 YAHOO.util.ImageLoader.srcImgObj.superclass.constructor.call(this, domId, url);
429 this.width = width;
430 this.height = height;
431 };
432
433 YAHOO.lang.extend(YAHOO.util.ImageLoader.srcImgObj, YAHOO.util.ImageLoader.imgObj);
434
435 /**
436 * Inserts the image URL into the DOM so that the image is displayed.
437 * Sets src
438 * @method _applyUrl
439 * @param {Object} el HTML DOM element
440 * @private
441 */
442 YAHOO.util.ImageLoader.srcImgObj.prototype._applyUrl = function(el) {
443 el.src = this.url;
444 };
445
446 /**
447 * 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
448 * @class YAHOO.util.ImageLoader.pngBgImgObj
449 * @constructor
450 * @extends YAHOO.util.ImageLoader.imgObj
451 * @param {String} domId HTML DOM id of the image element
452 * @param {String} url URL for the image
453 * @param {Object} ailProps The AlphaImageLoader properties to be set for the image
454 * Valid properties are 'sizingMethod' and 'enabled'
455 */
456 YAHOO.util.ImageLoader.pngBgImgObj = function(domId, url, ailProps) {
457 YAHOO.util.ImageLoader.pngBgImgObj.superclass.constructor.call(this, domId, url);
458
459 /**
460 * AlphaImageLoader properties to be set for the image.
461 * Valid properties are "sizingMethod" and "enabled".
462 * @property props
463 * @type Object
464 */
465 this.props = ailProps || {};
466 };
467
468 YAHOO.lang.extend(YAHOO.util.ImageLoader.pngBgImgObj, YAHOO.util.ImageLoader.imgObj);
469
470 /**
471 * Inserts the image URL into the DOM so that the image is displayed.
472 * If the browser is determined to be IE6 (or older), sets the AlphaImageLoader src; otherwise sets style.backgroundImage
473 * @method _applyUrl
474 * @param {Object} el HTML DOM element
475 * @private
476 */
477 YAHOO.util.ImageLoader.pngBgImgObj.prototype._applyUrl = function(el) {
478 if (YAHOO.env.ua.ie && YAHOO.env.ua.ie <= 6) {
479 var sizingMethod = (YAHOO.lang.isUndefined(this.props.sizingMethod)) ? 'scale' : this.props.sizingMethod;
480 var enabled = (YAHOO.lang.isUndefined(this.props.enabled)) ? 'true' : this.props.enabled;
481 el.style.filter = 'progid:DXImageTransform.Microsoft.AlphaImageLoader(src="' + this.url + '", sizingMethod="' + sizingMethod + '", enabled="' + enabled + '")';
482 }
483 else {
484 el.style.backgroundImage = "url('" + this.url + "')";
485 }
486 };
487 YAHOO.register("imageloader", YAHOO.util.ImageLoader, {version: "2.8.0r4", build: "2449"});