Diffstat (limited to 'frontend/beta/js/YUI-extensions/EventManager.js') (more/less context) (ignore whitespace changes)
-rw-r--r-- | frontend/beta/js/YUI-extensions/EventManager.js | 456 |
1 files changed, 456 insertions, 0 deletions
diff --git a/frontend/beta/js/YUI-extensions/EventManager.js b/frontend/beta/js/YUI-extensions/EventManager.js new file mode 100644 index 0000000..f9db759 --- a/dev/null +++ b/frontend/beta/js/YUI-extensions/EventManager.js | |||
@@ -0,0 +1,456 @@ | |||
1 | |||
2 | /** | ||
3 | * @class YAHOO.ext.EventManager | ||
4 | * Registers event handlers that want to receive a normalized EventObject instead of the standard browser event and provides | ||
5 | * several useful events directly. | ||
6 | * See {@link YAHOO.ext.EventObject} for more details on normalized event objects. | ||
7 | * @singleton | ||
8 | */ | ||
9 | YAHOO.ext.EventManager = new function(){ | ||
10 | var docReadyEvent; | ||
11 | var docReadyProcId; | ||
12 | var docReadyState = false; | ||
13 | this.ieDeferSrc = false; | ||
14 | var resizeEvent; | ||
15 | var resizeTask; | ||
16 | |||
17 | var fireDocReady = function(){ | ||
18 | if(!docReadyState){ | ||
19 | docReadyState = true; | ||
20 | if(docReadyProcId){ | ||
21 | clearInterval(docReadyProcId); | ||
22 | } | ||
23 | if(docReadyEvent){ | ||
24 | docReadyEvent.fire(); | ||
25 | } | ||
26 | } | ||
27 | }; | ||
28 | |||
29 | var initDocReady = function(){ | ||
30 | docReadyEvent = new YAHOO.util.CustomEvent('documentready'); | ||
31 | if(document.addEventListener) { | ||
32 | YAHOO.util.Event.on(document, "DOMContentLoaded", fireDocReady); | ||
33 | }else if(YAHOO.ext.util.Browser.isIE){ | ||
34 | // inspired by http://www.thefutureoftheweb.com/blog/2006/6/adddomloadevent | ||
35 | document.write('<s'+'cript id="ie-deferred-loader" defer="defer" src="' + | ||
36 | (YAHOO.ext.EventManager.ieDeferSrc || YAHOO.ext.SSL_SECURE_URL) + '"></s'+'cript>'); | ||
37 | YAHOO.util.Event.on('ie-deferred-loader', 'readystatechange', function(){ | ||
38 | if(this.readyState == 'complete'){ | ||
39 | fireDocReady(); | ||
40 | } | ||
41 | }); | ||
42 | }else if(YAHOO.ext.util.Browser.isSafari){ | ||
43 | docReadyProcId = setInterval(function(){ | ||
44 | var rs = document.readyState; | ||
45 | if(rs == 'loaded' || rs == 'complete') { | ||
46 | fireDocReady(); | ||
47 | } | ||
48 | }, 10); | ||
49 | } | ||
50 | // no matter what, make sure it fires on load | ||
51 | YAHOO.util.Event.on(window, 'load', fireDocReady); | ||
52 | }; | ||
53 | /** | ||
54 | * Places a simple wrapper around an event handler to override the browser event | ||
55 | * object with a YAHOO.ext.EventObject | ||
56 | * @param {Function} fn The method the event invokes | ||
57 | * @param {Object} scope An object that becomes the scope of the handler | ||
58 | * @param {boolean} override If true, the obj passed in becomes | ||
59 | * the execution scope of the listener | ||
60 | * @return {Function} The wrapped function | ||
61 | */ | ||
62 | this.wrap = function(fn, scope, override){ | ||
63 | var wrappedFn = function(e){ | ||
64 | YAHOO.ext.EventObject.setEvent(e); | ||
65 | fn.call(override ? scope || window : window, YAHOO.ext.EventObject, scope); | ||
66 | }; | ||
67 | return wrappedFn; | ||
68 | }; | ||
69 | |||
70 | /** | ||
71 | * Appends an event handler | ||
72 | * | ||
73 | * @param {Object} element The html element to assign the | ||
74 | * event to | ||
75 | * @param {String} eventName The type of event to append | ||
76 | * @param {Function} fn The method the event invokes | ||
77 | * @param {Object} scope An object that becomes the scope of the handler | ||
78 | * @param {boolean} override If true, the obj passed in becomes | ||
79 | * the execution scope of the listener | ||
80 | * @return {Function} The wrapper function created (to be used to remove the listener if necessary) | ||
81 | */ | ||
82 | this.addListener = function(element, eventName, fn, scope, override){ | ||
83 | var wrappedFn = this.wrap(fn, scope, override); | ||
84 | YAHOO.util.Event.addListener(element, eventName, wrappedFn); | ||
85 | return wrappedFn; | ||
86 | }; | ||
87 | |||
88 | /** | ||
89 | * Removes an event handler | ||
90 | * | ||
91 | * @param {Object} element The html element to remove the | ||
92 | * event from | ||
93 | * @param {String} eventName The type of event to append | ||
94 | * @param {Function} wrappedFn The wrapper method returned when adding the listener | ||
95 | * @return {Boolean} True if a listener was actually removed | ||
96 | */ | ||
97 | this.removeListener = function(element, eventName, wrappedFn){ | ||
98 | return YAHOO.util.Event.removeListener(element, eventName, wrappedFn); | ||
99 | }; | ||
100 | |||
101 | /** | ||
102 | * Appends an event handler (shorthand for addListener) | ||
103 | * | ||
104 | * @param {Object} element The html element to assign the | ||
105 | * event to | ||
106 | * @param {String} eventName The type of event to append | ||
107 | * @param {Function} fn The method the event invokes | ||
108 | * @param {Object} scope An arbitrary object that will be | ||
109 | * passed as a parameter to the handler | ||
110 | * @param {boolean} override If true, the obj passed in becomes | ||
111 | * the execution scope of the listener | ||
112 | * @return {Function} The wrapper function created (to be used to remove the listener if necessary) | ||
113 | * @method | ||
114 | */ | ||
115 | this.on = this.addListener; | ||
116 | |||
117 | /** | ||
118 | * Fires when the document is ready (before onload and before images are loaded). Can be | ||
119 | * accessed shorthanded Ext.onReady(). | ||
120 | * @param {Function} fn The method the event invokes | ||
121 | * @param {Object} scope An object that becomes the scope of the handler | ||
122 | * @param {boolean} override If true, the obj passed in becomes | ||
123 | * the execution scope of the listener | ||
124 | */ | ||
125 | this.onDocumentReady = function(fn, scope, override){ | ||
126 | if(docReadyState){ // if it already fired | ||
127 | fn.call(override? scope || window : window, scope); | ||
128 | return; | ||
129 | } | ||
130 | if(!docReadyEvent){ | ||
131 | initDocReady(); | ||
132 | } | ||
133 | docReadyEvent.subscribe(fn, scope, override); | ||
134 | } | ||
135 | |||
136 | /** | ||
137 | * Fires when the window is resized and provides resize event buffering (50 milliseconds), passes new viewport width and height to handlers. | ||
138 | * @param {Function} fn The method the event invokes | ||
139 | * @param {Object} scope An object that becomes the scope of the handler | ||
140 | * @param {boolean} override If true, the obj passed in becomes | ||
141 | * the execution scope of the listener | ||
142 | */ | ||
143 | this.onWindowResize = function(fn, scope, override){ | ||
144 | if(!resizeEvent){ | ||
145 | resizeEvent = new YAHOO.util.CustomEvent('windowresize'); | ||
146 | resizeTask = new YAHOO.ext.util.DelayedTask(function(){ | ||
147 | resizeEvent.fireDirect(YAHOO.util.Dom.getViewportWidth(), YAHOO.util.Dom.getViewportHeight()); | ||
148 | }); | ||
149 | YAHOO.util.Event.on(window, 'resize', function(){ | ||
150 | resizeTask.delay(50); | ||
151 | }); | ||
152 | } | ||
153 | resizeEvent.subscribe(fn, scope, override); | ||
154 | }; | ||
155 | |||
156 | /** | ||
157 | * Removes the passed window resize listener. | ||
158 | * @param {Function} fn The method the event invokes | ||
159 | * @param {Object} scope The scope of handler | ||
160 | */ | ||
161 | this.removeResizeListener = function(fn, scope){ | ||
162 | if(resizeEvent){ | ||
163 | resizeEvent.unsubscribe(fn, scope); | ||
164 | } | ||
165 | }; | ||
166 | |||
167 | this.fireResize = function(){ | ||
168 | if(resizeEvent){ | ||
169 | resizeEvent.fireDirect(YAHOO.util.Dom.getViewportWidth(), YAHOO.util.Dom.getViewportHeight()); | ||
170 | } | ||
171 | }; | ||
172 | }; | ||
173 | |||
174 | YAHOO.ext.onReady = YAHOO.ext.EventManager.onDocumentReady; | ||
175 | |||
176 | /** | ||
177 | * @class YAHOO.ext.EventObject | ||
178 | * EventObject exposes the Yahoo! UI Event functionality directly on the object | ||
179 | * passed to your event handler. It exists mostly for convenience. It also fixes the annoying null checks automatically to cleanup your code | ||
180 | * (All the YAHOO.util.Event methods throw javascript errors if the passed event is null). | ||
181 | * To get an EventObject instead of the standard browser event, | ||
182 | * your must register your listener thru the {@link YAHOO.ext.EventManager} or directly on an Element | ||
183 | * with {@link YAHOO.ext.Element#addManagedListener} or the shorthanded equivalent {@link YAHOO.ext.Element#mon}.<br> | ||
184 | * Example: | ||
185 | * <pre><code> | ||
186 | fu<>nction handleClick(e){ // e is not a standard event object, it is a YAHOO.ext.EventObject | ||
187 | e.preventDefault(); | ||
188 | var target = e.getTarget(); | ||
189 | ... | ||
190 | } | ||
191 | var myDiv = getEl('myDiv'); | ||
192 | myDiv.mon('click', handleClick); | ||
193 | //or | ||
194 | YAHOO.ext.EventManager.on('myDiv', 'click', handleClick); | ||
195 | YAHOO.ext.EventManager.addListener('myDiv', 'click', handleClick); | ||
196 | </code></pre> | ||
197 | * @singleton | ||
198 | */ | ||
199 | YAHOO.ext.EventObject = new function(){ | ||
200 | /** The normal browser event */ | ||
201 | this.browserEvent = null; | ||
202 | /** The button pressed in a mouse event */ | ||
203 | this.button = -1; | ||
204 | /** True if the shift key was down during the event */ | ||
205 | this.shiftKey = false; | ||
206 | /** True if the control key was down during the event */ | ||
207 | this.ctrlKey = false; | ||
208 | /** True if the alt key was down during the event */ | ||
209 | this.altKey = false; | ||
210 | |||
211 | /** Key constant @type Number */ | ||
212 | this.BACKSPACE = 8; | ||
213 | /** Key constant @type Number */ | ||
214 | this.TAB = 9; | ||
215 | /** Key constant @type Number */ | ||
216 | this.RETURN = 13; | ||
217 | /** Key constant @type Number */ | ||
218 | this.ESC = 27; | ||
219 | /** Key constant @type Number */ | ||
220 | this.SPACE = 32; | ||
221 | /** Key constant @type Number */ | ||
222 | this.PAGEUP = 33; | ||
223 | /** Key constant @type Number */ | ||
224 | this.PAGEDOWN = 34; | ||
225 | /** Key constant @type Number */ | ||
226 | this.END = 35; | ||
227 | /** Key constant @type Number */ | ||
228 | this.HOME = 36; | ||
229 | /** Key constant @type Number */ | ||
230 | this.LEFT = 37; | ||
231 | /** Key constant @type Number */ | ||
232 | this.UP = 38; | ||
233 | /** Key constant @type Number */ | ||
234 | this.RIGHT = 39; | ||
235 | /** Key constant @type Number */ | ||
236 | this.DOWN = 40; | ||
237 | /** Key constant @type Number */ | ||
238 | this.DELETE = 46; | ||
239 | /** Key constant @type Number */ | ||
240 | this.F5 = 116; | ||
241 | |||
242 | /** @private */ | ||
243 | this.setEvent = function(e){ | ||
244 | if(e == this){ // already wrapped | ||
245 | return this; | ||
246 | } | ||
247 | this.browserEvent = e; | ||
248 | if(e){ | ||
249 | this.button = e.button; | ||
250 | this.shiftKey = e.shiftKey; | ||
251 | this.ctrlKey = e.ctrlKey; | ||
252 | this.altKey = e.altKey; | ||
253 | }else{ | ||
254 | this.button = -1; | ||
255 | this.shiftKey = false; | ||
256 | this.ctrlKey = false; | ||
257 | this.altKey = false; | ||
258 | } | ||
259 | return this; | ||
260 | }; | ||
261 | |||
262 | /** | ||
263 | * Stop the event. Calls YAHOO.util.Event.stopEvent() if the event is not null. | ||
264 | */ | ||
265 | this.stopEvent = function(){ | ||
266 | if(this.browserEvent){ | ||
267 | YAHOO.util.Event.stopEvent(this.browserEvent); | ||
268 | } | ||
269 | }; | ||
270 | |||
271 | /** | ||
272 | * Prevents the browsers default handling of the event. Calls YAHOO.util.Event.preventDefault() if the event is not null. | ||
273 | */ | ||
274 | this.preventDefault = function(){ | ||
275 | if(this.browserEvent){ | ||
276 | YAHOO.util.Event.preventDefault(this.browserEvent); | ||
277 | } | ||
278 | }; | ||
279 | |||
280 | /** @private */ | ||
281 | this.isNavKeyPress = function(){ | ||
282 | return (this.browserEvent.keyCode && this.browserEvent.keyCode >= 33 && this.browserEvent.keyCode <= 40); | ||
283 | }; | ||
284 | |||
285 | /** | ||
286 | * Cancels bubbling of the event. Calls YAHOO.util.Event.stopPropagation() if the event is not null. | ||
287 | */ | ||
288 | this.stopPropagation = function(){ | ||
289 | if(this.browserEvent){ | ||
290 | YAHOO.util.Event.stopPropagation(this.browserEvent); | ||
291 | } | ||
292 | }; | ||
293 | |||
294 | /** | ||
295 | * Gets the key code for the event. Returns value from YAHOO.util.Event.getCharCode() if the event is not null. | ||
296 | * @return {Number} | ||
297 | */ | ||
298 | this.getCharCode = function(){ | ||
299 | if(this.browserEvent){ | ||
300 | return YAHOO.util.Event.getCharCode(this.browserEvent); | ||
301 | } | ||
302 | return null; | ||
303 | }; | ||
304 | |||
305 | /** | ||
306 | * Returns a browsers key for a keydown event | ||
307 | * @return {Number} The key code | ||
308 | */ | ||
309 | this.getKey = function(){ | ||
310 | if(this.browserEvent){ | ||
311 | return this.browserEvent.keyCode || this.browserEvent.charCode; | ||
312 | } | ||
313 | return null; | ||
314 | }; | ||
315 | |||
316 | /** | ||
317 | * Gets the x coordinate of the event. Returns value from YAHOO.util.Event.getPageX() if the event is not null. | ||
318 | * @return {Number} | ||
319 | */ | ||
320 | this.getPageX = function(){ | ||
321 | if(this.browserEvent){ | ||
322 | return YAHOO.util.Event.getPageX(this.browserEvent); | ||
323 | } | ||
324 | return null; | ||
325 | }; | ||
326 | |||
327 | /** | ||
328 | * Gets the y coordinate of the event. Returns value from YAHOO.util.Event.getPageY() if the event is not null. | ||
329 | * @return {Number} | ||
330 | */ | ||
331 | this.getPageY = function(){ | ||
332 | if(this.browserEvent){ | ||
333 | return YAHOO.util.Event.getPageY(this.browserEvent); | ||
334 | } | ||
335 | return null; | ||
336 | }; | ||
337 | |||
338 | /** | ||
339 | * Gets the time of the event. Returns value from YAHOO.util.Event.getTime() if the event is not null. | ||
340 | * @return {Number} | ||
341 | */ | ||
342 | this.getTime = function(){ | ||
343 | if(this.browserEvent){ | ||
344 | return YAHOO.util.Event.getTime(this.browserEvent); | ||
345 | } | ||
346 | return null; | ||
347 | }; | ||
348 | |||
349 | /** | ||
350 | * Gets the page coordinates of the event. Returns value from YAHOO.util.Event.getXY() if the event is not null. | ||
351 | * @return {Array} The xy values like [x, y] | ||
352 | */ | ||
353 | this.getXY = function(){ | ||
354 | if(this.browserEvent){ | ||
355 | return YAHOO.util.Event.getXY(this.browserEvent); | ||
356 | } | ||
357 | return []; | ||
358 | }; | ||
359 | |||
360 | /** | ||
361 | * Gets the target for the event. Returns value from YAHOO.util.Event.getTarget() if the event is not null. | ||
362 | * @return {HTMLelement} | ||
363 | */ | ||
364 | this.getTarget = function(){ | ||
365 | if(this.browserEvent){ | ||
366 | return YAHOO.util.Event.getTarget(this.browserEvent); | ||
367 | } | ||
368 | return null; | ||
369 | }; | ||
370 | |||
371 | /** | ||
372 | * Walk up the DOM looking for a particular target - if the default target matches, it is returned. | ||
373 | * @param {String} className The class name to look for or null | ||
374 | * @param {String} tagName (optional) The tag name to look for | ||
375 | * @return {HTMLelement} | ||
376 | */ | ||
377 | this.findTarget = function(className, tagName){ | ||
378 | if(tagName) tagName = tagName.toLowerCase(); | ||
379 | if(this.browserEvent){ | ||
380 | function isMatch(el){ | ||
381 | if(!el){ | ||
382 | return false; | ||
383 | } | ||
384 | if(className && !YAHOO.util.Dom.hasClass(el, className)){ | ||
385 | return false; | ||
386 | } | ||
387 | if(tagName && el.tagName.toLowerCase() != tagName){ | ||
388 | return false; | ||
389 | } | ||
390 | return true; | ||
391 | }; | ||
392 | |||
393 | var t = this.getTarget(); | ||
394 | if(!t || isMatch(t)){ | ||
395 | return t; | ||
396 | } | ||
397 | var p = t.parentNode; | ||
398 | var b = document.body; | ||
399 | while(p && p != b){ | ||
400 | if(isMatch(p)){ | ||
401 | return p; | ||
402 | } | ||
403 | p = p.parentNode; | ||
404 | } | ||
405 | } | ||
406 | return null; | ||
407 | }; | ||
408 | /** | ||
409 | * Gets the related target. Returns value from YAHOO.util.Event.getRelatedTarget() if the event is not null. | ||
410 | * @return {HTMLElement} | ||
411 | */ | ||
412 | this.getRelatedTarget = function(){ | ||
413 | if(this.browserEvent){ | ||
414 | return YAHOO.util.Event.getRelatedTarget(this.browserEvent); | ||
415 | } | ||
416 | return null; | ||
417 | }; | ||
418 | |||
419 | /** | ||
420 | * Normalizes mouse wheel delta across browsers | ||
421 | * @return {Number} The delta | ||
422 | */ | ||
423 | this.getWheelDelta = function(){ | ||
424 | var e = this.browserEvent; | ||
425 | var delta = 0; | ||
426 | if(e.wheelDelta){ /* IE/Opera. */ | ||
427 | delta = e.wheelDelta/120; | ||
428 | /* In Opera 9, delta differs in sign as compared to IE. */ | ||
429 | if(window.opera) delta = -delta; | ||
430 | }else if(e.detail){ /* Mozilla case. */ | ||
431 | delta = -e.detail/3; | ||
432 | } | ||
433 | return delta; | ||
434 | }; | ||
435 | |||
436 | /** | ||
437 | * Returns true if the control, shift or alt key was pressed during this event. | ||
438 | * @return {Boolean} | ||
439 | */ | ||
440 | this.hasModifier = function(){ | ||
441 | return this.ctrlKey || this.altKey || this.shiftKey; | ||
442 | }; | ||
443 | |||
444 | /** | ||
445 | * Returns true if the target of this event equals el or is a child of el | ||
446 | * @param {String/HTMLElement/Element} el | ||
447 | * @return {Boolean} | ||
448 | */ | ||
449 | this.within = function(el){ | ||
450 | el = getEl(el); | ||
451 | var t = this.getTarget(); | ||
452 | return t && el && (el.dom == t || YAHOO.util.Dom.isAncestor(el.dom, t)); | ||
453 | } | ||
454 | }(); | ||
455 | |||
456 | |||