Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

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