EventManager.js
上传用户:shuoshiled
上传日期:2018-01-28
资源大小:10124k
文件大小:23k
源码类别:

中间件编程

开发平台:

JavaScript

  1. /*!
  2.  * Ext JS Library 3.0.0
  3.  * Copyright(c) 2006-2009 Ext JS, LLC
  4.  * licensing@extjs.com
  5.  * http://www.extjs.com/license
  6.  */
  7. /**
  8.  * @class Ext.EventManager
  9.  * Registers event handlers that want to receive a normalized EventObject instead of the standard browser event and provides
  10.  * several useful events directly.
  11.  * See {@link Ext.EventObject} for more details on normalized event objects.
  12.  * @singleton
  13.  */
  14. Ext.EventManager = function(){
  15.     var docReadyEvent, 
  16.      docReadyProcId, 
  17.      docReadyState = false,    
  18.      E = Ext.lib.Event,
  19.      D = Ext.lib.Dom,
  20.      DOC = document,
  21.      WINDOW = window,
  22.      IEDEFERED = "ie-deferred-loader",
  23.      DOMCONTENTLOADED = "DOMContentLoaded",
  24.      elHash = {},
  25.      propRe = /^(?:scope|delay|buffer|single|stopEvent|preventDefault|stopPropagation|normalized|args|delegate)$/;
  26.     /// There is some jquery work around stuff here that isn't needed in Ext Core.
  27.     function addListener(el, ename, fn, wrap, scope){     
  28.         var id = Ext.id(el),
  29.          es = elHash[id] = elHash[id] || {};     
  30.        
  31.         (es[ename] = es[ename] || []).push([fn, wrap, scope]);
  32.         E.on(el, ename, wrap);
  33.         // this is a workaround for jQuery and should somehow be removed from Ext Core in the future
  34.         // without breaking ExtJS.
  35.         if(ename == "mousewheel" && el.addEventListener){ // workaround for jQuery
  36.          var args = ["DOMMouseScroll", wrap, false];
  37.          el.addEventListener.apply(el, args);
  38.             E.on(window, 'unload', function(){
  39.             el.removeEventListener.apply(el, args);                
  40.             });
  41.         }
  42.         if(ename == "mousedown" && el == document){ // fix stopped mousedowns on the document
  43.             Ext.EventManager.stoppedMouseDownEvent.addListener(wrap);
  44.         }
  45.     };
  46.     
  47.     function fireDocReady(){
  48.         if(!docReadyState){            
  49.             Ext.isReady = docReadyState = true;
  50.             if(docReadyProcId){
  51.                 clearInterval(docReadyProcId);
  52.             }
  53.             if(Ext.isGecko || Ext.isOpera) {
  54.                 DOC.removeEventListener(DOMCONTENTLOADED, fireDocReady, false);
  55.             }
  56.             if(Ext.isIE){
  57.                 var defer = DOC.getElementById(IEDEFERED);
  58.                 if(defer){
  59.                     defer.onreadystatechange = null;
  60.                     defer.parentNode.removeChild(defer);
  61.                 }
  62.             }
  63.             if(docReadyEvent){
  64.                 docReadyEvent.fire();
  65.                 docReadyEvent.clearListeners();
  66.             }
  67.         }
  68.     };
  69.     function initDocReady(){
  70.     var COMPLETE = "complete";
  71.     
  72.         docReadyEvent = new Ext.util.Event();
  73.         if (Ext.isGecko || Ext.isOpera) {
  74.             DOC.addEventListener(DOMCONTENTLOADED, fireDocReady, false);
  75.         } else if (Ext.isIE){
  76.             DOC.write("<s"+'cript id=' + IEDEFERED + ' defer="defer" src="/'+'/:"></s'+"cript>");            
  77.             DOC.getElementById(IEDEFERED).onreadystatechange = function(){
  78.                 if(this.readyState == COMPLETE){
  79.                     fireDocReady();
  80.                 }
  81.             };
  82.         } else if (Ext.isWebKit){
  83.             docReadyProcId = setInterval(function(){                
  84.                 if(DOC.readyState == COMPLETE) {
  85.                     fireDocReady();
  86.                  }
  87.             }, 10);
  88.         }
  89.         // no matter what, make sure it fires on load
  90.         E.on(WINDOW, "load", fireDocReady);
  91.     };
  92.     function createTargeted(h, o){
  93.         return function(){
  94.         var args = Ext.toArray(arguments);
  95.             if(o.target == Ext.EventObject.setEvent(args[0]).target){
  96.                 h.apply(this, args);
  97.             }
  98.         };
  99.     };    
  100.     
  101.     function createBuffered(h, o){
  102.         var task = new Ext.util.DelayedTask(h);
  103.         return function(e){
  104.             // create new event object impl so new events don't wipe out properties            
  105.             task.delay(o.buffer, h, null, [new Ext.EventObjectImpl(e)]);
  106.         };
  107.     };
  108.     function createSingle(h, el, ename, fn, scope){
  109.         return function(e){
  110.             Ext.EventManager.removeListener(el, ename, fn, scope);
  111.             h(e);
  112.         };
  113.     };
  114.     function createDelayed(h, o){
  115.         return function(e){
  116.             // create new event object impl so new events don't wipe out properties   
  117.             e = new Ext.EventObjectImpl(e);
  118.             setTimeout(function(){
  119.                 h(e);
  120.             }, o.delay || 10);
  121.         };
  122.     };
  123.     function listen(element, ename, opt, fn, scope){
  124.         var o = !Ext.isObject(opt) ? {} : opt,
  125.          el = Ext.getDom(element);
  126.         
  127.         fn = fn || o.fn; 
  128.         scope = scope || o.scope;
  129.         
  130.         if(!el){
  131.             throw "Error listening for "" + ename + '". Element "' + element + '" doesn't exist.';
  132.         }
  133.         function h(e){
  134.             // prevent errors while unload occurring
  135.             if(!Ext){// !window[xname]){  ==> can't we do this? 
  136.                 return;
  137.             }
  138.             e = Ext.EventObject.setEvent(e);
  139.             var t;
  140.             if (o.delegate) {
  141.                 if(!(t = e.getTarget(o.delegate, el))){
  142.                     return;
  143.                 }
  144.             } else {
  145.                 t = e.target;
  146.             }            
  147.             if (o.stopEvent) {
  148.                 e.stopEvent();
  149.             }
  150.             if (o.preventDefault) {
  151.                e.preventDefault();
  152.             }
  153.             if (o.stopPropagation) {
  154.                 e.stopPropagation();
  155.             }
  156.             if (o.normalized) {
  157.                 e = e.browserEvent;
  158.             }
  159.             
  160.             fn.call(scope || el, e, t, o);
  161.         };
  162.         if(o.target){
  163.             h = createTargeted(h, o);
  164.         }
  165.         if(o.delay){
  166.             h = createDelayed(h, o);
  167.         }
  168.         if(o.single){
  169.             h = createSingle(h, el, ename, fn, scope);
  170.         }
  171.         if(o.buffer){
  172.             h = createBuffered(h, o);
  173.         }
  174.         addListener(el, ename, fn, h, scope);
  175.         return h;
  176.     };
  177.     var pub = {
  178.     /**
  179.      * Appends an event handler to an element.  The shorthand version {@link #on} is equivalent.  Typically you will
  180.      * use {@link Ext.Element#addListener} directly on an Element in favor of calling this version.
  181.      * @param {String/HTMLElement} el The html element or id to assign the event handler to
  182.      * @param {String} eventName The type of event to listen for
  183.      * @param {Function} handler The handler function the event invokes This function is passed
  184.      * the following parameters:<ul>
  185.      * <li>evt : EventObject<div class="sub-desc">The {@link Ext.EventObject EventObject} describing the event.</div></li>
  186.      * <li>t : Element<div class="sub-desc">The {@link Ext.Element Element} which was the target of the event.
  187.      * Note that this may be filtered by using the <tt>delegate</tt> option.</div></li>
  188.      * <li>o : Object<div class="sub-desc">The options object from the addListener call.</div></li>
  189.      * </ul>
  190.      * @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>.
  191.      * @param {Object} options (optional) An object containing handler configuration properties.
  192.      * This may contain any of the following properties:<ul>
  193.      * <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>
  194.      * <li>delegate : String<div class="sub-desc">A simple selector to filter the target or look for a descendant of the target</div></li>
  195.      * <li>stopEvent : Boolean<div class="sub-desc">True to stop the event. That is stop propagation, and prevent the default action.</div></li>
  196.      * <li>preventDefault : Boolean<div class="sub-desc">True to prevent the default action</div></li>
  197.      * <li>stopPropagation : Boolean<div class="sub-desc">True to prevent event propagation</div></li>
  198.      * <li>normalized : Boolean<div class="sub-desc">False to pass a browser event to the handler function instead of an Ext.EventObject</div></li>
  199.      * <li>delay : Number<div class="sub-desc">The number of milliseconds to delay the invocation of the handler after te event fires.</div></li>
  200.      * <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>
  201.      * <li>buffer : Number<div class="sub-desc">Causes the handler to be scheduled to run in an {@link Ext.util.DelayedTask} delayed
  202.      * by the specified number of milliseconds. If the event fires again within that time, the original
  203.      * handler is <em>not</em> invoked, but the new handler is scheduled in its place.</div></li>
  204.      * <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>
  205.      * </ul><br>
  206.      * <p>See {@link Ext.Element#addListener} for examples of how to use these options.</p>
  207.      */
  208. addListener : function(element, eventName, fn, scope, options){                  
  209.             if(Ext.isObject(eventName)){                
  210.             var o = eventName, e, val;
  211.                 for(e in o){
  212.                 val = o[e];
  213.                     if(!propRe.test(e)){                                      
  214.                     if(Ext.isFunction(val)){
  215.                         // shared options
  216.                         listen(element, e, o, val, o.scope);
  217.                     }else{
  218.                         // individual options
  219.                         listen(element, e, val);
  220.                     }
  221.                     }
  222.                 }
  223.             } else {
  224.              listen(element, eventName, options, fn, scope);
  225.          }
  226.         },
  227.         
  228.         /**
  229.          * Removes an event handler from an element.  The shorthand version {@link #un} is equivalent.  Typically
  230.          * you will use {@link Ext.Element#removeListener} directly on an Element in favor of calling this version.
  231.          * @param {String/HTMLElement} el The id or html element from which to remove the event
  232.          * @param {String} eventName The type of event
  233.          * @param {Function} fn The handler function to remove
  234.          */
  235.         removeListener : function(element, eventName, fn, scope){            
  236.             var el = Ext.getDom(element),
  237.                 id = Ext.id(el),
  238.              wrap;      
  239.         
  240.         Ext.each((elHash[id] || {})[eventName], function (v,i,a) {
  241.     if (Ext.isArray(v) && v[0] == fn && (!scope || v[2] == scope)) {                  
  242.         E.un(el, eventName, wrap = v[1]);
  243.         a.splice(i,1);
  244.         return false;         
  245.         }
  246.         });
  247.             // jQuery workaround that should be removed from Ext Core
  248.         if(eventName == "mousewheel" && el.addEventListener && wrap){
  249.             el.removeEventListener("DOMMouseScroll", wrap, false);
  250.         }
  251.                      
  252.         if(eventName == "mousedown" && el == DOC && wrap){ // fix stopped mousedowns on the document
  253.             Ext.EventManager.stoppedMouseDownEvent.removeListener(wrap);
  254.         }
  255.         },
  256.         
  257.         /**
  258.          * Removes all event handers from an element.  Typically you will use {@link Ext.Element#removeAllListeners}
  259.          * directly on an Element in favor of calling this version.
  260.          * @param {String/HTMLElement} el The id or html element from which to remove the event
  261.          */
  262.         removeAll : function(el){
  263.         var id = Ext.id(el = Ext.getDom(el)), 
  264. es = elHash[id], 
  265. ename;
  266.        
  267.         for(ename in es){
  268.             if(es.hasOwnProperty(ename)){                     
  269.                 Ext.each(es[ename], function(v) {
  270.                     E.un(el, ename, v.wrap);                    
  271.                 });
  272.             }            
  273.         }
  274.         elHash[id] = null;       
  275.         },
  276.         /**
  277.          * Fires when the document is ready (before onload and before images are loaded). Can be
  278.          * accessed shorthanded as Ext.onReady().
  279.          * @param {Function} fn The method the event invokes
  280.          * @param {Object} scope (optional) An object that becomes the scope of the handler
  281.          * @param {boolean} options (optional) An object containing standard {@link #addListener} options
  282.          */
  283.         onDocumentReady : function(fn, scope, options){
  284.             if(docReadyState){ // if it already fired
  285.                 docReadyEvent.addListener(fn, scope, options);
  286.                 docReadyEvent.fire();
  287.                 docReadyEvent.clearListeners();               
  288.             } else {
  289.                 if(!docReadyEvent) initDocReady();
  290.                 options = options || {};
  291.             options.delay = options.delay || 1;             
  292.             docReadyEvent.addListener(fn, scope, options);
  293.             }
  294.         },
  295.         
  296.         elHash : elHash   
  297.     };
  298.      /**
  299.      * Appends an event handler to an element.  Shorthand for {@link #addListener}.
  300.      * @param {String/HTMLElement} el The html element or id to assign the event handler to
  301.      * @param {String} eventName The type of event to listen for
  302.      * @param {Function} handler The handler function the event invokes
  303.      * @param {Object} scope (optional) The scope in which to execute the handler
  304.      * function (the handler function's "this" context)
  305.      * @param {Object} options (optional) An object containing standard {@link #addListener} options
  306.      * @member Ext.EventManager
  307.      * @method on
  308.      */
  309.     pub.on = pub.addListener;
  310.     /**
  311.      * Removes an event handler from an element.  Shorthand for {@link #removeListener}.
  312.      * @param {String/HTMLElement} el The id or html element from which to remove the event
  313.      * @param {String} eventName The type of event
  314.      * @param {Function} fn The handler function to remove
  315.      * @return {Boolean} True if a listener was actually removed, else false
  316.      * @member Ext.EventManager
  317.      * @method un
  318.      */
  319.     pub.un = pub.removeListener;
  320.     pub.stoppedMouseDownEvent = new Ext.util.Event();
  321.     return pub;
  322. }();
  323. /**
  324.   * Fires when the document is ready (before onload and before images are loaded).  Shorthand of {@link Ext.EventManager#onDocumentReady}.
  325.   * @param {Function} fn The method the event invokes
  326.   * @param {Object} scope An object that becomes the scope of the handler
  327.   * @param {boolean} options (optional) An object containing standard {@link #addListener} options
  328.   * @member Ext
  329.   * @method onReady
  330.  */
  331. Ext.onReady = Ext.EventManager.onDocumentReady;
  332. //Initialize doc classes
  333. (function(){
  334.     
  335.     var initExtCss = function(){
  336.         // find the body element
  337.         var bd = document.body || document.getElementsByTagName('body')[0];
  338.         if(!bd){ return false; }
  339.         var cls = [' ',
  340.                 Ext.isIE ? "ext-ie " + (Ext.isIE6 ? 'ext-ie6' : (Ext.isIE7 ? 'ext-ie7' : 'ext-ie8'))
  341.                 : Ext.isGecko ? "ext-gecko " + (Ext.isGecko2 ? 'ext-gecko2' : 'ext-gecko3')
  342.                 : Ext.isOpera ? "ext-opera"
  343.                 : Ext.isWebKit ? "ext-webkit" : ""];
  344.         if(Ext.isSafari){
  345.             cls.push("ext-safari " + (Ext.isSafari2 ? 'ext-safari2' : (Ext.isSafari3 ? 'ext-safari3' : 'ext-safari4')));
  346.         }else if(Ext.isChrome){
  347.             cls.push("ext-chrome");
  348.         }
  349.         if(Ext.isMac){
  350.             cls.push("ext-mac");
  351.         }
  352.         if(Ext.isLinux){
  353.             cls.push("ext-linux");
  354.         }
  355.         if(Ext.isStrict || Ext.isBorderBox){ // add to the parent to allow for selectors like ".ext-strict .ext-ie"
  356.             var p = bd.parentNode;
  357.             if(p){
  358.                 p.className += Ext.isStrict ? ' ext-strict' : ' ext-border-box';
  359.             }
  360.         }
  361.         bd.className += cls.join(' ');
  362.         return true;
  363.     }
  364.     if(!initExtCss()){
  365.         Ext.onReady(initExtCss);
  366.     }
  367. })();
  368. /**
  369.  * @class Ext.EventObject
  370.  * Just as {@link Ext.Element} wraps around a native DOM node, Ext.EventObject 
  371.  * wraps the browser's native event-object normalizing cross-browser differences,
  372.  * such as which mouse button is clicked, keys pressed, mechanisms to stop
  373.  * event-propagation along with a method to prevent default actions from taking place.
  374.  * <p>For example:</p>
  375.  * <pre><code>
  376. function handleClick(e, t){ // e is not a standard event object, it is a Ext.EventObject
  377.     e.preventDefault();
  378.     var target = e.getTarget(); // same as t (the target HTMLElement)
  379.     ...
  380. }
  381. var myDiv = {@link Ext#get Ext.get}("myDiv");  // get reference to an {@link Ext.Element}
  382. myDiv.on(         // 'on' is shorthand for addListener
  383.     "click",      // perform an action on click of myDiv
  384.     handleClick   // reference to the action handler
  385. );  
  386. // other methods to do the same:
  387. Ext.EventManager.on("myDiv", 'click', handleClick);
  388. Ext.EventManager.addListener("myDiv", 'click', handleClick);
  389.  </code></pre>
  390.  * @singleton
  391.  */
  392. Ext.EventObject = function(){
  393.     var E = Ext.lib.Event,
  394.      // safari keypress events for special keys return bad keycodes
  395.      safariKeys = {
  396.         3 : 13, // enter
  397.         63234 : 37, // left
  398.         63235 : 39, // right
  399.         63232 : 38, // up
  400.         63233 : 40, // down
  401.         63276 : 33, // page up
  402.         63277 : 34, // page down
  403.         63272 : 46, // delete
  404.         63273 : 36, // home
  405.         63275 : 35  // end
  406.      },
  407.      // normalize button clicks
  408.      btnMap = Ext.isIE ? {1:0,4:1,2:2} :
  409.                 (Ext.isWebKit ? {1:0,2:1,3:2} : {0:0,1:1,2:2});
  410.     Ext.EventObjectImpl = function(e){
  411.         if(e){
  412.             this.setEvent(e.browserEvent || e);
  413.         }
  414.     };
  415.     Ext.EventObjectImpl.prototype = {
  416.            /** @private */
  417.         setEvent : function(e){
  418.         var me = this;
  419.             if(e == me || (e && e.browserEvent)){ // already wrapped
  420.                 return e;
  421.             }
  422.             me.browserEvent = e;
  423.             if(e){
  424.                 // normalize buttons
  425.                 me.button = e.button ? btnMap[e.button] : (e.which ? e.which - 1 : -1);
  426.                 if(e.type == 'click' && me.button == -1){
  427.                     me.button = 0;
  428.                 }
  429.                 me.type = e.type;
  430.                 me.shiftKey = e.shiftKey;
  431.                 // mac metaKey behaves like ctrlKey
  432.                 me.ctrlKey = e.ctrlKey || e.metaKey || false;
  433.                 me.altKey = e.altKey;
  434.                 // in getKey these will be normalized for the mac
  435.                 me.keyCode = e.keyCode;
  436.                 me.charCode = e.charCode;
  437.                 // cache the target for the delayed and or buffered events
  438.                 me.target = E.getTarget(e);
  439.                 // same for XY
  440.                 me.xy = E.getXY(e);
  441.             }else{
  442.                 me.button = -1;
  443.                 me.shiftKey = false;
  444.                 me.ctrlKey = false;
  445.                 me.altKey = false;
  446.                 me.keyCode = 0;
  447.                 me.charCode = 0;
  448.                 me.target = null;
  449.                 me.xy = [0, 0];
  450.             }
  451.             return me;
  452.         },
  453.         /**
  454.          * Stop the event (preventDefault and stopPropagation)
  455.          */
  456.         stopEvent : function(){
  457.         var me = this;
  458.             if(me.browserEvent){
  459.                 if(me.browserEvent.type == 'mousedown'){
  460.                     Ext.EventManager.stoppedMouseDownEvent.fire(me);
  461.                 }
  462.                 E.stopEvent(me.browserEvent);
  463.             }
  464.         },
  465.         /**
  466.          * Prevents the browsers default handling of the event.
  467.          */
  468.         preventDefault : function(){
  469.             if(this.browserEvent){
  470.                 E.preventDefault(this.browserEvent);
  471.             }
  472.         },        
  473.         /**
  474.          * Cancels bubbling of the event.
  475.          */
  476.         stopPropagation : function(){
  477.         var me = this;
  478.             if(me.browserEvent){
  479.                 if(me.browserEvent.type == 'mousedown'){
  480.                     Ext.EventManager.stoppedMouseDownEvent.fire(me);
  481.                 }
  482.                 E.stopPropagation(me.browserEvent);
  483.             }
  484.         },
  485.         /**
  486.          * Gets the character code for the event.
  487.          * @return {Number}
  488.          */
  489.         getCharCode : function(){
  490.             return this.charCode || this.keyCode;
  491.         },
  492.         /**
  493.          * Returns a normalized keyCode for the event.
  494.          * @return {Number} The key code
  495.          */
  496.         getKey : function(){
  497.             return this.normalizeKey(this.keyCode || this.charCode)
  498.         },
  499. // private
  500. normalizeKey: function(k){
  501. return Ext.isSafari ? (safariKeys[k] || k) : k; 
  502. },
  503.         /**
  504.          * Gets the x coordinate of the event.
  505.          * @return {Number}
  506.          */
  507.         getPageX : function(){
  508.             return this.xy[0];
  509.         },
  510.         /**
  511.          * Gets the y coordinate of the event.
  512.          * @return {Number}
  513.          */
  514.         getPageY : function(){
  515.             return this.xy[1];
  516.         },
  517.         /**
  518.          * Gets the page coordinates of the event.
  519.          * @return {Array} The xy values like [x, y]
  520.          */
  521.         getXY : function(){
  522.             return this.xy;
  523.         },
  524.         /**
  525.          * Gets the target for the event.
  526.          * @param {String} selector (optional) A simple selector to filter the target or look for an ancestor of the target
  527.          * @param {Number/Mixed} maxDepth (optional) The max depth to
  528.                 search as a number or element (defaults to 10 || document.body)
  529.          * @param {Boolean} returnEl (optional) True to return a Ext.Element object instead of DOM node
  530.          * @return {HTMLelement}
  531.          */
  532.         getTarget : function(selector, maxDepth, returnEl){
  533.             return selector ? Ext.fly(this.target).findParent(selector, maxDepth, returnEl) : (returnEl ? Ext.get(this.target) : this.target);
  534.         },
  535.         /**
  536.          * Gets the related target.
  537.          * @return {HTMLElement}
  538.          */
  539.         getRelatedTarget : function(){
  540.             return this.browserEvent ? E.getRelatedTarget(this.browserEvent) : null;
  541.         },
  542.         /**
  543.          * Normalizes mouse wheel delta across browsers
  544.          * @return {Number} The delta
  545.          */
  546.         getWheelDelta : function(){
  547.             var e = this.browserEvent;
  548.             var delta = 0;
  549.             if(e.wheelDelta){ /* IE/Opera. */
  550.                 delta = e.wheelDelta/120;
  551.             }else if(e.detail){ /* Mozilla case. */
  552.                 delta = -e.detail/3;
  553.             }
  554.             return delta;
  555.         },
  556. /**
  557. * 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.
  558. * Example usage:<pre><code>
  559. // Handle click on any child of an element
  560. Ext.getBody().on('click', function(e){
  561. if(e.within('some-el')){
  562. alert('Clicked on a child of some-el!');
  563. }
  564. });
  565. // Handle click directly on an element, ignoring clicks on child nodes
  566. Ext.getBody().on('click', function(e,t){
  567. if((t.id == 'some-el') && !e.within(t, true)){
  568. alert('Clicked directly on some-el!');
  569. }
  570. });
  571. </code></pre>
  572.  * @param {Mixed} el The id, DOM element or Ext.Element to check
  573.  * @param {Boolean} related (optional) true to test if the related target is within el instead of the target
  574.  * @param {Boolean} allowEl {optional} true to also check if the passed element is the target or related target
  575.  * @return {Boolean}
  576.  */
  577. within : function(el, related, allowEl){
  578.             if(el){
  579.     var t = this[related ? "getRelatedTarget" : "getTarget"]();
  580.     return t && ((allowEl ? (t == Ext.getDom(el)) : false) || Ext.fly(el).contains(t));
  581.             }
  582.             return false;
  583. }
  584.  };
  585.     return new Ext.EventObjectImpl();
  586. }();