--- /dev/null
+<html>\r
+<head>\r
+ <title>The source code</title>\r
+ <link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" />\r
+ <script type="text/javascript" src="../resources/prettify/prettify.js"></script>\r
+</head>\r
+<body onload="prettyPrint();">\r
+ <pre class="prettyprint lang-js">Ext.lib.Event = function() {\r
+ var loadComplete = false,\r
+ listeners = [],\r
+ unloadListeners = [],\r
+ retryCount = 0,\r
+ onAvailStack = [],\r
+ _interval,\r
+ locked = false,\r
+ win = window,\r
+ doc = document,\r
+ \r
+ // constants \r
+ POLL_RETRYS = 200,\r
+ POLL_INTERVAL = 20,\r
+ EL = 0,\r
+ TYPE = 1,\r
+ FN = 2,\r
+ WFN = 3,\r
+ OBJ = 3,\r
+ ADJ_SCOPE = 4, \r
+ SCROLLLEFT = 'scrollLeft',\r
+ SCROLLTOP = 'scrollTop',\r
+ UNLOAD = 'unload',\r
+ MOUSEOVER = 'mouseover',\r
+ MOUSEOUT = 'mouseout',\r
+ // private\r
+ doAdd = function() {\r
+ var ret;\r
+ if (win.addEventListener) {\r
+ ret = function(el, eventName, fn, capture) {\r
+ if (eventName == 'mouseenter') {\r
+ fn = fn.createInterceptor(checkRelatedTarget);\r
+ el.addEventListener(MOUSEOVER, fn, (capture));\r
+ } else if (eventName == 'mouseleave') {\r
+ fn = fn.createInterceptor(checkRelatedTarget);\r
+ el.addEventListener(MOUSEOUT, fn, (capture));\r
+ } else {\r
+ el.addEventListener(eventName, fn, (capture));\r
+ }\r
+ return fn;\r
+ };\r
+ } else if (win.attachEvent) {\r
+ ret = function(el, eventName, fn, capture) {\r
+ el.attachEvent("on" + eventName, fn);\r
+ return fn;\r
+ };\r
+ } else {\r
+ ret = function(){};\r
+ }\r
+ return ret;\r
+ }(), \r
+ // private\r
+ doRemove = function(){\r
+ var ret;\r
+ if (win.removeEventListener) {\r
+ ret = function (el, eventName, fn, capture) {\r
+ if (eventName == 'mouseenter') {\r
+ eventName = MOUSEOVER;\r
+ } else if (eventName == 'mouseleave') {\r
+ eventName = MOUSEOUT;\r
+ } \r
+ el.removeEventListener(eventName, fn, (capture));\r
+ };\r
+ } else if (win.detachEvent) {\r
+ ret = function (el, eventName, fn) {\r
+ el.detachEvent("on" + eventName, fn);\r
+ };\r
+ } else {\r
+ ret = function(){};\r
+ }\r
+ return ret;\r
+ }(); \r
+\r
+ var isXUL = Ext.isGecko ? function(node){ \r
+ return Object.prototype.toString.call(node) == '[object XULElement]';\r
+ } : function(){};\r
+ \r
+ var isTextNode = Ext.isGecko ? function(node){\r
+ try{\r
+ return node.nodeType == 3;\r
+ }catch(e) {\r
+ return false;\r
+ }\r
+\r
+ } : function(node){\r
+ return node.nodeType == 3;\r
+ };\r
+ \r
+ function checkRelatedTarget(e) {\r
+ var related = pub.getRelatedTarget(e);\r
+ return !(isXUL(related) || elContains(e.currentTarget,related));\r
+ }\r
+\r
+ function elContains(parent, child) {\r
+ if(parent && parent.firstChild){ \r
+ while(child) {\r
+ if(child === parent) {\r
+ return true;\r
+ }\r
+ try {\r
+ child = child.parentNode;\r
+ } catch(e) {\r
+ // In FF if you mouseout an text input element\r
+ // thats inside a div sometimes it randomly throws\r
+ // Permission denied to get property HTMLDivElement.parentNode\r
+ // See https://bugzilla.mozilla.org/show_bug.cgi?id=208427\r
+ \r
+ return false;\r
+ } \r
+ if(child && (child.nodeType != 1)) {\r
+ child = null;\r
+ }\r
+ }\r
+ }\r
+ return false;\r
+ }\r
+\r
+ \r
+ // private \r
+ function _getCacheIndex(el, eventName, fn) {\r
+ var index = -1;\r
+ Ext.each(listeners, function (v,i) {\r
+ if(v && v[FN] == fn && v[EL] == el && v[TYPE] == eventName) {\r
+ index = i;\r
+ }\r
+ });\r
+ return index;\r
+ }\r
+ \r
+ // private\r
+ function _tryPreloadAttach() {\r
+ var ret = false, \r
+ notAvail = [],\r
+ element,\r
+ tryAgain = !loadComplete || (retryCount > 0); \r
+ \r
+ if (!locked) {\r
+ locked = true;\r
+ \r
+ Ext.each(onAvailStack, function (v,i,a){\r
+ if(v && (element = doc.getElementById(v.id))){\r
+ if(!v.checkReady || loadComplete || element.nextSibling || (doc && doc.body)) {\r
+ element = v.override ? (v.override === true ? v.obj : v.override) : element;\r
+ v.fn.call(element, v.obj);\r
+ onAvailStack[i] = null;\r
+ } else {\r
+ notAvail.push(v);\r
+ }\r
+ } \r
+ });\r
+\r
+ retryCount = (notAvail.length === 0) ? 0 : retryCount - 1;\r
+\r
+ if (tryAgain) { \r
+ startInterval();\r
+ } else {\r
+ clearInterval(_interval);\r
+ _interval = null;\r
+ }\r
+\r
+ ret = !(locked = false);\r
+ }\r
+ return ret;\r
+ }\r
+ \r
+ // private \r
+ function startInterval() { \r
+ if(!_interval){ \r
+ var callback = function() {\r
+ _tryPreloadAttach();\r
+ };\r
+ _interval = setInterval(callback, POLL_INTERVAL);\r
+ }\r
+ }\r
+ \r
+ // private \r
+ function getScroll() {\r
+ var dd = doc.documentElement, \r
+ db = doc.body;\r
+ if(dd && (dd[SCROLLTOP] || dd[SCROLLLEFT])){\r
+ return [dd[SCROLLLEFT], dd[SCROLLTOP]];\r
+ }else if(db){\r
+ return [db[SCROLLLEFT], db[SCROLLTOP]];\r
+ }else{\r
+ return [0, 0];\r
+ }\r
+ }\r
+ \r
+ // private\r
+ function getPageCoord (ev, xy) {\r
+ ev = ev.browserEvent || ev;\r
+ var coord = ev['page' + xy];\r
+ if (!coord && coord !== 0) {\r
+ coord = ev['client' + xy] || 0;\r
+\r
+ if (Ext.isIE) {\r
+ coord += getScroll()[xy == "X" ? 0 : 1];\r
+ }\r
+ }\r
+\r
+ return coord;\r
+ }\r
+\r
+ var pub = {\r
+ onAvailable : function(p_id, p_fn, p_obj, p_override) { \r
+ onAvailStack.push({ \r
+ id: p_id,\r
+ fn: p_fn,\r
+ obj: p_obj,\r
+ override: p_override,\r
+ checkReady: false });\r
+\r
+ retryCount = POLL_RETRYS;\r
+ startInterval();\r
+ },\r
+\r
+\r
+ addListener: function(el, eventName, fn) {\r
+ var ret; \r
+ el = Ext.getDom(el); \r
+ if (el && fn) {\r
+ if (UNLOAD == eventName) {\r
+ ret = !!(unloadListeners[unloadListeners.length] = [el, eventName, fn]); \r
+ } else {\r
+ listeners.push([el, eventName, fn, ret = doAdd(el, eventName, fn, false)]);\r
+ }\r
+ }\r
+ return !!ret;\r
+ },\r
+\r
+ removeListener: function(el, eventName, fn) {\r
+ var ret = false,\r
+ index, \r
+ cacheItem;\r
+\r
+ el = Ext.getDom(el);\r
+\r
+ if(!fn) { \r
+ ret = this.purgeElement(el, false, eventName);\r
+ } else if (UNLOAD == eventName) { \r
+ Ext.each(unloadListeners, function(v, i, a) {\r
+ if( v && v[0] == el && v[1] == eventName && v[2] == fn) {\r
+ unloadListeners.splice(i, 1);\r
+ ret = true;\r
+ }\r
+ });\r
+ } else { \r
+ index = arguments[3] || _getCacheIndex(el, eventName, fn);\r
+ cacheItem = listeners[index];\r
+ \r
+ if (el && cacheItem) {\r
+ doRemove(el, eventName, cacheItem[WFN], false); \r
+ cacheItem[WFN] = cacheItem[FN] = null; \r
+ listeners.splice(index, 1); \r
+ ret = true;\r
+ }\r
+ }\r
+ return ret;\r
+ },\r
+\r
+ getTarget : function(ev) {\r
+ ev = ev.browserEvent || ev; \r
+ return this.resolveTextNode(ev.target || ev.srcElement);\r
+ },\r
+\r
+ resolveTextNode : function(node) {\r
+ return node && !isXUL(node) && isTextNode(node) ? node.parentNode : node;\r
+ },\r
+\r
+ getRelatedTarget : function(ev) {\r
+ ev = ev.browserEvent || ev;\r
+ return this.resolveTextNode(ev.relatedTarget || \r
+ (ev.type == MOUSEOUT ? ev.toElement :\r
+ ev.type == MOUSEOVER ? ev.fromElement : null));\r
+ },\r
+ \r
+ getPageX : function(ev) {\r
+ return getPageCoord(ev, "X");\r
+ },\r
+\r
+ getPageY : function(ev) {\r
+ return getPageCoord(ev, "Y");\r
+ },\r
+\r
+\r
+ getXY : function(ev) { \r
+ return [this.getPageX(ev), this.getPageY(ev)];\r
+ },\r
+\r
+// Is this useful? Removing to save space unless use case exists.\r
+// getTime: function(ev) {\r
+// ev = ev.browserEvent || ev;\r
+// if (!ev.time) {\r
+// var t = new Date().getTime();\r
+// try {\r
+// ev.time = t;\r
+// } catch(ex) {\r
+// return t;\r
+// }\r
+// }\r
+\r
+// return ev.time;\r
+// },\r
+\r
+ stopEvent : function(ev) { \r
+ this.stopPropagation(ev);\r
+ this.preventDefault(ev);\r
+ },\r
+\r
+ stopPropagation : function(ev) {\r
+ ev = ev.browserEvent || ev;\r
+ if (ev.stopPropagation) {\r
+ ev.stopPropagation();\r
+ } else {\r
+ ev.cancelBubble = true;\r
+ }\r
+ },\r
+\r
+ preventDefault : function(ev) {\r
+ ev = ev.browserEvent || ev;\r
+ if (ev.preventDefault) {\r
+ ev.preventDefault();\r
+ } else {\r
+ ev.returnValue = false;\r
+ }\r
+ },\r
+ \r
+ getEvent : function(e) {\r
+ e = e || win.event;\r
+ if (!e) {\r
+ var c = this.getEvent.caller;\r
+ while (c) {\r
+ e = c.arguments[0];\r
+ if (e && Event == e.constructor) {\r
+ break;\r
+ }\r
+ c = c.caller;\r
+ }\r
+ }\r
+ return e;\r
+ },\r
+\r
+ getCharCode : function(ev) {\r
+ ev = ev.browserEvent || ev;\r
+ return ev.charCode || ev.keyCode || 0;\r
+ },\r
+\r
+ //clearCache: function() {},\r
+\r
+ _load : function(e) {\r
+ loadComplete = true;\r
+ var EU = Ext.lib.Event; \r
+ if (Ext.isIE && e !== true) {\r
+ // IE8 complains that _load is null or not an object\r
+ // so lets remove self via arguments.callee\r
+ doRemove(win, "load", arguments.callee);\r
+ }\r
+ }, \r
+ \r
+ purgeElement : function(el, recurse, eventName) {\r
+ var me = this;\r
+ Ext.each( me.getListeners(el, eventName), function(v){\r
+ if(v){\r
+ me.removeListener(el, v.type, v.fn);\r
+ }\r
+ });\r
+\r
+ if (recurse && el && el.childNodes) {\r
+ Ext.each(el.childNodes, function(v){\r
+ me.purgeElement(v, recurse, eventName);\r
+ });\r
+ }\r
+ },\r
+\r
+ getListeners : function(el, eventName) {\r
+ var me = this,\r
+ results = [], \r
+ searchLists;\r
+\r
+ if (eventName){ \r
+ searchLists = eventName == UNLOAD ? unloadListeners : listeners;\r
+ }else{\r
+ searchLists = listeners.concat(unloadListeners);\r
+ }\r
+\r
+ Ext.each(searchLists, function(v, i){\r
+ if (v && v[EL] == el && (!eventName || eventName == v[TYPE])) {\r
+ results.push({\r
+ type: v[TYPE],\r
+ fn: v[FN],\r
+ obj: v[OBJ],\r
+ adjust: v[ADJ_SCOPE],\r
+ index: i\r
+ });\r
+ } \r
+ }); \r
+\r
+ return results.length ? results : null;\r
+ },\r
+\r
+ _unload : function(e) {\r
+ var EU = Ext.lib.Event, \r
+ i, \r
+ j, \r
+ l, \r
+ len, \r
+ index,\r
+ scope;\r
+ \r
+\r
+ Ext.each(unloadListeners, function(v) {\r
+ if (v) {\r
+ try{\r
+ scope = v[ADJ_SCOPE] ? (v[ADJ_SCOPE] === true ? v[OBJ] : v[ADJ_SCOPE]) : win; \r
+ v[FN].call(scope, EU.getEvent(e), v[OBJ]);\r
+ }catch(ex){}\r
+ } \r
+ }); \r
+\r
+ unloadListeners = null;\r
+\r
+ if(listeners && (j = listeners.length)){ \r
+ while(j){ \r
+ if((l = listeners[index = --j])){\r
+ EU.removeListener(l[EL], l[TYPE], l[FN], index);\r
+ } \r
+ }\r
+ //EU.clearCache();\r
+ }\r
+\r
+ doRemove(win, UNLOAD, EU._unload);\r
+ } \r
+ }; \r
+ \r
+ // Initialize stuff.\r
+ pub.on = pub.addListener;\r
+ pub.un = pub.removeListener;\r
+ if (doc && doc.body) {\r
+ pub._load(true);\r
+ } else {\r
+ doAdd(win, "load", pub._load);\r
+ }\r
+ doAdd(win, UNLOAD, pub._unload); \r
+ _tryPreloadAttach();\r
+ \r
+ return pub;\r
+}();</pre> \r
+</body>\r
+</html>
\ No newline at end of file