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;
152 ev = Roo.isTouch ? (ev.touches[0] || ev.changedTouches[0] ) : ev;
158 x += this.getScroll()[1];
166 getPageY: function(ev) {
167 ev = ev.browserEvent || ev;
168 ev = Roo.isTouch ? (ev.touches[0] || ev.changedTouches[0] ) : ev;
174 y += this.getScroll()[0];
183 getXY: function(ev) {
184 ev = ev.browserEvent || ev;
185 ev = Roo.isTouch ? (ev.touches[0] || ev.changedTouches[0] ) : ev;
186 return [this.getPageX(ev), this.getPageY(ev)];
190 getRelatedTarget: function(ev) {
191 ev = ev.browserEvent || ev;
192 ev = Roo.isTouch ? (ev.touches[0] || ev.changedTouches[0] ) : ev;
193 var t = ev.relatedTarget;
195 if (ev.type == "mouseout") {
197 } else if (ev.type == "mouseover") {
202 return this.resolveTextNode(t);
206 getTime: function(ev) {
207 ev = ev.browserEvent || ev;
208 ev = Roo.isTouch ? (ev.touches[0] || ev.changedTouches[0] ) : ev;
210 var t = new Date().getTime();
223 stopEvent: function(ev) {
224 this.stopPropagation(ev);
225 this.preventDefault(ev);
229 stopPropagation: function(ev) {
230 ev = ev.browserEvent || ev;
231 if (ev.stopPropagation) {
232 ev.stopPropagation();
234 ev.cancelBubble = true;
239 preventDefault: function(ev) {
240 ev = ev.browserEvent || ev;
241 if(ev.preventDefault) {
244 ev.returnValue = false;
249 getEvent: function(e) {
250 var ev = e || window.event;
252 var c = this.getEvent.caller;
255 if (ev && Event == ev.constructor) {
265 getCharCode: function(ev) {
266 ev = ev.browserEvent || ev;
267 return ev.charCode || ev.keyCode || 0;
271 _getCacheIndex: function(el, eventName, fn) {
272 for (var i = 0,len = listeners.length; i < len; ++i) {
273 var li = listeners[i];
277 li[this.TYPE] == eventName) {
289 getEl: function(id) {
290 return document.getElementById(id);
294 clearCache: function() {
300 var EU = Roo.lib.Event;
304 EU.doRemove(window, "load", EU._load);
309 _tryPreloadAttach: function() {
318 var tryAgain = !loadComplete;
320 tryAgain = (retryCount > 0);
325 for (var i = 0,len = onAvailStack.length; i < len; ++i) {
326 var item = onAvailStack[i];
328 var el = this.getEl(item.id);
331 if (!item.checkReady ||
334 (document && document.body)) {
338 if (item.override === true) {
341 scope = item.override;
344 item.fn.call(scope, item.obj);
345 onAvailStack[i] = null;
353 retryCount = (notAvail.length === 0) ? 0 : retryCount - 1;
357 this.startInterval();
359 clearInterval(this._interval);
360 this._interval = null;
370 purgeElement: function(el, recurse, eventName) {
371 var elListeners = this.getListeners(el, eventName);
373 for (var i = 0,len = elListeners.length; i < len; ++i) {
374 var l = elListeners[i];
375 this.removeListener(el, l.type, l.fn);
379 if (recurse && el && el.childNodes) {
380 for (i = 0,len = el.childNodes.length; i < len; ++i) {
381 this.purgeElement(el.childNodes[i], recurse, eventName);
387 getListeners: function(el, eventName) {
388 var results = [], searchLists;
390 searchLists = [listeners, unloadListeners];
391 } else if (eventName == "unload") {
392 searchLists = [unloadListeners];
394 searchLists = [listeners];
397 for (var j = 0; j < searchLists.length; ++j) {
398 var searchList = searchLists[j];
399 if (searchList && searchList.length > 0) {
400 for (var i = 0,len = searchList.length; i < len; ++i) {
401 var l = searchList[i];
402 if (l && l[this.EL] === el &&
403 (!eventName || eventName === l[this.TYPE])) {
408 adjust: l[this.ADJ_SCOPE],
416 return (results.length) ? results : null;
420 _unload: function(e) {
422 var EU = Roo.lib.Event, i, j, l, len, index;
424 for (i = 0,len = unloadListeners.length; i < len; ++i) {
425 l = unloadListeners[i];
428 if (l[EU.ADJ_SCOPE]) {
429 if (l[EU.ADJ_SCOPE] === true) {
432 scope = l[EU.ADJ_SCOPE];
435 l[EU.FN].call(scope, EU.getEvent(e), l[EU.OBJ]);
436 unloadListeners[i] = null;
442 unloadListeners = null;
444 if (listeners && listeners.length > 0) {
445 j = listeners.length;
448 l = listeners[index];
450 EU.removeListener(l[EU.EL], l[EU.TYPE],
460 EU.doRemove(window, "unload", EU._unload);
465 getScroll: function() {
466 var dd = document.documentElement, db = document.body;
467 if (dd && (dd.scrollTop || dd.scrollLeft)) {
468 return [dd.scrollTop, dd.scrollLeft];
470 return [db.scrollTop, db.scrollLeft];
478 if (window.addEventListener) {
479 return function(el, eventName, fn, capture) {
480 el.addEventListener(eventName, fn, (capture));
482 } else if (window.attachEvent) {
483 return function(el, eventName, fn, capture) {
484 el.attachEvent("on" + eventName, fn);
493 doRemove: function() {
494 if (window.removeEventListener) {
495 return function (el, eventName, fn, capture) {
496 el.removeEventListener(eventName, fn, (capture));
498 } else if (window.detachEvent) {
499 return function (el, eventName, fn) {
500 el.detachEvent("on" + eventName, fn);
512 var E = Roo.lib.Event;
513 E.on = E.addListener;
514 E.un = E.removeListener;
516 if (document && document.body) {
519 E.doAdd(window, "load", E._load);
521 E.doAdd(window, "unload", E._unload);
522 E._tryPreloadAttach();