ext-foundation-debug.js
上传用户:dawnssy
上传日期:2022-08-06
资源大小:9345k
文件大小:532k
源码类别:

JavaScript

开发平台:

JavaScript

  1.             "nth" : function(c, a){
  2.                 return c[a-1] || [];
  3.             },
  4.             "first" : function(c){
  5.                 return c[0] || [];
  6.             },
  7.             "last" : function(c){
  8.                 return c[c.length-1] || [];
  9.             },
  10.             "has" : function(c, ss){
  11.                 var s = Ext.DomQuery.select,
  12.                  r = [], ri = -1;
  13.                 for(var i = 0, ci; ci = c[i]; i++){
  14.                     if(s(ss, ci).length > 0){
  15.                         r[++ri] = ci;
  16.                     }
  17.                 }
  18.                 return r;
  19.             },
  20.             "next" : function(c, ss){
  21.                 var is = Ext.DomQuery.is,
  22.                  r = [], ri = -1;
  23.                 for(var i = 0, ci; ci = c[i]; i++){
  24.                     var n = next(ci);
  25.                     if(n && is(n, ss)){
  26.                         r[++ri] = ci;
  27.                     }
  28.                 }
  29.                 return r;
  30.             },
  31.             "prev" : function(c, ss){
  32.                 var is = Ext.DomQuery.is,
  33.                  r = [], ri = -1;
  34.                 for(var i = 0, ci; ci = c[i]; i++){
  35.                     var n = prev(ci);
  36.                     if(n && is(n, ss)){
  37.                         r[++ri] = ci;
  38.                     }
  39.                 }
  40.                 return r;
  41.             }
  42.         }
  43.     };
  44. }();
  45. /**
  46.  * Selects an array of DOM nodes by CSS/XPath selector. Shorthand of {@link Ext.DomQuery#select}
  47.  * @param {String} path The selector/xpath query
  48.  * @param {Node} root (optional) The start of the query (defaults to document).
  49.  * @return {Array}
  50.  * @member Ext
  51.  * @method query
  52.  */
  53. Ext.query = Ext.DomQuery.select;
  54. /**  * @class Ext.util.DelayedTask  * <p> The DelayedTask class provides a convenient way to "buffer" the execution of a method,  * performing setTimeout where a new timeout cancels the old timeout. When called, the  * task will wait the specified time period before executing. If durng that time period,  * the task is called again, the original call will be cancelled. This continues so that  * the function is only called a single time for each iteration.</p>  * <p>This method is especially useful for things like detecting whether a user has finished  * typing in a text field. An example would be performing validation on a keypress. You can  * use this class to buffer the keypress events for a certain number of milliseconds, and  * perform only if they stop for that amount of time.  Usage:</p><pre><code> var task = new Ext.util.DelayedTask(function(){     alert(Ext.getDom('myInputField').value.length); }); // Wait 500ms before calling our function. If the user presses another key  // during that 500ms, it will be cancelled and we'll wait another 500ms. Ext.get('myInputField').on('keypress', function(){     task.{@link #delay}(500);  });  * </code></pre>   * <p>Note that we are using a DelayedTask here to illustrate a point. The configuration  * option <tt>buffer</tt> for {@link Ext.util.Observable#addListener addListener/on} will  * also setup a delayed task for you to buffer events.</p>   * @constructor The parameters to this constructor serve as defaults and are not required.  * @param {Function} fn (optional) The default function to call.  * @param {Object} scope The default scope (The <code><b>this</b></code> reference) in which the  * function is called. If not specified, <code>this</code> will refer to the browser window.  * @param {Array} args (optional) The default Array of arguments.  */ Ext.util.DelayedTask = function(fn, scope, args){     var me = this,      id,          call = function(){      clearInterval(id);         id = null;         fn.apply(scope, args || []);     };          /**      * Cancels any pending timeout and queues a new one      * @param {Number} delay The milliseconds to delay      * @param {Function} newFn (optional) Overrides function passed to constructor      * @param {Object} newScope (optional) Overrides scope passed to constructor. Remember that if no scope      * is specified, <code>this</code> will refer to the browser window.      * @param {Array} newArgs (optional) Overrides args passed to constructor      */     me.delay = function(delay, newFn, newScope, newArgs){         me.cancel();         fn = newFn || fn;         scope = newScope || scope;         args = newArgs || args;         id = setInterval(call, delay);     };     /**      * Cancel the last queued timeout      */     me.cancel = function(){         if(id){             clearInterval(id);             id = null;         }     }; };(function(){ var EXTUTIL = Ext.util,     TOARRAY = Ext.toArray,     EACH = Ext.each,     ISOBJECT = Ext.isObject,     TRUE = true,     FALSE = false; /**  * @class Ext.util.Observable  * Base class that provides a common interface for publishing events. Subclasses are expected to  * to have a property "events" with all the events defined, and, optionally, a property "listeners"  * with configured listeners defined.<br>  * For example:  * <pre><code> Employee = Ext.extend(Ext.util.Observable, {     constructor: function(config){         this.name = config.name;         this.addEvents({             "fired" : true,             "quit" : true         });         // Copy configured listeners into *this* object so that the base class&#39;s         // constructor will add them.         this.listeners = config.listeners;         // Call our superclass constructor to complete construction process.         Employee.superclass.constructor.call(config)     } }); </code></pre>  * This could then be used like this:<pre><code> var newEmployee = new Employee({     name: employeeName,     listeners: {         quit: function() {             // By default, "this" will be the object that fired the event.             alert(this.name + " has quit!");         }     } }); </code></pre>  */ EXTUTIL.Observable = function(){     /**      * @cfg {Object} listeners (optional) <p>A config object containing one or more event handlers to be added to this      * object during initialization.  This should be a valid listeners config object as specified in the      * {@link #addListener} example for attaching multiple handlers at once.</p>      * <br><p><b><u>DOM events from ExtJs {@link Ext.Component Components}</u></b></p>      * <br><p>While <i>some</i> ExtJs Component classes export selected DOM events (e.g. "click", "mouseover" etc), this      * is usually only done when extra value can be added. For example the {@link Ext.DataView DataView}'s      * <b><code>{@link Ext.DataView#click click}</code></b> event passing the node clicked on. To access DOM      * events directly from a Component's HTMLElement, listeners must be added to the <i>{@link Ext.Component#getEl Element}</i> after the Component      * has been rendered. A plugin can simplify this step:<pre><code> // Plugin is configured with a listeners config object. // The Component is appended to the argument list of all handler functions. Ext.DomObserver = Ext.extend(Object, {     constructor: function(config) {         this.listeners = config.listeners ? config.listeners : config;     },     // Component passes itself into plugin&#39;s init method     init: function(c) {         var p, l = this.listeners;         for (p in l) {             if (Ext.isFunction(l[p])) {                 l[p] = this.createHandler(l[p], c);             } else {                 l[p].fn = this.createHandler(l[p].fn, c);             }         }         // Add the listeners to the Element immediately following the render call         c.render = c.render.{@link Function#createSequence createSequence}(function() {             var e = c.getEl();             if (e) {                 e.on(l);             }         });     },     createHandler: function(fn, c) {         return function(e) {             fn.call(this, e, c);         };     } }); var combo = new Ext.form.ComboBox({     // Collapse combo when its element is clicked on     plugins: [ new Ext.DomObserver({         click: function(evt, comp) {             comp.collapse();         }     })],     store: myStore,     typeAhead: true,     mode: 'local',     triggerAction: 'all' });      * </code></pre></p>      */     var me = this, e = me.events;     if(me.listeners){         me.on(me.listeners);         delete me.listeners;     }     me.events = e || {}; }; EXTUTIL.Observable.prototype = {     // private     filterOptRe : /^(?:scope|delay|buffer|single)$/,     /**      * <p>Fires the specified event with the passed parameters (minus the event name).</p>      * <p>An event may be set to bubble up an Observable parent hierarchy (See {@link Ext.Component#getBubbleTarget})      * by calling {@link #enableBubble}.</p>      * @param {String} eventName The name of the event to fire.      * @param {Object...} args Variable number of parameters are passed to handlers.      * @return {Boolean} returns false if any of the handlers return false otherwise it returns true.      */     fireEvent : function(){         var a = TOARRAY(arguments),             ename = a[0].toLowerCase(),             me = this,             ret = TRUE,             ce = me.events[ename],             q,             c;         if (me.eventsSuspended === TRUE) {             if (q = me.eventQueue) {                 q.push(a);             }         }         else if(ISOBJECT(ce) && ce.bubble){             if(ce.fire.apply(ce, a.slice(1)) === FALSE) {                 return FALSE;             }             c = me.getBubbleTarget && me.getBubbleTarget();             if(c && c.enableBubble) {                 if(!c.events[ename] || !Ext.isObject(c.events[ename]) || !c.events[ename].bubble) {                     c.enableBubble(ename);                 }                 return c.fireEvent.apply(c, a);             }         }         else {             if (ISOBJECT(ce)) {                 a.shift();                 ret = ce.fire.apply(ce, a);             }         }         return ret;     },     /**      * Appends an event handler to this object.      * @param {String}   eventName The name of the event to listen for.      * @param {Function} handler The method the event invokes.      * @param {Object}   scope (optional) The scope (<code><b>this</b></code> reference) in which the handler function is executed.      * <b>If omitted, defaults to the object which fired the event.</b>      * @param {Object}   options (optional) An object containing handler configuration.      * properties. This may contain any of the following properties:<ul>      * <li><b>scope</b> : Object<div class="sub-desc">The scope (<code><b>this</b></code> reference) in which the handler function is executed.      * <b>If omitted, defaults to the object which fired the event.</b></div></li>      * <li><b>delay</b> : Number<div class="sub-desc">The number of milliseconds to delay the invocation of the handler after the event fires.</div></li>      * <li><b>single</b> : 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><b>buffer</b> : 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><b>target</b> : Observable<div class="sub-desc">Only call the handler if the event was fired on the target Observable, <i>not</i>      * if the event was bubbled up from a child Observable.</div></li>      * </ul><br>      * <p>      * <b>Combining Options</b><br>      * Using the options argument, it is possible to combine different types of listeners:<br>      * <br>      * A delayed, one-time listener.      * <pre><code> myDataView.on('click', this.onClick, this, { single: true, delay: 100 });</code></pre>      * <p>      * <b>Attaching multiple handlers in 1 call</b><br>      * The method also allows for a single argument to be passed which is a config object containing properties      * which specify multiple handlers.      * <p>      * <pre><code> myGridPanel.on({ 'click' : {     fn: this.onClick,     scope: this,     delay: 100 }, 'mouseover' : {     fn: this.onMouseOver,     scope: this }, 'mouseout' : {     fn: this.onMouseOut,     scope: this } });</code></pre>  * <p>  * Or a shorthand syntax:<br>  * <pre><code> myGridPanel.on({ 'click' : this.onClick, 'mouseover' : this.onMouseOver, 'mouseout' : this.onMouseOut,  scope: this });</code></pre>      */     addListener : function(eventName, fn, scope, o){         var me = this,             e,             oe,             isF,         ce;         if (ISOBJECT(eventName)) {             o = eventName;             for (e in o){                 oe = o[e];                 if (!me.filterOptRe.test(e)) {                     me.addListener(e, oe.fn || oe, oe.scope || o.scope, oe.fn ? oe : o);                 }             }         } else {             eventName = eventName.toLowerCase();             ce = me.events[eventName] || TRUE;             if (Ext.isBoolean(ce)) {                 me.events[eventName] = ce = new EXTUTIL.Event(me, eventName);             }             ce.addListener(fn, scope, ISOBJECT(o) ? o : {});         }     },     /**      * Removes an event handler.      * @param {String}   eventName The type of event the handler was associated with.      * @param {Function} handler   The handler to remove. <b>This must be a reference to the function passed into the {@link #addListener} call.</b>      * @param {Object}   scope     (optional) The scope originally specified for the handler.      */     removeListener : function(eventName, fn, scope){         var ce = this.events[eventName.toLowerCase()];         if (ISOBJECT(ce)) {             ce.removeListener(fn, scope);         }     },     /**      * Removes all listeners for this object      */     purgeListeners : function(){         var events = this.events,             evt,             key;         for(key in events){             evt = events[key];             if(ISOBJECT(evt)){                 evt.clearListeners();             }         }     },     /**      * Adds the specified events to the list of events which this Observable may fire.      * @param {Object|String} o Either an object with event names as properties with a value of <code>true</code>      * or the first event name string if multiple event names are being passed as separate parameters.      * @param {string} Optional. Event name if multiple event names are being passed as separate parameters.      * Usage:<pre><code> this.addEvents('storeloaded', 'storecleared'); </code></pre>      */     addEvents : function(o){         var me = this;         me.events = me.events || {};         if (Ext.isString(o)) {             var a = arguments,                 i = a.length;             while(i--) {                 me.events[a[i]] = me.events[a[i]] || TRUE;             }         } else {             Ext.applyIf(me.events, o);         }     },     /**      * Checks to see if this object has any listeners for a specified event      * @param {String} eventName The name of the event to check for      * @return {Boolean} True if the event is being listened for, else false      */     hasListener : function(eventName){         var e = this.events[eventName];         return ISOBJECT(e) && e.listeners.length > 0;     },     /**      * Suspend the firing of all events. (see {@link #resumeEvents})      * @param {Boolean} queueSuspended Pass as true to queue up suspended events to be fired      * after the {@link #resumeEvents} call instead of discarding all suspended events;      */     suspendEvents : function(queueSuspended){         this.eventsSuspended = TRUE;         if(queueSuspended && !this.eventQueue){             this.eventQueue = [];         }     },     /**      * Resume firing events. (see {@link #suspendEvents})      * If events were suspended using the <tt><b>queueSuspended</b></tt> parameter, then all      * events fired during event suspension will be sent to any listeners now.      */     resumeEvents : function(){         var me = this,             queued = me.eventQueue || [];         me.eventsSuspended = FALSE;         delete me.eventQueue;         EACH(queued, function(e) {             me.fireEvent.apply(me, e);         });     } }; var OBSERVABLE = EXTUTIL.Observable.prototype; /**  * Appends an event handler to this object (shorthand for {@link #addListener}.)  * @param {String}   eventName     The type of event to listen for  * @param {Function} handler       The method the event invokes  * @param {Object}   scope         (optional) The scope (<code><b>this</b></code> reference) in which the handler function is executed.  * <b>If omitted, defaults to the object which fired the event.</b>  * @param {Object}   options       (optional) An object containing handler configuration.  * @method  */ OBSERVABLE.on = OBSERVABLE.addListener; /**  * Removes an event handler (shorthand for {@link #removeListener}.)  * @param {String}   eventName     The type of event the handler was associated with.  * @param {Function} handler       The handler to remove. <b>This must be a reference to the function passed into the {@link #addListener} call.</b>  * @param {Object}   scope         (optional) The scope originally specified for the handler.  * @method  */ OBSERVABLE.un = OBSERVABLE.removeListener; /**  * Removes <b>all</b> added captures from the Observable.  * @param {Observable} o The Observable to release  * @static  */ EXTUTIL.Observable.releaseCapture = function(o){     o.fireEvent = OBSERVABLE.fireEvent; }; function createTargeted(h, o, scope){     return function(){         if(o.target == arguments[0]){             h.apply(scope, TOARRAY(arguments));         }     }; }; function createBuffered(h, o, fn, scope){     fn.task = new EXTUTIL.DelayedTask();     return function(){         fn.task.delay(o.buffer, h, scope, TOARRAY(arguments));     }; } function createSingle(h, e, fn, scope){     return function(){         e.removeListener(fn, scope);         return h.apply(scope, arguments);     }; } function createDelayed(h, o, fn, scope){     return function(){         var task = new EXTUTIL.DelayedTask();         if(!fn.tasks) {             fn.tasks = [];         }         fn.tasks.push(task);         task.delay(o.delay || 10, h, scope, TOARRAY(arguments));     }; }; EXTUTIL.Event = function(obj, name){     this.name = name;     this.obj = obj;     this.listeners = []; }; EXTUTIL.Event.prototype = {     addListener : function(fn, scope, options){         var me = this,             l;         scope = scope || me.obj;         if(!me.isListening(fn, scope)){             l = me.createListener(fn, scope, options);             if(me.firing){ // if we are currently firing this event, don't disturb the listener loop                 me.listeners = me.listeners.slice(0);             }             me.listeners.push(l);         }     },     createListener: function(fn, scope, o){         o = o || {}, scope = scope || this.obj;         var l = {             fn: fn,             scope: scope,             options: o         }, h = fn;         if(o.target){             h = createTargeted(h, o, scope);         }         if(o.delay){             h = createDelayed(h, o, fn, scope);         }         if(o.single){             h = createSingle(h, this, fn, scope);         }         if(o.buffer){             h = createBuffered(h, o, fn, scope);         }         l.fireFn = h;         return l;     },     findListener : function(fn, scope){         var list = this.listeners,             i = list.length,             l,             s;         while(i--) {             l = list[i];             if(l) {                 s = l.scope;                 if(l.fn == fn && (s == scope || s == this.obj)){                     return i;                 }             }         }         return -1;     },     isListening : function(fn, scope){         return this.findListener(fn, scope) != -1;     },     removeListener : function(fn, scope){         var index,             l,             k,             me = this,             ret = FALSE;         if((index = me.findListener(fn, scope)) != -1){             if (me.firing) {                 me.listeners = me.listeners.slice(0);             }             l = me.listeners[index].fn;             // Cancel buffered tasks             if(l.task) {                 l.task.cancel();                 delete l.task;             }             // Cancel delayed tasks             k = l.tasks && l.tasks.length;             if(k) {                 while(k--) {                     l.tasks[k].cancel();                 }                 delete l.tasks;             }             me.listeners.splice(index, 1);             ret = TRUE;         }         return ret;     },     // Iterate to stop any buffered/delayed events     clearListeners : function(){         var me = this,             l = me.listeners,             i = l.length;         while(i--) {             me.removeListener(l[i].fn, l[i].scope);         }     },     fire : function(){         var me = this,             args = TOARRAY(arguments),             listeners = me.listeners,             len = listeners.length,             i = 0,             l;         if(len > 0){             me.firing = TRUE;             for (; i < len; i++) {                 l = listeners[i];                 if(l && l.fireFn.apply(l.scope || me.obj || window, args) === FALSE) {                     return (me.firing = FALSE);                 }             }         }         me.firing = FALSE;         return TRUE;     } }; })();/**
  55.  * @class Ext.util.Observable
  56.  */
  57. Ext.apply(Ext.util.Observable.prototype, function(){
  58.     // this is considered experimental (along with beforeMethod, afterMethod, removeMethodListener?)
  59.     // allows for easier interceptor and sequences, including cancelling and overwriting the return value of the call
  60.     // private
  61.     function getMethodEvent(method){
  62.         var e = (this.methodEvents = this.methodEvents ||
  63.         {})[method], returnValue, v, cancel, obj = this;
  64.         if (!e) {
  65.             this.methodEvents[method] = e = {};
  66.             e.originalFn = this[method];
  67.             e.methodName = method;
  68.             e.before = [];
  69.             e.after = [];
  70.             var makeCall = function(fn, scope, args){
  71.                 if (!Ext.isEmpty(v = fn.apply(scope || obj, args))) {
  72.                     if (Ext.isObject(v)) {
  73.                         returnValue = !Ext.isEmpty(v.returnValue) ? v.returnValue : v;
  74.                         cancel = !!v.cancel;
  75.                     }
  76.                     else
  77.                         if (v === false) {
  78.                             cancel = true;
  79.                         }
  80.                         else {
  81.                             returnValue = v;
  82.                         }
  83.                 }
  84.             };
  85.             this[method] = function(){
  86.                 var args = Ext.toArray(arguments);
  87.                 returnValue = v = undefined;
  88.                 cancel = false;
  89.                 Ext.each(e.before, function(b){
  90.                     makeCall(b.fn, b.scope, args);
  91.                     if (cancel) {
  92.                         return returnValue;
  93.                     }
  94.                 });
  95.                 if (!Ext.isEmpty(v = e.originalFn.apply(obj, args))) {
  96.                     returnValue = v;
  97.                 }
  98.                 Ext.each(e.after, function(a){
  99.                     makeCall(a.fn, a.scope, args);
  100.                     if (cancel) {
  101.                         return returnValue;
  102.                     }
  103.                 });
  104.                 return returnValue;
  105.             };
  106.         }
  107.         return e;
  108.     }
  109.     return {
  110.         // these are considered experimental
  111.         // allows for easier interceptor and sequences, including cancelling and overwriting the return value of the call
  112.         // adds an 'interceptor' called before the original method
  113.         beforeMethod : function(method, fn, scope){
  114.             getMethodEvent.call(this, method).before.push({
  115.                 fn: fn,
  116.                 scope: scope
  117.             });
  118.         },
  119.         // adds a 'sequence' called after the original method
  120.         afterMethod : function(method, fn, scope){
  121.             getMethodEvent.call(this, method).after.push({
  122.                 fn: fn,
  123.                 scope: scope
  124.             });
  125.         },
  126.         removeMethodListener: function(method, fn, scope){
  127.             var e = getMethodEvent.call(this, method), found = false;
  128.             Ext.each(e.before, function(b, i, arr){
  129.                 if (b.fn == fn && b.scope == scope) {
  130.                     arr.splice(i, 1);
  131.                     found = true;
  132.                     return false;
  133.                 }
  134.             });
  135.             if (!found) {
  136.                 Ext.each(e.after, function(a, i, arr){
  137.                     if (a.fn == fn && a.scope == scope) {
  138.                         arr.splice(i, 1);
  139.                         return false;
  140.                     }
  141.                 });
  142.             }
  143.         },
  144.         /**
  145.          * Relays selected events from the specified Observable as if the events were fired by <tt><b>this</b></tt>.
  146.          * @param {Object} o The Observable whose events this object is to relay.
  147.          * @param {Array} events Array of event names to relay.
  148.          */
  149.         relayEvents : function(o, events){
  150.             var me = this;
  151.             function createHandler(ename){
  152.                 return function(){
  153.                     return me.fireEvent.apply(me, [ename].concat(Ext.toArray(arguments)));
  154.                 };
  155.             }
  156.             Ext.each(events, function(ename){
  157.                 me.events[ename] = me.events[ename] || true;
  158.                 o.on(ename, createHandler(ename), me);
  159.             });
  160.         },
  161.         /**
  162.          * <p>Enables events fired by this Observable to bubble up an owner hierarchy by calling
  163.          * <code>this.getBubbleTarget()</code> if present. There is no implementation in the Observable base class.</p>
  164.          * <p>This is commonly used by Ext.Components to bubble events to owner Containers. See {@link Ext.Component.getBubbleTarget}. The default
  165.          * implementation in Ext.Component returns the Component's immediate owner. But if a known target is required, this can be overridden to
  166.          * access the required target more quickly.</p>
  167.          * <p>Example:</p><pre><code>
  168. Ext.override(Ext.form.Field, {
  169.     //  Add functionality to Field&#39;s initComponent to enable the change event to bubble
  170.     initComponent : Ext.form.Field.prototype.initComponent.createSequence(function() {
  171.         this.enableBubble('change');
  172.     }),
  173.     //  We know that we want Field&#39;s events to bubble directly to the FormPanel.
  174.     getBubbleTarget : function() {
  175.         if (!this.formPanel) {
  176.             this.formPanel = this.findParentByType('form');
  177.         }
  178.         return this.formPanel;
  179.     }
  180. });
  181. var myForm = new Ext.formPanel({
  182.     title: 'User Details',
  183.     items: [{
  184.         ...
  185.     }],
  186.     listeners: {
  187.         change: function() {
  188.             // Title goes red if form has been modified.
  189.             myForm.header.setStyle('color', 'red');
  190.         }
  191.     }
  192. });
  193. </code></pre>
  194.          * @param {String/Array} events The event name to bubble, or an Array of event names.
  195.          */
  196.         enableBubble : function(events){
  197.             var me = this;
  198.             if(!Ext.isEmpty(events)){
  199.                 events = Ext.isArray(events) ? events : Ext.toArray(arguments);
  200.                 Ext.each(events, function(ename){
  201.                     ename = ename.toLowerCase();
  202.                     var ce = me.events[ename] || true;
  203.                     if (Ext.isBoolean(ce)) {
  204.                         ce = new Ext.util.Event(me, ename);
  205.                         me.events[ename] = ce;
  206.                     }
  207.                     ce.bubble = true;
  208.                 });
  209.             }
  210.         }
  211.     };
  212. }());
  213. /**
  214.  * Starts capture on the specified Observable. All events will be passed
  215.  * to the supplied function with the event name + standard signature of the event
  216.  * <b>before</b> the event is fired. If the supplied function returns false,
  217.  * the event will not fire.
  218.  * @param {Observable} o The Observable to capture events from.
  219.  * @param {Function} fn The function to call when an event is fired.
  220.  * @param {Object} scope (optional) The scope (<code>this</code> reference) in which the function is executed. Defaults to the Observable firing the event.
  221.  * @static
  222.  */
  223. Ext.util.Observable.capture = function(o, fn, scope){
  224.     o.fireEvent = o.fireEvent.createInterceptor(fn, scope);
  225. };
  226. /**
  227.  * Sets observability on the passed class constructor.<p>
  228.  * <p>This makes any event fired on any instance of the passed class also fire a single event through
  229.  * the <i>class</i> allowing for central handling of events on many instances at once.</p>
  230.  * <p>Usage:</p><pre><code>
  231. Ext.util.Observable.observeClass(Ext.data.Connection);
  232. Ext.data.Connection.on('beforerequest', function(con, options) {
  233.     console.log('Ajax request made to ' + options.url);
  234. });</code></pre>
  235.  * @param {Function} c The class constructor to make observable.
  236.  * @param {Object} listeners An object containing a series of listeners to add. See {@link #addListener}. 
  237.  * @static
  238.  */
  239. Ext.util.Observable.observeClass = function(c, listeners){
  240.     if(c){
  241.       if(!c.fireEvent){
  242.           Ext.apply(c, new Ext.util.Observable());
  243.           Ext.util.Observable.capture(c.prototype, c.fireEvent, c);
  244.       }
  245.       if(Ext.isObject(listeners)){
  246.           c.on(listeners);
  247.       }
  248.       return c;
  249.    }
  250. };/**
  251.  * @class Ext.EventManager
  252.  * Registers event handlers that want to receive a normalized EventObject instead of the standard browser event and provides
  253.  * several useful events directly.
  254.  * See {@link Ext.EventObject} for more details on normalized event objects.
  255.  * @singleton
  256.  */
  257. Ext.EventManager = function(){
  258.     var docReadyEvent,
  259.         docReadyProcId,
  260.         docReadyState = false,
  261.         E = Ext.lib.Event,
  262.         D = Ext.lib.Dom,
  263.         DOC = document,
  264.         WINDOW = window,
  265.         IEDEFERED = "ie-deferred-loader",
  266.         DOMCONTENTLOADED = "DOMContentLoaded",
  267.         propRe = /^(?:scope|delay|buffer|single|stopEvent|preventDefault|stopPropagation|normalized|args|delegate)$/,
  268.         /*
  269.          * This cache is used to hold special js objects, the document and window, that don't have an id. We need to keep
  270.          * a reference to them so we can look them up at a later point.
  271.          */
  272.         specialElCache = [];
  273.      function getId(el){
  274.         var id = false,
  275.             i = 0,
  276.             len = specialElCache.length,
  277.             id = false,
  278.             skip = false,
  279.             o;
  280.         if(el){
  281.             if(el.getElementById || el.navigator){
  282.                 // look up the id
  283.                 for(; i < len; ++i){
  284.                     o = specialElCache[i];
  285.                     if(o.el === el){
  286.                         id = o.id;
  287.                         break;
  288.                     }
  289.                 }
  290.                 if(!id){
  291.                     // for browsers that support it, ensure that give the el the same id
  292.                     id = Ext.id(el);
  293.                     specialElCache.push({
  294.                         id: id,
  295.                         el: el
  296.                     });
  297.                     skip = true;
  298.                 }
  299.             }else{
  300.                 id = Ext.id(el);
  301.             }
  302.             if(!Ext.elCache[id]){
  303.                 Ext.Element.addToCache(new Ext.Element(el), id);
  304.                 if(skip){
  305.                     Ext.elCache[id].skipGC = true;
  306.                 }
  307.             }
  308.         }
  309.         return id;
  310.      };
  311.     /// There is some jquery work around stuff here that isn't needed in Ext Core.
  312.     function addListener(el, ename, fn, wrap, scope){
  313.         el = Ext.getDom(el);
  314.         var id = getId(el),
  315.             es = Ext.elCache[id].events,
  316.             wfn;
  317.         wfn = E.on(el, ename, wrap);
  318.         es[ename] = es[ename] || [];
  319.         es[ename].push([fn, wrap, scope, wfn]);
  320.         // this is a workaround for jQuery and should somehow be removed from Ext Core in the future
  321.         // without breaking ExtJS.
  322.         if(ename == "mousewheel" && el.addEventListener){ // workaround for jQuery
  323.             var args = ["DOMMouseScroll", wrap, false];
  324.             el.addEventListener.apply(el, args);
  325.             Ext.EventManager.addListener(WINDOW, 'unload', function(){
  326.                 el.removeEventListener.apply(el, args);
  327.             });
  328.         }
  329.         if(ename == "mousedown" && el == document){ // fix stopped mousedowns on the document
  330.             Ext.EventManager.stoppedMouseDownEvent.addListener(wrap);
  331.         }
  332.     };
  333.     function fireDocReady(){
  334.         if(!docReadyState){
  335.             Ext.isReady = docReadyState = true;
  336.             if(docReadyProcId){
  337.                 clearInterval(docReadyProcId);
  338.             }
  339.             if(Ext.isGecko || Ext.isOpera) {
  340.                 DOC.removeEventListener(DOMCONTENTLOADED, fireDocReady, false);
  341.             }
  342.             if(Ext.isIE){
  343.                 var defer = DOC.getElementById(IEDEFERED);
  344.                 if(defer){
  345.                     defer.onreadystatechange = null;
  346.                     defer.parentNode.removeChild(defer);
  347.                 }
  348.             }
  349.             if(docReadyEvent){
  350.                 docReadyEvent.fire();
  351.                 docReadyEvent.listeners = []; // clearListeners no longer compatible.  Force single: true?
  352.             }
  353.         }
  354.     };
  355.     function initDocReady(){
  356.         var COMPLETE = "complete";
  357.         docReadyEvent = new Ext.util.Event();
  358.         if (Ext.isGecko || Ext.isOpera) {
  359.             DOC.addEventListener(DOMCONTENTLOADED, fireDocReady, false);
  360.         } else if (Ext.isIE){
  361.             DOC.write("<s"+'cript id=' + IEDEFERED + ' defer="defer" src="/'+'/:"></s'+"cript>");
  362.             DOC.getElementById(IEDEFERED).onreadystatechange = function(){
  363.                 if(this.readyState == COMPLETE){
  364.                     fireDocReady();
  365.                 }
  366.             };
  367.         } else if (Ext.isWebKit){
  368.             docReadyProcId = setInterval(function(){
  369.                 if(DOC.readyState == COMPLETE) {
  370.                     fireDocReady();
  371.                  }
  372.             }, 10);
  373.         }
  374.         // no matter what, make sure it fires on load
  375.         E.on(WINDOW, "load", fireDocReady);
  376.     };
  377.     function createTargeted(h, o){
  378.         return function(){
  379.             var args = Ext.toArray(arguments);
  380.             if(o.target == Ext.EventObject.setEvent(args[0]).target){
  381.                 h.apply(this, args);
  382.             }
  383.         };
  384.     };
  385.     function createBuffered(h, o, fn){
  386.         fn.task = new Ext.util.DelayedTask(h);
  387.         var w = function(e){
  388.             // create new event object impl so new events don't wipe out properties
  389.             fn.task.delay(o.buffer, h, null, [new Ext.EventObjectImpl(e)]);
  390.         };
  391.         return w;
  392.     };
  393.     function createSingle(h, el, ename, fn, scope){
  394.         return function(e){
  395.             Ext.EventManager.removeListener(el, ename, fn, scope);
  396.             h(e);
  397.         };
  398.     };
  399.     function createDelayed(h, o, fn){
  400.         return function(e){
  401.             var task = new Ext.util.DelayedTask(h);
  402.             if(!fn.tasks) {
  403.                 fn.tasks = [];
  404.             }
  405.             fn.tasks.push(task);
  406.             task.delay(o.delay || 10, h, null, [new Ext.EventObjectImpl(e)]);
  407.         };
  408.     };
  409.     function listen(element, ename, opt, fn, scope){
  410.         var o = !Ext.isObject(opt) ? {} : opt,
  411.             el = Ext.getDom(element);
  412.         fn = fn || o.fn;
  413.         scope = scope || o.scope;
  414.         if(!el){
  415.             throw "Error listening for "" + ename + '". Element "' + element + '" doesn't exist.';
  416.         }
  417.         function h(e){
  418.             // prevent errors while unload occurring
  419.             if(!Ext){// !window[xname]){  ==> can't we do this?
  420.                 return;
  421.             }
  422.             e = Ext.EventObject.setEvent(e);
  423.             var t;
  424.             if (o.delegate) {
  425.                 if(!(t = e.getTarget(o.delegate, el))){
  426.                     return;
  427.                 }
  428.             } else {
  429.                 t = e.target;
  430.             }
  431.             if (o.stopEvent) {
  432.                 e.stopEvent();
  433.             }
  434.             if (o.preventDefault) {
  435.                e.preventDefault();
  436.             }
  437.             if (o.stopPropagation) {
  438.                 e.stopPropagation();
  439.             }
  440.             if (o.normalized) {
  441.                 e = e.browserEvent;
  442.             }
  443.             fn.call(scope || el, e, t, o);
  444.         };
  445.         if(o.target){
  446.             h = createTargeted(h, o);
  447.         }
  448.         if(o.delay){
  449.             h = createDelayed(h, o, fn);
  450.         }
  451.         if(o.single){
  452.             h = createSingle(h, el, ename, fn, scope);
  453.         }
  454.         if(o.buffer){
  455.             h = createBuffered(h, o, fn);
  456.         }
  457.         addListener(el, ename, fn, h, scope);
  458.         return h;
  459.     };
  460.     var pub = {
  461.         /**
  462.          * Appends an event handler to an element.  The shorthand version {@link #on} is equivalent.  Typically you will
  463.          * use {@link Ext.Element#addListener} directly on an Element in favor of calling this version.
  464.          * @param {String/HTMLElement} el The html element or id to assign the event handler to.
  465.          * @param {String} eventName The name of the event to listen for.
  466.          * @param {Function} handler The handler function the event invokes. This function is passed
  467.          * the following parameters:<ul>
  468.          * <li>evt : EventObject<div class="sub-desc">The {@link Ext.EventObject EventObject} describing the event.</div></li>
  469.          * <li>t : Element<div class="sub-desc">The {@link Ext.Element Element} which was the target of the event.
  470.          * Note that this may be filtered by using the <tt>delegate</tt> option.</div></li>
  471.          * <li>o : Object<div class="sub-desc">The options object from the addListener call.</div></li>
  472.          * </ul>
  473.          * @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>.
  474.          * @param {Object} options (optional) An object containing handler configuration properties.
  475.          * This may contain any of the following properties:<ul>
  476.          * <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>
  477.          * <li>delegate : String<div class="sub-desc">A simple selector to filter the target or look for a descendant of the target</div></li>
  478.          * <li>stopEvent : Boolean<div class="sub-desc">True to stop the event. That is stop propagation, and prevent the default action.</div></li>
  479.          * <li>preventDefault : Boolean<div class="sub-desc">True to prevent the default action</div></li>
  480.          * <li>stopPropagation : Boolean<div class="sub-desc">True to prevent event propagation</div></li>
  481.          * <li>normalized : Boolean<div class="sub-desc">False to pass a browser event to the handler function instead of an Ext.EventObject</div></li>
  482.          * <li>delay : Number<div class="sub-desc">The number of milliseconds to delay the invocation of the handler after te event fires.</div></li>
  483.          * <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>
  484.          * <li>buffer : Number<div class="sub-desc">Causes the handler to be scheduled to run in an {@link Ext.util.DelayedTask} delayed
  485.          * by the specified number of milliseconds. If the event fires again within that time, the original
  486.          * handler is <em>not</em> invoked, but the new handler is scheduled in its place.</div></li>
  487.          * <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>
  488.          * </ul><br>
  489.          * <p>See {@link Ext.Element#addListener} for examples of how to use these options.</p>
  490.          */
  491.         addListener : function(element, eventName, fn, scope, options){
  492.             if(Ext.isObject(eventName)){
  493.                 var o = eventName, e, val;
  494.                 for(e in o){
  495.                     val = o[e];
  496.                     if(!propRe.test(e)){
  497.                         if(Ext.isFunction(val)){
  498.                             // shared options
  499.                             listen(element, e, o, val, o.scope);
  500.                         }else{
  501.                             // individual options
  502.                             listen(element, e, val);
  503.                         }
  504.                     }
  505.                 }
  506.             } else {
  507.                 listen(element, eventName, options, fn, scope);
  508.             }
  509.         },
  510.         /**
  511.          * Removes an event handler from an element.  The shorthand version {@link #un} is equivalent.  Typically
  512.          * you will use {@link Ext.Element#removeListener} directly on an Element in favor of calling this version.
  513.          * @param {String/HTMLElement} el The id or html element from which to remove the listener.
  514.          * @param {String} eventName The name of the event.
  515.          * @param {Function} fn The handler function to remove. <b>This must be a reference to the function passed into the {@link #addListener} call.</b>
  516.          * @param {Object} scope If a scope (<b><code>this</code></b> reference) was specified when the listener was added,
  517.          * then this must refer to the same object.
  518.          */
  519.         removeListener : function(el, eventName, fn, scope){
  520.             el = Ext.getDom(el);
  521.             var id = getId(el),
  522.                 f = el && (Ext.elCache[id].events)[eventName] || [],
  523.                 wrap, i, l, k, wf;
  524.             for (i = 0, len = f.length; i < len; i++) {
  525.                 if (Ext.isArray(f[i]) && f[i][0] == fn && (!scope || f[i][2] == scope)) {
  526.                     if(fn.task) {
  527.                         fn.task.cancel();
  528.                         delete fn.task;
  529.                     }
  530.                     k = fn.tasks && fn.tasks.length;
  531.                     if(k) {
  532.                         while(k--) {
  533.                             fn.tasks[k].cancel();
  534.                         }
  535.                         delete fn.tasks;
  536.                     }
  537.                     wf = wrap = f[i][1];
  538.                     if (E.extAdapter) {
  539.                         wf = f[i][3];
  540.                     }
  541.                     E.un(el, eventName, wf);
  542.                     f.splice(i,1);
  543.                     if (f.length === 0) {
  544.                         delete Ext.elCache[id].events[eventName];
  545.                     }
  546.                     for (k in Ext.elCache[id].events) {
  547.                         return false;
  548.                     }
  549.                     Ext.elCache[id].events = {};
  550.                     return false;
  551.                 }
  552.             }
  553.             // jQuery workaround that should be removed from Ext Core
  554.             if(eventName == "mousewheel" && el.addEventListener && wrap){
  555.                 el.removeEventListener("DOMMouseScroll", wrap, false);
  556.             }
  557.             if(eventName == "mousedown" && el == DOC && wrap){ // fix stopped mousedowns on the document
  558.                 Ext.EventManager.stoppedMouseDownEvent.removeListener(wrap);
  559.             }
  560.         },
  561.         /**
  562.          * Removes all event handers from an element.  Typically you will use {@link Ext.Element#removeAllListeners}
  563.          * directly on an Element in favor of calling this version.
  564.          * @param {String/HTMLElement} el The id or html element from which to remove all event handlers.
  565.          */
  566.         removeAll : function(el){
  567.             el = Ext.getDom(el);
  568.             var id = getId(el),
  569.                 ec = Ext.elCache[id] || {},
  570.                 es = ec.events || {},
  571.                 f, i, len, ename, fn, k;
  572.             for(ename in es){
  573.                 if(es.hasOwnProperty(ename)){
  574.                     f = es[ename];
  575.                     for (i = 0, len = f.length; i < len; i++) {
  576.                         fn = f[i][0];
  577.                         if(fn.task) {
  578.                             fn.task.cancel();
  579.                             delete fn.task;
  580.                         }
  581.                         if(fn.tasks && (k = fn.tasks.length)) {
  582.                             while(k--) {
  583.                                 fn.tasks[k].cancel();
  584.                             }
  585.                             delete fn.tasks;
  586.                         }
  587.                         E.un(el, ename, E.extAdapter ? f[i][3] : f[i][1]);
  588.                     }
  589.                 }
  590.             }
  591.             if (Ext.elCache[id]) {
  592.                 Ext.elCache[id].events = {};
  593.             }
  594.         },
  595.         getListeners : function(el, eventName) {
  596.             el = Ext.getDom(el);
  597.             var id = getId(el),
  598.                 ec = Ext.elCache[id] || {},
  599.                 es = ec.events || {},
  600.                 results = [];
  601.             if (es && es[eventName]) {
  602.                 return es[eventName];
  603.             } else {
  604.                 return null;
  605.             }
  606.         },
  607.         purgeElement : function(el, recurse, eventName) {
  608.             el = Ext.getDom(el);
  609.             var id = getId(el),
  610.                 ec = Ext.elCache[id] || {},
  611.                 es = ec.events || {},
  612.                 i, f, len;
  613.             if (eventName) {
  614.                 if (es && es.hasOwnProperty(eventName)) {
  615.                     f = es[eventName];
  616.                     for (i = 0, len = f.length; i < len; i++) {
  617.                         Ext.EventManager.removeListener(el, eventName, f[i][0]);
  618.                     }
  619.                 }
  620.             } else {
  621.                 Ext.EventManager.removeAll(el);
  622.             }
  623.             if (recurse && el && el.childNodes) {
  624.                 for (i = 0, len = el.childNodes.length; i < len; i++) {
  625.                     Ext.EventManager.purgeElement(el.childNodes[i], recurse, eventName);
  626.                 }
  627.             }
  628.         },
  629.         _unload : function() {
  630.             var el;
  631.             for (el in Ext.elCache) {
  632.                 Ext.EventManager.removeAll(el);
  633.             }
  634.         },
  635.         /**
  636.          * Adds a listener to be notified when the document is ready (before onload and before images are loaded). Can be
  637.          * accessed shorthanded as Ext.onReady().
  638.          * @param {Function} fn The method the event invokes.
  639.          * @param {Object} scope (optional) The scope (<code>this</code> reference) in which the handler function executes. Defaults to the browser window.
  640.          * @param {boolean} options (optional) Options object as passed to {@link Ext.Element#addListener}. It is recommended that the options
  641.          * <code>{single: true}</code> be used so that the handler is removed on first invocation.
  642.          */
  643.         onDocumentReady : function(fn, scope, options){
  644.             if(docReadyState){ // if it already fired
  645.                 docReadyEvent.addListener(fn, scope, options);
  646.                 docReadyEvent.fire();
  647.                 docReadyEvent.listeners = []; // clearListeners no longer compatible.  Force single: true?
  648.             } else {
  649.                 if(!docReadyEvent) initDocReady();
  650.                 options = options || {};
  651.                 options.delay = options.delay || 1;
  652.                 docReadyEvent.addListener(fn, scope, options);
  653.             }
  654.         }
  655.     };
  656.      /**
  657.      * Appends an event handler to an element.  Shorthand for {@link #addListener}.
  658.      * @param {String/HTMLElement} el The html element or id to assign the event handler to
  659.      * @param {String} eventName The name of the event to listen for.
  660.      * @param {Function} handler The handler function the event invokes.
  661.      * @param {Object} scope (optional) (<code>this</code> reference) in which the handler function executes. <b>Defaults to the Element</b>.
  662.      * @param {Object} options (optional) An object containing standard {@link #addListener} options
  663.      * @member Ext.EventManager
  664.      * @method on
  665.      */
  666.     pub.on = pub.addListener;
  667.     /**
  668.      * Removes an event handler from an element.  Shorthand for {@link #removeListener}.
  669.      * @param {String/HTMLElement} el The id or html element from which to remove the listener.
  670.      * @param {String} eventName The name of the event.
  671.      * @param {Function} fn The handler function to remove. <b>This must be a reference to the function passed into the {@link #on} call.</b>
  672.      * @param {Object} scope If a scope (<b><code>this</code></b> reference) was specified when the listener was added,
  673.      * then this must refer to the same object.
  674.      * @member Ext.EventManager
  675.      * @method un
  676.      */
  677.     pub.un = pub.removeListener;
  678.     pub.stoppedMouseDownEvent = new Ext.util.Event();
  679.     return pub;
  680. }();
  681. /**
  682.   * Adds a listener to be notified when the document is ready (before onload and before images are loaded). Shorthand of {@link Ext.EventManager#onDocumentReady}.
  683.   * @param {Function} fn The method the event invokes.
  684.   * @param {Object} scope (optional) The scope (<code>this</code> reference) in which the handler function executes. Defaults to the browser window.
  685.   * @param {boolean} options (optional) Options object as passed to {@link Ext.Element#addListener}. It is recommended that the options
  686.   * <code>{single: true}</code> be used so that the handler is removed on first invocation.
  687.   * @member Ext
  688.   * @method onReady
  689.  */
  690. Ext.onReady = Ext.EventManager.onDocumentReady;
  691. //Initialize doc classes
  692. (function(){
  693.     var initExtCss = function(){
  694.         // find the body element
  695.         var bd = document.body || document.getElementsByTagName('body')[0];
  696.         if(!bd){ return false; }
  697.         var cls = [' ',
  698.                 Ext.isIE ? "ext-ie " + (Ext.isIE6 ? 'ext-ie6' : (Ext.isIE7 ? 'ext-ie7' : 'ext-ie8'))
  699.                 : Ext.isGecko ? "ext-gecko " + (Ext.isGecko2 ? 'ext-gecko2' : 'ext-gecko3')
  700.                 : Ext.isOpera ? "ext-opera"
  701.                 : Ext.isWebKit ? "ext-webkit" : ""];
  702.         if(Ext.isSafari){
  703.             cls.push("ext-safari " + (Ext.isSafari2 ? 'ext-safari2' : (Ext.isSafari3 ? 'ext-safari3' : 'ext-safari4')));
  704.         }else if(Ext.isChrome){
  705.             cls.push("ext-chrome");
  706.         }
  707.         if(Ext.isMac){
  708.             cls.push("ext-mac");
  709.         }
  710.         if(Ext.isLinux){
  711.             cls.push("ext-linux");
  712.         }
  713.         if(Ext.isStrict || Ext.isBorderBox){ // add to the parent to allow for selectors like ".ext-strict .ext-ie"
  714.             var p = bd.parentNode;
  715.             if(p){
  716.                 p.className += Ext.isStrict ? ' ext-strict' : ' ext-border-box';
  717.             }
  718.         }
  719.         bd.className += cls.join(' ');
  720.         return true;
  721.     }
  722.     if(!initExtCss()){
  723.         Ext.onReady(initExtCss);
  724.     }
  725. })();
  726. /**
  727.  * @class Ext.EventObject
  728.  * Just as {@link Ext.Element} wraps around a native DOM node, Ext.EventObject
  729.  * wraps the browser's native event-object normalizing cross-browser differences,
  730.  * such as which mouse button is clicked, keys pressed, mechanisms to stop
  731.  * event-propagation along with a method to prevent default actions from taking place.
  732.  * <p>For example:</p>
  733.  * <pre><code>
  734. function handleClick(e, t){ // e is not a standard event object, it is a Ext.EventObject
  735.     e.preventDefault();
  736.     var target = e.getTarget(); // same as t (the target HTMLElement)
  737.     ...
  738. }
  739. var myDiv = {@link Ext#get Ext.get}("myDiv");  // get reference to an {@link Ext.Element}
  740. myDiv.on(         // 'on' is shorthand for addListener
  741.     "click",      // perform an action on click of myDiv
  742.     handleClick   // reference to the action handler
  743. );
  744. // other methods to do the same:
  745. Ext.EventManager.on("myDiv", 'click', handleClick);
  746. Ext.EventManager.addListener("myDiv", 'click', handleClick);
  747.  </code></pre>
  748.  * @singleton
  749.  */
  750. Ext.EventObject = function(){
  751.     var E = Ext.lib.Event,
  752.         // safari keypress events for special keys return bad keycodes
  753.         safariKeys = {
  754.             3 : 13, // enter
  755.             63234 : 37, // left
  756.             63235 : 39, // right
  757.             63232 : 38, // up
  758.             63233 : 40, // down
  759.             63276 : 33, // page up
  760.             63277 : 34, // page down
  761.             63272 : 46, // delete
  762.             63273 : 36, // home
  763.             63275 : 35  // end
  764.         },
  765.         // normalize button clicks
  766.         btnMap = Ext.isIE ? {1:0,4:1,2:2} :
  767.                 (Ext.isWebKit ? {1:0,2:1,3:2} : {0:0,1:1,2:2});
  768.     Ext.EventObjectImpl = function(e){
  769.         if(e){
  770.             this.setEvent(e.browserEvent || e);
  771.         }
  772.     };
  773.     Ext.EventObjectImpl.prototype = {
  774.            /** @private */
  775.         setEvent : function(e){
  776.             var me = this;
  777.             if(e == me || (e && e.browserEvent)){ // already wrapped
  778.                 return e;
  779.             }
  780.             me.browserEvent = e;
  781.             if(e){
  782.                 // normalize buttons
  783.                 me.button = e.button ? btnMap[e.button] : (e.which ? e.which - 1 : -1);
  784.                 if(e.type == 'click' && me.button == -1){
  785.                     me.button = 0;
  786.                 }
  787.                 me.type = e.type;
  788.                 me.shiftKey = e.shiftKey;
  789.                 // mac metaKey behaves like ctrlKey
  790.                 me.ctrlKey = e.ctrlKey || e.metaKey || false;
  791.                 me.altKey = e.altKey;
  792.                 // in getKey these will be normalized for the mac
  793.                 me.keyCode = e.keyCode;
  794.                 me.charCode = e.charCode;
  795.                 // cache the target for the delayed and or buffered events
  796.                 me.target = E.getTarget(e);
  797.                 // same for XY
  798.                 me.xy = E.getXY(e);
  799.             }else{
  800.                 me.button = -1;
  801.                 me.shiftKey = false;
  802.                 me.ctrlKey = false;
  803.                 me.altKey = false;
  804.                 me.keyCode = 0;
  805.                 me.charCode = 0;
  806.                 me.target = null;
  807.                 me.xy = [0, 0];
  808.             }
  809.             return me;
  810.         },
  811.         /**
  812.          * Stop the event (preventDefault and stopPropagation)
  813.          */
  814.         stopEvent : function(){
  815.             var me = this;
  816.             if(me.browserEvent){
  817.                 if(me.browserEvent.type == 'mousedown'){
  818.                     Ext.EventManager.stoppedMouseDownEvent.fire(me);
  819.                 }
  820.                 E.stopEvent(me.browserEvent);
  821.             }
  822.         },
  823.         /**
  824.          * Prevents the browsers default handling of the event.
  825.          */
  826.         preventDefault : function(){
  827.             if(this.browserEvent){
  828.                 E.preventDefault(this.browserEvent);
  829.             }
  830.         },
  831.         /**
  832.          * Cancels bubbling of the event.
  833.          */
  834.         stopPropagation : function(){
  835.             var me = this;
  836.             if(me.browserEvent){
  837.                 if(me.browserEvent.type == 'mousedown'){
  838.                     Ext.EventManager.stoppedMouseDownEvent.fire(me);
  839.                 }
  840.                 E.stopPropagation(me.browserEvent);
  841.             }
  842.         },
  843.         /**
  844.          * Gets the character code for the event.
  845.          * @return {Number}
  846.          */
  847.         getCharCode : function(){
  848.             return this.charCode || this.keyCode;
  849.         },
  850.         /**
  851.          * Returns a normalized keyCode for the event.
  852.          * @return {Number} The key code
  853.          */
  854.         getKey : function(){
  855.             return this.normalizeKey(this.keyCode || this.charCode)
  856.         },
  857.         // private
  858.         normalizeKey: function(k){
  859.             return Ext.isSafari ? (safariKeys[k] || k) : k;
  860.         },
  861.         /**
  862.          * Gets the x coordinate of the event.
  863.          * @return {Number}
  864.          */
  865.         getPageX : function(){
  866.             return this.xy[0];
  867.         },
  868.         /**
  869.          * Gets the y coordinate of the event.
  870.          * @return {Number}
  871.          */
  872.         getPageY : function(){
  873.             return this.xy[1];
  874.         },
  875.         /**
  876.          * Gets the page coordinates of the event.
  877.          * @return {Array} The xy values like [x, y]
  878.          */
  879.         getXY : function(){
  880.             return this.xy;
  881.         },
  882.         /**
  883.          * Gets the target for the event.
  884.          * @param {String} selector (optional) A simple selector to filter the target or look for an ancestor of the target
  885.          * @param {Number/Mixed} maxDepth (optional) The max depth to
  886.                 search as a number or element (defaults to 10 || document.body)
  887.          * @param {Boolean} returnEl (optional) True to return a Ext.Element object instead of DOM node
  888.          * @return {HTMLelement}
  889.          */
  890.         getTarget : function(selector, maxDepth, returnEl){
  891.             return selector ? Ext.fly(this.target).findParent(selector, maxDepth, returnEl) : (returnEl ? Ext.get(this.target) : this.target);
  892.         },
  893.         /**
  894.          * Gets the related target.
  895.          * @return {HTMLElement}
  896.          */
  897.         getRelatedTarget : function(){
  898.             return this.browserEvent ? E.getRelatedTarget(this.browserEvent) : null;
  899.         },
  900.         /**
  901.          * Normalizes mouse wheel delta across browsers
  902.          * @return {Number} The delta
  903.          */
  904.         getWheelDelta : function(){
  905.             var e = this.browserEvent;
  906.             var delta = 0;
  907.             if(e.wheelDelta){ /* IE/Opera. */
  908.                 delta = e.wheelDelta/120;
  909.             }else if(e.detail){ /* Mozilla case. */
  910.                 delta = -e.detail/3;
  911.             }
  912.             return delta;
  913.         },
  914.         /**
  915.         * 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.
  916.         * Example usage:<pre><code>
  917.         // Handle click on any child of an element
  918.         Ext.getBody().on('click', function(e){
  919.             if(e.within('some-el')){
  920.                 alert('Clicked on a child of some-el!');
  921.             }
  922.         });
  923.         // Handle click directly on an element, ignoring clicks on child nodes
  924.         Ext.getBody().on('click', function(e,t){
  925.             if((t.id == 'some-el') && !e.within(t, true)){
  926.                 alert('Clicked directly on some-el!');
  927.             }
  928.         });
  929.         </code></pre>
  930.          * @param {Mixed} el The id, DOM element or Ext.Element to check
  931.          * @param {Boolean} related (optional) true to test if the related target is within el instead of the target
  932.          * @param {Boolean} allowEl {optional} true to also check if the passed element is the target or related target
  933.          * @return {Boolean}
  934.          */
  935.         within : function(el, related, allowEl){
  936.             if(el){
  937.                 var t = this[related ? "getRelatedTarget" : "getTarget"]();
  938.                 return t && ((allowEl ? (t == Ext.getDom(el)) : false) || Ext.fly(el).contains(t));
  939.             }
  940.             return false;
  941.         }
  942.      };
  943.     return new Ext.EventObjectImpl();
  944. }();
  945. /** * @class Ext.EventManager */ Ext.apply(Ext.EventManager, function(){    var resizeEvent,        resizeTask,        textEvent,        textSize,        D = Ext.lib.Dom,        propRe = /^(?:scope|delay|buffer|single|stopEvent|preventDefault|stopPropagation|normalized|args|delegate)$/,        curWidth = 0,        curHeight = 0,        // 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)        useKeydown = Ext.isWebKit ?                    Ext.num(navigator.userAgent.match(/AppleWebKit/(d+)/)[1]) >= 525 :                    !((Ext.isGecko && !Ext.isWindows) || Ext.isOpera);    return {        // private        doResizeEvent: function(){            var h = D.getViewHeight(),                w = D.getViewWidth();            //whacky problem in IE where the resize event will fire even though the w/h are the same.            if(curHeight != h || curWidth != w){                resizeEvent.fire(curWidth = w, curHeight = h);            }        },        /**         * Adds a listener to be notified when the browser window is resized and provides resize event buffering (50 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){            if(!resizeEvent){                resizeEvent = new Ext.util.Event();                resizeTask = new Ext.util.DelayedTask(this.doResizeEvent);                Ext.EventManager.on(window, "resize", this.fireWindowResize, this);            }            resizeEvent.addListener(fn, scope, options);        },        // exposed only to allow manual firing        fireWindowResize : function(){            if(resizeEvent){                if((Ext.isIE||Ext.isAir) && resizeTask){                    resizeTask.delay(50);                }else{                    resizeEvent.fire(D.getViewWidth(), D.getViewHeight());                }            }        },        /**         * Adds a listener to be notified when the user changes the active text size. Handler gets called with 2 params, the old size and the new size.         * @param {Function} fn      The function the 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}         */        onTextResize : function(fn, scope, options){            if(!textEvent){                textEvent = new Ext.util.Event();                var textEl = new Ext.Element(document.createElement('div'));                textEl.dom.className = 'x-text-resize';                textEl.dom.innerHTML = 'X';                textEl.appendTo(document.body);                textSize = textEl.dom.offsetHeight;                setInterval(function(){                    if(textEl.dom.offsetHeight != textSize){                        textEvent.fire(textSize, textSize = textEl.dom.offsetHeight);                    }                }, this.textResizeInterval);            }            textEvent.addListener(fn, scope, options);        },        /**         * 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(resizeEvent){                resizeEvent.removeListener(fn, scope);            }        },        // private        fireResize : function(){            if(resizeEvent){                resizeEvent.fire(D.getViewWidth(), D.getViewHeight());            }        },         /**         * The frequency, in milliseconds, to check for text resize events (defaults to 50)         */        textResizeInterval : 50,        /**         * Url used for onDocumentReady with using SSL (defaults to Ext.SSL_SECURE_URL)         */        ieDeferSrc : false,        // protected for use inside the framework        // detects whether we should use keydown or keypress based on the browser.        useKeydown: useKeydown    }; }()); Ext.EventManager.on = Ext.EventManager.addListener; Ext.apply(Ext.EventObjectImpl.prototype, {    /** Key constant @type Number */    BACKSPACE: 8,    /** Key constant @type Number */    TAB: 9,    /** Key constant @type Number */    NUM_CENTER: 12,    /** Key constant @type Number */    ENTER: 13,    /** Key constant @type Number */    RETURN: 13,    /** Key constant @type Number */    SHIFT: 16,    /** Key constant @type Number */    CTRL: 17,    CONTROL : 17, // legacy    /** Key constant @type Number */    ALT: 18,    /** Key constant @type Number */    PAUSE: 19,    /** Key constant @type Number */    CAPS_LOCK: 20,    /** Key constant @type Number */    ESC: 27,    /** Key constant @type Number */    SPACE: 32,    /** Key constant @type Number */    PAGE_UP: 33,    PAGEUP : 33, // legacy    /** Key constant @type Number */    PAGE_DOWN: 34,    PAGEDOWN : 34, // legacy    /** Key constant @type Number */    END: 35,    /** Key constant @type Number */    HOME: 36,    /** Key constant @type Number */    LEFT: 37,    /** Key constant @type Number */    UP: 38,    /** Key constant @type Number */    RIGHT: 39,    /** Key constant @type Number */    DOWN: 40,    /** Key constant @type Number */    PRINT_SCREEN: 44,    /** Key constant @type Number */    INSERT: 45,    /** Key constant @type Number */    DELETE: 46,    /** Key constant @type Number */    ZERO: 48,    /** Key constant @type Number */    ONE: 49,    /** Key constant @type Number */    TWO: 50,    /** Key constant @type Number */    THREE: 51,    /** Key constant @type Number */    FOUR: 52,    /** Key constant @type Number */    FIVE: 53,    /** Key constant @type Number */    SIX: 54,    /** Key constant @type Number */    SEVEN: 55,    /** Key constant @type Number */    EIGHT: 56,    /** Key constant @type Number */    NINE: 57,    /** Key constant @type Number */    A: 65,    /** Key constant @type Number */    B: 66,    /** Key constant @type Number */    C: 67,    /** Key constant @type Number */    D: 68,    /** Key constant @type Number */    E: 69,    /** Key constant @type Number */    F: 70,    /** Key constant @type Number */    G: 71,    /** Key constant @type Number */    H: 72,    /** Key constant @type Number */    I: 73,    /** Key constant @type Number */    J: 74,    /** Key constant @type Number */    K: 75,    /** Key constant @type Number */    L: 76,    /** Key constant @type Number */    M: 77,    /** Key constant @type Number */    N: 78,    /** Key constant @type Number */    O: 79,    /** Key constant @type Number */    P: 80,    /** Key constant @type Number */    Q: 81,    /** Key constant @type Number */    R: 82,    /** Key constant @type Number */    S: 83,    /** Key constant @type Number */    T: 84,    /** Key constant @type Number */    U: 85,    /** Key constant @type Number */    V: 86,    /** Key constant @type Number */    W: 87,    /** Key constant @type Number */    X: 88,    /** Key constant @type Number */    Y: 89,    /** Key constant @type Number */    Z: 90,    /** Key constant @type Number */    CONTEXT_MENU: 93,    /** Key constant @type Number */    NUM_ZERO: 96,    /** Key constant @type Number */    NUM_ONE: 97,    /** Key constant @type Number */    NUM_TWO: 98,    /** Key constant @type Number */    NUM_THREE: 99,    /** Key constant @type Number */    NUM_FOUR: 100,    /** Key constant @type Number */    NUM_FIVE: 101,    /** Key constant @type Number */    NUM_SIX: 102,    /** Key constant @type Number */    NUM_SEVEN: 103,    /** Key constant @type Number */    NUM_EIGHT: 104,    /** Key constant @type Number */    NUM_NINE: 105,    /** Key constant @type Number */    NUM_MULTIPLY: 106,    /** Key constant @type Number */    NUM_PLUS: 107,    /** Key constant @type Number */    NUM_MINUS: 109,    /** Key constant @type Number */    NUM_PERIOD: 110,    /** Key constant @type Number */    NUM_DIVISION: 111,    /** Key constant @type Number */    F1: 112,    /** Key constant @type Number */    F2: 113,    /** Key constant @type Number */    F3: 114,    /** Key constant @type Number */    F4: 115,    /** Key constant @type Number */    F5: 116,    /** Key constant @type Number */    F6: 117,    /** Key constant @type Number */    F7: 118,    /** Key constant @type Number */    F8: 119,    /** Key constant @type Number */    F9: 120,    /** Key constant @type Number */    F10: 121,    /** Key constant @type Number */    F11: 122,    /** Key constant @type Number */    F12: 123,    /** @private */    isNavKeyPress : function(){        var me = this,            k = this.normalizeKey(me.keyCode);        return (k >= 33 && k <= 40) ||  // Page Up/Down, End, Home, Left, Up, Right, Down        k == me.RETURN ||        k == me.TAB ||        k == me.ESC;    },    isSpecialKey : function(){        var k = this.normalizeKey(this.keyCode);        return (this.type == 'keypress' && this.ctrlKey) ||        this.isNavKeyPress() ||        (k == this.BACKSPACE) || // Backspace        (k >= 16 && k <= 20) || // Shift, Ctrl, Alt, Pause, Caps Lock        (k >= 44 && k <= 45);   // Print Screen, Insert    },    getPoint : function(){        return new Ext.lib.Point(this.xy[0], this.xy[1]);    },    /**     * Returns true if the control, meta, shift or alt key was pressed during this event.     * @return {Boolean}     */    hasModifier : function(){        return ((this.ctrlKey || this.altKey) || this.shiftKey);    } });/**  * @class Ext.Element  * <p>Encapsulates a DOM element, adding simple DOM manipulation facilities, normalizing for browser differences.</p>  * <p>All instances of this class inherit the methods of {@link Ext.Fx} making visual effects easily available to all DOM elements.</p>  * <p>Note that the events documented in this class are not Ext events, they encapsulate browser events. To  * access the underlying browser event, see {@link Ext.EventObject#browserEvent}. Some older  * browsers may not support the full range of events. Which events are supported is beyond the control of ExtJs.</p>  * Usage:<br> <pre><code> // by id var el = Ext.get("my-div"); // by DOM element reference var el = Ext.get(myDivElement); </code></pre>  * <b>Animations</b><br />  * <p>When an element is manipulated, by default there is no animation.</p>  * <pre><code> var el = Ext.get("my-div"); // no animation el.setWidth(100);  * </code></pre>  * <p>Many of the functions for manipulating an element have an optional "animate" parameter.  This  * parameter can be specified as boolean (<tt>true</tt>) for default animation effects.</p>  * <pre><code> // default animation el.setWidth(100, true);  * </code></pre>  *  * <p>To configure the effects, an object literal with animation options to use as the Element animation  * configuration object can also be specified. Note that the supported Element animation configuration  * options are a subset of the {@link Ext.Fx} animation options specific to Fx effects.  The supported  * Element animation configuration options are:</p> <pre> Option    Default   Description --------- --------  --------------------------------------------- {@link Ext.Fx#duration duration}  .35       The duration of the animation in seconds {@link Ext.Fx#easing easing}    easeOut   The easing method {@link Ext.Fx#callback callback}  none      A function to execute when the anim completes {@link Ext.Fx#scope scope}     this      The scope (this) of the callback function </pre>  *  * <pre><code> // Element animation options object var opt = {     {@link Ext.Fx#duration duration}: 1,     {@link Ext.Fx#easing easing}: 'elasticIn',     {@link Ext.Fx#callback callback}: this.foo,     {@link Ext.Fx#scope scope}: this }; // animation with some options set el.setWidth(100, opt);  * </code></pre>  * <p>The Element animation object being used for the animation will be set on the options  * object as "anim", which allows you to stop or manipulate the animation. Here is an example:</p>  * <pre><code> // using the "anim" property to get the Anim object if(opt.anim.isAnimated()){     opt.anim.stop(); }  * </code></pre>  * <p>Also see the <tt>{@link #animate}</tt> method for another animation technique.</p>  * <p><b> Composite (Collections of) Elements</b></p>  * <p>For working with collections of Elements, see {@link Ext.CompositeElement}</p>  * @constructor Create a new Element directly.  * @param {String/HTMLElement} element  * @param {Boolean} forceNew (optional) By default the constructor checks to see if there is already an instance of this element in the cache and if there is it returns the same instance. This will skip that check (useful for extending this class).  */ (function(){ var DOC = document; Ext.Element = function(element, forceNew){     var dom = typeof element == "string" ?               DOC.getElementById(element) : element,         id;     if(!dom) return null;     id = dom.id;     if(!forceNew && id && Ext.elCache[id]){ // element object already exists         return Ext.elCache[id].el;     }     /**      * The DOM element      * @type HTMLElement      */     this.dom = dom;     /**      * The DOM element ID      * @type String      */     this.id = id || Ext.id(dom); }; var D = Ext.lib.Dom,     DH = Ext.DomHelper,     E = Ext.lib.Event,     A = Ext.lib.Anim,     El = Ext.Element,     EC = Ext.elCache; El.prototype = {     /**      * Sets the passed attributes as attributes of this element (a style attribute can be a string, object or function)      * @param {Object} o The object with the attributes      * @param {Boolean} useSet (optional) false to override the default setAttribute to use expandos.      * @return {Ext.Element} this      */     set : function(o, useSet){         var el = this.dom,             attr,             val,             useSet = (useSet !== false) && !!el.setAttribute;         for(attr in o){             if (o.hasOwnProperty(attr)) {                 val = o[attr];                 if (attr == 'style') {                     DH.applyStyles(el, val);                 } else if (attr == 'cls') {                     el.className = val;                 } else if (useSet) {                     el.setAttribute(attr, val);                 } else {                     el[attr] = val;                 }             }         }         return this;     }, //  Mouse events     /**      * @event click      * Fires when a mouse click is detected within the element.      * @param {Ext.EventObject} e The {@link Ext.EventObject} encapsulating the DOM event.      * @param {HtmlElement} t The target of the event.      * @param {Object} o The options configuration passed to the {@link #addListener} call.      */     /**      * @event contextmenu      * Fires when a right click is detected within the element.      * @param {Ext.EventObject} e The {@link Ext.EventObject} encapsulating the DOM event.      * @param {HtmlElement} t The target of the event.      * @param {Object} o The options configuration passed to the {@link #addListener} call.      */     /**      * @event dblclick      * Fires when a mouse double click is detected within the element.      * @param {Ext.EventObject} e The {@link Ext.EventObject} encapsulating the DOM event.      * @param {HtmlElement} t The target of the event.      * @param {Object} o The options configuration passed to the {@link #addListener} call.      */     /**      * @event mousedown      * Fires when a mousedown is detected within the element.      * @param {Ext.EventObject} e The {@link Ext.EventObject} encapsulating the DOM event.      * @param {HtmlElement} t The target of the event.      * @param {Object} o The options configuration passed to the {@link #addListener} call.      */     /**      * @event mouseup      * Fires when a mouseup is detected within the element.      * @param {Ext.EventObject} e The {@link Ext.EventObject} encapsulating the DOM event.      * @param {HtmlElement} t The target of the event.      * @param {Object} o The options configuration passed to the {@link #addListener} call.      */     /**      * @event mouseover      * Fires when a mouseover is detected within the element.      * @param {Ext.EventObject} e The {@link Ext.EventObject} encapsulating the DOM event.      * @param {HtmlElement} t The target of the event.      * @param {Object} o The options configuration passed to the {@link #addListener} call.      */     /**      * @event mousemove      * Fires when a mousemove is detected with the element.      * @param {Ext.EventObject} e The {@link Ext.EventObject} encapsulating the DOM event.      * @param {HtmlElement} t The target of the event.      * @param {Object} o The options configuration passed to the {@link #addListener} call.      */     /**      * @event mouseout      * Fires when a mouseout is detected with the element.      * @param {Ext.EventObject} e The {@link Ext.EventObject} encapsulating the DOM event.      * @param {HtmlElement} t The target of the event.      * @param {Object} o The options configuration passed to the {@link #addListener} call.      */     /**      * @event mouseenter      * Fires when the mouse enters the element.      * @param {Ext.EventObject} e The {@link Ext.EventObject} encapsulating the DOM event.      * @param {HtmlElement} t The target of the event.      * @param {Object} o The options configuration passed to the {@link #addListener} call.      */     /**      * @event mouseleave      * Fires when the mouse leaves the element.      * @param {Ext.EventObject} e The {@link Ext.EventObject} encapsulating the DOM event.      * @param {HtmlElement} t The target of the event.      * @param {Object} o The options configuration passed to the {@link #addListener} call.      */ //  Keyboard events     /**      * @event keypress      * Fires when a keypress is detected within the element.      * @param {Ext.EventObject} e The {@link Ext.EventObject} encapsulating the DOM event.      * @param {HtmlElement} t The target of the event.      * @param {Object} o The options configuration passed to the {@link #addListener} call.      */     /**      * @event keydown      * Fires when a keydown is detected within the element.      * @param {Ext.EventObject} e The {@link Ext.EventObject} encapsulating the DOM event.      * @param {HtmlElement} t The target of the event.      * @param {Object} o The options configuration passed to the {@link #addListener} call.      */     /**      * @event keyup      * Fires when a keyup is detected within the element.      * @param {Ext.EventObject} e The {@link Ext.EventObject} encapsulating the DOM event.      * @param {HtmlElement} t The target of the event.      * @param {Object} o The options configuration passed to the {@link #addListener} call.      */ //  HTML frame/object events     /**      * @event load      * Fires when the user agent finishes loading all content within the element. Only supported by window, frames, objects and images.      * @param {Ext.EventObject} e The {@link Ext.EventObject} encapsulating the DOM event.      * @param {HtmlElement} t The target of the event.      * @param {Object} o The options configuration passed to the {@link #addListener} call.      */     /**      * @event unload      * Fires when the user agent removes all content from a window or frame. For elements, it fires when the target element or any of its content has been removed.      * @param {Ext.EventObject} e The {@link Ext.EventObject} encapsulating the DOM event.      * @param {HtmlElement} t The target of the event.      * @param {Object} o The options configuration passed to the {@link #addListener} call.      */     /**      * @event abort      * Fires when an object/image is stopped from loading before completely loaded.      * @param {Ext.EventObject} e The {@link Ext.EventObject} encapsulating the DOM event.      * @param {HtmlElement} t The target of the event.      * @param {Object} o The options configuration passed to the {@link #addListener} call.      */     /**      * @event error      * Fires when an object/image/frame cannot be loaded properly.      * @param {Ext.EventObject} e The {@link Ext.EventObject} encapsulating the DOM event.      * @param {HtmlElement} t The target of the event.      * @param {Object} o The options configuration passed to the {@link #addListener} call.      */     /**      * @event resize      * Fires when a document view is resized.      * @param {Ext.EventObject} e The {@link Ext.EventObject} encapsulating the DOM event.      * @param {HtmlElement} t The target of the event.      * @param {Object} o The options configuration passed to the {@link #addListener} call.      */     /**      * @event scroll      * Fires when a document view is scrolled.      * @param {Ext.EventObject} e The {@link Ext.EventObject} encapsulating the DOM event.      * @param {HtmlElement} t The target of the event.      * @param {Object} o The options configuration passed to the {@link #addListener} call.      */ //  Form events     /**      * @event select      * Fires when a user selects some text in a text field, including input and textarea.      * @param {Ext.EventObject} e The {@link Ext.EventObject} encapsulating the DOM event.      * @param {HtmlElement} t The target of the event.      * @param {Object} o The options configuration passed to the {@link #addListener} call.      */     /**      * @event change      * Fires when a control loses the input focus and its value has been modified since gaining focus.      * @param {Ext.EventObject} e The {@link Ext.EventObject} encapsulating the DOM event.      * @param {HtmlElement} t The target of the event.      * @param {Object} o The options configuration passed to the {@link #addListener} call.      */     /**      * @event submit      * Fires when a form is submitted.      * @param {Ext.EventObject} e The {@link Ext.EventObject} encapsulating the DOM event.      * @param {HtmlElement} t The target of the event.      * @param {Object} o The options configuration passed to the {@link #addListener} call.      */     /**      * @event reset      * Fires when a form is reset.      * @param {Ext.EventObject} e The {@link Ext.EventObject} encapsulating the DOM event.      * @param {HtmlElement} t The target of the event.      * @param {Object} o The options configuration passed to the {@link #addListener} call.      */     /**      * @event focus      * Fires when an element receives focus either via the pointing device or by tab navigation.      * @param {Ext.EventObject} e The {@link Ext.EventObject} encapsulating the DOM event.      * @param {HtmlElement} t The target of the event.      * @param {Object} o The options configuration passed to the {@link #addListener} call.      */     /**      * @event blur      * Fires when an element loses focus either via the pointing device or by tabbing navigation.      * @param {Ext.EventObject} e The {@link Ext.EventObject} encapsulating the DOM event.      * @param {HtmlElement} t The target of the event.      * @param {Object} o The options configuration passed to the {@link #addListener} call.      */ //  User Interface events     /**      * @event DOMFocusIn      * Where supported. Similar to HTML focus event, but can be applied to any focusable element.      * @param {Ext.EventObject} e The {@link Ext.EventObject} encapsulating the DOM event.      * @param {HtmlElement} t The target of the event.      * @param {Object} o The options configuration passed to the {@link #addListener} call.      */     /**      * @event DOMFocusOut      * Where supported. Similar to HTML blur event, but can be applied to any focusable element.      * @param {Ext.EventObject} e The {@link Ext.EventObject} encapsulating the DOM event.      * @param {HtmlElement} t The target of the event.      * @param {Object} o The options configuration passed to the {@link #addListener} call.      */     /**      * @event DOMActivate      * Where supported. Fires when an element is activated, for instance, through a mouse click or a keypress.      * @param {Ext.EventObject} e The {@link Ext.EventObject} encapsulating the DOM event.      * @param {HtmlElement} t The target of the event.      * @param {Object} o The options configuration passed to the {@link #addListener} call.      */ //  DOM Mutation events     /**      * @event DOMSubtreeModified      * Where supported. Fires when the subtree is modified.      * @param {Ext.EventObject} e The {@link Ext.EventObject} encapsulating the DOM event.      * @param {HtmlElement} t The target of the event.      * @param {Object} o The options configuration passed to the {@link #addListener} call.      */     /**      * @event DOMNodeInserted      * Where supported. Fires when a node has been added as a child of another node.      * @param {Ext.EventObject} e The {@link Ext.EventObject} encapsulating the DOM event.      * @param {HtmlElement} t The target of the event.      * @param {Object} o The options configuration passed to the {@link #addListener} call.      */     /**      * @event DOMNodeRemoved      * Where supported. Fires when a descendant node of the element is removed.      * @param {Ext.EventObject} e The {@link Ext.EventObject} encapsulating the DOM event.      * @param {HtmlElement} t The target of the event.      * @param {Object} o The options configuration passed to the {@link #addListener} call.      */     /**      * @event DOMNodeRemovedFromDocument      * Where supported. Fires when a node is being removed from a document.      * @param {Ext.EventObject} e The {@link Ext.EventObject} encapsulating the DOM event.      * @param {HtmlElement} t The target of the event.      * @param {Object} o The options configuration passed to the {@link #addListener} call.      */     /**      * @event DOMNodeInsertedIntoDocument      * Where supported. Fires when a node is being inserted into a document.      * @param {Ext.EventObject} e The {@link Ext.EventObject} encapsulating the DOM event.      * @param {HtmlElement} t The target of the event.      * @param {Object} o The options configuration passed to the {@link #addListener} call.      */     /**      * @event DOMAttrModified      * Where supported. Fires when an attribute has been modified.      * @param {Ext.EventObject} e The {@link Ext.EventObject} encapsulating the DOM event.      * @param {HtmlElement} t The target of the event.      * @param {Object} o The options configuration passed to the {@link #addListener} call.      */     /**      * @event DOMCharacterDataModified      * Where supported. Fires when the character data has been modified.      * @param {Ext.EventObject} e The {@link Ext.EventObject} encapsulating the DOM event.      * @param {HtmlElement} t The target of the event.      * @param {Object} o The options configuration passed to the {@link #addListener} call.      */     /**      * The default unit to append to CSS values where a unit isn't provided (defaults to px).      * @type String      */     defaultUnit : "px",     /**      * Returns true if this element matches the passed simple selector (e.g. div.some-class or span:first-child)      * @param {String} selector The simple selector to test      * @return {Boolean} True if this element matches the selector, else false      */     is : function(simpleSelector){         return Ext.DomQuery.is(this.dom, simpleSelector);     },     /**      * Tries to focus the element. Any exceptions are caught and ignored.      * @param {Number} defer (optional) Milliseconds to defer the focus      * @return {Ext.Element} this      */     focus : function(defer, /* private */ dom) {         var me = this,             dom = dom || me.dom;         try{             if(Number(defer)){                 me.focus.defer(defer, null, [null, dom]);             }else{                 dom.focus();             }         }catch(e){}         return me;     },     /**      * Tries to blur the element. Any exceptions are caught and ignored.      * @return {Ext.Element} this      */     blur : function() {         try{             this.dom.blur();         }catch(e){}         return this;     },     /**      * Returns the value of the "value" attribute      * @param {Boolean} asNumber true to parse the value as a number      * @return {String/Number}      */     getValue : function(asNumber){         var val = this.dom.value;         return asNumber ? parseInt(val, 10) : val;     },     /**      * Appends an event handler to this element.  The shorthand version {@link #on} is equivalent.      * @param {String} eventName The name of event to handle.      * @param {Function} fn The handler function the event invokes. This function is passed      * the following parameters:<ul>      * <li><b>evt</b> : EventObject<div class="sub-desc">The {@link Ext.EventObject EventObject} describing the event.</div></li>      * <li><b>el</b> : HtmlElement<div class="sub-desc">The DOM element which was the target of the event.      * Note that this may be filtered by using the <tt>delegate</tt> option.</div></li>      * <li><b>o</b> : Object<div class="sub-desc">The options object from the addListener call.</div></li>      * </ul>      * @param {Object} scope (optional) The scope (<code><b>this</b></code> reference) in which the handler function is executed.      * <b>If omitted, defaults to this Element.</b>.      * @param {Object} options (optional) An object containing handler configuration properties.      * This may contain any of the following properties:<ul>      * <li><b>scope</b> Object : <div class="sub-desc">The scope (<code><b>this</b></code> reference) in which the handler function is executed.      * <b>If omitted, defaults to this Element.</b></div></li>      * <li><b>delegate</b> String: <div class="sub-desc">A simple selector to filter the target or look for a descendant of the target. See below for additional details.</div></li>      * <li><b>stopEvent</b> Boolean: <div class="sub-desc">True to stop the event. That is stop propagation, and prevent the default action.</div></li>      * <li><b>preventDefault</b> Boolean: <div class="sub-desc">True to prevent the default action</div></li>      * <li><b>stopPropagation</b> Boolean: <div class="sub-desc">True to prevent event propagation</div></li>      * <li><b>normalized</b> Boolean: <div class="sub-desc">False to pass a browser event to the handler function instead of an Ext.EventObject</div></li>      * <li><b>target</b> Ext.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>      * <li><b>delay</b> Number: <div class="sub-desc">The number of milliseconds to delay the invocation of the handler after the event fires.</div></li>      * <li><b>single</b> 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><b>buffer</b> 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>      * </ul><br>      * <p>      * <b>Combining Options</b><br>      * In the following examples, the shorthand form {@link #on} is used rather than the more verbose      * addListener.  The two are equivalent.  Using the options argument, it is possible to combine different      * types of listeners:<br>      * <br>      * A delayed, one-time listener that auto stops the event and adds a custom argument (forumId) to the      * options object. The options object is available as the third parameter in the handler function.<div style="margin: 5px 20px 20px;">      * Code:<pre><code> el.on('click', this.onClick, this, {     single: true,     delay: 100,     stopEvent : true,     forumId: 4 });</code></pre></p>      * <p>      * <b>Attaching multiple handlers in 1 call</b><br>      * The method also allows for a single argument to be passed which is a config object containing properties      * which specify multiple handlers.</p>      * <p>      * Code:<pre><code> el.on({     'click' : {         fn: this.onClick,         scope: this,         delay: 100     },     'mouseover' : {         fn: this.onMouseOver,         scope: this     },     'mouseout' : {         fn: this.onMouseOut,         scope: this     } });</code></pre>      * <p>      * Or a shorthand syntax:<br>      * Code:<pre><code></p> el.on({     'click' : this.onClick,     'mouseover' : this.onMouseOver,     'mouseout' : this.onMouseOut,     scope: this });      * </code></pre></p>      * <p><b>delegate</b></p>      * <p>This is a configuration option that you can pass along when registering a handler for      * an event to assist with event delegation. Event delegation is a technique that is used to      * reduce memory consumption and prevent exposure to memory-leaks. By registering an event      * for a container element as opposed to each element within a container. By setting this      * configuration option to a simple selector, the target element will be filtered to look for      * a descendant of the target.      * For example:<pre><code> // using this markup: &lt;div id='elId'>     &lt;p id='p1'>paragraph one&lt;/p>     &lt;p id='p2' class='clickable'>paragraph two&lt;/p>     &lt;p id='p3'>paragraph three&lt;/p> &lt;/div> // utilize event delegation to registering just one handler on the container element: el = Ext.get('elId'); el.on(     'click',     function(e,t) {         // handle click         console.info(t.id); // 'p2'     },     this,     {         // filter the target element to be a descendant with the class 'clickable'         delegate: '.clickable'     } );      * </code></pre></p>      * @return {Ext.Element} this      */     addListener : function(eventName, fn, scope, options){         Ext.EventManager.on(this.dom,  eventName, fn, scope || this, options);         return this;     },     /**      * Removes an event handler from this element.  The shorthand version {@link #un} is equivalent.      * <b>Note</b>: if a <i>scope</i> was explicitly specified when {@link #addListener adding} the      * listener, the same scope must be specified here.      * Example:      * <pre><code> el.removeListener('click', this.handlerFn); // or el.un('click', this.handlerFn); </code></pre>      * @param {String} eventName The name of the event from which to remove the handler.      * @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.      * @return {Ext.Element} this      */     removeListener : function(eventName, fn, scope){         Ext.EventManager.removeListener(this.dom,  eventName, fn, scope || this);         return this;     },     /**      * Removes all previous added listeners from this element      * @return {Ext.Element} this      */     removeAllListeners : function(){         Ext.EventManager.removeAll(this.dom);         return this;     },     /**      * Recursively removes all previous added listeners from this element and its children      * @return {Ext.Element} this      */     purgeAllListeners : function() {         Ext.EventManager.purgeElement(this, true);         return this;     },     /**      * @private Test if size has a unit, otherwise appends the default      */     addUnits : function(size){         if(size === "" || size == "auto" || size === undefined){             size = size || '';         } else if(!isNaN(size) || !unitPattern.test(size)){             size = size + (this.defaultUnit || 'px');         }         return size;     },     /**      * <p>Updates the <a href="http://developer.mozilla.org/en/DOM/element.innerHTML">innerHTML</a> of this Element      * from a specified URL. Note that this is subject to the <a href="http://en.wikipedia.org/wiki/Same_origin_policy">Same Origin Policy</a></p>      * <p>Updating innerHTML of an element will <b>not</b> execute embedded <tt>&lt;script></tt> elements. This is a browser restriction.</p>      * @param {Mixed} options. Either a sring containing the URL from which to load the HTML, or an {@link Ext.Ajax#request} options object specifying      * exactly how to request the HTML.      * @return {Ext.Element} this      */     load : function(url, params, cb){         Ext.Ajax.request(Ext.apply({             params: params,             url: url.url || url,             callback: cb,             el: this.dom,             indicatorText: url.indicatorText || ''         }, Ext.isObject(url) ? url : {}));         return this;     },     /**      * Tests various css rules/browsers to determine if this element uses a border box      * @return {Boolean}      */     isBorderBox : function(){         return noBoxAdjust[(this.dom.tagName || "").toLowerCase()] || Ext.isBorderBox;     },     /**      * <p>Removes this element's dom reference.  Note that event and cache removal is handled at {@link Ext#removeNode}</p>      */     remove : function(){         var me = this,             dom = me.dom;         if (dom) {             delete me.dom;             Ext.removeNode(dom);         }     },     /**      * Sets up event handlers to call the passed functions when the mouse is moved into and out of the Element.      * @param {Function} overFn The function to call when the mouse enters the Element.      * @param {Function} outFn The function to call when the mouse leaves the Element.      * @param {Object} scope (optional) The scope (<code>this</code> reference) in which the functions are executed. Defaults to the Element's DOM element.      * @param {Object} options (optional) Options for the listener. See {@link Ext.util.Observable#addListener the <tt>options</tt> parameter}.      * @return {Ext.Element} this      */     hover : function(overFn, outFn, scope, options){         var me = this;         me.on('mouseenter', overFn, scope || me.dom, options);         me.on('mouseleave', outFn, scope || me.dom, options);         return me;     },     /**      * Returns true if this element is an ancestor of the passed element      * @param {HTMLElement/String} el The element to check      * @return {Boolean} True if this element is an ancestor of el, else false      */     contains : function(el){         return !el ? false : Ext.lib.Dom.isAncestor(this.dom, el.dom ? el.dom : el);     },     /**      * Returns the value of a namespaced attribute from the element's underlying DOM node.      * @param {String} namespace The namespace in which to look for the attribute      * @param {String} name The attribute name      * @return {String} The attribute value      * @deprecated      */     getAttributeNS : function(ns, name){         return this.getAttribute(name, ns);     },     /**      * Returns the value of an attribute from the element's underlying DOM node.      * @param {String} name The attribute name      * @param {String} namespace (optional) The namespace in which to look for the attribute      * @return {String} The attribute value      */     getAttribute : Ext.isIE ? function(name, ns){         var d = this.dom,             type = typeof d[ns + ":" + name];         if(['undefined', 'unknown'].indexOf(type) == -1){             return d[ns + ":" + name];         }         return d[name];     } : function(name, ns){         var d = this.dom;         return d.getAttributeNS(ns, name) || d.getAttribute(ns + ":" + name) || d.getAttribute(name) || d[name];     },     /**     * Update the innerHTML of this element     * @param {String} html The new HTML     * @return {Ext.Element} this      */     update : function(html) {         if (this.dom) {             this.dom.innerHTML = html;         }         return this;     } }; var ep = El.prototype; El.addMethods = function(o){    Ext.apply(ep, o); }; /**  * Appends an event handler (shorthand for {@link #addListener}).  * @param {String} eventName The name of event to handle.  * @param {Function} fn The handler function the event invokes.  * @param {Object} scope (optional) The scope (<code>this</code> reference) in which the handler function is executed.  * @param {Object} options (optional) An object containing standard {@link #addListener} options  * @member Ext.Element  * @method on  */ ep.on = ep.addListener; /**  * Removes an event handler from this element (see {@link #removeListener} for additional notes).  * @param {String} eventName The name of the event from which to remove the handler.  * @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.  * @return {Ext.Element} this  * @member Ext.Element  * @method un  */ ep.un = ep.removeListener; /**  * true to automatically adjust width and height settings for box-model issues (default to true)  */ ep.autoBoxAdjust = true; // private var unitPattern = /d+(px|em|%|en|ex|pt|in|cm|mm|pc)$/i,     docEl; /**  * @private  */ /**  * Retrieves Ext.Element objects.  * <p><b>This method does not retrieve {@link Ext.Component Component}s.</b> This method  * retrieves Ext.Element objects which encapsulate DOM elements. To retrieve a Component by  * its ID, use {@link Ext.ComponentMgr#get}.</p>  * <p>Uses simple caching to consistently return the same object. Automatically fixes if an  * object was recreated with the same id via AJAX or DOM.</p>  * @param {Mixed} el The id of the node, a DOM Node or an existing Element.  * @return {Element} The Element object (or null if no matching element was found)  * @static  * @member Ext.Element  * @method get  */ El.get = function(el){     var ex,         elm,         id;     if(!el){ return null; }     if (typeof el == "string") { // element id         if (!(elm = DOC.getElementById(el))) {             return null;         }         if (EC[el] && EC[el].el) {             ex = EC[el].el;             ex.dom = elm;         } else {             ex = El.addToCache(new El(elm));         }         return ex;     } else if (el.tagName) { // dom element         if(!(id = el.id)){             id = Ext.id(el);         }         if (EC[id] && EC[id].el) {             ex = EC[id].el;             ex.dom = el;         } else {             ex = El.addToCache(new El(el));         }         return ex;     } else if (el instanceof El) {         if(el != docEl){             el.dom = DOC.getElementById(el.id) || el.dom; // refresh dom element in case no longer valid,                                                           // catch case where it hasn't been appended         }         return el;     } else if(el.isComposite) {         return el;     } else if(Ext.isArray(el)) {         return El.select(el);     } else if(el == DOC) {         // create a bogus element object representing the document object         if(!docEl){             var f = function(){};             f.prototype = El.prototype;             docEl = new f();             docEl.dom = DOC;         }         return docEl;     }     return null; }; El.addToCache = function(el, id){     id = id || el.id;         EC[id] = {         el:  el,         data: {},         events: {}     };     return el; }; // private method for getting and setting element data El.data = function(el, key, value){     el = El.get(el);     if (!el) {         return null;     }     var c = EC[el.id].data;     if(arguments.length == 2){         return c[key];     }else{         return (c[key] = value);     } }; // private // Garbage collection - uncache elements/purge listeners on orphaned elements // so we don't hold a reference and cause the browser to retain them function garbageCollect(){     if(!Ext.enableGarbageCollector){         clearInterval(El.collectorThreadId);     } else {         var eid,             el,             d,             o;         for(eid in EC){             o = EC[eid];             if(o.skipGC){                 continue;             }             el = o.el;             d = el.dom;             // -------------------------------------------------------             // Determining what is garbage:             // -------------------------------------------------------             // !d             // dom node is null, definitely garbage             // -------------------------------------------------------             // !d.parentNode             // no parentNode == direct orphan, definitely garbage             // -------------------------------------------------------             // !d.offsetParent && !document.getElementById(eid)             // display none elements have no offsetParent so we will             // also try to look it up by it's id. However, check             // offsetParent first so we don't do unneeded lookups.             // This enables collection of elements that are not orphans             // directly, but somewhere up the line they have an orphan             // parent.             // -------------------------------------------------------             if(!d || !d.parentNode || (!d.offsetParent && !DOC.getElementById(eid))){                 if(Ext.enableListenerCollection){                     Ext.EventManager.removeAll(d);                 }                 delete EC[eid];             }         }         // Cleanup IE Object leaks         if (Ext.isIE) {             var t = {};             for (eid in EC) {                 t[eid] = EC[eid];             }             EC = Ext.elCache = t;         }     } } El.collectorThreadId = setInterval(garbageCollect, 30000); var flyFn = function(){}; flyFn.prototype = El.prototype; // dom is optional El.Flyweight = function(dom){     this.dom = dom; }; El.Flyweight.prototype = new flyFn(); El.Flyweight.prototype.isFlyweight = true; El._flyweights = {}; /**  * <p>Gets the globally shared flyweight Element, with the passed node as the active element. Do not store a reference to this element -  * the dom node can be overwritten by other code. Shorthand of {@link Ext.Element#fly}</p>  * <p>Use this to make one-time references to DOM elements which are not going to be accessed again either by  * application code, or by Ext's classes. If accessing an element which will be processed regularly, then {@link Ext#get}  * will be more appropriate to take advantage of the caching provided by the Ext.Element class.</p>  * @param {String/HTMLElement} el The dom node or id  * @param {String} named (optional) Allows for creation of named reusable flyweights to prevent conflicts  * (e.g. internally Ext uses "_global")  * @return {Element} The shared Element object (or null if no matching element was found)  * @member Ext.Element  * @method fly  */ El.fly = function(el, named){     var ret = null;     named = named || '_global';     if (el = Ext.getDom(el)) {         (El._flyweights[named] = El._flyweights[named] || new El.Flyweight()).dom = el;         ret = El._flyweights[named];     }     return ret; }; /**  * Retrieves Ext.Element objects.  * <p><b>This method does not retrieve {@link Ext.Component Component}s.</b> This method  * retrieves Ext.Element objects which encapsulate DOM elements. To retrieve a Component by  * its ID, use {@link Ext.ComponentMgr#get}.</p>  * <p>Uses simple caching to consistently return the same object. Automatically fixes if an  * object was recreated with the same id via AJAX or DOM.</p>  * Shorthand of {@link Ext.Element#get}  * @param {Mixed} el The id of the node, a DOM Node or an existing Element.  * @return {Element} The Element object (or null if no matching element was found)  * @member Ext  * @method get  */ Ext.get = El.get; /**  * <p>Gets the globally shared flyweight Element, with the passed node as the active element. Do not store a reference to this element -  * the dom node can be overwritten by other code. Shorthand of {@link Ext.Element#fly}</p>  * <p>Use this to make one-time references to DOM elements which are not going to be accessed again either by  * application code, or by Ext's classes. If accessing an element which will be processed regularly, then {@link Ext#get}  * will be more appropriate to take advantage of the caching provided by the Ext.Element class.</p>  * @param {String/HTMLElement} el The dom node or id  * @param {String} named (optional) Allows for creation of named reusable flyweights to prevent conflicts  * (e.g. internally Ext uses "_global")  * @return {Element} The shared Element object (or null if no matching element was found)  * @member Ext  * @method fly  */ Ext.fly = El.fly; // speedy lookup for elements never to box adjust var noBoxAdjust = Ext.isStrict ? {     select:1 } : {     input:1, select:1, textarea:1 }; if(Ext.isIE || Ext.isGecko){     noBoxAdjust['button'] = 1; } Ext.EventManager.on(window, 'unload', function(){     delete EC;     delete El._flyweights; }); })(); /**  * @class Ext.Element  */ Ext.Element.addMethods({     /**      * Stops the specified event(s) from bubbling and optionally prevents the default action      * @param {String/Array} eventName an event / array of events to stop from bubbling      * @param {Boolean} preventDefault (optional) true to prevent the default action too      * @return {Ext.Element} this      */     swallowEvent : function(eventName, preventDefault){         var me = this;         function fn(e){             e.stopPropagation();             if(preventDefault){                 e.preventDefault();             }         }         if(Ext.isArray(eventName)){             Ext.each(eventName, function(e) {                  me.on(e, fn);             });             return me;         }         me.on(eventName, fn);         return me;     },     /**      * Create an event handler on this element such that when the event fires and is handled by this element,      * it will be relayed to another object (i.e., fired again as if it originated from that object instead).      * @param {String} eventName The type of event to relay      * @param {Object} object Any object that extends {@link Ext.util.Observable} that will provide the context      * for firing the relayed event      */     relayEvent : function(eventName, observable){         this.on(eventName, function(e){             observable.fireEvent(eventName, e);         });     },     /**      * Removes worthless text nodes      * @param {Boolean} forceReclean (optional) By default the element      * keeps track if it has been cleaned already so      * you can call this over and over. However, if you update the element and      * need to force a reclean, you can pass true.      */     clean : function(forceReclean){         var me = this,             dom = me.dom,             n = dom.firstChild,             ni = -1;         if(Ext.Element.data(dom, 'isCleaned') && forceReclean !== true){             return me;         }         while(n){             var nx = n.nextSibling;             if(n.nodeType == 3 && !/S/.test(n.nodeValue)){                 dom.removeChild(n);             }else{                 n.nodeIndex = ++ni;             }             n = nx;         }         Ext.Element.data(dom, 'isCleaned', true);         return me;     },     /**      * Direct access to the Updater {@link Ext.Updater#update} method. The method takes the same object      * parameter as {@link Ext.Updater#update}      * @return {Ext.Element} this      */     load : function(){         var um = this.getUpdater();         um.update.apply(um, arguments);         return this;     },     /**     * Gets this element's {@link Ext.Updater Updater}     * @return {Ext.Updater} The Updater     */     getUpdater : function(){         return this.updateManager || (this.updateManager = new Ext.Updater(this));     },     /**     * Update the innerHTML of this element, optionally searching for and processing scripts     * @param {String} html The new HTML     * @param {Boolean} loadScripts (optional) True to look for and process scripts (defaults to false)     * @param {Function} callback (optional) For async script loading you can be notified when the update completes     * @return {Ext.Element} this      */     update : function(html, loadScripts, callback){         if (!this.dom) {             return this;         }         html = html || "";         if(loadScripts !== true){             this.dom.innerHTML = html;             if(Ext.isFunction(callback)){                 callback();             }             return this;         }         var id = Ext.id(),             dom = this.dom;         html += '<span id="' + id + '"></span>';         Ext.lib.Event.onAvailable(id, function(){             var DOC = document,                 hd = DOC.getElementsByTagName("head")[0],                 re = /(?:<script([^>]*)?>)((n|r|.)*?)(?:</script>)/ig,                 srcRe = /ssrc=(['"])(.*?)1/i,                 typeRe = /stype=(['"])(.*?)1/i,                 match,                 attrs,                 srcMatch,                 typeMatch,                 el,                 s;             while((match = re.exec(html))){                 attrs = match[1];                 srcMatch = attrs ? attrs.match(srcRe) : false;                 if(srcMatch && srcMatch[2]){                    s = DOC.createElement("script");                    s.src = srcMatch[2];                    typeMatch = attrs.match(typeRe);                    if(typeMatch && typeMatch[2]){                        s.type = typeMatch[2];                    }                    hd.appendChild(s);                 }else if(match[2] && match[2].length > 0){                     if(window.execScript) {                        window.execScript(match[2]);                     } else {                        window.eval(match[2]);                     }                 }             }             el = DOC.getElementById(id);             if(el){Ext.removeNode(el);}             if(Ext.isFunction(callback)){                 callback();             }         });         dom.innerHTML = html.replace(/(?:<script.*?>)((n|r|.)*?)(?:</script>)/ig, "");         return this;     },     // inherit docs, overridden so we can add removeAnchor     removeAllListeners : function(){         this.removeAnchor();         Ext.EventManager.removeAll(this.dom);         return this;     },     /**      * Creates a proxy element of this element      * @param {String/Object} config The class name of the proxy element or a DomHelper config object      * @param {String/HTMLElement} renderTo (optional) The element or element id to render the proxy to (defaults to document.body)      * @param {Boolean} matchBox (optional) True to align and size the proxy to this element now (defaults to false)      * @return {Ext.Element} The new proxy element      */     createProxy : function(config, renderTo, matchBox){         config = Ext.isObject(config) ? config : {tag : "div", cls: config};         var me = this,             proxy = renderTo ? Ext.DomHelper.append(renderTo, config, true) :                                Ext.DomHelper.insertBefore(me.dom, config, true);         if(matchBox && me.setBox && me.getBox){ // check to make sure Element.position.js is loaded            proxy.setBox(me.getBox());         }         return proxy;     } }); Ext.Element.prototype.getUpdateManager = Ext.Element.prototype.getUpdater; /**  * @class Ext.Element  */ Ext.Element.addMethods({     /**      * Gets the x,y coordinates specified by the anchor position on the element.      * @param {String} anchor (optional) The specified anchor position (defaults to "c").  See {@link #alignTo}      * for details on supported anchor positions.      * @param {Boolean} local (optional) True to get the local (element top/left-relative) anchor position instead      * of page coordinates      * @param {Object} size (optional) An object containing the size to use for calculating anchor position      * {width: (target width), height: (target height)} (defaults to the element's current size)      * @return {Array} [x, y] An array containing the element's x and y coordinates      */     getAnchorXY : function(anchor, local, s){         //Passing a different size is useful for pre-calculating anchors,         //especially for anchored animations that change the el size. anchor = (anchor || "tl").toLowerCase();         s = s || {};                  var me = this,                  vp = me.dom == document.body || me.dom == document,          w = s.width || vp ? Ext.lib.Dom.getViewWidth() : me.getWidth(),          h = s.height || vp ? Ext.lib.Dom.getViewHeight() : me.getHeight(),                            xy,                 r = Math.round,          o = me.getXY(),          scroll = me.getScroll(),          extraX = vp ? scroll.left : !local ? o[0] : 0,          extraY = vp ? scroll.top : !local ? o[1] : 0,          hash = {          c  : [r(w * 0.5), r(h * 0.5)],          t  : [r(w * 0.5), 0],          l  : [0, r(h * 0.5)],          r  : [w, r(h * 0.5)],          b  : [r(w * 0.5), h],          tl : [0, 0],          bl : [0, h],          br : [w, h],          tr : [w, 0]          };                  xy = hash[anchor];         return [xy[0] + extraX, xy[1] + extraY];      },     /**      * Anchors an element to another element and realigns it when the window is resized.      * @param {Mixed} element The element to align to.      * @param {String} position The position to align to.      * @param {Array} offsets (optional) Offset the positioning by [x, y]      * @param {Boolean/Object} animate (optional) True for the default animation or a standard Element animation config object      * @param {Boolean/Number} monitorScroll (optional) True to monitor body scroll and reposition. If this parameter      * is a number, it is used as the buffer delay (defaults to 50ms).      * @param {Function} callback The function to call after the animation finishes      * @return {Ext.Element} this      */     anchorTo : function(el, alignment, offsets, animate, monitorScroll, callback){             var me = this,             dom = me.dom,             scroll = !Ext.isEmpty(monitorScroll),             action = function(){                 Ext.fly(dom).alignTo(el, alignment, offsets, animate);                 Ext.callback(callback, Ext.fly(dom));             },             anchor = this.getAnchor();                      // previous listener anchor, remove it         this.removeAnchor();         Ext.apply(anchor, {             fn: action,             scroll: scroll         });         Ext.EventManager.onWindowResize(action, null);                  if(scroll){             Ext.EventManager.on(window, 'scroll', action, null,                 {buffer: !isNaN(monitorScroll) ? monitorScroll : 50});         }         action.call(me); // align immediately         return me;     },          /**      * Remove any anchor to this element. See {@link #anchorTo}.      * @return {Ext.Element} this      */     removeAnchor : function(){         var me = this,             anchor = this.getAnchor();                      if(anchor && anchor.fn){             Ext.EventManager.removeResizeListener(anchor.fn);             if(anchor.scroll){                 Ext.EventManager.un(window, 'scroll', anchor.fn);             }             delete anchor.fn;         }         return me;     },          // private     getAnchor : function(){         var data = Ext.Element.data,             dom = this.dom;             if (!dom) {                 return;             }             var anchor = data(dom, '_anchor');                      if(!anchor){             anchor = data(dom, '_anchor', {});         }         return anchor;     },     /**      * Gets the x,y coordinates to align this element with another element. See {@link #alignTo} for more info on the      * supported position values.      * @param {Mixed} element The element to align to.      * @param {String} position (optional, defaults to "tl-bl?") The position to align to.      * @param {Array} offsets (optional) Offset the positioning by [x, y]      * @return {Array} [x, y]      */     getAlignToXY : function(el, p, o){              el = Ext.get(el);                  if(!el || !el.dom){             throw "Element.alignToXY with an element that doesn't exist";         }                  o = o || [0,0];         p = (!p || p == "?" ? "tl-bl?" : (!/-/.test(p) && p !== "" ? "tl-" + p : p || "tl-bl")).toLowerCase();                                 var me = this,          d = me.dom,          a1,          a2,          x,          y,          //constrain the aligned el to viewport if necessary          w,          h,          r,          dw = Ext.lib.Dom.getViewWidth() -10, // 10px of margin for ie          dh = Ext.lib.Dom.getViewHeight()-10, // 10px of margin for ie          p1y,          p1x,                  p2y,          p2x,          swapY,          swapX,          doc = document,          docElement = doc.documentElement,          docBody = doc.body,          scrollX = (docElement.scrollLeft || docBody.scrollLeft || 0)+5,          scrollY = (docElement.scrollTop || docBody.scrollTop || 0)+5,          c = false, //constrain to viewport          p1 = "",           p2 = "",          m = p.match(/^([a-z]+)-([a-z]+)(?)?$/);                  if(!m){            throw "Element.alignTo with an invalid alignment " + p;         }                  p1 = m[1];          p2 = m[2];          c = !!m[3];         //Subtract the aligned el's internal xy from the target's offset xy         //plus custom offset to get the aligned el's new offset xy         a1 = me.getAnchorXY(p1, true);         a2 = el.getAnchorXY(p2, false);         x = a2[0] - a1[0] + o[0];         y = a2[1] - a1[1] + o[1];         if(c){            w = me.getWidth();            h = me.getHeight();            r = el.getRegion();                   //If we are at a viewport boundary and the aligned el is anchored on a target border that is            //perpendicular to the vp border, allow the aligned el to slide on that border,            //otherwise swap the aligned el to the opposite border of the target.            p1y = p1.charAt(0);            p1x = p1.charAt(p1.length-1);            p2y = p2.charAt(0);            p2x = p2.charAt(p2.length-1);            swapY = ((p1y=="t" && p2y=="b") || (p1y=="b" && p2y=="t"));            swapX = ((p1x=="r" && p2x=="l") || (p1x=="l" && p2x=="r"));                                  if (x + w > dw + scrollX) {                 x = swapX ? r.left-w : dw+scrollX-w;            }            if (x < scrollX) {                x = swapX ? r.right : scrollX;            }            if (y + h > dh + scrollY) {                 y = swapY ? r.top-h : dh+scrollY-h;             }            if (y < scrollY){                y = swapY ? r.bottom : scrollY;            }         }         return [x,y];     },     /**      * Aligns this element with another element relative to the specified anchor points. If the other element is the      * document it aligns it to the viewport.      * The position parameter is optional, and can be specified in any one of the following formats:      * <ul>      *   <li><b>Blank</b>: Defaults to aligning the element's top-left corner to the target's bottom-left corner ("tl-bl").</li>      *   <li><b>One anchor (deprecated)</b>: The passed anchor position is used as the target element's anchor point.      *       The element being aligned will position its top-left corner (tl) to that point.  <i>This method has been      *       deprecated in favor of the newer two anchor syntax below</i>.</li>      *   <li><b>Two anchors</b>: If two values from the table below are passed separated by a dash, the first value is used as the      *       element's anchor point, and the second value is used as the target's anchor point.</li>      * </ul>      * In addition to the anchor points, the position parameter also supports the "?" character.  If "?" is passed at the end of      * the position string, the element will attempt to align as specified, but the position will be adjusted to constrain to      * the viewport if necessary.  Note that the element being aligned might be swapped to align to a different position than      * that specified in order to enforce the viewport constraints.      * Following are all of the supported anchor positions: <pre> Value  Description -----  ----------------------------- tl     The top left corner (default) t      The center of the top edge tr     The top right corner l      The center of the left edge c      In the center of the element r      The center of the right edge bl     The bottom left corner b      The center of the bottom edge br     The bottom right corner </pre> Example Usage: <pre><code> // align el to other-el using the default positioning ("tl-bl", non-constrained) el.alignTo("other-el"); // align the top left corner of el with the top right corner of other-el (constrained to viewport) el.alignTo("other-el", "tr?"); // align the bottom right corner of el with the center left edge of other-el el.alignTo("other-el", "br-l?"); // align the center of el with the bottom left corner of other-el and // adjust the x position by -6 pixels (and the y position by 0) el.alignTo("other-el", "c-bl", [-6, 0]); </code></pre>      * @param {Mixed} element The element to align to.      * @param {String} position (optional, defaults to "tl-bl?") The position to align to.      * @param {Array} offsets (optional) Offset the positioning by [x, y]      * @param {Boolean/Object} animate (optional) true for the default animation or a standard Element animation config object      * @return {Ext.Element} this      */     alignTo : function(element, position, offsets, animate){     var me = this;         return me.setXY(me.getAlignToXY(element, position, offsets),                    me.preanim && !!animate ? me.preanim(arguments, 3) : false);     },          // private ==>  used outside of core     adjustForConstraints : function(xy, parent, offsets){         return this.getConstrainToXY(parent || document, false, offsets, xy) ||  xy;     },     // private ==>  used outside of core     getConstrainToXY : function(el, local, offsets, proposedXY){        var os = {top:0, left:0, bottom:0, right: 0};         return function(el, local, offsets, proposedXY){             el = Ext.get(el);             offsets = offsets ? Ext.applyIf(offsets, os) : os;             var vw, vh, vx = 0, vy = 0;             if(el.dom == document.body || el.dom == document){                 vw =Ext.lib.Dom.getViewWidth();                 vh = Ext.lib.Dom.getViewHeight();             }else{                 vw = el.dom.clientWidth;                 vh = el.dom.clientHeight;                 if(!local){                     var vxy = el.getXY();                     vx = vxy[0];                     vy = vxy[1];                 }             }             var s = el.getScroll();             vx += offsets.left + s.left;             vy += offsets.top + s.top;             vw -= offsets.right;             vh -= offsets.bottom;             var vr = vx+vw;             var vb = vy+vh;             var xy = proposedXY || (!local ? this.getXY() : [this.getLeft(true), this.getTop(true)]);             var x = xy[0], y = xy[1];             var w = this.dom.offsetWidth, h = this.dom.offsetHeight;             // only move it if it needs it             var moved = false;             // first validate right/bottom             if((x + w) > vr){                 x = vr - w;                 moved = true;             }             if((y + h) > vb){                 y = vb - h;                 moved = true;             }             // then make sure top/left isn't negative             if(x < vx){                 x = vx;                 moved = true;             }             if(y < vy){                 y = vy;                 moved = true;             }             return moved ? [x, y] : false;         };     }(),                    //         el = Ext.get(el); //         offsets = Ext.applyIf(offsets || {}, {top : 0, left : 0, bottom : 0, right : 0}); //         var me = this, //          doc = document, //          s = el.getScroll(), //          vxy = el.getXY(), //          vx = offsets.left + s.left,  //          vy = offsets.top + s.top,             //          vw = -offsets.right,  //          vh = -offsets.bottom,  //          vr, //          vb, //          xy = proposedXY || (!local ? me.getXY() : [me.getLeft(true), me.getTop(true)]), //          x = xy[0], //          y = xy[1], //          w = me.dom.offsetWidth, h = me.dom.offsetHeight, //          moved = false; // only move it if it needs it //        //          //         if(el.dom == doc.body || el.dom == doc){ //             vw += Ext.lib.Dom.getViewWidth(); //             vh += Ext.lib.Dom.getViewHeight(); //         }else{ //             vw += el.dom.clientWidth; //             vh += el.dom.clientHeight; //             if(!local){                     //                 vx += vxy[0]; //                 vy += vxy[1]; //             } //         } //         // first validate right/bottom //         if(x + w > vx + vw){ //             x = vx + vw - w; //             moved = true; //         } //         if(y + h > vy + vh){ //             y = vy + vh - h; //             moved = true; //         } //         // then make sure top/left isn't negative //         if(x < vx){ //             x = vx; //             moved = true; //         } //         if(y < vy){ //             y = vy; //             moved = true; //         } //         return moved ? [x, y] : false; //    },          /**     * Calculates the x, y to center this element on the screen     * @return {Array} The x, y values [x, y]     */     getCenterXY : function(){         return this.getAlignToXY(document, 'c-c');     },     /**     * Centers the Element in either the viewport, or another Element.     * @param {Mixed} centerIn (optional) The element in which to center the element.     */     center : function(centerIn){         return this.alignTo(centerIn || document, 'c-c');             }     }); /**
  946.  * @class Ext.Element
  947.  */
  948. Ext.Element.addMethods(function(){
  949. var PARENTNODE = 'parentNode',
  950. NEXTSIBLING = 'nextSibling',
  951. PREVIOUSSIBLING = 'previousSibling',
  952. DQ = Ext.DomQuery,
  953. GET = Ext.get;
  954. return {
  955. /**
  956.      * Looks at this node and then at parent nodes for a match of the passed simple selector (e.g. div.some-class or span:first-child)
  957.      * @param {String} selector The simple selector to test
  958.      * @param {Number/Mixed} maxDepth (optional) The max depth to search as a number or element (defaults to 50 || document.body)
  959.      * @param {Boolean} returnEl (optional) True to return a Ext.Element object instead of DOM node
  960.      * @return {HTMLElement} The matching DOM node (or null if no match was found)
  961.      */
  962.     findParent : function(simpleSelector, maxDepth, returnEl){
  963.         var p = this.dom,
  964.          b = document.body, 
  965.          depth = 0,          
  966.          stopEl;         
  967.             if(Ext.isGecko && Object.prototype.toString.call(p) == '[object XULElement]') {
  968.                 return null;
  969.             }
  970.         maxDepth = maxDepth || 50;
  971.         if (isNaN(maxDepth)) {
  972.             stopEl = Ext.getDom(maxDepth);
  973.             maxDepth = Number.MAX_VALUE;
  974.         }
  975.         while(p && p.nodeType == 1 && depth < maxDepth && p != b && p != stopEl){
  976.             if(DQ.is(p, simpleSelector)){
  977.                 return returnEl ? GET(p) : p;
  978.             }
  979.             depth++;
  980.             p = p.parentNode;
  981.         }
  982.         return null;
  983.     },
  984.     /**
  985.      * Looks at parent nodes for a match of the passed simple selector (e.g. div.some-class or span:first-child)
  986.      * @param {String} selector The simple selector to test
  987.      * @param {Number/Mixed} maxDepth (optional) The max depth to
  988.             search as a number or element (defaults to 10 || document.body)
  989.      * @param {Boolean} returnEl (optional) True to return a Ext.Element object instead of DOM node
  990.      * @return {HTMLElement} The matching DOM node (or null if no match was found)
  991.      */
  992.     findParentNode : function(simpleSelector, maxDepth, returnEl){
  993.         var p = Ext.fly(this.dom.parentNode, '_internal');
  994.         return p ? p.findParent(simpleSelector, maxDepth, returnEl) : null;
  995.     },
  996.     /**
  997.      * Walks up the dom looking for a parent node that matches the passed simple selector (e.g. div.some-class or span:first-child).
  998.      * This is a shortcut for findParentNode() that always returns an Ext.Element.
  999.      * @param {String} selector The simple selector to test
  1000.      * @param {Number/Mixed} maxDepth (optional) The max depth to
  1001.             search as a number or element (defaults to 10 || document.body)
  1002.      * @return {Ext.Element} The matching DOM node (or null if no match was found)
  1003.      */
  1004.     up : function(simpleSelector, maxDepth){
  1005.         return this.findParentNode(simpleSelector, maxDepth, true);
  1006.     },
  1007.     /**
  1008.      * Creates a {@link Ext.CompositeElement} for child nodes based on the passed CSS selector (the selector should not contain an id).
  1009.      * @param {String} selector The CSS selector
  1010.      * @return {CompositeElement/CompositeElementLite} The composite element
  1011.      */
  1012.     select : function(selector){
  1013.         return Ext.Element.select(selector, this.dom);
  1014.     },
  1015.     /**
  1016.      * Selects child nodes based on the passed CSS selector (the selector should not contain an id).
  1017.      * @param {String} selector The CSS selector
  1018.      * @return {Array} An array of the matched nodes
  1019.      */
  1020.     query : function(selector){
  1021.         return DQ.select(selector, this.dom);
  1022.     },
  1023.     /**
  1024.      * Selects a single child at any depth below this element based on the passed CSS selector (the selector should not contain an id).
  1025.      * @param {String} selector The CSS selector
  1026.      * @param {Boolean} returnDom (optional) True to return the DOM node instead of Ext.Element (defaults to false)
  1027.      * @return {HTMLElement/Ext.Element} The child Ext.Element (or DOM node if returnDom = true)
  1028.      */
  1029.     child : function(selector, returnDom){
  1030.         var n = DQ.selectNode(selector, this.dom);
  1031.         return returnDom ? n : GET(n);
  1032.     },
  1033.     /**
  1034.      * Selects a single *direct* child based on the passed CSS selector (the selector should not contain an id).
  1035.      * @param {String} selector The CSS selector
  1036.      * @param {Boolean} returnDom (optional) True to return the DOM node instead of Ext.Element (defaults to false)
  1037.      * @return {HTMLElement/Ext.Element} The child Ext.Element (or DOM node if returnDom = true)
  1038.      */
  1039.     down : function(selector, returnDom){
  1040.         var n = DQ.selectNode(" > " + selector, this.dom);
  1041.         return returnDom ? n : GET(n);
  1042.     },
  1043.  /**
  1044.      * Gets the parent node for this element, optionally chaining up trying to match a selector
  1045.      * @param {String} selector (optional) Find a parent node that matches the passed simple selector
  1046.      * @param {Boolean} returnDom (optional) True to return a raw dom node instead of an Ext.Element
  1047.      * @return {Ext.Element/HTMLElement} The parent node or null
  1048.  */
  1049.     parent : function(selector, returnDom){
  1050.         return this.matchNode(PARENTNODE, PARENTNODE, selector, returnDom);
  1051.     },
  1052.      /**
  1053.      * Gets the next sibling, skipping text nodes
  1054.      * @param {String} selector (optional) Find the next sibling that matches the passed simple selector
  1055.      * @param {Boolean} returnDom (optional) True to return a raw dom node instead of an Ext.Element
  1056.      * @return {Ext.Element/HTMLElement} The next sibling or null
  1057.  */
  1058.     next : function(selector, returnDom){
  1059.         return this.matchNode(NEXTSIBLING, NEXTSIBLING, selector, returnDom);
  1060.     },
  1061.     /**
  1062.      * Gets the previous sibling, skipping text nodes
  1063.      * @param {String} selector (optional) Find the previous sibling that matches the passed simple selector
  1064.      * @param {Boolean} returnDom (optional) True to return a raw dom node instead of an Ext.Element
  1065.      * @return {Ext.Element/HTMLElement} The previous sibling or null
  1066.  */
  1067.     prev : function(selector, returnDom){
  1068.         return this.matchNode(PREVIOUSSIBLING, PREVIOUSSIBLING, selector, returnDom);
  1069.     },
  1070.     /**
  1071.      * Gets the first child, skipping text nodes
  1072.      * @param {String} selector (optional) Find the next sibling that matches the passed simple selector
  1073.      * @param {Boolean} returnDom (optional) True to return a raw dom node instead of an Ext.Element
  1074.      * @return {Ext.Element/HTMLElement} The first child or null
  1075.  */
  1076.     first : function(selector, returnDom){
  1077.         return this.matchNode(NEXTSIBLING, 'firstChild', selector, returnDom);
  1078.     },
  1079.     /**
  1080.      * Gets the last child, skipping text nodes
  1081.      * @param {String} selector (optional) Find the previous sibling that matches the passed simple selector
  1082.      * @param {Boolean} returnDom (optional) True to return a raw dom node instead of an Ext.Element
  1083.      * @return {Ext.Element/HTMLElement} The last child or null
  1084.  */
  1085.     last : function(selector, returnDom){
  1086.         return this.matchNode(PREVIOUSSIBLING, 'lastChild', selector, returnDom);
  1087.     },
  1088.     
  1089.     matchNode : function(dir, start, selector, returnDom){
  1090.         var n = this.dom[start];
  1091.         while(n){
  1092.             if(n.nodeType == 1 && (!selector || DQ.is(n, selector))){
  1093.                 return !returnDom ? GET(n) : n;
  1094.             }
  1095.             n = n[dir];
  1096.         }
  1097.         return null;
  1098.     }
  1099.     }
  1100. }());/**
  1101.  * @class Ext.Element
  1102.  */
  1103. Ext.Element.addMethods({
  1104.     /**
  1105.      * Creates a {@link Ext.CompositeElement} for child nodes based on the passed CSS selector (the selector should not contain an id).
  1106.      * @param {String} selector The CSS selector
  1107.      * @param {Boolean} unique (optional) True to create a unique Ext.Element for each child (defaults to false, which creates a single shared flyweight object)
  1108.      * @return {CompositeElement/CompositeElementLite} The composite element
  1109.      */
  1110.     select : function(selector, unique){
  1111.         return Ext.Element.select(selector, unique, this.dom);
  1112.     }
  1113. });/**
  1114.  * @class Ext.Element
  1115.  */
  1116. Ext.Element.addMethods(
  1117. function() {
  1118. var GETDOM = Ext.getDom,
  1119. GET = Ext.get,
  1120. DH = Ext.DomHelper;
  1121. return {
  1122.     /**
  1123.      * Appends the passed element(s) to this element
  1124.      * @param {String/HTMLElement/Array/Element/CompositeElement} el
  1125.      * @return {Ext.Element} this
  1126.      */
  1127.     appendChild: function(el){        
  1128.         return GET(el).appendTo(this);        
  1129.     },
  1130.     /**
  1131.      * Appends this element to the passed element
  1132.      * @param {Mixed} el The new parent element
  1133.      * @return {Ext.Element} this
  1134.      */
  1135.     appendTo: function(el){        
  1136.         GETDOM(el).appendChild(this.dom);        
  1137.         return this;
  1138.     },
  1139.     /**
  1140.      * Inserts this element before the passed element in the DOM
  1141.      * @param {Mixed} el The element before which this element will be inserted
  1142.      * @return {Ext.Element} this
  1143.      */
  1144.     insertBefore: function(el){             
  1145.         (el = GETDOM(el)).parentNode.insertBefore(this.dom, el);
  1146.         return this;
  1147.     },
  1148.     /**
  1149.      * Inserts this element after the passed element in the DOM
  1150.      * @param {Mixed} el The element to insert after
  1151.      * @return {Ext.Element} this
  1152.      */
  1153.     insertAfter: function(el){
  1154.         (el = GETDOM(el)).parentNode.insertBefore(this.dom, el.nextSibling);
  1155.         return this;
  1156.     },
  1157.     /**
  1158.      * Inserts (or creates) an element (or DomHelper config) as the first child of this element
  1159.      * @param {Mixed/Object} el The id or element to insert or a DomHelper config to create and insert
  1160.      * @return {Ext.Element} The new child
  1161.      */
  1162.     insertFirst: function(el, returnDom){
  1163.             el = el || {};
  1164.             if(el.nodeType || el.dom || typeof el == 'string'){ // element
  1165.                 el = GETDOM(el);
  1166.                 this.dom.insertBefore(el, this.dom.firstChild);
  1167.                 return !returnDom ? GET(el) : el;
  1168.             }else{ // dh config
  1169.                 return this.createChild(el, this.dom.firstChild, returnDom);
  1170.             }
  1171.         },
  1172.     /**
  1173.      * Replaces the passed element with this element
  1174.      * @param {Mixed} el The element to replace
  1175.      * @return {Ext.Element} this
  1176.      */
  1177.     replace: function(el){
  1178.         el = GET(el);
  1179.         this.insertBefore(el);
  1180.         el.remove();
  1181.         return this;
  1182.     },
  1183.     /**
  1184.      * Replaces this element with the passed element
  1185.      * @param {Mixed/Object} el The new element or a DomHelper config of an element to create
  1186.      * @return {Ext.Element} this
  1187.      */
  1188.     replaceWith: function(el){
  1189.     var me = this;
  1190.                 
  1191.             if(el.nodeType || el.dom || typeof el == 'string'){
  1192.                 el = GETDOM(el);
  1193.                 me.dom.parentNode.insertBefore(el, me.dom);
  1194.             }else{
  1195.                 el = DH.insertBefore(me.dom, el);
  1196.             }
  1197.         
  1198.         delete Ext.elCache[me.id];
  1199.         Ext.removeNode(me.dom);      
  1200.         me.id = Ext.id(me.dom = el);
  1201.         Ext.Element.addToCache(me.isFlyweight ? new Ext.Element(me.dom) : me);     
  1202.             return me;
  1203.     },
  1204.     
  1205. /**
  1206.  * Creates the passed DomHelper config and appends it to this element or optionally inserts it before the passed child element.
  1207.  * @param {Object} config DomHelper element config object.  If no tag is specified (e.g., {tag:'input'}) then a div will be
  1208.  * automatically generated with the specified attributes.
  1209.  * @param {HTMLElement} insertBefore (optional) a child element of this element
  1210.  * @param {Boolean} returnDom (optional) true to return the dom node instead of creating an Element
  1211.  * @return {Ext.Element} The new child element
  1212.  */
  1213. createChild: function(config, insertBefore, returnDom){
  1214.     config = config || {tag:'div'};
  1215.     return insertBefore ? 
  1216.         DH.insertBefore(insertBefore, config, returnDom !== true) :
  1217.         DH[!this.dom.firstChild ? 'overwrite' : 'append'](this.dom, config,  returnDom !== true);
  1218. },
  1219. /**
  1220.  * Creates and wraps this element with another element
  1221.  * @param {Object} config (optional) DomHelper element config object for the wrapper element or null for an empty div
  1222.  * @param {Boolean} returnDom (optional) True to return the raw DOM element instead of Ext.Element
  1223.  * @return {HTMLElement/Element} The newly created wrapper element
  1224.  */
  1225. wrap: function(config, returnDom){        
  1226.     var newEl = DH.insertBefore(this.dom, config || {tag: "div"}, !returnDom);
  1227.     newEl.dom ? newEl.dom.appendChild(this.dom) : newEl.appendChild(this.dom);
  1228.     return newEl;
  1229. },
  1230. /**
  1231.  * Inserts an html fragment into this element
  1232.  * @param {String} where Where to insert the html in relation to this element - beforeBegin, afterBegin, beforeEnd, afterEnd.
  1233.  * @param {String} html The HTML fragment
  1234.  * @param {Boolean} returnEl (optional) True to return an Ext.Element (defaults to false)
  1235.  * @return {HTMLElement/Ext.Element} The inserted node (or nearest related if more than 1 inserted)
  1236.  */
  1237. insertHtml : function(where, html, returnEl){
  1238.     var el = DH.insertHtml(where, this.dom, html);
  1239.     return returnEl ? Ext.get(el) : el;
  1240. }
  1241. }
  1242. }());/**
  1243.  * @class Ext.Element
  1244.  */
  1245. Ext.apply(Ext.Element.prototype, function() {
  1246. var GETDOM = Ext.getDom,
  1247. GET = Ext.get,
  1248. DH = Ext.DomHelper;
  1249. return {
  1250. /**
  1251.      * Inserts (or creates) the passed element (or DomHelper config) as a sibling of this element
  1252.      * @param {Mixed/Object/Array} el The id, element to insert or a DomHelper config to create and insert *or* an array of any of those.
  1253.      * @param {String} where (optional) 'before' or 'after' defaults to before
  1254.      * @param {Boolean} returnDom (optional) True to return the raw DOM element instead of Ext.Element
  1255.      * @return {Ext.Element} The inserted Element. If an array is passed, the last inserted element is returned.
  1256.      */
  1257.     insertSibling: function(el, where, returnDom){
  1258.         var me = this,
  1259.          rt,
  1260.                 isAfter = (where || 'before').toLowerCase() == 'after',
  1261.                 insertEl;
  1262.         
  1263.         if(Ext.isArray(el)){
  1264.                 insertEl = me;
  1265.             Ext.each(el, function(e) {
  1266.             rt = Ext.fly(insertEl, '_internal').insertSibling(e, where, returnDom);
  1267.                     if(isAfter){
  1268.                         insertEl = rt;
  1269.                     }
  1270.             });
  1271.             return rt;
  1272.         }
  1273.                 
  1274.         el = el || {};
  1275.        
  1276.             if(el.nodeType || el.dom){
  1277.                 rt = me.dom.parentNode.insertBefore(GETDOM(el), isAfter ? me.dom.nextSibling : me.dom);
  1278.                 if (!returnDom) {
  1279.                     rt = GET(rt);
  1280.                 }
  1281.             }else{
  1282.                 if (isAfter && !me.dom.nextSibling) {
  1283.                     rt = DH.append(me.dom.parentNode, el, !returnDom);
  1284.                 } else {                    
  1285.                     rt = DH[isAfter ? 'insertAfter' : 'insertBefore'](me.dom, el, !returnDom);
  1286.                 }
  1287.             }
  1288.         return rt;
  1289.     }
  1290.     };
  1291. }());/**  * @class Ext.Element  */ Ext.Element.addMethods(function(){     // local style camelizing for speed     var propCache = {},         camelRe = /(-[a-z])/gi,         classReCache = {},         view = document.defaultView,         propFloat = Ext.isIE ? 'styleFloat' : 'cssFloat',         opacityRe = /alpha(opacity=(.*))/i,         trimRe = /^s+|s+$/g,         EL = Ext.Element,         PADDING = "padding",         MARGIN = "margin",         BORDER = "border",         LEFT = "-left",         RIGHT = "-right",         TOP = "-top",         BOTTOM = "-bottom",         WIDTH = "-width",         MATH = Math,         HIDDEN = 'hidden',         ISCLIPPED = 'isClipped',         OVERFLOW = 'overflow',         OVERFLOWX = 'overflow-x',         OVERFLOWY = 'overflow-y',         ORIGINALCLIP = 'originalClip',         // special markup used throughout Ext when box wrapping elements         borders = {l: BORDER + LEFT + WIDTH, r: BORDER + RIGHT + WIDTH, t: BORDER + TOP + WIDTH, b: BORDER + BOTTOM + WIDTH},         paddings = {l: PADDING + LEFT, r: PADDING + RIGHT, t: PADDING + TOP, b: PADDING + BOTTOM},         margins = {l: MARGIN + LEFT, r: MARGIN + RIGHT, t: MARGIN + TOP, b: MARGIN + BOTTOM},         data = Ext.Element.data;     // private     function camelFn(m, a) {         return a.charAt(1).toUpperCase();     }     function chkCache(prop) {         return propCache[prop] || (propCache[prop] = prop == 'float' ? propFloat : prop.replace(camelRe, camelFn));     }     return {         // private  ==> used by Fx         adjustWidth : function(width) {             var me = this;             var isNum = Ext.isNumber(width);             if(isNum && me.autoBoxAdjust && !me.isBorderBox()){                width -= (me.getBorderWidth("lr") + me.getPadding("lr"));             }             return (isNum && width < 0) ? 0 : width;         },         // private   ==> used by Fx         adjustHeight : function(height) {             var me = this;             var isNum = Ext.isNumber(height);             if(isNum && me.autoBoxAdjust && !me.isBorderBox()){                height -= (me.getBorderWidth("tb") + me.getPadding("tb"));             }             return (isNum && height < 0) ? 0 : height;         },         /**          * Adds one or more CSS classes to the element. Duplicate classes are automatically filtered out.          * @param {String/Array} className The CSS class to add, or an array of classes          * @return {Ext.Element} this          */         addClass : function(className){             var me = this, i, len, v;             className = Ext.isArray(className) ? className : [className];             for (i=0, len = className.length; i < len; i++) {                 v = className[i];                 if (v) {                     me.dom.className += (!me.hasClass(v) && v ? " " + v : "");                 };             };             return me;         },         /**          * Adds one or more CSS classes to this element and removes the same class(es) from all siblings.          * @param {String/Array} className The CSS class to add, or an array of classes          * @return {Ext.Element} this          */         radioClass : function(className){             var cn = this.dom.parentNode.childNodes, v;             className = Ext.isArray(className) ? className : [className];             for (var i=0, len = cn.length; i < len; i++) {                 v = cn[i];                 if(v && v.nodeType == 1) {                     Ext.fly(v, '_internal').removeClass(className);                 }             };             return this.addClass(className);         },         /**          * Removes one or more CSS classes from the element.          * @param {String/Array} className The CSS class to remove, or an array of classes          * @return {Ext.Element} this          */         removeClass : function(className){             var me = this, v;             className = Ext.isArray(className) ? className : [className];             if (me.dom && me.dom.className) {                 for (var i=0, len=className.length; i < len; i++) {                     v = className[i];                     if(v) {                         me.dom.className = me.dom.className.replace(                             classReCache[v] = classReCache[v] || new RegExp('(?:^|\s+)' + v + '(?:\s+|$)', "g"), " "                         );                     }                 };             }             return me;         },         /**          * Toggles the specified CSS class on this element (removes it if it already exists, otherwise adds it).          * @param {String} className The CSS class to toggle          * @return {Ext.Element} this          */         toggleClass : function(className){             return this.hasClass(className) ? this.removeClass(className) : this.addClass(className);         },         /**          * Checks if the specified CSS class exists on this element's DOM node.          * @param {String} className The CSS class to check for          * @return {Boolean} True if the class exists, else false          */         hasClass : function(className){             return className && (' '+this.dom.className+' ').indexOf(' '+className+' ') != -1;         },         /**          * Replaces a CSS class on the element with another.  If the old name does not exist, the new name will simply be added.          * @param {String} oldClassName The CSS class to replace          * @param {String} newClassName The replacement CSS class          * @return {Ext.Element} this          */         replaceClass : function(oldClassName, newClassName){             return this.removeClass(oldClassName).addClass(newClassName);         },         isStyle : function(style, val) {             return this.getStyle(style) == val;         },         /**          * Normalizes currentStyle and computedStyle.          * @param {String} property The style property whose value is returned.          * @return {String} The current value of the style property for this element.          */         getStyle : function(){             return view && view.getComputedStyle ?                 function(prop){                     var el = this.dom,                         v,                         cs,                         out,                         display,                         wk = Ext.isWebKit,                         display;                                              if(el == document){                         return null;                     }                     prop = chkCache(prop);                     // Fix bug caused by this: https://bugs.webkit.org/show_bug.cgi?id=13343                     if(wk && /marginRight/.test(prop)){                         display = this.getStyle('display');                         el.style.display = 'inline-block';                     }                     out = (v = el.style[prop]) ? v :                            (cs = view.getComputedStyle(el, "")) ? cs[prop] : null;                     // Webkit returns rgb values for transparent.                     if(wk){                         if(out == 'rgba(0, 0, 0, 0)'){                             out = 'transparent';                         }else if(display){                             el.style.display = display;                         }                     }                     return out;                 } :                 function(prop){                     var el = this.dom,                         m,                         cs;                     if(el == document) return null;                     if (prop == 'opacity') {                         if (el.style.filter.match) {                             if(m = el.style.filter.match(opacityRe)){                                 var fv = parseFloat(m[1]);                                 if(!isNaN(fv)){                                     return fv ? fv / 100 : 0;                                 }                             }                         }                         return 1;                     }                     prop = chkCache(prop);                     return el.style[prop] || ((cs = el.currentStyle) ? cs[prop] : null);                 };         }(),         /**          * Return the CSS color for the specified CSS attribute. rgb, 3 digit (like #fff) and valid values          * are convert to standard 6 digit hex color.          * @param {String} attr The css attribute          * @param {String} defaultValue The default value to use when a valid color isn't found          * @param {String} prefix (optional) defaults to #. Use an empty string when working with          * color anims.          */         getColor : function(attr, defaultValue, prefix){             var v = this.getStyle(attr),                 color = Ext.isDefined(prefix) ? prefix : '#',                 h;             if(!v || /transparent|inherit/.test(v)){                 return defaultValue;             }             if(/^r/.test(v)){                 Ext.each(v.slice(4, v.length -1).split(','), function(s){                     h = parseInt(s, 10);                     color += (h < 16 ? '0' : '') + h.toString(16);                 });             }else{                 v = v.replace('#', '');                 color += v.length == 3 ? v.replace(/^(w)(w)(w)$/, '$1$1$2$2$3$3') : v;             }             return(color.length > 5 ? color.toLowerCase() : defaultValue);         },         /**          * Wrapper for setting style properties, also takes single object parameter of multiple styles.          * @param {String/Object} property The style property to be set, or an object of multiple styles.          * @param {String} value (optional) The value to apply to the given property, or null if an object was passed.          * @return {Ext.Element} this          */         setStyle : function(prop, value){             var tmp,                 style,                 camel;             if (!Ext.isObject(prop)) {                 tmp = {};                 tmp[prop] = value;                 prop = tmp;             }             for (style in prop) {                 value = prop[style];                 style == 'opacity' ?                     this.setOpacity(value) :                     this.dom.style[chkCache(style)] = value;             }             return this;         },         /**          * Set the opacity of the element          * @param {Float} opacity The new opacity. 0 = transparent, .5 = 50% visibile, 1 = fully visible, etc          * @param {Boolean/Object} animate (optional) a standard Element animation config object or <tt>true</tt> for          * the default animation (<tt>{duration: .35, easing: 'easeIn'}</tt>)          * @return {Ext.Element} this          */          setOpacity : function(opacity, animate){             var me = this,                 s = me.dom.style;             if(!animate || !me.anim){                 if(Ext.isIE){                     var opac = opacity < 1 ? 'alpha(opacity=' + opacity * 100 + ')' : '',                     val = s.filter.replace(opacityRe, '').replace(trimRe, '');                     s.zoom = 1;                     s.filter = val + (val.length > 0 ? ' ' : '') + opac;                 }else{                     s.opacity = opacity;                 }             }else{                 me.anim({opacity: {to: opacity}}, me.preanim(arguments, 1), null, .35, 'easeIn');             }             return me;         },         /**          * Clears any opacity settings from this element. Required in some cases for IE.          * @return {Ext.Element} this          */         clearOpacity : function(){             var style = this.dom.style;             if(Ext.isIE){                 if(!Ext.isEmpty(style.filter)){                     style.filter = style.filter.replace(opacityRe, '').replace(trimRe, '');                 }             }else{                 style.opacity = style['-moz-opacity'] = style['-khtml-opacity'] = '';             }             return this;         },         /**          * Returns the offset height of the element          * @param {Boolean} contentHeight (optional) true to get the height minus borders and padding          * @return {Number} The element's height          */         getHeight : function(contentHeight){             var me = this,                 dom = me.dom,                 hidden = Ext.isIE && me.isStyle('display', 'none'),                 h = MATH.max(dom.offsetHeight, hidden ? 0 : dom.clientHeight) || 0;             h = !contentHeight ? h : h - me.getBorderWidth("tb") - me.getPadding("tb");             return h < 0 ? 0 : h;         },         /**          * Returns the offset width of the element          * @param {Boolean} contentWidth (optional) true to get the width minus borders and padding          * @return {Number} The element's width          */         getWidth : function(contentWidth){             var me = this,                 dom = me.dom,                 hidden = Ext.isIE && me.isStyle('display', 'none'),                 w = MATH.max(dom.offsetWidth, hidden ? 0 : dom.clientWidth) || 0;             w = !contentWidth ? w : w - me.getBorderWidth("lr") - me.getPadding("lr");             return w < 0 ? 0 : w;         },         /**          * Set the width of this Element.          * @param {Mixed} width The new width. This may be one of:<div class="mdetail-params"><ul>          * <li>A Number specifying the new width in this Element's {@link #defaultUnit}s (by default, pixels).</li>          * <li>A String used to set the CSS width style. Animation may <b>not</b> be used.          * </ul></div>          * @param {Boolean/Object} animate (optional) true for the default animation or a standard Element animation config object          * @return {Ext.Element} this          */         setWidth : function(width, animate){             var me = this;             width = me.adjustWidth(width);             !animate || !me.anim ?                 me.dom.style.width = me.addUnits(width) :                 me.anim({width : {to : width}}, me.preanim(arguments, 1));             return me;         },         /**          * Set the height of this Element.          * <pre><code> // change the height to 200px and animate with default configuration Ext.fly('elementId').setHeight(200, true); // change the height to 150px and animate with a custom configuration Ext.fly('elId').setHeight(150, {     duration : .5, // animation will have a duration of .5 seconds     // will change the content to "finished"     callback: function(){ this.{@link #update}("finished"); } });          * </code></pre>          * @param {Mixed} height The new height. This may be one of:<div class="mdetail-params"><ul>          * <li>A Number specifying the new height in this Element's {@link #defaultUnit}s (by default, pixels.)</li>          * <li>A String used to set the CSS height style. Animation may <b>not</b> be used.</li>          * </ul></div>          * @param {Boolean/Object} animate (optional) true for the default animation or a standard Element animation config object          * @return {Ext.Element} this          */          setHeight : function(height, animate){             var me = this;             height = me.adjustHeight(height);             !animate || !me.anim ?                 me.dom.style.height = me.addUnits(height) :                 me.anim({height : {to : height}}, me.preanim(arguments, 1));             return me;         },         /**          * Gets the width of the border(s) for the specified side(s)          * @param {String} side Can be t, l, r, b or any combination of those to add multiple values. For example,          * passing <tt>'lr'</tt> would get the border <b><u>l</u></b>eft width + the border <b><u>r</u></b>ight width.          * @return {Number} The width of the sides passed added together          */         getBorderWidth : function(side){             return this.addStyles(side, borders);         },         /**          * Gets the width of the padding(s) for the specified side(s)          * @param {String} side Can be t, l, r, b or any combination of those to add multiple values. For example,          * passing <tt>'lr'</tt> would get the padding <b><u>l</u></b>eft + the padding <b><u>r</u></b>ight.          * @return {Number} The padding of the sides passed added together          */         getPadding : function(side){             return this.addStyles(side, paddings);         },         /**          *  Store the current overflow setting and clip overflow on the element - use <tt>{@link #unclip}</tt> to remove          * @return {Ext.Element} this          */         clip : function(){             var me = this,                 dom = me.dom;             if(!data(dom, ISCLIPPED)){                 data(dom, ISCLIPPED, true);                 data(dom, ORIGINALCLIP, {                     o: me.getStyle(OVERFLOW),                     x: me.getStyle(OVERFLOWX),                     y: me.getStyle(OVERFLOWY)                 });                 me.setStyle(OVERFLOW, HIDDEN);                 me.setStyle(OVERFLOWX, HIDDEN);                 me.setStyle(OVERFLOWY, HIDDEN);             }             return me;         },         /**          *  Return clipping (overflow) to original clipping before <tt>{@link #clip}</tt> was called          * @return {Ext.Element} this          */         unclip : function(){             var me = this,                 dom = me.dom;             if(data(dom, ISCLIPPED)){                 data(dom, ISCLIPPED, false);                 var o = data(dom, ORIGINALCLIP);                 if(o.o){                     me.setStyle(OVERFLOW, o.o);                 }                 if(o.x){                     me.setStyle(OVERFLOWX, o.x);                 }                 if(o.y){                     me.setStyle(OVERFLOWY, o.y);                 }             }             return me;         },         // private         addStyles : function(sides, styles){             var val = 0,                 m = sides.match(/w/g),                 s;             for (var i=0, len=m.length; i<len; i++) {                 s = m[i] && parseInt(this.getStyle(styles[m[i]]), 10);                 if (s) {                     val += MATH.abs(s);                 }             }             return val;         },         margins : margins     } }() ); /**
  1292.  * @class Ext.Element
  1293.  */
  1294. // special markup used throughout Ext when box wrapping elements
  1295. Ext.Element.boxMarkup = '<div class="{0}-tl"><div class="{0}-tr"><div class="{0}-tc"></div></div></div><div class="{0}-ml"><div class="{0}-mr"><div class="{0}-mc"></div></div></div><div class="{0}-bl"><div class="{0}-br"><div class="{0}-bc"></div></div></div>';
  1296. Ext.Element.addMethods(function(){
  1297.     var INTERNAL = "_internal",
  1298.         pxMatch = /(d+)px/;
  1299.     return {
  1300.         /**
  1301.          * More flexible version of {@link #setStyle} for setting style properties.
  1302.          * @param {String/Object/Function} styles A style specification string, e.g. "width:100px", or object in the form {width:"100px"}, or
  1303.          * a function which returns such a specification.
  1304.          * @return {Ext.Element} this
  1305.          */
  1306.         applyStyles : function(style){
  1307.             Ext.DomHelper.applyStyles(this.dom, style);
  1308.             return this;
  1309.         },
  1310.         /**
  1311.          * Returns an object with properties matching the styles requested.
  1312.          * For example, el.getStyles('color', 'font-size', 'width') might return
  1313.          * {'color': '#FFFFFF', 'font-size': '13px', 'width': '100px'}.
  1314.          * @param {String} style1 A style name
  1315.          * @param {String} style2 A style name
  1316.          * @param {String} etc.
  1317.          * @return {Object} The style object
  1318.          */
  1319.         getStyles : function(){
  1320.             var ret = {};
  1321.             Ext.each(arguments, function(v) {
  1322.                ret[v] = this.getStyle(v);
  1323.             },
  1324.             this);
  1325.             return ret;
  1326.         },
  1327.         // deprecated
  1328.         getStyleSize : function(){
  1329.             var me = this,
  1330.                 w,
  1331.                 h,
  1332.                 d = this.dom,
  1333.                 s = d.style;
  1334.             if(s.width && s.width != 'auto'){
  1335.                 w = parseInt(s.width, 10);
  1336.                 if(me.isBorderBox()){
  1337.                    w -= me.getFrameWidth('lr');
  1338.                 }
  1339.             }
  1340.             if(s.height && s.height != 'auto'){
  1341.                 h = parseInt(s.height, 10);
  1342.                 if(me.isBorderBox()){
  1343.                    h -= me.getFrameWidth('tb');
  1344.                 }
  1345.             }
  1346.             return {width: w || me.getWidth(true), height: h || me.getHeight(true)};
  1347.         },
  1348.         // private  ==> used by ext full
  1349.         setOverflow : function(v){
  1350.             var dom = this.dom;
  1351.             if(v=='auto' && Ext.isMac && Ext.isGecko2){ // work around stupid FF 2.0/Mac scroll bar bug
  1352.                 dom.style.overflow = 'hidden';
  1353.                 (function(){dom.style.overflow = 'auto';}).defer(1);
  1354.             }else{
  1355.                 dom.style.overflow = v;
  1356.             }
  1357.         },
  1358.        /**
  1359.         * <p>Wraps the specified element with a special 9 element markup/CSS block that renders by default as
  1360.         * a gray container with a gradient background, rounded corners and a 4-way shadow.</p>