2 * Portions of this file are based on pieces of Yahoo User Interface Library
3 * Copyright (c) 2007, Yahoo! Inc. All rights reserved.
4 * YUI licensed under the BSD License:
5 * http://developer.yahoo.net/yui/license.txt
6 * <script type="text/javascript">
10 Roo.lib.Event = function() {
11 var loadComplete = false;
13 var unloadListeners = [];
15 var onAvailStack = [];
30 startInterval: function() {
31 if (!this._interval) {
33 var callback = function() {
34 self._tryPreloadAttach();
36 this._interval = setInterval(callback, this.POLL_INTERVAL);
41 onAvailable: function(p_id, p_fn, p_obj, p_override) {
42 onAvailStack.push({ id: p_id,
48 retryCount = this.POLL_RETRYS;
53 addListener: function(el, eventName, fn) {
59 if ("unload" == eventName) {
60 unloadListeners[unloadListeners.length] =
65 var wrappedFn = function(e) {
66 return fn(Roo.lib.Event.getEvent(e));
69 var li = [el, eventName, fn, wrappedFn];
71 var index = listeners.length;
72 listeners[index] = li;
74 this.doAdd(el, eventName, wrappedFn, false);
80 removeListener: function(el, eventName, fn) {
86 return this.purgeElement(el, false, eventName);
90 if ("unload" == eventName) {
92 for (i = 0,len = unloadListeners.length; i < len; i++) {
93 var li = unloadListeners[i];
98 unloadListeners.splice(i, 1);
106 var cacheItem = null;
109 var index = arguments[3];
111 if ("undefined" == typeof index) {
112 index = this._getCacheIndex(el, eventName, fn);
116 cacheItem = listeners[index];
119 if (!el || !cacheItem) {
123 this.doRemove(el, eventName, cacheItem[this.WFN], false);
125 delete listeners[index][this.WFN];
126 delete listeners[index][this.FN];
127 listeners.splice(index, 1);
134 getTarget: function(ev, resolveTextNode) {
135 ev = ev.browserEvent || ev;
136 var t = ev.target || ev.srcElement;
137 return this.resolveTextNode(t);
141 resolveTextNode: function(node) {
142 if (Roo.isSafari && node && 3 == node.nodeType) {
143 return node.parentNode;
150 getPageX: function(ev) {
151 ev = ev.browserEvent || ev;
157 x += this.getScroll()[1];
165 getPageY: function(ev) {
166 ev = ev.browserEvent || ev;
172 y += this.getScroll()[0];
181 getXY: function(ev) {
182 ev = ev.browserEvent || ev;
183 return [this.getPageX(ev), this.getPageY(ev)];
187 getRelatedTarget: function(ev) {
188 ev = ev.browserEvent || ev;
189 var t = ev.relatedTarget;
191 if (ev.type == "mouseout") {
193 } else if (ev.type == "mouseover") {
198 return this.resolveTextNode(t);
202 getTime: function(ev) {
203 ev = ev.browserEvent || ev;
205 var t = new Date().getTime();
218 stopEvent: function(ev) {
219 this.stopPropagation(ev);
220 this.preventDefault(ev);
224 stopPropagation: function(ev) {
225 ev = ev.browserEvent || ev;
226 if (ev.stopPropagation) {
227 ev.stopPropagation();
229 ev.cancelBubble = true;
234 preventDefault: function(ev) {
235 ev = ev.browserEvent || ev;
236 if(ev.preventDefault) {
239 ev.returnValue = false;
244 getEvent: function(e) {
245 var ev = e || window.event;
247 var c = this.getEvent.caller;
250 if (ev && Event == ev.constructor) {
260 getCharCode: function(ev) {
261 ev = ev.browserEvent || ev;
262 return ev.charCode || ev.keyCode || 0;
266 _getCacheIndex: function(el, eventName, fn) {
267 for (var i = 0,len = listeners.length; i < len; ++i) {
268 var li = listeners[i];
272 li[this.TYPE] == eventName) {
284 getEl: function(id) {
285 return document.getElementById(id);
289 clearCache: function() {
295 var EU = Roo.lib.Event;
299 EU.doRemove(window, "load", EU._load);
304 _tryPreloadAttach: function() {
313 var tryAgain = !loadComplete;
315 tryAgain = (retryCount > 0);
320 for (var i = 0,len = onAvailStack.length; i < len; ++i) {
321 var item = onAvailStack[i];
323 var el = this.getEl(item.id);
326 if (!item.checkReady ||
329 (document && document.body)) {
333 if (item.override === true) {
336 scope = item.override;
339 item.fn.call(scope, item.obj);
340 onAvailStack[i] = null;
348 retryCount = (notAvail.length === 0) ? 0 : retryCount - 1;
352 this.startInterval();
354 clearInterval(this._interval);
355 this._interval = null;
365 purgeElement: function(el, recurse, eventName) {
366 var elListeners = this.getListeners(el, eventName);
368 for (var i = 0,len = elListeners.length; i < len; ++i) {
369 var l = elListeners[i];
370 this.removeListener(el, l.type, l.fn);
374 if (recurse && el && el.childNodes) {
375 for (i = 0,len = el.childNodes.length; i < len; ++i) {
376 this.purgeElement(el.childNodes[i], recurse, eventName);
382 getListeners: function(el, eventName) {
383 var results = [], searchLists;
385 searchLists = [listeners, unloadListeners];
386 } else if (eventName == "unload") {
387 searchLists = [unloadListeners];
389 searchLists = [listeners];
392 for (var j = 0; j < searchLists.length; ++j) {
393 var searchList = searchLists[j];
394 if (searchList && searchList.length > 0) {
395 for (var i = 0,len = searchList.length; i < len; ++i) {
396 var l = searchList[i];
397 if (l && l[this.EL] === el &&
398 (!eventName || eventName === l[this.TYPE])) {
403 adjust: l[this.ADJ_SCOPE],
411 return (results.length) ? results : null;
415 _unload: function(e) {
417 var EU = Roo.lib.Event, i, j, l, len, index;
419 for (i = 0,len = unloadListeners.length; i < len; ++i) {
420 l = unloadListeners[i];
423 if (l[EU.ADJ_SCOPE]) {
424 if (l[EU.ADJ_SCOPE] === true) {
427 scope = l[EU.ADJ_SCOPE];
430 l[EU.FN].call(scope, EU.getEvent(e), l[EU.OBJ]);
431 unloadListeners[i] = null;
437 unloadListeners = null;
439 if (listeners && listeners.length > 0) {
440 j = listeners.length;
443 l = listeners[index];
445 EU.removeListener(l[EU.EL], l[EU.TYPE],
455 EU.doRemove(window, "unload", EU._unload);
460 getScroll: function() {
461 var dd = document.documentElement, db = document.body;
462 if (dd && (dd.scrollTop || dd.scrollLeft)) {
463 return [dd.scrollTop, dd.scrollLeft];
465 return [db.scrollTop, db.scrollLeft];
473 if (window.addEventListener) {
474 return function(el, eventName, fn, capture) {
475 el.addEventListener(eventName, fn, (capture));
477 } else if (window.attachEvent) {
478 return function(el, eventName, fn, capture) {
479 el.attachEvent("on" + eventName, fn);
488 doRemove: function() {
489 if (window.removeEventListener) {
490 return function (el, eventName, fn, capture) {
491 el.removeEventListener(eventName, fn, (capture));
493 } else if (window.detachEvent) {
494 return function (el, eventName, fn) {
495 el.detachEvent("on" + eventName, fn);
507 var E = Roo.lib.Event;
508 E.on = E.addListener;
509 E.un = E.removeListener;
511 if (document && document.body) {
514 E.doAdd(window, "load", E._load);
516 E.doAdd(window, "unload", E._unload);
517 E._tryPreloadAttach();