-<html>\r
-<head>\r
- <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> \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"><div id="cls-Ext.EventManager"></div>/**\r
- * @class Ext.EventManager\r
- * Registers event handlers that want to receive a normalized EventObject instead of the standard browser event and provides\r
- * several useful events directly.\r
- * See {@link Ext.EventObject} for more details on normalized event objects.\r
- * @singleton\r
- */\r
-Ext.EventManager = function(){\r
- var docReadyEvent,\r
- docReadyProcId,\r
- docReadyState = false,\r
- E = Ext.lib.Event,\r
- D = Ext.lib.Dom,\r
- DOC = document,\r
- WINDOW = window,\r
- IEDEFERED = "ie-deferred-loader",\r
- DOMCONTENTLOADED = "DOMContentLoaded",\r
- propRe = /^(?:scope|delay|buffer|single|stopEvent|preventDefault|stopPropagation|normalized|args|delegate)$/,\r
- /*\r
- * This cache is used to hold special js objects, the document and window, that don't have an id. We need to keep\r
- * a reference to them so we can look them up at a later point.\r
- */\r
- specialElCache = [];\r
-\r
- function getId(el){\r
- var id = false,\r
- i = 0,\r
- len = specialElCache.length,\r
- id = false,\r
- skip = false,\r
- o;\r
- if(el){\r
- if(el.getElementById || el.navigator){\r
- // look up the id\r
- for(; i < len; ++i){\r
- o = specialElCache[i];\r
- if(o.el === el){\r
- id = o.id;\r
- break;\r
- }\r
- }\r
- if(!id){\r
- // for browsers that support it, ensure that give the el the same id\r
- id = Ext.id(el);\r
- specialElCache.push({\r
- id: id,\r
- el: el\r
- });\r
- skip = true;\r
- }\r
- }else{\r
- id = Ext.id(el);\r
- }\r
- if(!Ext.elCache[id]){\r
- Ext.Element.addToCache(new Ext.Element(el), id);\r
- if(skip){\r
- Ext.elCache[id].skipGC = true;\r
- }\r
- }\r
- }\r
- return id;\r
- };\r
-\r
- /// There is some jquery work around stuff here that isn't needed in Ext Core.\r
- function addListener(el, ename, fn, wrap, scope){\r
- el = Ext.getDom(el);\r
- var id = getId(el),\r
- es = Ext.elCache[id].events,\r
- wfn;\r
-\r
- wfn = E.on(el, ename, wrap);\r
- es[ename] = es[ename] || [];\r
- es[ename].push([fn, wrap, scope, wfn]);\r
-\r
- // this is a workaround for jQuery and should somehow be removed from Ext Core in the future\r
- // without breaking ExtJS.\r
- if(ename == "mousewheel" && el.addEventListener){ // workaround for jQuery\r
- var args = ["DOMMouseScroll", wrap, false];\r
- el.addEventListener.apply(el, args);\r
- Ext.EventManager.addListener(WINDOW, 'unload', function(){\r
- el.removeEventListener.apply(el, args);\r
- });\r
- }\r
- if(ename == "mousedown" && el == document){ // fix stopped mousedowns on the document\r
- Ext.EventManager.stoppedMouseDownEvent.addListener(wrap);\r
- }\r
- };\r
-\r
- function fireDocReady(){\r
- if(!docReadyState){\r
- Ext.isReady = docReadyState = true;\r
- if(docReadyProcId){\r
- clearInterval(docReadyProcId);\r
- }\r
- if(Ext.isGecko || Ext.isOpera) {\r
- DOC.removeEventListener(DOMCONTENTLOADED, fireDocReady, false);\r
- }\r
- if(Ext.isIE){\r
- var defer = DOC.getElementById(IEDEFERED);\r
- if(defer){\r
- defer.onreadystatechange = null;\r
- defer.parentNode.removeChild(defer);\r
- }\r
- }\r
- if(docReadyEvent){\r
- docReadyEvent.fire();\r
- docReadyEvent.listeners = []; // clearListeners no longer compatible. Force single: true?\r
- }\r
- }\r
- };\r
-\r
- function initDocReady(){\r
- var COMPLETE = "complete";\r
-\r
- docReadyEvent = new Ext.util.Event();\r
- if (Ext.isGecko || Ext.isOpera) {\r
- DOC.addEventListener(DOMCONTENTLOADED, fireDocReady, false);\r
- } else if (Ext.isIE){\r
- DOC.write("<s"+'cript id=' + IEDEFERED + ' defer="defer" src="/'+'/:"></s'+"cript>");\r
- DOC.getElementById(IEDEFERED).onreadystatechange = function(){\r
- if(this.readyState == COMPLETE){\r
- fireDocReady();\r
- }\r
- };\r
- } else if (Ext.isWebKit){\r
- docReadyProcId = setInterval(function(){\r
- if(DOC.readyState == COMPLETE) {\r
- fireDocReady();\r
- }\r
- }, 10);\r
- }\r
- // no matter what, make sure it fires on load\r
- E.on(WINDOW, "load", fireDocReady);\r
- };\r
-\r
- function createTargeted(h, o){\r
- return function(){\r
- var args = Ext.toArray(arguments);\r
- if(o.target == Ext.EventObject.setEvent(args[0]).target){\r
- h.apply(this, args);\r
- }\r
- };\r
- };\r
-\r
- function createBuffered(h, o, fn){\r
- fn.task = new Ext.util.DelayedTask(h);\r
- var w = function(e){\r
- // create new event object impl so new events don't wipe out properties\r
- fn.task.delay(o.buffer, h, null, [new Ext.EventObjectImpl(e)]);\r
- };\r
- return w;\r
- };\r
-\r
- function createSingle(h, el, ename, fn, scope){\r
- return function(e){\r
- Ext.EventManager.removeListener(el, ename, fn, scope);\r
- h(e);\r
- };\r
- };\r
-\r
- function createDelayed(h, o, fn){\r
- return function(e){\r
- var task = new Ext.util.DelayedTask(h);\r
- if(!fn.tasks) {\r
- fn.tasks = [];\r
- }\r
- fn.tasks.push(task);\r
- task.delay(o.delay || 10, h, null, [new Ext.EventObjectImpl(e)]);\r
- };\r
- };\r
-\r
- function listen(element, ename, opt, fn, scope){\r
- var o = !Ext.isObject(opt) ? {} : opt,\r
- el = Ext.getDom(element);\r
-\r
- fn = fn || o.fn;\r
- scope = scope || o.scope;\r
-\r
- if(!el){\r
- throw "Error listening for \"" + ename + '\". Element "' + element + '" doesn\'t exist.';\r
- }\r
- function h(e){\r
- // prevent errors while unload occurring\r
- if(!Ext){// !window[xname]){ ==> can't we do this?\r
- return;\r
- }\r
- e = Ext.EventObject.setEvent(e);\r
- var t;\r
- if (o.delegate) {\r
- if(!(t = e.getTarget(o.delegate, el))){\r
- return;\r
- }\r
- } else {\r
- t = e.target;\r
- }\r
- if (o.stopEvent) {\r
- e.stopEvent();\r
- }\r
- if (o.preventDefault) {\r
- e.preventDefault();\r
- }\r
- if (o.stopPropagation) {\r
- e.stopPropagation();\r
- }\r
- if (o.normalized) {\r
- e = e.browserEvent;\r
- }\r
-\r
- fn.call(scope || el, e, t, o);\r
- };\r
- if(o.target){\r
- h = createTargeted(h, o);\r
- }\r
- if(o.delay){\r
- h = createDelayed(h, o, fn);\r
- }\r
- if(o.single){\r
- h = createSingle(h, el, ename, fn, scope);\r
- }\r
- if(o.buffer){\r
- h = createBuffered(h, o, fn);\r
- }\r
-\r
- addListener(el, ename, fn, h, scope);\r
- return h;\r
- };\r
-\r
- var pub = {\r
- <div id="method-Ext.EventManager-addListener"></div>/**\r
- * Appends an event handler to an element. The shorthand version {@link #on} is equivalent. Typically you will\r
- * use {@link Ext.Element#addListener} directly on an Element in favor of calling this version.\r
- * @param {String/HTMLElement} el The html element or id to assign the event handler to.\r
- * @param {String} eventName The name of the event to listen for.\r
- * @param {Function} handler The handler function the event invokes. This function is passed\r
- * the following parameters:<ul>\r
- * <li>evt : EventObject<div class="sub-desc">The {@link Ext.EventObject EventObject} describing the event.</div></li>\r
- * <li>t : Element<div class="sub-desc">The {@link Ext.Element Element} which was the target of the event.\r
- * Note that this may be filtered by using the <tt>delegate</tt> option.</div></li>\r
- * <li>o : Object<div class="sub-desc">The options object from the addListener call.</div></li>\r
- * </ul>\r
- * @param {Object} scope (optional) The scope (<b><code>this</code></b> reference) in which the handler function is executed. <b>Defaults to the Element</b>.\r
- * @param {Object} options (optional) An object containing handler configuration properties.\r
- * This may contain any of the following properties:<ul>\r
- * <li>scope : Object<div class="sub-desc">The scope (<b><code>this</code></b> reference) in which the handler function is executed. <b>Defaults to the Element</b>.</div></li>\r
- * <li>delegate : String<div class="sub-desc">A simple selector to filter the target or look for a descendant of the target</div></li>\r
- * <li>stopEvent : Boolean<div class="sub-desc">True to stop the event. That is stop propagation, and prevent the default action.</div></li>\r
- * <li>preventDefault : Boolean<div class="sub-desc">True to prevent the default action</div></li>\r
- * <li>stopPropagation : Boolean<div class="sub-desc">True to prevent event propagation</div></li>\r
- * <li>normalized : Boolean<div class="sub-desc">False to pass a browser event to the handler function instead of an Ext.EventObject</div></li>\r
- * <li>delay : Number<div class="sub-desc">The number of milliseconds to delay the invocation of the handler after te event fires.</div></li>\r
- * <li>single : Boolean<div class="sub-desc">True to add a handler to handle just the next firing of the event, and then remove itself.</div></li>\r
- * <li>buffer : Number<div class="sub-desc">Causes the handler to be scheduled to run in an {@link Ext.util.DelayedTask} delayed\r
- * by the specified number of milliseconds. If the event fires again within that time, the original\r
- * handler is <em>not</em> invoked, but the new handler is scheduled in its place.</div></li>\r
- * <li>target : Element<div class="sub-desc">Only call the handler if the event was fired on the target Element, <i>not</i> if the event was bubbled up from a child node.</div></li>\r
- * </ul><br>\r
- * <p>See {@link Ext.Element#addListener} for examples of how to use these options.</p>\r
- */\r
- addListener : function(element, eventName, fn, scope, options){\r
- if(Ext.isObject(eventName)){\r
- var o = eventName, e, val;\r
- for(e in o){\r
- val = o[e];\r
- if(!propRe.test(e)){\r
- if(Ext.isFunction(val)){\r
- // shared options\r
- listen(element, e, o, val, o.scope);\r
- }else{\r
- // individual options\r
- listen(element, e, val);\r
- }\r
- }\r
- }\r
- } else {\r
- listen(element, eventName, options, fn, scope);\r
- }\r
- },\r
-\r
- <div id="method-Ext.EventManager-removeListener"></div>/**\r
- * Removes an event handler from an element. The shorthand version {@link #un} is equivalent. Typically\r
- * you will use {@link Ext.Element#removeListener} directly on an Element in favor of calling this version.\r
- * @param {String/HTMLElement} el The id or html element from which to remove the listener.\r
- * @param {String} eventName The name of the event.\r
- * @param {Function} fn The handler function to remove. <b>This must be a reference to the function passed into the {@link #addListener} call.</b>\r
- * @param {Object} scope If a scope (<b><code>this</code></b> reference) was specified when the listener was added,\r
- * then this must refer to the same object.\r
- */\r
- removeListener : function(el, eventName, fn, scope){\r
- el = Ext.getDom(el);\r
- var id = getId(el),\r
- f = el && (Ext.elCache[id].events)[eventName] || [],\r
- wrap, i, l, k, wf;\r
-\r
- for (i = 0, len = f.length; i < len; i++) {\r
- if (Ext.isArray(f[i]) && f[i][0] == fn && (!scope || f[i][2] == scope)) {\r
- if(fn.task) {\r
- fn.task.cancel();\r
- delete fn.task;\r
- }\r
- k = fn.tasks && fn.tasks.length;\r
- if(k) {\r
- while(k--) {\r
- fn.tasks[k].cancel();\r
- }\r
- delete fn.tasks;\r
- }\r
- wf = wrap = f[i][1];\r
- if (E.extAdapter) {\r
- wf = f[i][3];\r
- }\r
- E.un(el, eventName, wf);\r
- f.splice(i,1);\r
- if (f.length === 0) {\r
- delete Ext.elCache[id].events[eventName];\r
- }\r
- for (k in Ext.elCache[id].events) {\r
- return false;\r
- }\r
- Ext.elCache[id].events = {};\r
- return false;\r
- }\r
- }\r
-\r
- // jQuery workaround that should be removed from Ext Core\r
- if(eventName == "mousewheel" && el.addEventListener && wrap){\r
- el.removeEventListener("DOMMouseScroll", wrap, false);\r
- }\r
-\r
- if(eventName == "mousedown" && el == DOC && wrap){ // fix stopped mousedowns on the document\r
- Ext.EventManager.stoppedMouseDownEvent.removeListener(wrap);\r
- }\r
- },\r
-\r
- <div id="method-Ext.EventManager-removeAll"></div>/**\r
- * Removes all event handers from an element. Typically you will use {@link Ext.Element#removeAllListeners}\r
- * directly on an Element in favor of calling this version.\r
- * @param {String/HTMLElement} el The id or html element from which to remove all event handlers.\r
- */\r
- removeAll : function(el){\r
- el = Ext.getDom(el);\r
- var id = getId(el),\r
- ec = Ext.elCache[id] || {},\r
- es = ec.events || {},\r
- f, i, len, ename, fn, k;\r
-\r
- for(ename in es){\r
- if(es.hasOwnProperty(ename)){\r
- f = es[ename];\r
- for (i = 0, len = f.length; i < len; i++) {\r
- fn = f[i][0];\r
- if(fn.task) {\r
- fn.task.cancel();\r
- delete fn.task;\r
- }\r
- if(fn.tasks && (k = fn.tasks.length)) {\r
- while(k--) {\r
- fn.tasks[k].cancel();\r
- }\r
- delete fn.tasks;\r
- }\r
- E.un(el, ename, E.extAdapter ? f[i][3] : f[i][1]);\r
- }\r
- }\r
- }\r
- if (Ext.elCache[id]) {\r
- Ext.elCache[id].events = {};\r
- }\r
- },\r
-\r
- getListeners : function(el, eventName) {\r
- el = Ext.getDom(el);\r
- var id = getId(el),\r
- ec = Ext.elCache[id] || {},\r
- es = ec.events || {},\r
- results = [];\r
- if (es && es[eventName]) {\r
- return es[eventName];\r
- } else {\r
- return null;\r
- }\r
- },\r
-\r
- purgeElement : function(el, recurse, eventName) {\r
- el = Ext.getDom(el);\r
- var id = getId(el),\r
- ec = Ext.elCache[id] || {},\r
- es = ec.events || {},\r
- i, f, len;\r
- if (eventName) {\r
- if (es && es.hasOwnProperty(eventName)) {\r
- f = es[eventName];\r
- for (i = 0, len = f.length; i < len; i++) {\r
- Ext.EventManager.removeListener(el, eventName, f[i][0]);\r
- }\r
- }\r
- } else {\r
- Ext.EventManager.removeAll(el);\r
- }\r
- if (recurse && el && el.childNodes) {\r
- for (i = 0, len = el.childNodes.length; i < len; i++) {\r
- Ext.EventManager.purgeElement(el.childNodes[i], recurse, eventName);\r
- }\r
- }\r
- },\r
-\r
- _unload : function() {\r
- var el;\r
- for (el in Ext.elCache) {\r
- Ext.EventManager.removeAll(el);\r
- }\r
- },\r
- <div id="method-Ext.EventManager-onDocumentReady"></div>/**\r
- * Adds a listener to be notified when the document is ready (before onload and before images are loaded). Can be\r
- * accessed shorthanded as Ext.onReady().\r
- * @param {Function} fn The method the event invokes.\r
- * @param {Object} scope (optional) The scope (<code>this</code> reference) in which the handler function executes. Defaults to the browser window.\r
- * @param {boolean} options (optional) Options object as passed to {@link Ext.Element#addListener}. It is recommended that the options\r
- * <code>{single: true}</code> be used so that the handler is removed on first invocation.\r
- */\r
- onDocumentReady : function(fn, scope, options){\r
- if(docReadyState){ // if it already fired\r
- docReadyEvent.addListener(fn, scope, options);\r
- docReadyEvent.fire();\r
- docReadyEvent.listeners = []; // clearListeners no longer compatible. Force single: true?\r
- } else {\r
- if(!docReadyEvent) initDocReady();\r
- options = options || {};\r
- options.delay = options.delay || 1;\r
- docReadyEvent.addListener(fn, scope, options);\r
- }\r
- }\r
- };\r
- <div id="method-Ext.EventManager-on"></div>/**\r
- * Appends an event handler to an element. Shorthand for {@link #addListener}.\r
- * @param {String/HTMLElement} el The html element or id to assign the event handler to\r
- * @param {String} eventName The name of the event to listen for.\r
- * @param {Function} handler The handler function the event invokes.\r
- * @param {Object} scope (optional) (<code>this</code> reference) in which the handler function executes. <b>Defaults to the Element</b>.\r
- * @param {Object} options (optional) An object containing standard {@link #addListener} options\r
- * @member Ext.EventManager\r
- * @method on\r
- */\r
- pub.on = pub.addListener;\r
- <div id="method-Ext.EventManager-un"></div>/**\r
- * Removes an event handler from an element. Shorthand for {@link #removeListener}.\r
- * @param {String/HTMLElement} el The id or html element from which to remove the listener.\r
- * @param {String} eventName The name of the event.\r
- * @param {Function} fn The handler function to remove. <b>This must be a reference to the function passed into the {@link #on} call.</b>\r
- * @param {Object} scope If a scope (<b><code>this</code></b> reference) was specified when the listener was added,\r
- * then this must refer to the same object.\r
- * @member Ext.EventManager\r
- * @method un\r
- */\r
- pub.un = pub.removeListener;\r
-\r
- pub.stoppedMouseDownEvent = new Ext.util.Event();\r
- return pub;\r
-}();\r
-<div id="method-Ext-onReady"></div>/**\r
- * Adds a listener to be notified when the document is ready (before onload and before images are loaded). Shorthand of {@link Ext.EventManager#onDocumentReady}.\r
- * @param {Function} fn The method the event invokes.\r
- * @param {Object} scope (optional) The scope (<code>this</code> reference) in which the handler function executes. Defaults to the browser window.\r
- * @param {boolean} options (optional) Options object as passed to {@link Ext.Element#addListener}. It is recommended that the options\r
- * <code>{single: true}</code> be used so that the handler is removed on first invocation.\r
- * @member Ext\r
- * @method onReady\r
- */\r
-Ext.onReady = Ext.EventManager.onDocumentReady;\r
-\r
-\r
-//Initialize doc classes\r
-(function(){\r
-\r
- var initExtCss = function(){\r
- // find the body element\r
- var bd = document.body || document.getElementsByTagName('body')[0];\r
- if(!bd){ return false; }\r
- var cls = [' ',\r
- Ext.isIE ? "ext-ie " + (Ext.isIE6 ? 'ext-ie6' : (Ext.isIE7 ? 'ext-ie7' : 'ext-ie8'))\r
- : Ext.isGecko ? "ext-gecko " + (Ext.isGecko2 ? 'ext-gecko2' : 'ext-gecko3')\r
- : Ext.isOpera ? "ext-opera"\r
- : Ext.isWebKit ? "ext-webkit" : ""];\r
-\r
- if(Ext.isSafari){\r
- cls.push("ext-safari " + (Ext.isSafari2 ? 'ext-safari2' : (Ext.isSafari3 ? 'ext-safari3' : 'ext-safari4')));\r
- }else if(Ext.isChrome){\r
- cls.push("ext-chrome");\r
- }\r
-\r
- if(Ext.isMac){\r
- cls.push("ext-mac");\r
- }\r
- if(Ext.isLinux){\r
- cls.push("ext-linux");\r
- }\r
-\r
- if(Ext.isStrict || Ext.isBorderBox){ // add to the parent to allow for selectors like ".ext-strict .ext-ie"\r
- var p = bd.parentNode;\r
- if(p){\r
- p.className += Ext.isStrict ? ' ext-strict' : ' ext-border-box';\r
- }\r
- }\r
- bd.className += cls.join(' ');\r
- return true;\r
- }\r
-\r
- if(!initExtCss()){\r
- Ext.onReady(initExtCss);\r
- }\r
-})();\r
-\r
-\r
-<div id="cls-Ext.EventObject"></div>/**\r
- * @class Ext.EventObject\r
- * Just as {@link Ext.Element} wraps around a native DOM node, Ext.EventObject\r
- * wraps the browser's native event-object normalizing cross-browser differences,\r
- * such as which mouse button is clicked, keys pressed, mechanisms to stop\r
- * event-propagation along with a method to prevent default actions from taking place.\r
- * <p>For example:</p>\r
- * <pre><code>\r
-function handleClick(e, t){ // e is not a standard event object, it is a Ext.EventObject\r
- e.preventDefault();\r
- var target = e.getTarget(); // same as t (the target HTMLElement)\r
- ...\r
-}\r
-var myDiv = {@link Ext#get Ext.get}("myDiv"); // get reference to an {@link Ext.Element}\r
-myDiv.on( // 'on' is shorthand for addListener\r
- "click", // perform an action on click of myDiv\r
- handleClick // reference to the action handler\r
-);\r
-// other methods to do the same:\r
-Ext.EventManager.on("myDiv", 'click', handleClick);\r
-Ext.EventManager.addListener("myDiv", 'click', handleClick);\r
- </code></pre>\r
- * @singleton\r
- */\r
-Ext.EventObject = function(){\r
- var E = Ext.lib.Event,\r
- // safari keypress events for special keys return bad keycodes\r
- safariKeys = {\r
- 3 : 13, // enter\r
- 63234 : 37, // left\r
- 63235 : 39, // right\r
- 63232 : 38, // up\r
- 63233 : 40, // down\r
- 63276 : 33, // page up\r
- 63277 : 34, // page down\r
- 63272 : 46, // delete\r
- 63273 : 36, // home\r
- 63275 : 35 // end\r
- },\r
- // normalize button clicks\r
- btnMap = Ext.isIE ? {1:0,4:1,2:2} :\r
- (Ext.isWebKit ? {1:0,2:1,3:2} : {0:0,1:1,2:2});\r
-\r
- Ext.EventObjectImpl = function(e){\r
- if(e){\r
- this.setEvent(e.browserEvent || e);\r
- }\r
- };\r
-\r
- Ext.EventObjectImpl.prototype = {\r
- /** @private */\r
- setEvent : function(e){\r
- var me = this;\r
- if(e == me || (e && e.browserEvent)){ // already wrapped\r
- return e;\r
- }\r
- me.browserEvent = e;\r
- if(e){\r
- // normalize buttons\r
- me.button = e.button ? btnMap[e.button] : (e.which ? e.which - 1 : -1);\r
- if(e.type == 'click' && me.button == -1){\r
- me.button = 0;\r
- }\r
- me.type = e.type;\r
- me.shiftKey = e.shiftKey;\r
- // mac metaKey behaves like ctrlKey\r
- me.ctrlKey = e.ctrlKey || e.metaKey || false;\r
- me.altKey = e.altKey;\r
- // in getKey these will be normalized for the mac\r
- me.keyCode = e.keyCode;\r
- me.charCode = e.charCode;\r
- // cache the target for the delayed and or buffered events\r
- me.target = E.getTarget(e);\r
- // same for XY\r
- me.xy = E.getXY(e);\r
- }else{\r
- me.button = -1;\r
- me.shiftKey = false;\r
- me.ctrlKey = false;\r
- me.altKey = false;\r
- me.keyCode = 0;\r
- me.charCode = 0;\r
- me.target = null;\r
- me.xy = [0, 0];\r
- }\r
- return me;\r
- },\r
-\r
- <div id="method-Ext.EventObject-stopEvent"></div>/**\r
- * Stop the event (preventDefault and stopPropagation)\r
- */\r
- stopEvent : function(){\r
- var me = this;\r
- if(me.browserEvent){\r
- if(me.browserEvent.type == 'mousedown'){\r
- Ext.EventManager.stoppedMouseDownEvent.fire(me);\r
- }\r
- E.stopEvent(me.browserEvent);\r
- }\r
- },\r
-\r
- <div id="method-Ext.EventObject-preventDefault"></div>/**\r
- * Prevents the browsers default handling of the event.\r
- */\r
- preventDefault : function(){\r
- if(this.browserEvent){\r
- E.preventDefault(this.browserEvent);\r
- }\r
- },\r
-\r
- <div id="method-Ext.EventObject-stopPropagation"></div>/**\r
- * Cancels bubbling of the event.\r
- */\r
- stopPropagation : function(){\r
- var me = this;\r
- if(me.browserEvent){\r
- if(me.browserEvent.type == 'mousedown'){\r
- Ext.EventManager.stoppedMouseDownEvent.fire(me);\r
- }\r
- E.stopPropagation(me.browserEvent);\r
- }\r
- },\r
-\r
- <div id="method-Ext.EventObject-getCharCode"></div>/**\r
- * Gets the character code for the event.\r
- * @return {Number}\r
- */\r
- getCharCode : function(){\r
- return this.charCode || this.keyCode;\r
- },\r
-\r
- <div id="method-Ext.EventObject-getKey"></div>/**\r
- * Returns a normalized keyCode for the event.\r
- * @return {Number} The key code\r
- */\r
- getKey : function(){\r
- return this.normalizeKey(this.keyCode || this.charCode)\r
- },\r
-\r
- // private\r
- normalizeKey: function(k){\r
- return Ext.isSafari ? (safariKeys[k] || k) : k;\r
- },\r
-\r
- <div id="method-Ext.EventObject-getPageX"></div>/**\r
- * Gets the x coordinate of the event.\r
- * @return {Number}\r
- */\r
- getPageX : function(){\r
- return this.xy[0];\r
- },\r
-\r
- <div id="method-Ext.EventObject-getPageY"></div>/**\r
- * Gets the y coordinate of the event.\r
- * @return {Number}\r
- */\r
- getPageY : function(){\r
- return this.xy[1];\r
- },\r
-\r
- <div id="method-Ext.EventObject-getXY"></div>/**\r
- * Gets the page coordinates of the event.\r
- * @return {Array} The xy values like [x, y]\r
- */\r
- getXY : function(){\r
- return this.xy;\r
- },\r
-\r
- <div id="method-Ext.EventObject-getTarget"></div>/**\r
- * Gets the target for the event.\r
- * @param {String} selector (optional) A simple selector to filter the target or look for an ancestor of the target\r
- * @param {Number/Mixed} maxDepth (optional) The max depth to\r
- search as a number or element (defaults to 10 || document.body)\r
- * @param {Boolean} returnEl (optional) True to return a Ext.Element object instead of DOM node\r
- * @return {HTMLelement}\r
- */\r
- getTarget : function(selector, maxDepth, returnEl){\r
- return selector ? Ext.fly(this.target).findParent(selector, maxDepth, returnEl) : (returnEl ? Ext.get(this.target) : this.target);\r
- },\r
-\r
- <div id="method-Ext.EventObject-getRelatedTarget"></div>/**\r
- * Gets the related target.\r
- * @return {HTMLElement}\r
- */\r
- getRelatedTarget : function(){\r
- return this.browserEvent ? E.getRelatedTarget(this.browserEvent) : null;\r
- },\r
-\r
- <div id="method-Ext.EventObject-getWheelDelta"></div>/**\r
- * Normalizes mouse wheel delta across browsers\r
- * @return {Number} The delta\r
- */\r
- getWheelDelta : function(){\r
- var e = this.browserEvent;\r
- var delta = 0;\r
- if(e.wheelDelta){ /* IE/Opera. */\r
- delta = e.wheelDelta/120;\r
- }else if(e.detail){ /* Mozilla case. */\r
- delta = -e.detail/3;\r
- }\r
- return delta;\r
- },\r
-\r
- <div id="method-Ext.EventObject-within"></div>/**\r
- * Returns true if the target of this event is a child of el. Unless the allowEl parameter is set, it will return false if if the target is el.\r
- * Example usage:<pre><code>\r
- // Handle click on any child of an element\r
- Ext.getBody().on('click', function(e){\r
- if(e.within('some-el')){\r
- alert('Clicked on a child of some-el!');\r
- }\r
- });\r
-\r
- // Handle click directly on an element, ignoring clicks on child nodes\r
- Ext.getBody().on('click', function(e,t){\r
- if((t.id == 'some-el') && !e.within(t, true)){\r
- alert('Clicked directly on some-el!');\r
- }\r
- });\r
- </code></pre>\r
- * @param {Mixed} el The id, DOM element or Ext.Element to check\r
- * @param {Boolean} related (optional) true to test if the related target is within el instead of the target\r
- * @param {Boolean} allowEl {optional} true to also check if the passed element is the target or related target\r
- * @return {Boolean}\r
- */\r
- within : function(el, related, allowEl){\r
- if(el){\r
- var t = this[related ? "getRelatedTarget" : "getTarget"]();\r
- return t && ((allowEl ? (t == Ext.getDom(el)) : false) || Ext.fly(el).contains(t));\r
- }\r
- return false;\r
- }\r
- };\r
-\r
- return new Ext.EventObjectImpl();\r
-}();\r
-\r
-</pre> \r
-</body>\r
-</html>
\ No newline at end of file
+<!DOCTYPE html>
+<html>
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+ <title>The source code</title>
+ <link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" />
+ <script type="text/javascript" src="../resources/prettify/prettify.js"></script>
+ <style type="text/css">
+ .highlight { display: block; background-color: #ddd; }
+ </style>
+ <script type="text/javascript">
+ function highlight() {
+ document.getElementById(location.hash.replace(/#/, "")).className = "highlight";
+ }
+ </script>
+</head>
+<body onload="prettyPrint(); highlight();">
+ <pre class="prettyprint lang-js"><span id='Ext-EventManager'>/**
+</span> * @class Ext.EventManager
+ * Registers event handlers that want to receive a normalized EventObject instead of the standard browser event and provides
+ * several useful events directly.
+ * See {@link Ext.EventObject} for more details on normalized event objects.
+ * @singleton
+ */
+Ext.EventManager = {
+
+ // --------------------- onReady ---------------------
+
+<span id='Ext-EventManager-property-hasBoundOnReady'> /**
+</span> * Check if we have bound our global onReady listener
+ * @private
+ */
+ hasBoundOnReady: false,
+
+<span id='Ext-EventManager-property-hasFiredReady'> /**
+</span> * Check if fireDocReady has been called
+ * @private
+ */
+ hasFiredReady: false,
+
+<span id='Ext-EventManager-property-readyTimeout'> /**
+</span> * Timer for the document ready event in old IE versions
+ * @private
+ */
+ readyTimeout: null,
+
+<span id='Ext-EventManager-property-hasOnReadyStateChange'> /**
+</span> * Checks if we have bound an onreadystatechange event
+ * @private
+ */
+ hasOnReadyStateChange: false,
+
+<span id='Ext-EventManager-property-readyEvent'> /**
+</span> * Holds references to any onReady functions
+ * @private
+ */
+ readyEvent: new Ext.util.Event(),
+
+<span id='Ext-EventManager-method-checkReadyState'> /**
+</span> * Check the ready state for old IE versions
+ * @private
+ * @return {Boolean} True if the document is ready
+ */
+ checkReadyState: function(){
+ var me = Ext.EventManager;
+
+ if(window.attachEvent){
+ // See here for reference: http://javascript.nwbox.com/IEContentLoaded/
+ // licensed courtesy of http://developer.yahoo.com/yui/license.html
+ if (window != top) {
+ return false;
+ }
+ try{
+ document.documentElement.doScroll('left');
+ }catch(e){
+ return false;
+ }
+ me.fireDocReady();
+ return true;
+ }
+ if (document.readyState == 'complete') {
+ me.fireDocReady();
+ return true;
+ }
+ me.readyTimeout = setTimeout(arguments.callee, 2);
+ return false;
+ },
+
+<span id='Ext-EventManager-method-bindReadyEvent'> /**
+</span> * Binds the appropriate browser event for checking if the DOM has loaded.
+ * @private
+ */
+ bindReadyEvent: function(){
+ var me = Ext.EventManager;
+ if (me.hasBoundOnReady) {
+ return;
+ }
+
+ if (document.addEventListener) {
+ document.addEventListener('DOMContentLoaded', me.fireDocReady, false);
+ // fallback, load will ~always~ fire
+ window.addEventListener('load', me.fireDocReady, false);
+ } else {
+ // check if the document is ready, this will also kick off the scroll checking timer
+ if (!me.checkReadyState()) {
+ document.attachEvent('onreadystatechange', me.checkReadyState);
+ me.hasOnReadyStateChange = true;
+ }
+ // fallback, onload will ~always~ fire
+ window.attachEvent('onload', me.fireDocReady, false);
+ }
+ me.hasBoundOnReady = true;
+ },
+
+<span id='Ext-EventManager-method-fireDocReady'> /**
+</span> * We know the document is loaded, so trigger any onReady events.
+ * @private
+ */
+ fireDocReady: function(){
+ var me = Ext.EventManager;
+
+ // only unbind these events once
+ if (!me.hasFiredReady) {
+ me.hasFiredReady = true;
+
+ if (document.addEventListener) {
+ document.removeEventListener('DOMContentLoaded', me.fireDocReady, false);
+ window.removeEventListener('load', me.fireDocReady, false);
+ } else {
+ if (me.readyTimeout !== null) {
+ clearTimeout(me.readyTimeout);
+ }
+ if (me.hasOnReadyStateChange) {
+ document.detachEvent('onreadystatechange', me.checkReadyState);
+ }
+ window.detachEvent('onload', me.fireDocReady);
+ }
+ Ext.supports.init();
+ }
+ if (!Ext.isReady) {
+ Ext.isReady = true;
+ me.onWindowUnload();
+ me.readyEvent.fire();
+ }
+ },
+
+<span id='Ext-EventManager-method-onDocumentReady'> /**
+</span> * Adds a listener to be notified when the document is ready (before onload and before images are loaded). Can be
+ * accessed shorthanded as Ext.onReady().
+ * @param {Function} fn The method the event invokes.
+ * @param {Object} scope (optional) The scope (<code>this</code> reference) in which the handler function executes. Defaults to the browser window.
+ * @param {Boolean} options (optional) Options object as passed to {@link Ext.Element#addListener}.
+ */
+ onDocumentReady: function(fn, scope, options){
+ options = options || {};
+ var me = Ext.EventManager,
+ readyEvent = me.readyEvent;
+
+ // force single to be true so our event is only ever fired once.
+ options.single = true;
+
+ // Document already loaded, let's just fire it
+ if (Ext.isReady) {
+ readyEvent.addListener(fn, scope, options);
+ readyEvent.fire();
+ } else {
+ options.delay = options.delay || 1;
+ readyEvent.addListener(fn, scope, options);
+ me.bindReadyEvent();
+ }
+ },
+
+
+ // --------------------- event binding ---------------------
+
+<span id='Ext-EventManager-property-stoppedMouseDownEvent'> /**
+</span> * Contains a list of all document mouse downs, so we can ensure they fire even when stopEvent is called.
+ * @private
+ */
+ stoppedMouseDownEvent: new Ext.util.Event(),
+
+<span id='Ext-EventManager-property-propRe'> /**
+</span> * Options to parse for the 4th argument to addListener.
+ * @private
+ */
+ propRe: /^(?:scope|delay|buffer|single|stopEvent|preventDefault|stopPropagation|normalized|args|delegate|freezeEvent)$/,
+
+<span id='Ext-EventManager-method-getId'> /**
+</span> * Get the id of the element. If one has not been assigned, automatically assign it.
+ * @param {HTMLElement/Ext.Element} element The element to get the id for.
+ * @return {String} id
+ */
+ getId : function(element) {
+ var skipGarbageCollection = false,
+ id;
+
+ element = Ext.getDom(element);
+
+ if (element === document || element === window) {
+ id = element === document ? Ext.documentId : Ext.windowId;
+ }
+ else {
+ id = Ext.id(element);
+ }
+ // skip garbage collection for special elements (window, document, iframes)
+ if (element && (element.getElementById || element.navigator)) {
+ skipGarbageCollection = true;
+ }
+
+ if (!Ext.cache[id]){
+ Ext.Element.addToCache(new Ext.Element(element), id);
+ if (skipGarbageCollection) {
+ Ext.cache[id].skipGarbageCollection = true;
+ }
+ }
+ return id;
+ },
+
+<span id='Ext-EventManager-method-prepareListenerConfig'> /**
+</span> * Convert a "config style" listener into a set of flat arguments so they can be passed to addListener
+ * @private
+ * @param {Object} element The element the event is for
+ * @param {Object} event The event configuration
+ * @param {Object} isRemove True if a removal should be performed, otherwise an add will be done.
+ */
+ prepareListenerConfig: function(element, config, isRemove){
+ var me = this,
+ propRe = me.propRe,
+ key, value, args;
+
+ // loop over all the keys in the object
+ for (key in config) {
+ if (config.hasOwnProperty(key)) {
+ // if the key is something else then an event option
+ if (!propRe.test(key)) {
+ value = config[key];
+ // if the value is a function it must be something like click: function(){}, scope: this
+ // which means that there might be multiple event listeners with shared options
+ if (Ext.isFunction(value)) {
+ // shared options
+ args = [element, key, value, config.scope, config];
+ } else {
+ // if its not a function, it must be an object like click: {fn: function(){}, scope: this}
+ args = [element, key, value.fn, value.scope, value];
+ }
+
+ if (isRemove === true) {
+ me.removeListener.apply(this, args);
+ } else {
+ me.addListener.apply(me, args);
+ }
+ }
+ }
+ }
+ },
+
+<span id='Ext-EventManager-method-normalizeEvent'> /**
+</span> * Normalize cross browser event differences
+ * @private
+ * @param {Object} eventName The event name
+ * @param {Object} fn The function to execute
+ * @return {Object} The new event name/function
+ */
+ normalizeEvent: function(eventName, fn){
+ if (/mouseenter|mouseleave/.test(eventName) && !Ext.supports.MouseEnterLeave) {
+ if (fn) {
+ fn = Ext.Function.createInterceptor(fn, this.contains, this);
+ }
+ eventName = eventName == 'mouseenter' ? 'mouseover' : 'mouseout';
+ } else if (eventName == 'mousewheel' && !Ext.supports.MouseWheel && !Ext.isOpera){
+ eventName = 'DOMMouseScroll';
+ }
+ return {
+ eventName: eventName,
+ fn: fn
+ };
+ },
+
+<span id='Ext-EventManager-method-contains'> /**
+</span> * Checks whether the event's relatedTarget is contained inside (or <b>is</b>) the element.
+ * @private
+ * @param {Object} event
+ */
+ contains: function(event){
+ var parent = event.browserEvent.currentTarget,
+ child = this.getRelatedTarget(event);
+
+ if (parent && parent.firstChild) {
+ while (child) {
+ if (child === parent) {
+ return false;
+ }
+ child = child.parentNode;
+ if (child && (child.nodeType != 1)) {
+ child = null;
+ }
+ }
+ }
+ return true;
+ },
+
+<span id='Ext-EventManager-method-addListener'> /**
+</span> * Appends an event handler to an element. The shorthand version {@link #on} is equivalent. Typically you will
+ * use {@link Ext.Element#addListener} directly on an Element in favor of calling this version.
+ * @param {String/HTMLElement} el The html element or id to assign the event handler to.
+ * @param {String} eventName The name of the event to listen for.
+ * @param {Function} handler The handler function the event invokes. This function is passed
+ * the following parameters:<ul>
+ * <li>evt : EventObject<div class="sub-desc">The {@link Ext.EventObject EventObject} describing the event.</div></li>
+ * <li>t : Element<div class="sub-desc">The {@link Ext.Element Element} which was the target of the event.
+ * Note that this may be filtered by using the <tt>delegate</tt> option.</div></li>
+ * <li>o : Object<div class="sub-desc">The options object from the addListener call.</div></li>
+ * </ul>
+ * @param {Object} scope (optional) The scope (<b><code>this</code></b> reference) in which the handler function is executed. <b>Defaults to the Element</b>.
+ * @param {Object} options (optional) An object containing handler configuration properties.
+ * This may contain any of the following properties:<ul>
+ * <li>scope : Object<div class="sub-desc">The scope (<b><code>this</code></b> reference) in which the handler function is executed. <b>Defaults to the Element</b>.</div></li>
+ * <li>delegate : String<div class="sub-desc">A simple selector to filter the target or look for a descendant of the target</div></li>
+ * <li>stopEvent : Boolean<div class="sub-desc">True to stop the event. That is stop propagation, and prevent the default action.</div></li>
+ * <li>preventDefault : Boolean<div class="sub-desc">True to prevent the default action</div></li>
+ * <li>stopPropagation : Boolean<div class="sub-desc">True to prevent event propagation</div></li>
+ * <li>normalized : Boolean<div class="sub-desc">False to pass a browser event to the handler function instead of an Ext.EventObject</div></li>
+ * <li>delay : Number<div class="sub-desc">The number of milliseconds to delay the invocation of the handler after te event fires.</div></li>
+ * <li>single : Boolean<div class="sub-desc">True to add a handler to handle just the next firing of the event, and then remove itself.</div></li>
+ * <li>buffer : Number<div class="sub-desc">Causes the handler to be scheduled to run in an {@link Ext.util.DelayedTask} delayed
+ * by the specified number of milliseconds. If the event fires again within that time, the original
+ * handler is <em>not</em> invoked, but the new handler is scheduled in its place.</div></li>
+ * <li>target : Element<div class="sub-desc">Only call the handler if the event was fired on the target Element, <i>not</i> if the event was bubbled up from a child node.</div></li>
+ * </ul><br>
+ * <p>See {@link Ext.Element#addListener} for examples of how to use these options.</p>
+ */
+ addListener: function(element, eventName, fn, scope, options){
+ // Check if we've been passed a "config style" event.
+ if (typeof eventName !== 'string') {
+ this.prepareListenerConfig(element, eventName);
+ return;
+ }
+
+ var dom = Ext.getDom(element),
+ bind,
+ wrap;
+
+ //<debug>
+ if (!dom){
+ Ext.Error.raise({
+ sourceClass: 'Ext.EventManager',
+ sourceMethod: 'addListener',
+ targetElement: element,
+ eventName: eventName,
+ msg: 'Error adding "' + eventName + '\" listener for nonexistent element "' + element + '"'
+ });
+ }
+ if (!fn) {
+ Ext.Error.raise({
+ sourceClass: 'Ext.EventManager',
+ sourceMethod: 'addListener',
+ targetElement: element,
+ eventName: eventName,
+ msg: 'Error adding "' + eventName + '\" listener. The handler function is undefined.'
+ });
+ }
+ //</debug>
+
+ // create the wrapper function
+ options = options || {};
+
+ bind = this.normalizeEvent(eventName, fn);
+ wrap = this.createListenerWrap(dom, eventName, bind.fn, scope, options);
+
+
+ if (dom.attachEvent) {
+ dom.attachEvent('on' + bind.eventName, wrap);
+ } else {
+ dom.addEventListener(bind.eventName, wrap, options.capture || false);
+ }
+
+ if (dom == document && eventName == 'mousedown') {
+ this.stoppedMouseDownEvent.addListener(wrap);
+ }
+
+ // add all required data into the event cache
+ this.getEventListenerCache(dom, eventName).push({
+ fn: fn,
+ wrap: wrap,
+ scope: scope
+ });
+ },
+
+<span id='Ext-EventManager-method-removeListener'> /**
+</span> * Removes an event handler from an element. The shorthand version {@link #un} is equivalent. Typically
+ * you will use {@link Ext.Element#removeListener} directly on an Element in favor of calling this version.
+ * @param {String/HTMLElement} el The id or html element from which to remove the listener.
+ * @param {String} eventName The name of the event.
+ * @param {Function} fn The handler function to remove. <b>This must be a reference to the function passed into the {@link #addListener} call.</b>
+ * @param {Object} scope If a scope (<b><code>this</code></b> reference) was specified when the listener was added,
+ * then this must refer to the same object.
+ */
+ removeListener : function(element, eventName, fn, scope) {
+ // handle our listener config object syntax
+ if (typeof eventName !== 'string') {
+ this.prepareListenerConfig(element, eventName, true);
+ return;
+ }
+
+ var dom = Ext.getDom(element),
+ cache = this.getEventListenerCache(dom, eventName),
+ bindName = this.normalizeEvent(eventName).eventName,
+ i = cache.length, j,
+ listener, wrap, tasks;
+
+
+ while (i--) {
+ listener = cache[i];
+
+ if (listener && (!fn || listener.fn == fn) && (!scope || listener.scope === scope)) {
+ wrap = listener.wrap;
+
+ // clear buffered calls
+ if (wrap.task) {
+ clearTimeout(wrap.task);
+ delete wrap.task;
+ }
+
+ // clear delayed calls
+ j = wrap.tasks && wrap.tasks.length;
+ if (j) {
+ while (j--) {
+ clearTimeout(wrap.tasks[j]);
+ }
+ delete wrap.tasks;
+ }
+
+ if (dom.detachEvent) {
+ dom.detachEvent('on' + bindName, wrap);
+ } else {
+ dom.removeEventListener(bindName, wrap, false);
+ }
+
+ if (wrap && dom == document && eventName == 'mousedown') {
+ this.stoppedMouseDownEvent.removeListener(wrap);
+ }
+
+ // remove listener from cache
+ Ext.Array.erase(cache, i, 1);
+ }
+ }
+ },
+
+<span id='Ext-EventManager-method-removeAll'> /**
+</span> * Removes all event handers from an element. Typically you will use {@link Ext.Element#removeAllListeners}
+ * directly on an Element in favor of calling this version.
+ * @param {String/HTMLElement} el The id or html element from which to remove all event handlers.
+ */
+ removeAll : function(element){
+ var dom = Ext.getDom(element),
+ cache, ev;
+ if (!dom) {
+ return;
+ }
+ cache = this.getElementEventCache(dom);
+
+ for (ev in cache) {
+ if (cache.hasOwnProperty(ev)) {
+ this.removeListener(dom, ev);
+ }
+ }
+ Ext.cache[dom.id].events = {};
+ },
+
+<span id='Ext-EventManager-method-purgeElement'> /**
+</span> * Recursively removes all previous added listeners from an element and its children. Typically you will use {@link Ext.Element#purgeAllListeners}
+ * directly on an Element in favor of calling this version.
+ * @param {String/HTMLElement} el The id or html element from which to remove all event handlers.
+ * @param {String} eventName (optional) The name of the event.
+ */
+ purgeElement : function(element, eventName) {
+ var dom = Ext.getDom(element),
+ i = 0, len;
+
+ if(eventName) {
+ this.removeListener(dom, eventName);
+ }
+ else {
+ this.removeAll(dom);
+ }
+
+ if(dom && dom.childNodes) {
+ for(len = element.childNodes.length; i < len; i++) {
+ this.purgeElement(element.childNodes[i], eventName);
+ }
+ }
+ },
+
+<span id='Ext-EventManager-method-createListenerWrap'> /**
+</span> * Create the wrapper function for the event
+ * @private
+ * @param {HTMLElement} dom The dom element
+ * @param {String} ename The event name
+ * @param {Function} fn The function to execute
+ * @param {Object} scope The scope to execute callback in
+ * @param {Object} options The options
+ * @return {Function} the wrapper function
+ */
+ createListenerWrap : function(dom, ename, fn, scope, options) {
+ options = options || {};
+
+ var f, gen;
+
+ return function wrap(e, args) {
+ // Compile the implementation upon first firing
+ if (!gen) {
+ f = ['if(!Ext) {return;}'];
+
+ if(options.buffer || options.delay || options.freezeEvent) {
+ f.push('e = new Ext.EventObjectImpl(e, ' + (options.freezeEvent ? 'true' : 'false' ) + ');');
+ } else {
+ f.push('e = Ext.EventObject.setEvent(e);');
+ }
+
+ if (options.delegate) {
+ f.push('var t = e.getTarget("' + options.delegate + '", this);');
+ f.push('if(!t) {return;}');
+ } else {
+ f.push('var t = e.target;');
+ }
+
+ if (options.target) {
+ f.push('if(e.target !== options.target) {return;}');
+ }
+
+ if(options.stopEvent) {
+ f.push('e.stopEvent();');
+ } else {
+ if(options.preventDefault) {
+ f.push('e.preventDefault();');
+ }
+ if(options.stopPropagation) {
+ f.push('e.stopPropagation();');
+ }
+ }
+
+ if(options.normalized === false) {
+ f.push('e = e.browserEvent;');
+ }
+
+ if(options.buffer) {
+ f.push('(wrap.task && clearTimeout(wrap.task));');
+ f.push('wrap.task = setTimeout(function(){');
+ }
+
+ if(options.delay) {
+ f.push('wrap.tasks = wrap.tasks || [];');
+ f.push('wrap.tasks.push(setTimeout(function(){');
+ }
+
+ // finally call the actual handler fn
+ f.push('fn.call(scope || dom, e, t, options);');
+
+ if(options.single) {
+ f.push('Ext.EventManager.removeListener(dom, ename, fn, scope);');
+ }
+
+ if(options.delay) {
+ f.push('}, ' + options.delay + '));');
+ }
+
+ if(options.buffer) {
+ f.push('}, ' + options.buffer + ');');
+ }
+
+ gen = Ext.functionFactory('e', 'options', 'fn', 'scope', 'ename', 'dom', 'wrap', 'args', f.join('\n'));
+ }
+
+ gen.call(dom, e, options, fn, scope, ename, dom, wrap, args);
+ };
+ },
+
+<span id='Ext-EventManager-method-getEventListenerCache'> /**
+</span> * Get the event cache for a particular element for a particular event
+ * @private
+ * @param {HTMLElement} element The element
+ * @param {Object} eventName The event name
+ * @return {Array} The events for the element
+ */
+ getEventListenerCache : function(element, eventName) {
+ if (!element) {
+ return [];
+ }
+
+ var eventCache = this.getElementEventCache(element);
+ return eventCache[eventName] || (eventCache[eventName] = []);
+ },
+
+<span id='Ext-EventManager-method-getElementEventCache'> /**
+</span> * Gets the event cache for the object
+ * @private
+ * @param {HTMLElement} element The element
+ * @return {Object} The event cache for the object
+ */
+ getElementEventCache : function(element) {
+ if (!element) {
+ return {};
+ }
+ var elementCache = Ext.cache[this.getId(element)];
+ return elementCache.events || (elementCache.events = {});
+ },
+
+ // --------------------- utility methods ---------------------
+ mouseLeaveRe: /(mouseout|mouseleave)/,
+ mouseEnterRe: /(mouseover|mouseenter)/,
+
+<span id='Ext-EventManager-method-stopEvent'> /**
+</span> * Stop the event (preventDefault and stopPropagation)
+ * @param {Event} The event to stop
+ */
+ stopEvent: function(event) {
+ this.stopPropagation(event);
+ this.preventDefault(event);
+ },
+
+<span id='Ext-EventManager-method-stopPropagation'> /**
+</span> * Cancels bubbling of the event.
+ * @param {Event} The event to stop bubbling.
+ */
+ stopPropagation: function(event) {
+ event = event.browserEvent || event;
+ if (event.stopPropagation) {
+ event.stopPropagation();
+ } else {
+ event.cancelBubble = true;
+ }
+ },
+
+<span id='Ext-EventManager-method-preventDefault'> /**
+</span> * Prevents the browsers default handling of the event.
+ * @param {Event} The event to prevent the default
+ */
+ preventDefault: function(event) {
+ event = event.browserEvent || event;
+ if (event.preventDefault) {
+ event.preventDefault();
+ } else {
+ event.returnValue = false;
+ // Some keys events require setting the keyCode to -1 to be prevented
+ try {
+ // all ctrl + X and F1 -> F12
+ if (event.ctrlKey || event.keyCode > 111 && event.keyCode < 124) {
+ event.keyCode = -1;
+ }
+ } catch (e) {
+ // see this outdated document http://support.microsoft.com/kb/934364/en-us for more info
+ }
+ }
+ },
+
+<span id='Ext-EventManager-method-getRelatedTarget'> /**
+</span> * Gets the related target from the event.
+ * @param {Object} event The event
+ * @return {HTMLElement} The related target.
+ */
+ getRelatedTarget: function(event) {
+ event = event.browserEvent || event;
+ var target = event.relatedTarget;
+ if (!target) {
+ if (this.mouseLeaveRe.test(event.type)) {
+ target = event.toElement;
+ } else if (this.mouseEnterRe.test(event.type)) {
+ target = event.fromElement;
+ }
+ }
+ return this.resolveTextNode(target);
+ },
+
+<span id='Ext-EventManager-method-getPageX'> /**
+</span> * Gets the x coordinate from the event
+ * @param {Object} event The event
+ * @return {Number} The x coordinate
+ */
+ getPageX: function(event) {
+ return this.getXY(event)[0];
+ },
+
+<span id='Ext-EventManager-method-getPageY'> /**
+</span> * Gets the y coordinate from the event
+ * @param {Object} event The event
+ * @return {Number} The y coordinate
+ */
+ getPageY: function(event) {
+ return this.getXY(event)[1];
+ },
+
+<span id='Ext-EventManager-method-getPageXY'> /**
+</span> * Gets the x & y coordinate from the event
+ * @param {Object} event The event
+ * @return {Number[]} The x/y coordinate
+ */
+ getPageXY: function(event) {
+ event = event.browserEvent || event;
+ var x = event.pageX,
+ y = event.pageY,
+ doc = document.documentElement,
+ body = document.body;
+
+ // pageX/pageY not available (undefined, not null), use clientX/clientY instead
+ if (!x && x !== 0) {
+ x = event.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc && doc.clientLeft || body && body.clientLeft || 0);
+ y = event.clientY + (doc && doc.scrollTop || body && body.scrollTop || 0) - (doc && doc.clientTop || body && body.clientTop || 0);
+ }
+ return [x, y];
+ },
+
+<span id='Ext-EventManager-method-getTarget'> /**
+</span> * Gets the target of the event.
+ * @param {Object} event The event
+ * @return {HTMLElement} target
+ */
+ getTarget: function(event) {
+ event = event.browserEvent || event;
+ return this.resolveTextNode(event.target || event.srcElement);
+ },
+
+<span id='Ext-EventManager-property-resolveTextNode'> /**
+</span> * Resolve any text nodes accounting for browser differences.
+ * @private
+ * @param {HTMLElement} node The node
+ * @return {HTMLElement} The resolved node
+ */
+ // technically no need to browser sniff this, however it makes no sense to check this every time, for every event, whether the string is equal.
+ resolveTextNode: Ext.isGecko ?
+ function(node) {
+ if (!node) {
+ return;
+ }
+ // work around firefox bug, https://bugzilla.mozilla.org/show_bug.cgi?id=101197
+ var s = HTMLElement.prototype.toString.call(node);
+ if (s == '[xpconnect wrapped native prototype]' || s == '[object XULElement]') {
+ return;
+ }
+ return node.nodeType == 3 ? node.parentNode: node;
+ }: function(node) {
+ return node && node.nodeType == 3 ? node.parentNode: node;
+ },
+
+ // --------------------- custom event binding ---------------------
+
+ // Keep track of the current width/height
+ curWidth: 0,
+ curHeight: 0,
+
+<span id='Ext-EventManager-method-onWindowResize'> /**
+</span> * Adds a listener to be notified when the browser window is resized and provides resize event buffering (100 milliseconds),
+ * passes new viewport width and height to handlers.
+ * @param {Function} fn The handler function the window resize event invokes.
+ * @param {Object} scope The scope (<code>this</code> reference) in which the handler function executes. Defaults to the browser window.
+ * @param {Boolean} options Options object as passed to {@link Ext.Element#addListener}
+ */
+ onWindowResize: function(fn, scope, options){
+ var resize = this.resizeEvent;
+ if(!resize){
+ this.resizeEvent = resize = new Ext.util.Event();
+ this.on(window, 'resize', this.fireResize, this, {buffer: 100});
+ }
+ resize.addListener(fn, scope, options);
+ },
+
+<span id='Ext-EventManager-method-fireResize'> /**
+</span> * Fire the resize event.
+ * @private
+ */
+ fireResize: function(){
+ var me = this,
+ w = Ext.Element.getViewWidth(),
+ h = Ext.Element.getViewHeight();
+
+ //whacky problem in IE where the resize event will sometimes fire even though the w/h are the same.
+ if(me.curHeight != h || me.curWidth != w){
+ me.curHeight = h;
+ me.curWidth = w;
+ me.resizeEvent.fire(w, h);
+ }
+ },
+
+<span id='Ext-EventManager-method-removeResizeListener'> /**
+</span> * Removes the passed window resize listener.
+ * @param {Function} fn The method the event invokes
+ * @param {Object} scope The scope of handler
+ */
+ removeResizeListener: function(fn, scope){
+ if (this.resizeEvent) {
+ this.resizeEvent.removeListener(fn, scope);
+ }
+ },
+
+ onWindowUnload: function() {
+ var unload = this.unloadEvent;
+ if (!unload) {
+ this.unloadEvent = unload = new Ext.util.Event();
+ this.addListener(window, 'unload', this.fireUnload, this);
+ }
+ },
+
+<span id='Ext-EventManager-method-fireUnload'> /**
+</span> * Fires the unload event for items bound with onWindowUnload
+ * @private
+ */
+ fireUnload: function() {
+ // wrap in a try catch, could have some problems during unload
+ try {
+ this.removeUnloadListener();
+ // Work around FF3 remembering the last scroll position when refreshing the grid and then losing grid view
+ if (Ext.isGecko3) {
+ var gridviews = Ext.ComponentQuery.query('gridview'),
+ i = 0,
+ ln = gridviews.length;
+ for (; i < ln; i++) {
+ gridviews[i].scrollToTop();
+ }
+ }
+ // Purge all elements in the cache
+ var el,
+ cache = Ext.cache;
+ for (el in cache) {
+ if (cache.hasOwnProperty(el)) {
+ Ext.EventManager.removeAll(el);
+ }
+ }
+ } catch(e) {
+ }
+ },
+
+<span id='Ext-EventManager-method-removeUnloadListener'> /**
+</span> * Removes the passed window unload listener.
+ * @param {Function} fn The method the event invokes
+ * @param {Object} scope The scope of handler
+ */
+ removeUnloadListener: function(){
+ if (this.unloadEvent) {
+ this.removeListener(window, 'unload', this.fireUnload);
+ }
+ },
+
+<span id='Ext-EventManager-property-useKeyDown'> /**
+</span> * note 1: IE fires ONLY the keydown event on specialkey autorepeat
+ * note 2: Safari < 3.1, Gecko (Mac/Linux) & Opera fire only the keypress event on specialkey autorepeat
+ * (research done by Jan Wolter at http://unixpapa.com/js/key.html)
+ * @private
+ */
+ useKeyDown: Ext.isWebKit ?
+ parseInt(navigator.userAgent.match(/AppleWebKit\/(\d+)/)[1], 10) >= 525 :
+ !((Ext.isGecko && !Ext.isWindows) || Ext.isOpera),
+
+<span id='Ext-EventManager-method-getKeyEvent'> /**
+</span> * Indicates which event to use for getting key presses.
+ * @return {String} The appropriate event name.
+ */
+ getKeyEvent: function(){
+ return this.useKeyDown ? 'keydown' : 'keypress';
+ }
+};
+
+<span id='Ext-method-onReady'>/**
+</span> * Alias for {@link Ext.Loader#onReady Ext.Loader.onReady} with withDomReady set to true
+ * @member Ext
+ * @method onReady
+ */
+Ext.onReady = function(fn, scope, options) {
+ Ext.Loader.onReady(fn, scope, true, options);
+};
+
+<span id='Ext-method-onDocumentReady'>/**
+</span> * Alias for {@link Ext.EventManager#onDocumentReady Ext.EventManager.onDocumentReady}
+ * @member Ext
+ * @method onDocumentReady
+ */
+Ext.onDocumentReady = Ext.EventManager.onDocumentReady;
+
+<span id='Ext-EventManager-method-on'>/**
+</span> * Alias for {@link Ext.EventManager#addListener Ext.EventManager.addListener}
+ * @member Ext.EventManager
+ * @method on
+ */
+Ext.EventManager.on = Ext.EventManager.addListener;
+
+<span id='Ext-EventManager-method-un'>/**
+</span> * Alias for {@link Ext.EventManager#removeListener Ext.EventManager.removeListener}
+ * @member Ext.EventManager
+ * @method un
+ */
+Ext.EventManager.un = Ext.EventManager.removeListener;
+
+(function(){
+ var initExtCss = function() {
+ // find the body element
+ var bd = document.body || document.getElementsByTagName('body')[0],
+ baseCSSPrefix = Ext.baseCSSPrefix,
+ cls = [baseCSSPrefix + 'body'],
+ htmlCls = [],
+ html;
+
+ if (!bd) {
+ return false;
+ }
+
+ html = bd.parentNode;
+
+ function add (c) {
+ cls.push(baseCSSPrefix + c);
+ }
+
+ //Let's keep this human readable!
+ if (Ext.isIE) {
+ add('ie');
+
+ // very often CSS needs to do checks like "IE7+" or "IE6 or 7". To help
+ // reduce the clutter (since CSS/SCSS cannot do these tests), we add some
+ // additional classes:
+ //
+ // x-ie7p : IE7+ : 7 <= ieVer
+ // x-ie7m : IE7- : ieVer <= 7
+ // x-ie8p : IE8+ : 8 <= ieVer
+ // x-ie8m : IE8- : ieVer <= 8
+ // x-ie9p : IE9+ : 9 <= ieVer
+ // x-ie78 : IE7 or 8 : 7 <= ieVer <= 8
+ //
+ if (Ext.isIE6) {
+ add('ie6');
+ } else { // ignore pre-IE6 :)
+ add('ie7p');
+
+ if (Ext.isIE7) {
+ add('ie7');
+ } else {
+ add('ie8p');
+
+ if (Ext.isIE8) {
+ add('ie8');
+ } else {
+ add('ie9p');
+
+ if (Ext.isIE9) {
+ add('ie9');
+ }
+ }
+ }
+ }
+
+ if (Ext.isIE6 || Ext.isIE7) {
+ add('ie7m');
+ }
+ if (Ext.isIE6 || Ext.isIE7 || Ext.isIE8) {
+ add('ie8m');
+ }
+ if (Ext.isIE7 || Ext.isIE8) {
+ add('ie78');
+ }
+ }
+ if (Ext.isGecko) {
+ add('gecko');
+ if (Ext.isGecko3) {
+ add('gecko3');
+ }
+ if (Ext.isGecko4) {
+ add('gecko4');
+ }
+ if (Ext.isGecko5) {
+ add('gecko5');
+ }
+ }
+ if (Ext.isOpera) {
+ add('opera');
+ }
+ if (Ext.isWebKit) {
+ add('webkit');
+ }
+ if (Ext.isSafari) {
+ add('safari');
+ if (Ext.isSafari2) {
+ add('safari2');
+ }
+ if (Ext.isSafari3) {
+ add('safari3');
+ }
+ if (Ext.isSafari4) {
+ add('safari4');
+ }
+ if (Ext.isSafari5) {
+ add('safari5');
+ }
+ }
+ if (Ext.isChrome) {
+ add('chrome');
+ }
+ if (Ext.isMac) {
+ add('mac');
+ }
+ if (Ext.isLinux) {
+ add('linux');
+ }
+ if (!Ext.supports.CSS3BorderRadius) {
+ add('nbr');
+ }
+ if (!Ext.supports.CSS3LinearGradient) {
+ add('nlg');
+ }
+ if (!Ext.scopeResetCSS) {
+ add('reset');
+ }
+
+ // add to the parent to allow for selectors x-strict x-border-box, also set the isBorderBox property correctly
+ if (html) {
+ if (Ext.isStrict && (Ext.isIE6 || Ext.isIE7)) {
+ Ext.isBorderBox = false;
+ }
+ else {
+ Ext.isBorderBox = true;
+ }
+
+ htmlCls.push(baseCSSPrefix + (Ext.isBorderBox ? 'border-box' : 'strict'));
+ if (!Ext.isStrict) {
+ htmlCls.push(baseCSSPrefix + 'quirks');
+ }
+ Ext.fly(html, '_internal').addCls(htmlCls);
+ }
+
+ Ext.fly(bd, '_internal').addCls(cls);
+ return true;
+ };
+
+ Ext.onReady(initExtCss);
+})();
+</pre>
+</body>
+</html>