Mercurial > kallithea
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"}); |