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 ev = ev.touches ? (ev.touches[0] || ev.changedTouches[0] || ev ) : ev;
137 var t = ev.target || ev.srcElement;
138 return this.resolveTextNode(t);
142 resolveTextNode: function(node) {
143 if (Roo.isSafari && node && 3 == node.nodeType) {
144 return node.parentNode;
151 getPageX: function(ev) {
152 ev = ev.browserEvent || ev;
153 ev = ev.touches ? (ev.touches[0] || ev.changedTouches[0] || ev ) : ev;
159 x += this.getScroll()[1];
167 getPageY: function(ev) {
168 ev = ev.browserEvent || ev;
169 ev = ev.touches ? (ev.touches[0] || ev.changedTouches[0] || ev ) : ev;
175 y += this.getScroll()[0];
184 getXY: function(ev) {
185 ev = ev.browserEvent || ev;
186 ev = ev.touches ? (ev.touches[0] || ev.changedTouches[0] || ev ) : ev;
187 return [this.getPageX(ev), this.getPageY(ev)];
191 getRelatedTarget: function(ev) {
192 ev = ev.browserEvent || ev;
193 ev = ev.touches ? (ev.touches[0] || ev.changedTouches[0] || ev ) : ev;
194 var t = ev.relatedTarget;
196 if (ev.type == "mouseout") {
198 } else if (ev.type == "mouseover") {
203 return this.resolveTextNode(t);
207 getTime: function(ev) {
208 ev = ev.browserEvent || ev;
209 ev = ev.touches ? (ev.touches[0] || ev.changedTouches[0] || ev ) : ev;
211 var t = new Date().getTime();
224 stopEvent: function(ev) {
225 this.stopPropagation(ev);
226 this.preventDefault(ev);
230 stopPropagation: function(ev) {
231 ev = ev.browserEvent || ev;
232 if (ev.stopPropagation) {
233 ev.stopPropagation();
235 ev.cancelBubble = true;
240 preventDefault: function(ev) {
241 ev = ev.browserEvent || ev;
242 if(ev.preventDefault) {
245 ev.returnValue = false;
250 getEvent: function(e) {
251 var ev = e || window.event;
253 var c = this.getEvent.caller;
256 if (ev && Event == ev.constructor) {
266 getCharCode: function(ev) {
267 ev = ev.browserEvent || ev;
268 return ev.charCode || ev.keyCode || 0;
272 _getCacheIndex: function(el, eventName, fn) {
273 for (var i = 0,len = listeners.length; i < len; ++i) {
274 var li = listeners[i];
278 li[this.TYPE] == eventName) {
290 getEl: function(id) {
291 return document.getElementById(id);
295 clearCache: function() {
301 var EU = Roo.lib.Event;
305 EU.doRemove(window, "load", EU._load);
310 _tryPreloadAttach: function() {
319 var tryAgain = !loadComplete;
321 tryAgain = (retryCount > 0);
326 for (var i = 0,len = onAvailStack.length; i < len; ++i) {
327 var item = onAvailStack[i];
329 var el = this.getEl(item.id);
332 if (!item.checkReady ||
335 (document && document.body)) {
339 if (item.override === true) {
342 scope = item.override;
345 item.fn.call(scope, item.obj);
346 onAvailStack[i] = null;
354 retryCount = (notAvail.length === 0) ? 0 : retryCount - 1;
358 this.startInterval();
360 clearInterval(this._interval);
361 this._interval = null;
371 purgeElement: function(el, recurse, eventName) {
372 var elListeners = this.getListeners(el, eventName);
374 for (var i = 0,len = elListeners.length; i < len; ++i) {
375 var l = elListeners[i];
376 this.removeListener(el, l.type, l.fn);
380 if (recurse && el && el.childNodes) {
381 for (i = 0,len = el.childNodes.length; i < len; ++i) {
382 this.purgeElement(el.childNodes[i], recurse, eventName);
388 getListeners: function(el, eventName) {
389 var results = [], searchLists;
391 searchLists = [listeners, unloadListeners];
392 } else if (eventName == "unload") {
393 searchLists = [unloadListeners];
395 searchLists = [listeners];
398 for (var j = 0; j < searchLists.length; ++j) {
399 var searchList = searchLists[j];
400 if (searchList && searchList.length > 0) {
401 for (var i = 0,len = searchList.length; i < len; ++i) {
402 var l = searchList[i];
403 if (l && l[this.EL] === el &&
404 (!eventName || eventName === l[this.TYPE])) {
409 adjust: l[this.ADJ_SCOPE],
417 return (results.length) ? results : null;
421 _unload: function(e) {
423 var EU = Roo.lib.Event, i, j, l, len, index;
425 for (i = 0,len = unloadListeners.length; i < len; ++i) {
426 l = unloadListeners[i];
429 if (l[EU.ADJ_SCOPE]) {
430 if (l[EU.ADJ_SCOPE] === true) {
433 scope = l[EU.ADJ_SCOPE];
436 l[EU.FN].call(scope, EU.getEvent(e), l[EU.OBJ]);
437 unloadListeners[i] = null;
443 unloadListeners = null;
445 if (listeners && listeners.length > 0) {
446 j = listeners.length;
449 l = listeners[index];
451 EU.removeListener(l[EU.EL], l[EU.TYPE],
461 EU.doRemove(window, "unload", EU._unload);
466 getScroll: function() {
467 var dd = document.documentElement, db = document.body;
468 if (dd && (dd.scrollTop || dd.scrollLeft)) {
469 return [dd.scrollTop, dd.scrollLeft];
471 return [db.scrollTop, db.scrollLeft];
479 if (window.addEventListener) {
480 return function(el, eventName, fn, capture) {
481 el.addEventListener(eventName, fn, (capture));
483 } else if (window.attachEvent) {
484 return function(el, eventName, fn, capture) {
485 el.attachEvent("on" + eventName, fn);
494 doRemove: function() {
495 if (window.removeEventListener) {
496 return function (el, eventName, fn, capture) {
497 el.removeEventListener(eventName, fn, (capture));
499 } else if (window.detachEvent) {
500 return function (el, eventName, fn) {
501 el.detachEvent("on" + eventName, fn);
513 var E = Roo.lib.Event;
514 E.on = E.addListener;
515 E.un = E.removeListener;
517 if (document && document.body) {
520 E.doAdd(window, "load", E._load);
522 E.doAdd(window, "unload", E._unload);
523 E._tryPreloadAttach();