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

中间件编程

开发平台:

JavaScript

  1.      */
  2.     load : function(url, params, cb){
  3.         Ext.Ajax.request(Ext.apply({
  4.             params: params,
  5.             url: url.url || url,
  6.             callback: cb,
  7.             el: this.dom,
  8.             indicatorText: url.indicatorText || ''
  9.         }, Ext.isObject(url) ? url : {}));
  10.         return this;
  11.     },
  12.     /**
  13.      * Tests various css rules/browsers to determine if this element uses a border box
  14.      * @return {Boolean}
  15.      */
  16.     isBorderBox : function(){
  17.         return noBoxAdjust[(this.dom.tagName || "").toLowerCase()] || Ext.isBorderBox;
  18.     },
  19.     /**
  20.      * Removes this element from the DOM and deletes it from the cache
  21.      */
  22.     remove : function(){
  23.         var me = this,
  24.             dom = me.dom;
  25.         
  26.         me.removeAllListeners();
  27.         delete El.cache[dom.id];
  28.         delete El.dataCache[dom.id]
  29.         Ext.removeNode(dom);
  30.     },
  31.     /**
  32.      * Sets up event handlers to call the passed functions when the mouse is moved into and out of the Element.
  33.      * @param {Function} overFn The function to call when the mouse enters the Element.
  34.      * @param {Function} outFn The function to call when the mouse leaves the Element.
  35.      * @param {Object} scope (optional) The scope (<tt>this</tt> reference) in which the functions are executed. Defaults to the Element's DOM element.
  36.      * @param {Object} options (optional) Options for the listener. See {@link Ext.util.Observable#addListener the <tt>options</tt> parameter}.
  37.      * @return {Ext.Element} this
  38.      */
  39.     hover : function(overFn, outFn, scope, options){
  40.         var me = this;
  41.         me.on('mouseenter', overFn, scope || me.dom, options);
  42.         me.on('mouseleave', outFn, scope || me.dom, options);
  43.         return me;
  44.     },
  45.     /**
  46.      * Returns true if this element is an ancestor of the passed element
  47.      * @param {HTMLElement/String} el The element to check
  48.      * @return {Boolean} True if this element is an ancestor of el, else false
  49.      */
  50.     contains : function(el){
  51.         return !el ? false : Ext.lib.Dom.isAncestor(this.dom, el.dom ? el.dom : el);
  52.     },
  53.     /**
  54.      * Returns the value of a namespaced attribute from the element's underlying DOM node.
  55.      * @param {String} namespace The namespace in which to look for the attribute
  56.      * @param {String} name The attribute name
  57.      * @return {String} The attribute value
  58.      * @deprecated
  59.      */
  60.     getAttributeNS : function(ns, name){
  61.         return this.getAttribute(name, ns); 
  62.     },
  63.     
  64.     /**
  65.      * Returns the value of an attribute from the element's underlying DOM node.
  66.      * @param {String} name The attribute name
  67.      * @param {String} namespace (optional) The namespace in which to look for the attribute
  68.      * @return {String} The attribute value
  69.      */
  70.     getAttribute : Ext.isIE ? function(name, ns){
  71.         var d = this.dom,
  72.             type = typeof d[ns + ":" + name];
  73.         if(['undefined', 'unknown'].indexOf(type) == -1){
  74.             return d[ns + ":" + name];
  75.         }
  76.         return d[name];
  77.     } : function(name, ns){
  78.         var d = this.dom;
  79.         return d.getAttributeNS(ns, name) || d.getAttribute(ns + ":" + name) || d.getAttribute(name) || d[name];
  80.     },
  81.     
  82.     /**
  83.     * Update the innerHTML of this element
  84.     * @param {String} html The new HTML
  85.     * @return {Ext.Element} this
  86.      */
  87.     update : function(html) {
  88.         this.dom.innerHTML = html;
  89.         return this;
  90.     }
  91. };
  92. var ep = El.prototype;
  93. El.addMethods = function(o){
  94.    Ext.apply(ep, o);
  95. };
  96. /**
  97.  * Appends an event handler (shorthand for {@link #addListener}).
  98.  * @param {String} eventName The type of event to handle
  99.  * @param {Function} fn The handler function the event invokes
  100.  * @param {Object} scope (optional) The scope (this element) of the handler function
  101.  * @param {Object} options (optional) An object containing standard {@link #addListener} options
  102.  * @member Ext.Element
  103.  * @method on
  104.  */
  105. ep.on = ep.addListener;
  106. /**
  107.  * Removes an event handler from this element (see {@link #removeListener} for additional notes).
  108.  * @param {String} eventName the type of event to remove
  109.  * @param {Function} fn the method the event invokes
  110.  * @param {Object} scope (optional) The scope (The <tt>this</tt> reference) of the handler function. Defaults
  111.  * to this Element.
  112.  * @return {Ext.Element} this
  113.  * @member Ext.Element
  114.  * @method un
  115.  */
  116. ep.un = ep.removeListener;
  117. /**
  118.  * true to automatically adjust width and height settings for box-model issues (default to true)
  119.  */
  120. ep.autoBoxAdjust = true;
  121. // private
  122. var unitPattern = /d+(px|em|%|en|ex|pt|in|cm|mm|pc)$/i,
  123.     docEl;
  124. /**
  125.  * @private
  126.  */
  127. El.cache = {};
  128. El.dataCache = {};
  129. /**
  130.  * Retrieves Ext.Element objects.
  131.  * <p><b>This method does not retrieve {@link Ext.Component Component}s.</b> This method
  132.  * retrieves Ext.Element objects which encapsulate DOM elements. To retrieve a Component by
  133.  * its ID, use {@link Ext.ComponentMgr#get}.</p>
  134.  * <p>Uses simple caching to consistently return the same object. Automatically fixes if an
  135.  * object was recreated with the same id via AJAX or DOM.</p>
  136.  * @param {Mixed} el The id of the node, a DOM Node or an existing Element.
  137.  * @return {Element} The Element object (or null if no matching element was found)
  138.  * @static
  139.  * @member Ext.Element
  140.  * @method get
  141.  */
  142. El.get = function(el){
  143.     var ex,
  144.         elm,
  145.         id;
  146.     if(!el){ return null; }
  147.     if (typeof el == "string") { // element id
  148.         if (!(elm = DOC.getElementById(el))) {
  149.             return null;
  150.         }
  151.         if (ex = El.cache[el]) {
  152.             ex.dom = elm;
  153.         } else {
  154.             ex = El.cache[el] = new El(elm);
  155.         }
  156.         return ex;
  157.     } else if (el.tagName) { // dom element
  158.         if(!(id = el.id)){
  159.             id = Ext.id(el);
  160.         }
  161.         if(ex = El.cache[id]){
  162.             ex.dom = el;
  163.         }else{
  164.             ex = El.cache[id] = new El(el);
  165.         }
  166.         return ex;
  167.     } else if (el instanceof El) {
  168.         if(el != docEl){
  169.             el.dom = DOC.getElementById(el.id) || el.dom; // refresh dom element in case no longer valid,
  170.                                                           // catch case where it hasn't been appended
  171.             El.cache[el.id] = el; // in case it was created directly with Element(), let's cache it
  172.         }
  173.         return el;
  174.     } else if(el.isComposite) {
  175.         return el;
  176.     } else if(Ext.isArray(el)) {
  177.         return El.select(el);
  178.     } else if(el == DOC) {
  179.         // create a bogus element object representing the document object
  180.         if(!docEl){
  181.             var f = function(){};
  182.             f.prototype = El.prototype;
  183.             docEl = new f();
  184.             docEl.dom = DOC;
  185.         }
  186.         return docEl;
  187.     }
  188.     return null;
  189. };
  190. // private method for getting and setting element data
  191. El.data = function(el, key, value){
  192.     var c = El.dataCache[el.id];
  193.     if(!c){
  194.         c = El.dataCache[el.id] = {};
  195.     }
  196.     if(arguments.length == 2){
  197.         return c[key];    
  198.     }else{
  199.         c[key] = value;
  200.     }
  201. };
  202. // private
  203. // Garbage collection - uncache elements/purge listeners on orphaned elements
  204. // so we don't hold a reference and cause the browser to retain them
  205. function garbageCollect(){
  206.     if(!Ext.enableGarbageCollector){
  207.         clearInterval(El.collectorThread);
  208.     } else {
  209.         var eid,
  210.             el,
  211.             d;
  212.         for(eid in El.cache){
  213.             el = El.cache[eid];
  214.             d = el.dom;
  215.             // -------------------------------------------------------
  216.             // Determining what is garbage:
  217.             // -------------------------------------------------------
  218.             // !d
  219.             // dom node is null, definitely garbage
  220.             // -------------------------------------------------------
  221.             // !d.parentNode
  222.             // no parentNode == direct orphan, definitely garbage
  223.             // -------------------------------------------------------
  224.             // !d.offsetParent && !document.getElementById(eid)
  225.             // display none elements have no offsetParent so we will
  226.             // also try to look it up by it's id. However, check
  227.             // offsetParent first so we don't do unneeded lookups.
  228.             // This enables collection of elements that are not orphans
  229.             // directly, but somewhere up the line they have an orphan
  230.             // parent.
  231.             // -------------------------------------------------------
  232.             if(!d || !d.parentNode || (!d.offsetParent && !DOC.getElementById(eid))){
  233.                 delete El.cache[eid];
  234.                 if(d && Ext.enableListenerCollection){
  235.                     Ext.EventManager.removeAll(d);
  236.                 }
  237.             }
  238.         }
  239.     }
  240. }
  241. El.collectorThreadId = setInterval(garbageCollect, 30000);
  242. var flyFn = function(){};
  243. flyFn.prototype = El.prototype;
  244. // dom is optional
  245. El.Flyweight = function(dom){
  246.     this.dom = dom;
  247. };
  248. El.Flyweight.prototype = new flyFn();
  249. El.Flyweight.prototype.isFlyweight = true;
  250. El._flyweights = {};
  251. /**
  252.  * <p>Gets the globally shared flyweight Element, with the passed node as the active element. Do not store a reference to this element -
  253.  * the dom node can be overwritten by other code. Shorthand of {@link Ext.Element#fly}</p>
  254.  * <p>Use this to make one-time references to DOM elements which are not going to be accessed again either by
  255.  * application code, or by Ext's classes. If accessing an element which will be processed regularly, then {@link Ext#get}
  256.  * will be more appropriate to take advantage of the caching provided by the Ext.Element class.</p>
  257.  * @param {String/HTMLElement} el The dom node or id
  258.  * @param {String} named (optional) Allows for creation of named reusable flyweights to prevent conflicts
  259.  * (e.g. internally Ext uses "_global")
  260.  * @return {Element} The shared Element object (or null if no matching element was found)
  261.  * @member Ext.Element
  262.  * @method fly
  263.  */
  264. El.fly = function(el, named){
  265.     var ret = null;
  266.     named = named || '_global';
  267.     if (el = Ext.getDom(el)) {
  268.         (El._flyweights[named] = El._flyweights[named] || new El.Flyweight()).dom = el;
  269.         ret = El._flyweights[named];
  270.     }
  271.     return ret;
  272. };
  273. /**
  274.  * Retrieves Ext.Element objects.
  275.  * <p><b>This method does not retrieve {@link Ext.Component Component}s.</b> This method
  276.  * retrieves Ext.Element objects which encapsulate DOM elements. To retrieve a Component by
  277.  * its ID, use {@link Ext.ComponentMgr#get}.</p>
  278.  * <p>Uses simple caching to consistently return the same object. Automatically fixes if an
  279.  * object was recreated with the same id via AJAX or DOM.</p>
  280.  * Shorthand of {@link Ext.Element#get}
  281.  * @param {Mixed} el The id of the node, a DOM Node or an existing Element.
  282.  * @return {Element} The Element object (or null if no matching element was found)
  283.  * @member Ext
  284.  * @method get
  285.  */
  286. Ext.get = El.get;
  287. /**
  288.  * <p>Gets the globally shared flyweight Element, with the passed node as the active element. Do not store a reference to this element -
  289.  * the dom node can be overwritten by other code. Shorthand of {@link Ext.Element#fly}</p>
  290.  * <p>Use this to make one-time references to DOM elements which are not going to be accessed again either by
  291.  * application code, or by Ext's classes. If accessing an element which will be processed regularly, then {@link Ext#get}
  292.  * will be more appropriate to take advantage of the caching provided by the Ext.Element class.</p>
  293.  * @param {String/HTMLElement} el The dom node or id
  294.  * @param {String} named (optional) Allows for creation of named reusable flyweights to prevent conflicts
  295.  * (e.g. internally Ext uses "_global")
  296.  * @return {Element} The shared Element object (or null if no matching element was found)
  297.  * @member Ext
  298.  * @method fly
  299.  */
  300. Ext.fly = El.fly;
  301. // speedy lookup for elements never to box adjust
  302. var noBoxAdjust = Ext.isStrict ? {
  303.     select:1
  304. } : {
  305.     input:1, select:1, textarea:1
  306. };
  307. if(Ext.isIE || Ext.isGecko){
  308.     noBoxAdjust['button'] = 1;
  309. }
  310. Ext.EventManager.on(window, 'unload', function(){
  311.     delete El.cache;
  312.     delete El.dataCache;
  313.     delete El._flyweights;
  314. });
  315. })();
  316. /**
  317.  * @class Ext.Element
  318.  */
  319. Ext.Element.addMethods({    
  320.     /**
  321.      * Stops the specified event(s) from bubbling and optionally prevents the default action
  322.      * @param {String/Array} eventName an event / array of events to stop from bubbling
  323.      * @param {Boolean} preventDefault (optional) true to prevent the default action too
  324.      * @return {Ext.Element} this
  325.      */
  326.     swallowEvent : function(eventName, preventDefault){
  327.     var me = this;
  328.         function fn(e){
  329.             e.stopPropagation();
  330.             if(preventDefault){
  331.                 e.preventDefault();
  332.             }
  333.         }
  334.         if(Ext.isArray(eventName)){            
  335.         Ext.each(eventName, function(e) {
  336.                  me.on(e, fn);
  337.             });
  338.             return me;
  339.         }
  340.         me.on(eventName, fn);
  341.         return me;
  342.     },
  343.     
  344.     /**
  345.      * Create an event handler on this element such that when the event fires and is handled by this element,
  346.      * it will be relayed to another object (i.e., fired again as if it originated from that object instead).
  347.      * @param {String} eventName The type of event to relay
  348.      * @param {Object} object Any object that extends {@link Ext.util.Observable} that will provide the context
  349.      * for firing the relayed event
  350.      */
  351.     relayEvent : function(eventName, observable){
  352.         this.on(eventName, function(e){
  353.             observable.fireEvent(eventName, e);
  354.         });
  355.     },
  356.     
  357. /**
  358.      * Removes worthless text nodes
  359.      * @param {Boolean} forceReclean (optional) By default the element
  360.      * keeps track if it has been cleaned already so
  361.      * you can call this over and over. However, if you update the element and
  362.      * need to force a reclean, you can pass true.
  363.      */
  364.     clean : function(forceReclean){
  365.         var me = this, 
  366.             dom = me.dom,
  367.          n = dom.firstChild, 
  368.          ni = -1;
  369.         
  370.     if(Ext.Element.data(dom, 'isCleaned') && forceReclean !== true){
  371.             return me;
  372.         }      
  373.         
  374.       while(n){
  375.           var nx = n.nextSibling;
  376.             if(n.nodeType == 3 && !/S/.test(n.nodeValue)){
  377.                 dom.removeChild(n);
  378.             }else{
  379.                 n.nodeIndex = ++ni;
  380.             }
  381.           n = nx;
  382.       }
  383.         Ext.Element.data(dom, 'isCleaned', true);
  384.       return me;
  385.   },
  386.     
  387.     /**
  388.      * Direct access to the Updater {@link Ext.Updater#update} method. The method takes the same object
  389.      * parameter as {@link Ext.Updater#update}
  390.      * @return {Ext.Element} this
  391.      */
  392.     load : function(){
  393.         var um = this.getUpdater();
  394.         um.update.apply(um, arguments);
  395.         return this;
  396.     },
  397.     /**
  398.     * Gets this element's {@link Ext.Updater Updater}
  399.     * @return {Ext.Updater} The Updater
  400.     */
  401.     getUpdater : function(){
  402.         return this.updateManager || (this.updateManager = new Ext.Updater(this));
  403.     },
  404.     
  405. /**
  406.     * Update the innerHTML of this element, optionally searching for and processing scripts
  407.     * @param {String} html The new HTML
  408.     * @param {Boolean} loadScripts (optional) True to look for and process scripts (defaults to false)
  409.     * @param {Function} callback (optional) For async script loading you can be notified when the update completes
  410.     * @return {Ext.Element} this
  411.      */
  412.     update : function(html, loadScripts, callback){
  413.         html = html || "";
  414.     
  415.         if(loadScripts !== true){
  416.             this.dom.innerHTML = html;
  417.             if(Ext.isFunction(callback)){
  418.                 callback();
  419.             }
  420.             return this;
  421.         }
  422.         
  423.         var id = Ext.id(),
  424.          dom = this.dom;
  425.         html += '<span id="' + id + '"></span>';
  426.         Ext.lib.Event.onAvailable(id, function(){
  427.             var DOC = document,
  428.                 hd = DOC.getElementsByTagName("head")[0],
  429.              re = /(?:<script([^>]*)?>)((n|r|.)*?)(?:</script>)/ig,
  430.              srcRe = /ssrc=(['"])(.*?)1/i,
  431.              typeRe = /stype=(['"])(.*?)1/i,
  432.              match,
  433.              attrs,
  434.              srcMatch,
  435.              typeMatch,
  436.              el,
  437.              s;
  438.             while((match = re.exec(html))){
  439.                 attrs = match[1];
  440.                 srcMatch = attrs ? attrs.match(srcRe) : false;
  441.                 if(srcMatch && srcMatch[2]){
  442.                    s = DOC.createElement("script");
  443.                    s.src = srcMatch[2];
  444.                    typeMatch = attrs.match(typeRe);
  445.                    if(typeMatch && typeMatch[2]){
  446.                        s.type = typeMatch[2];
  447.                    }
  448.                    hd.appendChild(s);
  449.                 }else if(match[2] && match[2].length > 0){
  450.                     if(window.execScript) {
  451.                        window.execScript(match[2]);
  452.                     } else {
  453.                        window.eval(match[2]);
  454.                     }
  455.                 }
  456.             }
  457.             el = DOC.getElementById(id);
  458.             if(el){Ext.removeNode(el);}
  459.             if(Ext.isFunction(callback)){
  460.                 callback();
  461.             }
  462.         });
  463.         dom.innerHTML = html.replace(/(?:<script.*?>)((n|r|.)*?)(?:</script>)/ig, "");
  464.         return this;
  465.     },
  466.     
  467.     /**
  468.      * Creates a proxy element of this element
  469.      * @param {String/Object} config The class name of the proxy element or a DomHelper config object
  470.      * @param {String/HTMLElement} renderTo (optional) The element or element id to render the proxy to (defaults to document.body)
  471.      * @param {Boolean} matchBox (optional) True to align and size the proxy to this element now (defaults to false)
  472.      * @return {Ext.Element} The new proxy element
  473.      */
  474.     createProxy : function(config, renderTo, matchBox){
  475.         config = Ext.isObject(config) ? config : {tag : "div", cls: config};
  476.         var me = this,
  477.          proxy = renderTo ? Ext.DomHelper.append(renderTo, config, true) :
  478.             Ext.DomHelper.insertBefore(me.dom, config, true);        
  479.         
  480.         if(matchBox && me.setBox && me.getBox){ // check to make sure Element.position.js is loaded
  481.            proxy.setBox(me.getBox());
  482.         }
  483.         return proxy;
  484.     }
  485. });
  486. Ext.Element.prototype.getUpdateManager = Ext.Element.prototype.getUpdater;
  487. // private
  488. Ext.Element.uncache = function(el){
  489.     for(var i = 0, a = arguments, len = a.length; i < len; i++) {
  490.         if(a[i]){
  491.             delete Ext.Element.cache[a[i].id || a[i]];
  492.         }
  493.     }
  494. };/**
  495.  * @class Ext.Element
  496.  */
  497. Ext.Element.addMethods({
  498.     /**
  499.      * Gets the x,y coordinates specified by the anchor position on the element.
  500.      * @param {String} anchor (optional) The specified anchor position (defaults to "c").  See {@link #alignTo}
  501.      * for details on supported anchor positions.
  502.      * @param {Boolean} local (optional) True to get the local (element top/left-relative) anchor position instead
  503.      * of page coordinates
  504.      * @param {Object} size (optional) An object containing the size to use for calculating anchor position
  505.      * {width: (target width), height: (target height)} (defaults to the element's current size)
  506.      * @return {Array} [x, y] An array containing the element's x and y coordinates
  507.      */
  508.     getAnchorXY : function(anchor, local, s){
  509.         //Passing a different size is useful for pre-calculating anchors,
  510.         //especially for anchored animations that change the el size.
  511. anchor = (anchor || "tl").toLowerCase();
  512.         s = s || {};
  513.         
  514.         var me = this,        
  515.          vp = me.dom == document.body || me.dom == document,
  516.          w = s.width || vp ? Ext.lib.Dom.getViewWidth() : me.getWidth(),
  517.          h = s.height || vp ? Ext.lib.Dom.getViewHeight() : me.getHeight(),                  
  518.          xy,       
  519.          r = Math.round,
  520.          o = me.getXY(),
  521.          scroll = me.getScroll(),
  522.          extraX = vp ? scroll.left : !local ? o[0] : 0,
  523.          extraY = vp ? scroll.top : !local ? o[1] : 0,
  524.          hash = {
  525.          c  : [r(w * 0.5), r(h * 0.5)],
  526.          t  : [r(w * 0.5), 0],
  527.          l  : [0, r(h * 0.5)],
  528.          r  : [w, r(h * 0.5)],
  529.          b  : [r(w * 0.5), h],
  530.          tl : [0, 0],
  531.          bl : [0, h],
  532.          br : [w, h],
  533.          tr : [w, 0]
  534.          };
  535.         
  536.         xy = hash[anchor];
  537.         return [xy[0] + extraX, xy[1] + extraY]; 
  538.     },
  539.     /**
  540.      * Anchors an element to another element and realigns it when the window is resized.
  541.      * @param {Mixed} element The element to align to.
  542.      * @param {String} position The position to align to.
  543.      * @param {Array} offsets (optional) Offset the positioning by [x, y]
  544.      * @param {Boolean/Object} animate (optional) True for the default animation or a standard Element animation config object
  545.      * @param {Boolean/Number} monitorScroll (optional) True to monitor body scroll and reposition. If this parameter
  546.      * is a number, it is used as the buffer delay (defaults to 50ms).
  547.      * @param {Function} callback The function to call after the animation finishes
  548.      * @return {Ext.Element} this
  549.      */
  550.     anchorTo : function(el, alignment, offsets, animate, monitorScroll, callback){        
  551.     var me = this,
  552.             dom = me.dom;
  553.     
  554.     function action(){
  555.             Ext.fly(dom).alignTo(el, alignment, offsets, animate);
  556.             Ext.callback(callback, Ext.fly(dom));
  557.         }
  558.         
  559.         Ext.EventManager.onWindowResize(action, me);
  560.         
  561.         if(!Ext.isEmpty(monitorScroll)){
  562.             Ext.EventManager.on(window, 'scroll', action, me,
  563.                 {buffer: !isNaN(monitorScroll) ? monitorScroll : 50});
  564.         }
  565.         action.call(me); // align immediately
  566.         return me;
  567.     },
  568.     /**
  569.      * Gets the x,y coordinates to align this element with another element. See {@link #alignTo} for more info on the
  570.      * supported position values.
  571.      * @param {Mixed} element The element to align to.
  572.      * @param {String} position The position to align to.
  573.      * @param {Array} offsets (optional) Offset the positioning by [x, y]
  574.      * @return {Array} [x, y]
  575.      */
  576.     getAlignToXY : function(el, p, o){     
  577.         el = Ext.get(el);
  578.         
  579.         if(!el || !el.dom){
  580.             throw "Element.alignToXY with an element that doesn't exist";
  581.         }
  582.         
  583.         o = o || [0,0];
  584.         p = (p == "?" ? "tl-bl?" : (!/-/.test(p) && p !== "" ? "tl-" + p : p || "tl-bl")).toLowerCase();       
  585.                 
  586.         var me = this,
  587.          d = me.dom,
  588.          a1,
  589.          a2,
  590.          x,
  591.          y,
  592.          //constrain the aligned el to viewport if necessary
  593.          w,
  594.          h,
  595.          r,
  596.          dw = Ext.lib.Dom.getViewWidth() -10, // 10px of margin for ie
  597.          dh = Ext.lib.Dom.getViewHeight()-10, // 10px of margin for ie
  598.          p1y,
  599.          p1x,        
  600.          p2y,
  601.          p2x,
  602.          swapY,
  603.          swapX,
  604.          doc = document,
  605.          docElement = doc.documentElement,
  606.          docBody = doc.body,
  607.          scrollX = (docElement.scrollLeft || docBody.scrollLeft || 0)+5,
  608.          scrollY = (docElement.scrollTop || docBody.scrollTop || 0)+5,
  609.          c = false, //constrain to viewport
  610.          p1 = "", 
  611.          p2 = "",
  612.          m = p.match(/^([a-z]+)-([a-z]+)(?)?$/);
  613.         
  614.         if(!m){
  615.            throw "Element.alignTo with an invalid alignment " + p;
  616.         }
  617.         
  618.         p1 = m[1]; 
  619.         p2 = m[2]; 
  620.         c = !!m[3];
  621.         //Subtract the aligned el's internal xy from the target's offset xy
  622.         //plus custom offset to get the aligned el's new offset xy
  623.         a1 = me.getAnchorXY(p1, true);
  624.         a2 = el.getAnchorXY(p2, false);
  625.         x = a2[0] - a1[0] + o[0];
  626.         y = a2[1] - a1[1] + o[1];
  627.         if(c){    
  628.        w = me.getWidth();
  629.            h = me.getHeight();
  630.            r = el.getRegion();       
  631.            //If we are at a viewport boundary and the aligned el is anchored on a target border that is
  632.            //perpendicular to the vp border, allow the aligned el to slide on that border,
  633.            //otherwise swap the aligned el to the opposite border of the target.
  634.            p1y = p1.charAt(0);
  635.            p1x = p1.charAt(p1.length-1);
  636.            p2y = p2.charAt(0);
  637.            p2x = p2.charAt(p2.length-1);
  638.            swapY = ((p1y=="t" && p2y=="b") || (p1y=="b" && p2y=="t"));
  639.            swapX = ((p1x=="r" && p2x=="l") || (p1x=="l" && p2x=="r"));          
  640.            
  641.            if (x + w > dw + scrollX) {
  642.                 x = swapX ? r.left-w : dw+scrollX-w;
  643.            }
  644.            if (x < scrollX) {
  645.                x = swapX ? r.right : scrollX;
  646.            }
  647.            if (y + h > dh + scrollY) {
  648.                 y = swapY ? r.top-h : dh+scrollY-h;
  649.             }
  650.            if (y < scrollY){
  651.                y = swapY ? r.bottom : scrollY;
  652.            }
  653.         }
  654.         return [x,y];
  655.     },
  656.     /**
  657.      * Aligns this element with another element relative to the specified anchor points. If the other element is the
  658.      * document it aligns it to the viewport.
  659.      * The position parameter is optional, and can be specified in any one of the following formats:
  660.      * <ul>
  661.      *   <li><b>Blank</b>: Defaults to aligning the element's top-left corner to the target's bottom-left corner ("tl-bl").</li>
  662.      *   <li><b>One anchor (deprecated)</b>: The passed anchor position is used as the target element's anchor point.
  663.      *       The element being aligned will position its top-left corner (tl) to that point.  <i>This method has been
  664.      *       deprecated in favor of the newer two anchor syntax below</i>.</li>
  665.      *   <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
  666.      *       element's anchor point, and the second value is used as the target's anchor point.</li>
  667.      * </ul>
  668.      * In addition to the anchor points, the position parameter also supports the "?" character.  If "?" is passed at the end of
  669.      * the position string, the element will attempt to align as specified, but the position will be adjusted to constrain to
  670.      * the viewport if necessary.  Note that the element being aligned might be swapped to align to a different position than
  671.      * that specified in order to enforce the viewport constraints.
  672.      * Following are all of the supported anchor positions:
  673. <pre>
  674. Value  Description
  675. -----  -----------------------------
  676. tl     The top left corner (default)
  677. t      The center of the top edge
  678. tr     The top right corner
  679. l      The center of the left edge
  680. c      In the center of the element
  681. r      The center of the right edge
  682. bl     The bottom left corner
  683. b      The center of the bottom edge
  684. br     The bottom right corner
  685. </pre>
  686. Example Usage:
  687. <pre><code>
  688. // align el to other-el using the default positioning ("tl-bl", non-constrained)
  689. el.alignTo("other-el");
  690. // align the top left corner of el with the top right corner of other-el (constrained to viewport)
  691. el.alignTo("other-el", "tr?");
  692. // align the bottom right corner of el with the center left edge of other-el
  693. el.alignTo("other-el", "br-l?");
  694. // align the center of el with the bottom left corner of other-el and
  695. // adjust the x position by -6 pixels (and the y position by 0)
  696. el.alignTo("other-el", "c-bl", [-6, 0]);
  697. </code></pre>
  698.      * @param {Mixed} element The element to align to.
  699.      * @param {String} position The position to align to.
  700.      * @param {Array} offsets (optional) Offset the positioning by [x, y]
  701.      * @param {Boolean/Object} animate (optional) true for the default animation or a standard Element animation config object
  702.      * @return {Ext.Element} this
  703.      */
  704.     alignTo : function(element, position, offsets, animate){
  705.     var me = this;
  706.         return me.setXY(me.getAlignToXY(element, position, offsets),
  707.                    me.preanim && !!animate ? me.preanim(arguments, 3) : false);
  708.     },
  709.     
  710.     // private ==>  used outside of core
  711.     adjustForConstraints : function(xy, parent, offsets){
  712.         return this.getConstrainToXY(parent || document, false, offsets, xy) ||  xy;
  713.     },
  714.     // private ==>  used outside of core
  715.     getConstrainToXY : function(el, local, offsets, proposedXY){   
  716.     var os = {top:0, left:0, bottom:0, right: 0};
  717.         return function(el, local, offsets, proposedXY){
  718.             el = Ext.get(el);
  719.             offsets = offsets ? Ext.applyIf(offsets, os) : os;
  720.             var vw, vh, vx = 0, vy = 0;
  721.             if(el.dom == document.body || el.dom == document){
  722.                 vw =Ext.lib.Dom.getViewWidth();
  723.                 vh = Ext.lib.Dom.getViewHeight();
  724.             }else{
  725.                 vw = el.dom.clientWidth;
  726.                 vh = el.dom.clientHeight;
  727.                 if(!local){
  728.                     var vxy = el.getXY();
  729.                     vx = vxy[0];
  730.                     vy = vxy[1];
  731.                 }
  732.             }
  733.             var s = el.getScroll();
  734.             vx += offsets.left + s.left;
  735.             vy += offsets.top + s.top;
  736.             vw -= offsets.right;
  737.             vh -= offsets.bottom;
  738.             var vr = vx+vw;
  739.             var vb = vy+vh;
  740.             var xy = proposedXY || (!local ? this.getXY() : [this.getLeft(true), this.getTop(true)]);
  741.             var x = xy[0], y = xy[1];
  742.             var w = this.dom.offsetWidth, h = this.dom.offsetHeight;
  743.             // only move it if it needs it
  744.             var moved = false;
  745.             // first validate right/bottom
  746.             if((x + w) > vr){
  747.                 x = vr - w;
  748.                 moved = true;
  749.             }
  750.             if((y + h) > vb){
  751.                 y = vb - h;
  752.                 moved = true;
  753.             }
  754.             // then make sure top/left isn't negative
  755.             if(x < vx){
  756.                 x = vx;
  757.                 moved = true;
  758.             }
  759.             if(y < vy){
  760.                 y = vy;
  761.                 moved = true;
  762.             }
  763.             return moved ? [x, y] : false;
  764.         };
  765.     }(),
  766.     
  767.     
  768.         
  769. //         el = Ext.get(el);
  770. //         offsets = Ext.applyIf(offsets || {}, {top : 0, left : 0, bottom : 0, right : 0});
  771. //         var me = this,
  772. //          doc = document,
  773. //          s = el.getScroll(),
  774. //          vxy = el.getXY(),
  775. //          vx = offsets.left + s.left, 
  776. //          vy = offsets.top + s.top,            
  777. //          vw = -offsets.right, 
  778. //          vh = -offsets.bottom, 
  779. //          vr,
  780. //          vb,
  781. //          xy = proposedXY || (!local ? me.getXY() : [me.getLeft(true), me.getTop(true)]),
  782. //          x = xy[0],
  783. //          y = xy[1],
  784. //          w = me.dom.offsetWidth, h = me.dom.offsetHeight,
  785. //          moved = false; // only move it if it needs it
  786. //       
  787. //         
  788. //         if(el.dom == doc.body || el.dom == doc){
  789. //             vw += Ext.lib.Dom.getViewWidth();
  790. //             vh += Ext.lib.Dom.getViewHeight();
  791. //         }else{
  792. //             vw += el.dom.clientWidth;
  793. //             vh += el.dom.clientHeight;
  794. //             if(!local){                    
  795. //                 vx += vxy[0];
  796. //                 vy += vxy[1];
  797. //             }
  798. //         }
  799. //         // first validate right/bottom
  800. //         if(x + w > vx + vw){
  801. //             x = vx + vw - w;
  802. //             moved = true;
  803. //         }
  804. //         if(y + h > vy + vh){
  805. //             y = vy + vh - h;
  806. //             moved = true;
  807. //         }
  808. //         // then make sure top/left isn't negative
  809. //         if(x < vx){
  810. //             x = vx;
  811. //             moved = true;
  812. //         }
  813. //         if(y < vy){
  814. //             y = vy;
  815. //             moved = true;
  816. //         }
  817. //         return moved ? [x, y] : false;
  818. //    },
  819.     
  820.     /**
  821.     * Calculates the x, y to center this element on the screen
  822.     * @return {Array} The x, y values [x, y]
  823.     */
  824.     getCenterXY : function(){
  825.         return this.getAlignToXY(document, 'c-c');
  826.     },
  827.     /**
  828.     * Centers the Element in either the viewport, or another Element.
  829.     * @param {Mixed} centerIn (optional) The element in which to center the element.
  830.     */
  831.     center : function(centerIn){
  832.         return this.alignTo(centerIn || document, 'c-c');        
  833.     }    
  834. });
  835. /**
  836.  * @class Ext.Element
  837.  */
  838. Ext.Element.addMethods(function(){
  839. var PARENTNODE = 'parentNode',
  840. NEXTSIBLING = 'nextSibling',
  841. PREVIOUSSIBLING = 'previousSibling',
  842. DQ = Ext.DomQuery,
  843. GET = Ext.get;
  844. return {
  845. /**
  846.      * 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)
  847.      * @param {String} selector The simple selector to test
  848.      * @param {Number/Mixed} maxDepth (optional) The max depth to search as a number or element (defaults to 50 || document.body)
  849.      * @param {Boolean} returnEl (optional) True to return a Ext.Element object instead of DOM node
  850.      * @return {HTMLElement} The matching DOM node (or null if no match was found)
  851.      */
  852.     findParent : function(simpleSelector, maxDepth, returnEl){
  853.         var p = this.dom,
  854.          b = document.body, 
  855.          depth = 0,          
  856.          stopEl;         
  857.             if(Ext.isGecko && Object.prototype.toString.call(p) == '[object XULElement]') {
  858.                 return null;
  859.             }
  860.         maxDepth = maxDepth || 50;
  861.         if (isNaN(maxDepth)) {
  862.             stopEl = Ext.getDom(maxDepth);
  863.             maxDepth = Number.MAX_VALUE;
  864.         }
  865.         while(p && p.nodeType == 1 && depth < maxDepth && p != b && p != stopEl){
  866.             if(DQ.is(p, simpleSelector)){
  867.                 return returnEl ? GET(p) : p;
  868.             }
  869.             depth++;
  870.             p = p.parentNode;
  871.         }
  872.         return null;
  873.     },
  874.     /**
  875.      * Looks at parent nodes for a match of the passed simple selector (e.g. div.some-class or span:first-child)
  876.      * @param {String} selector The simple selector to test
  877.      * @param {Number/Mixed} maxDepth (optional) The max depth to
  878.             search as a number or element (defaults to 10 || document.body)
  879.      * @param {Boolean} returnEl (optional) True to return a Ext.Element object instead of DOM node
  880.      * @return {HTMLElement} The matching DOM node (or null if no match was found)
  881.      */
  882.     findParentNode : function(simpleSelector, maxDepth, returnEl){
  883.         var p = Ext.fly(this.dom.parentNode, '_internal');
  884.         return p ? p.findParent(simpleSelector, maxDepth, returnEl) : null;
  885.     },
  886.     /**
  887.      * Walks up the dom looking for a parent node that matches the passed simple selector (e.g. div.some-class or span:first-child).
  888.      * This is a shortcut for findParentNode() that always returns an Ext.Element.
  889.      * @param {String} selector The simple selector to test
  890.      * @param {Number/Mixed} maxDepth (optional) The max depth to
  891.             search as a number or element (defaults to 10 || document.body)
  892.      * @return {Ext.Element} The matching DOM node (or null if no match was found)
  893.      */
  894.     up : function(simpleSelector, maxDepth){
  895.         return this.findParentNode(simpleSelector, maxDepth, true);
  896.     },
  897.     /**
  898.      * Creates a {@link Ext.CompositeElement} for child nodes based on the passed CSS selector (the selector should not contain an id).
  899.      * @param {String} selector The CSS selector
  900.      * @param {Boolean} unique (optional) True to create a unique Ext.Element for each child (defaults to false, which creates a single shared flyweight object)
  901.      * @return {CompositeElement/CompositeElementLite} The composite element
  902.      */
  903.     select : function(selector, unique){
  904.         return Ext.Element.select(selector, unique, this.dom);
  905.     },
  906.     /**
  907.      * Selects child nodes based on the passed CSS selector (the selector should not contain an id).
  908.      * @param {String} selector The CSS selector
  909.      * @return {Array} An array of the matched nodes
  910.      */
  911.     query : function(selector, unique){
  912.         return DQ.select(selector, this.dom);
  913.     },
  914.     /**
  915.      * Selects a single child at any depth below this element based on the passed CSS selector (the selector should not contain an id).
  916.      * @param {String} selector The CSS selector
  917.      * @param {Boolean} returnDom (optional) True to return the DOM node instead of Ext.Element (defaults to false)
  918.      * @return {HTMLElement/Ext.Element} The child Ext.Element (or DOM node if returnDom = true)
  919.      */
  920.     child : function(selector, returnDom){
  921.         var n = DQ.selectNode(selector, this.dom);
  922.         return returnDom ? n : GET(n);
  923.     },
  924.     /**
  925.      * Selects a single *direct* child based on the passed CSS selector (the selector should not contain an id).
  926.      * @param {String} selector The CSS selector
  927.      * @param {Boolean} returnDom (optional) True to return the DOM node instead of Ext.Element (defaults to false)
  928.      * @return {HTMLElement/Ext.Element} The child Ext.Element (or DOM node if returnDom = true)
  929.      */
  930.     down : function(selector, returnDom){
  931.         var n = DQ.selectNode(" > " + selector, this.dom);
  932.         return returnDom ? n : GET(n);
  933.     },
  934.  /**
  935.      * Gets the parent node for this element, optionally chaining up trying to match a selector
  936.      * @param {String} selector (optional) Find a parent node that matches the passed simple selector
  937.      * @param {Boolean} returnDom (optional) True to return a raw dom node instead of an Ext.Element
  938.      * @return {Ext.Element/HTMLElement} The parent node or null
  939.  */
  940.     parent : function(selector, returnDom){
  941.         return this.matchNode(PARENTNODE, PARENTNODE, selector, returnDom);
  942.     },
  943.      /**
  944.      * Gets the next sibling, skipping text nodes
  945.      * @param {String} selector (optional) Find the next sibling that matches the passed simple selector
  946.      * @param {Boolean} returnDom (optional) True to return a raw dom node instead of an Ext.Element
  947.      * @return {Ext.Element/HTMLElement} The next sibling or null
  948.  */
  949.     next : function(selector, returnDom){
  950.         return this.matchNode(NEXTSIBLING, NEXTSIBLING, selector, returnDom);
  951.     },
  952.     /**
  953.      * Gets the previous sibling, skipping text nodes
  954.      * @param {String} selector (optional) Find the previous sibling that matches the passed simple selector
  955.      * @param {Boolean} returnDom (optional) True to return a raw dom node instead of an Ext.Element
  956.      * @return {Ext.Element/HTMLElement} The previous sibling or null
  957.  */
  958.     prev : function(selector, returnDom){
  959.         return this.matchNode(PREVIOUSSIBLING, PREVIOUSSIBLING, selector, returnDom);
  960.     },
  961.     /**
  962.      * Gets the first child, skipping text nodes
  963.      * @param {String} selector (optional) Find the next sibling that matches the passed simple selector
  964.      * @param {Boolean} returnDom (optional) True to return a raw dom node instead of an Ext.Element
  965.      * @return {Ext.Element/HTMLElement} The first child or null
  966.  */
  967.     first : function(selector, returnDom){
  968.         return this.matchNode(NEXTSIBLING, 'firstChild', selector, returnDom);
  969.     },
  970.     /**
  971.      * Gets the last child, skipping text nodes
  972.      * @param {String} selector (optional) Find the previous sibling that matches the passed simple selector
  973.      * @param {Boolean} returnDom (optional) True to return a raw dom node instead of an Ext.Element
  974.      * @return {Ext.Element/HTMLElement} The last child or null
  975.  */
  976.     last : function(selector, returnDom){
  977.         return this.matchNode(PREVIOUSSIBLING, 'lastChild', selector, returnDom);
  978.     },
  979.     
  980.     matchNode : function(dir, start, selector, returnDom){
  981.         var n = this.dom[start];
  982.         while(n){
  983.             if(n.nodeType == 1 && (!selector || DQ.is(n, selector))){
  984.                 return !returnDom ? GET(n) : n;
  985.             }
  986.             n = n[dir];
  987.         }
  988.         return null;
  989.     }
  990.     }
  991. }());/**
  992.  * @class Ext.Element
  993.  */
  994. Ext.Element.addMethods(
  995. function() {
  996. var GETDOM = Ext.getDom,
  997. GET = Ext.get,
  998. DH = Ext.DomHelper,
  999.         isEl = function(el){
  1000.             return  (el.nodeType || el.dom || typeof el == 'string');  
  1001.         };
  1002. return {
  1003.     /**
  1004.      * Appends the passed element(s) to this element
  1005.      * @param {String/HTMLElement/Array/Element/CompositeElement} el
  1006.      * @return {Ext.Element} this
  1007.      */
  1008.     appendChild: function(el){        
  1009.         return GET(el).appendTo(this);        
  1010.     },
  1011.     /**
  1012.      * Appends this element to the passed element
  1013.      * @param {Mixed} el The new parent element
  1014.      * @return {Ext.Element} this
  1015.      */
  1016.     appendTo: function(el){        
  1017.         GETDOM(el).appendChild(this.dom);        
  1018.         return this;
  1019.     },
  1020.     /**
  1021.      * Inserts this element before the passed element in the DOM
  1022.      * @param {Mixed} el The element before which this element will be inserted
  1023.      * @return {Ext.Element} this
  1024.      */
  1025.     insertBefore: function(el){             
  1026.         (el = GETDOM(el)).parentNode.insertBefore(this.dom, el);
  1027.         return this;
  1028.     },
  1029.     /**
  1030.      * Inserts this element after the passed element in the DOM
  1031.      * @param {Mixed} el The element to insert after
  1032.      * @return {Ext.Element} this
  1033.      */
  1034.     insertAfter: function(el){
  1035.         (el = GETDOM(el)).parentNode.insertBefore(this.dom, el.nextSibling);
  1036.         return this;
  1037.     },
  1038.     /**
  1039.      * Inserts (or creates) an element (or DomHelper config) as the first child of this element
  1040.      * @param {Mixed/Object} el The id or element to insert or a DomHelper config to create and insert
  1041.      * @return {Ext.Element} The new child
  1042.      */
  1043.     insertFirst: function(el, returnDom){
  1044.             el = el || {};
  1045.             if(isEl(el)){ // element
  1046.                 el = GETDOM(el);
  1047.                 this.dom.insertBefore(el, this.dom.firstChild);
  1048.                 return !returnDom ? GET(el) : el;
  1049.             }else{ // dh config
  1050.                 return this.createChild(el, this.dom.firstChild, returnDom);
  1051.             }
  1052.     },
  1053.     /**
  1054.      * Replaces the passed element with this element
  1055.      * @param {Mixed} el The element to replace
  1056.      * @return {Ext.Element} this
  1057.      */
  1058.     replace: function(el){
  1059.         el = GET(el);
  1060.         this.insertBefore(el);
  1061.         el.remove();
  1062.         return this;
  1063.     },
  1064.     /**
  1065.      * Replaces this element with the passed element
  1066.      * @param {Mixed/Object} el The new element or a DomHelper config of an element to create
  1067.      * @return {Ext.Element} this
  1068.      */
  1069.     replaceWith: function(el){
  1070.     var me = this,
  1071.      Element = Ext.Element;
  1072.             if(isEl(el)){
  1073.                 el = GETDOM(el);
  1074.                 me.dom.parentNode.insertBefore(el, me.dom);
  1075.             }else{
  1076.                 el = DH.insertBefore(me.dom, el);
  1077.             }
  1078.         
  1079.         delete Element.cache[me.id];
  1080.         Ext.removeNode(me.dom);      
  1081.         me.id = Ext.id(me.dom = el);
  1082.         return Element.cache[me.id] = me;        
  1083.     },
  1084.     
  1085. /**
  1086.  * Creates the passed DomHelper config and appends it to this element or optionally inserts it before the passed child element.
  1087.  * @param {Object} config DomHelper element config object.  If no tag is specified (e.g., {tag:'input'}) then a div will be
  1088.  * automatically generated with the specified attributes.
  1089.  * @param {HTMLElement} insertBefore (optional) a child element of this element
  1090.  * @param {Boolean} returnDom (optional) true to return the dom node instead of creating an Element
  1091.  * @return {Ext.Element} The new child element
  1092.  */
  1093. createChild: function(config, insertBefore, returnDom){
  1094.     config = config || {tag:'div'};
  1095.     return insertBefore ? 
  1096.         DH.insertBefore(insertBefore, config, returnDom !== true) :
  1097.         DH[!this.dom.firstChild ? 'overwrite' : 'append'](this.dom, config,  returnDom !== true);
  1098. },
  1099. /**
  1100.  * Creates and wraps this element with another element
  1101.  * @param {Object} config (optional) DomHelper element config object for the wrapper element or null for an empty div
  1102.  * @param {Boolean} returnDom (optional) True to return the raw DOM element instead of Ext.Element
  1103.  * @return {HTMLElement/Element} The newly created wrapper element
  1104.  */
  1105. wrap: function(config, returnDom){        
  1106.     var newEl = DH.insertBefore(this.dom, config || {tag: "div"}, !returnDom);
  1107.     newEl.dom ? newEl.dom.appendChild(this.dom) : newEl.appendChild(this.dom);
  1108.     return newEl;
  1109. },
  1110. /**
  1111.  * Inserts an html fragment into this element
  1112.  * @param {String} where Where to insert the html in relation to this element - beforeBegin, afterBegin, beforeEnd, afterEnd.
  1113.  * @param {String} html The HTML fragment
  1114.  * @param {Boolean} returnEl (optional) True to return an Ext.Element (defaults to false)
  1115.  * @return {HTMLElement/Ext.Element} The inserted node (or nearest related if more than 1 inserted)
  1116.  */
  1117. insertHtml : function(where, html, returnEl){
  1118.     var el = DH.insertHtml(where, this.dom, html);
  1119.     return returnEl ? Ext.get(el) : el;
  1120. }
  1121. }
  1122. }());/**
  1123.  * @class Ext.Element
  1124.  */
  1125. Ext.apply(Ext.Element.prototype, function() {
  1126. var GETDOM = Ext.getDom,
  1127. GET = Ext.get,
  1128. DH = Ext.DomHelper;
  1129. return {
  1130. /**
  1131.      * Inserts (or creates) the passed element (or DomHelper config) as a sibling of this element
  1132.      * @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.
  1133.      * @param {String} where (optional) 'before' or 'after' defaults to before
  1134.      * @param {Boolean} returnDom (optional) True to return the raw DOM element instead of Ext.Element
  1135.      * @return {Ext.Element} the inserted Element
  1136.      */
  1137.     insertSibling: function(el, where, returnDom){
  1138.         var me = this,
  1139.          rt;
  1140.         
  1141.         if(Ext.isArray(el)){            
  1142.             Ext.each(el, function(e) {
  1143.             rt = me.insertSibling(e, where, returnDom);
  1144.             });
  1145.             return rt;
  1146.         }
  1147.                 
  1148.         where = (where || 'before').toLowerCase();
  1149.         el = el || {};
  1150.        
  1151.             if(el.nodeType || el.dom){
  1152.                 rt = me.dom.parentNode.insertBefore(GETDOM(el), where == 'before' ? me.dom : me.dom.nextSibling);
  1153.                 if (!returnDom) {
  1154.                     rt = GET(rt);
  1155.                 }
  1156.             }else{
  1157.                 if (where == 'after' && !me.dom.nextSibling) {
  1158.                     rt = DH.append(me.dom.parentNode, el, !returnDom);
  1159.                 } else {                    
  1160.                     rt = DH[where == 'after' ? 'insertAfter' : 'insertBefore'](me.dom, el, !returnDom);
  1161.                 }
  1162.             }
  1163.         return rt;
  1164.     }
  1165.     };
  1166. }());/**
  1167.  * @class Ext.Element
  1168.  */
  1169. Ext.Element.addMethods(function(){  
  1170.     // local style camelizing for speed
  1171.     var propCache = {},
  1172.         camelRe = /(-[a-z])/gi,
  1173.         classReCache = {},
  1174.         view = document.defaultView,
  1175.         propFloat = Ext.isIE ? 'styleFloat' : 'cssFloat',
  1176.         opacityRe = /alpha(opacity=(.*))/i,
  1177.         trimRe = /^s+|s+$/g,
  1178.         EL = Ext.Element,   
  1179.         PADDING = "padding",
  1180.         MARGIN = "margin",
  1181.         BORDER = "border",
  1182.         LEFT = "-left",
  1183.         RIGHT = "-right",
  1184.         TOP = "-top",
  1185.         BOTTOM = "-bottom",
  1186.         WIDTH = "-width",    
  1187.         MATH = Math,
  1188.         HIDDEN = 'hidden',
  1189.         ISCLIPPED = 'isClipped',
  1190.         OVERFLOW = 'overflow',
  1191.         OVERFLOWX = 'overflow-x',
  1192.         OVERFLOWY = 'overflow-y',
  1193.         ORIGINALCLIP = 'originalClip',
  1194.         // special markup used throughout Ext when box wrapping elements    
  1195.         borders = {l: BORDER + LEFT + WIDTH, r: BORDER + RIGHT + WIDTH, t: BORDER + TOP + WIDTH, b: BORDER + BOTTOM + WIDTH},
  1196.         paddings = {l: PADDING + LEFT, r: PADDING + RIGHT, t: PADDING + TOP, b: PADDING + BOTTOM},
  1197.         margins = {l: MARGIN + LEFT, r: MARGIN + RIGHT, t: MARGIN + TOP, b: MARGIN + BOTTOM},
  1198.         data = Ext.Element.data;
  1199.         
  1200.     
  1201.     // private  
  1202.     function camelFn(m, a) {
  1203.         return a.charAt(1).toUpperCase();
  1204.     }
  1205.     
  1206.     // private (needs to be called => addStyles.call(this, sides, styles))
  1207.     function addStyles(sides, styles){
  1208.         var val = 0;    
  1209.         
  1210.         Ext.each(sides.match(/w/g), function(s) {
  1211.             if (s = parseInt(this.getStyle(styles[s]), 10)) {
  1212.                 val += MATH.abs(s);      
  1213.             }
  1214.         },
  1215.         this);
  1216.         return val;
  1217.     }
  1218.     function chkCache(prop) {
  1219.         return propCache[prop] || (propCache[prop] = prop == 'float' ? propFloat : prop.replace(camelRe, camelFn));
  1220.     }
  1221.             
  1222.     return {    
  1223.         // private  ==> used by Fx  
  1224.         adjustWidth : function(width) {
  1225.             var me = this;
  1226.             var isNum = (typeof width == "number");
  1227.             if(isNum && me.autoBoxAdjust && !me.isBorderBox()){
  1228.                width -= (me.getBorderWidth("lr") + me.getPadding("lr"));
  1229.             }
  1230.             return (isNum && width < 0) ? 0 : width;
  1231.         },
  1232.         
  1233.         // private   ==> used by Fx 
  1234.         adjustHeight : function(height) {
  1235.             var me = this;
  1236.             var isNum = (typeof height == "number");
  1237.             if(isNum && me.autoBoxAdjust && !me.isBorderBox()){
  1238.                height -= (me.getBorderWidth("tb") + me.getPadding("tb"));               
  1239.             }
  1240.             return (isNum && height < 0) ? 0 : height;
  1241.         },
  1242.     
  1243.     
  1244.         /**
  1245.          * Adds one or more CSS classes to the element. Duplicate classes are automatically filtered out.
  1246.          * @param {String/Array} className The CSS class to add, or an array of classes
  1247.          * @return {Ext.Element} this
  1248.          */
  1249.         addClass : function(className){
  1250.             var me = this;
  1251.             Ext.each(className, function(v) {
  1252.                 me.dom.className += (!me.hasClass(v) && v ? " " + v : "");  
  1253.             });
  1254.             return me;
  1255.         },
  1256.     
  1257.         /**
  1258.          * Adds one or more CSS classes to this element and removes the same class(es) from all siblings.
  1259.          * @param {String/Array} className The CSS class to add, or an array of classes
  1260.          * @return {Ext.Element} this
  1261.          */
  1262.         radioClass : function(className){
  1263.             Ext.each(this.dom.parentNode.childNodes, function(v) {
  1264.                 if(v.nodeType == 1) {
  1265.                     Ext.fly(v, '_internal').removeClass(className);          
  1266.                 }
  1267.             });
  1268.             return this.addClass(className);
  1269.         },
  1270.     
  1271.         /**
  1272.          * Removes one or more CSS classes from the element.
  1273.          * @param {String/Array} className The CSS class to remove, or an array of classes
  1274.          * @return {Ext.Element} this
  1275.          */
  1276.         removeClass : function(className){
  1277.             var me = this;
  1278.             if (me.dom.className) {
  1279.                 Ext.each(className, function(v) {               
  1280.                     me.dom.className = me.dom.className.replace(
  1281.                         classReCache[v] = classReCache[v] || new RegExp('(?:^|\s+)' + v + '(?:\s+|$)', "g"), 
  1282.                         " ");               
  1283.                 });    
  1284.             }
  1285.             return me;
  1286.         },
  1287.     
  1288.         /**
  1289.          * Toggles the specified CSS class on this element (removes it if it already exists, otherwise adds it).
  1290.          * @param {String} className The CSS class to toggle
  1291.          * @return {Ext.Element} this
  1292.          */
  1293.         toggleClass : function(className){
  1294.             return this.hasClass(className) ? this.removeClass(className) : this.addClass(className);
  1295.         },
  1296.     
  1297.         /**
  1298.          * Checks if the specified CSS class exists on this element's DOM node.
  1299.          * @param {String} className The CSS class to check for
  1300.          * @return {Boolean} True if the class exists, else false
  1301.          */
  1302.         hasClass : function(className){
  1303.             return className && (' '+this.dom.className+' ').indexOf(' '+className+' ') != -1;
  1304.         },
  1305.     
  1306.         /**
  1307.          * Replaces a CSS class on the element with another.  If the old name does not exist, the new name will simply be added.
  1308.          * @param {String} oldClassName The CSS class to replace
  1309.          * @param {String} newClassName The replacement CSS class
  1310.          * @return {Ext.Element} this
  1311.          */
  1312.         replaceClass : function(oldClassName, newClassName){
  1313.             return this.removeClass(oldClassName).addClass(newClassName);
  1314.         },
  1315.         
  1316.         isStyle : function(style, val) {
  1317.             return this.getStyle(style) == val;  
  1318.         },
  1319.     
  1320.         /**
  1321.          * Normalizes currentStyle and computedStyle.
  1322.          * @param {String} property The style property whose value is returned.
  1323.          * @return {String} The current value of the style property for this element.
  1324.          */
  1325.         getStyle : function(){         
  1326.             return view && view.getComputedStyle ?
  1327.                 function(prop){
  1328.                     var el = this.dom,
  1329.                         v,                  
  1330.                         cs;
  1331.                     if(el == document) return null;
  1332.                     prop = chkCache(prop);
  1333.                     return (v = el.style[prop]) ? v : 
  1334.                            (cs = view.getComputedStyle(el, "")) ? cs[prop] : null;
  1335.                 } :
  1336.                 function(prop){      
  1337.                     var el = this.dom, 
  1338.                         m, 
  1339.                         cs;     
  1340.                         
  1341.                     if(el == document) return null;      
  1342.                     if (prop == 'opacity') {
  1343.                         if (el.style.filter.match) {                       
  1344.                             if(m = el.style.filter.match(opacityRe)){
  1345.                                 var fv = parseFloat(m[1]);
  1346.                                 if(!isNaN(fv)){
  1347.                                     return fv ? fv / 100 : 0;
  1348.                                 }
  1349.                             }
  1350.                         }
  1351.                         return 1;
  1352.                     }
  1353.                     prop = chkCache(prop);  
  1354.                     return el.style[prop] || ((cs = el.currentStyle) ? cs[prop] : null);
  1355.                 };
  1356.         }(),
  1357.         
  1358.         /**
  1359.          * Return the CSS color for the specified CSS attribute. rgb, 3 digit (like #fff) and valid values
  1360.          * are convert to standard 6 digit hex color.
  1361.          * @param {String} attr The css attribute
  1362.          * @param {String} defaultValue The default value to use when a valid color isn't found
  1363.          * @param {String} prefix (optional) defaults to #. Use an empty string when working with
  1364.          * color anims.
  1365.          */
  1366.         getColor : function(attr, defaultValue, prefix){
  1367.             var v = this.getStyle(attr),
  1368.                 color = prefix || '#',
  1369.                 h;
  1370.                 
  1371.             if(!v || /transparent|inherit/.test(v)){
  1372.                 return defaultValue;
  1373.             }
  1374.             if(/^r/.test(v)){
  1375.                 Ext.each(v.slice(4, v.length -1).split(','), function(s){
  1376.                     h = parseInt(s, 10);
  1377.                     color += (h < 16 ? '0' : '') + h.toString(16); 
  1378.                 });
  1379.             }else{
  1380.                 v = v.replace('#', '');
  1381.                 color += v.length == 3 ? v.replace(/^(w)(w)(w)$/, '$1$1$2$2$3$3') : v;
  1382.             }
  1383.             return(color.length > 5 ? color.toLowerCase() : defaultValue);
  1384.         },
  1385.     
  1386.         /**
  1387.          * Wrapper for setting style properties, also takes single object parameter of multiple styles.
  1388.          * @param {String/Object} property The style property to be set, or an object of multiple styles.
  1389.          * @param {String} value (optional) The value to apply to the given property, or null if an object was passed.
  1390.          * @return {Ext.Element} this
  1391.          */
  1392.         setStyle : function(prop, value){
  1393.             var tmp, 
  1394.                 style,
  1395.                 camel;
  1396.             if (!Ext.isObject(prop)) {
  1397.                 tmp = {};
  1398.                 tmp[prop] = value;          
  1399.                 prop = tmp;
  1400.             }
  1401.             for (style in prop) {
  1402.                 value = prop[style];            
  1403.                 style == 'opacity' ? 
  1404.                     this.setOpacity(value) : 
  1405.                     this.dom.style[chkCache(style)] = value;
  1406.             }
  1407.             return this;
  1408.         },
  1409.         
  1410.         /**
  1411.          * Set the opacity of the element
  1412.          * @param {Float} opacity The new opacity. 0 = transparent, .5 = 50% visibile, 1 = fully visible, etc
  1413.          * @param {Boolean/Object} animate (optional) a standard Element animation config object or <tt>true</tt> for
  1414.          * the default animation (<tt>{duration: .35, easing: 'easeIn'}</tt>)
  1415.          * @return {Ext.Element} this
  1416.          */
  1417.          setOpacity : function(opacity, animate){
  1418.             var me = this,
  1419.                 s = me.dom.style;
  1420.                 
  1421.             if(!animate || !me.anim){            
  1422.                 if(Ext.isIE){
  1423.                     var opac = opacity < 1 ? 'alpha(opacity=' + opacity * 100 + ')' : '', 
  1424.                     val = s.filter.replace(opacityRe, '').replace(trimRe, '');
  1425.                     s.zoom = 1;
  1426.                     s.filter = val + (val.length > 0 ? ' ' : '') + opac;
  1427.                 }else{
  1428.                     s.opacity = opacity;
  1429.                 }
  1430.             }else{
  1431.                 me.anim({opacity: {to: opacity}}, me.preanim(arguments, 1), null, .35, 'easeIn');
  1432.             }
  1433.             return me;
  1434.         },
  1435.         
  1436.         /**
  1437.          * Clears any opacity settings from this element. Required in some cases for IE.
  1438.          * @return {Ext.Element} this
  1439.          */
  1440.         clearOpacity : function(){
  1441.             var style = this.dom.style;
  1442.             if(Ext.isIE){
  1443.                 if(!Ext.isEmpty(style.filter)){
  1444.                     style.filter = style.filter.replace(opacityRe, '').replace(trimRe, '');
  1445.                 }
  1446.             }else{
  1447.                 style.opacity = style['-moz-opacity'] = style['-khtml-opacity'] = '';
  1448.             }
  1449.             return this;
  1450.         },
  1451.     
  1452.         /**
  1453.          * Returns the offset height of the element
  1454.          * @param {Boolean} contentHeight (optional) true to get the height minus borders and padding
  1455.          * @return {Number} The element's height
  1456.          */
  1457.         getHeight : function(contentHeight){
  1458.             var me = this,
  1459.                 dom = me.dom,
  1460.                 h = MATH.max(dom.offsetHeight, dom.clientHeight) || 0;
  1461.             h = !contentHeight ? h : h - me.getBorderWidth("tb") - me.getPadding("tb");
  1462.             return h < 0 ? 0 : h;
  1463.         },
  1464.     
  1465.         /**
  1466.          * Returns the offset width of the element
  1467.          * @param {Boolean} contentWidth (optional) true to get the width minus borders and padding
  1468.          * @return {Number} The element's width
  1469.          */
  1470.         getWidth : function(contentWidth){
  1471.             var me = this,
  1472.                 dom = me.dom,
  1473.                 w = MATH.max(dom.offsetWidth, dom.clientWidth) || 0;
  1474.             w = !contentWidth ? w : w - me.getBorderWidth("lr") - me.getPadding("lr");
  1475.             return w < 0 ? 0 : w;
  1476.         },
  1477.     
  1478.         /**
  1479.          * Set the width of this Element.
  1480.          * @param {Mixed} width The new width. This may be one of:<div class="mdetail-params"><ul>
  1481.          * <li>A Number specifying the new width in this Element's {@link #defaultUnit}s (by default, pixels).</li>
  1482.          * <li>A String used to set the CSS width style. Animation may <b>not</b> be used.
  1483.          * </ul></div>
  1484.          * @param {Boolean/Object} animate (optional) true for the default animation or a standard Element animation config object
  1485.          * @return {Ext.Element} this
  1486.          */
  1487.         setWidth : function(width, animate){
  1488.             var me = this;
  1489.             width = me.adjustWidth(width);
  1490.             !animate || !me.anim ? 
  1491.                 me.dom.style.width = me.addUnits(width) :
  1492.                 me.anim({width : {to : width}}, me.preanim(arguments, 1));
  1493.             return me;
  1494.         },
  1495.     
  1496.         /**
  1497.          * Set the height of this Element.
  1498.          * <pre><code>
  1499. // change the height to 200px and animate with default configuration
  1500. Ext.fly('elementId').setHeight(200, true);
  1501. // change the height to 150px and animate with a custom configuration
  1502. Ext.fly('elId').setHeight(150, {
  1503.     duration : .5, // animation will have a duration of .5 seconds
  1504.     // will change the content to "finished"
  1505.     callback: function(){ this.{@link #update}("finished"); } 
  1506. });
  1507.          * </code></pre>
  1508.          * @param {Mixed} height The new height. This may be one of:<div class="mdetail-params"><ul>
  1509.          * <li>A Number specifying the new height in this Element's {@link #defaultUnit}s (by default, pixels.)</li>
  1510.          * <li>A String used to set the CSS height style. Animation may <b>not</b> be used.</li>
  1511.          * </ul></div>
  1512.          * @param {Boolean/Object} animate (optional) true for the default animation or a standard Element animation config object
  1513.          * @return {Ext.Element} this
  1514.          */
  1515.          setHeight : function(height, animate){
  1516.             var me = this;
  1517.             height = me.adjustHeight(height);
  1518.             !animate || !me.anim ? 
  1519.                 me.dom.style.height = me.addUnits(height) :
  1520.                 me.anim({height : {to : height}}, me.preanim(arguments, 1));
  1521.             return me;
  1522.         },
  1523.         
  1524.         /**
  1525.          * Gets the width of the border(s) for the specified side(s)
  1526.          * @param {String} side Can be t, l, r, b or any combination of those to add multiple values. For example,
  1527.          * passing <tt>'lr'</tt> would get the border <b><u>l</u></b>eft width + the border <b><u>r</u></b>ight width.
  1528.          * @return {Number} The width of the sides passed added together
  1529.          */
  1530.         getBorderWidth : function(side){
  1531.             return addStyles.call(this, side, borders);
  1532.         },
  1533.     
  1534.         /**
  1535.          * Gets the width of the padding(s) for the specified side(s)
  1536.          * @param {String} side Can be t, l, r, b or any combination of those to add multiple values. For example,
  1537.          * passing <tt>'lr'</tt> would get the padding <b><u>l</u></b>eft + the padding <b><u>r</u></b>ight.
  1538.          * @return {Number} The padding of the sides passed added together
  1539.          */
  1540.         getPadding : function(side){
  1541.             return addStyles.call(this, side, paddings);
  1542.         },
  1543.     
  1544.         /**
  1545.          *  Store the current overflow setting and clip overflow on the element - use <tt>{@link #unclip}</tt> to remove
  1546.          * @return {Ext.Element} this
  1547.          */
  1548.         clip : function(){
  1549.             var me = this,
  1550.                 dom = me.dom;
  1551.                 
  1552.             if(!data(dom, ISCLIPPED)){
  1553.                 data(dom, ISCLIPPED, true);
  1554.                 data(dom, ORIGINALCLIP, {
  1555.                     o: me.getStyle(OVERFLOW),
  1556.                     x: me.getStyle(OVERFLOWX),
  1557.                     y: me.getStyle(OVERFLOWY)
  1558.                 });
  1559.                 me.setStyle(OVERFLOW, HIDDEN);
  1560.                 me.setStyle(OVERFLOWX, HIDDEN);
  1561.                 me.setStyle(OVERFLOWY, HIDDEN);
  1562.             }
  1563.             return me;
  1564.         },
  1565.     
  1566.         /**
  1567.          *  Return clipping (overflow) to original clipping before <tt>{@link #clip}</tt> was called
  1568.          * @return {Ext.Element} this
  1569.          */
  1570.         unclip : function(){
  1571.             var me = this,
  1572.                 dom = me.dom;
  1573.                 
  1574.             if(data(dom, ISCLIPPED)){
  1575.                 data(dom, ISCLIPPED, false);
  1576.                 var o = data(dom, ORIGINALCLIP);
  1577.                 if(o.o){
  1578.                     me.setStyle(OVERFLOW, o.o);
  1579.                 }
  1580.                 if(o.x){
  1581.                     me.setStyle(OVERFLOWX, o.x);
  1582.                 }
  1583.                 if(o.y){
  1584.                     me.setStyle(OVERFLOWY, o.y);
  1585.                 }
  1586.             }
  1587.             return me;
  1588.         },
  1589.         
  1590.         addStyles : addStyles,
  1591.         margins : margins
  1592.     }
  1593. }()         
  1594. );/**
  1595.  * @class Ext.Element
  1596.  */
  1597. // special markup used throughout Ext when box wrapping elements
  1598. 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>';
  1599. Ext.Element.addMethods(function(){
  1600. var INTERNAL = "_internal";
  1601. return {
  1602.     /**
  1603.      * More flexible version of {@link #setStyle} for setting style properties.
  1604.      * @param {String/Object/Function} styles A style specification string, e.g. "width:100px", or object in the form {width:"100px"}, or
  1605.      * a function which returns such a specification.
  1606.      * @return {Ext.Element} this
  1607.      */
  1608.     applyStyles : function(style){
  1609.         Ext.DomHelper.applyStyles(this.dom, style);
  1610.         return this;
  1611.     },
  1612. /**
  1613.      * Returns an object with properties matching the styles requested.
  1614.      * For example, el.getStyles('color', 'font-size', 'width') might return
  1615.      * {'color': '#FFFFFF', 'font-size': '13px', 'width': '100px'}.
  1616.      * @param {String} style1 A style name
  1617.      * @param {String} style2 A style name
  1618.      * @param {String} etc.
  1619.      * @return {Object} The style object
  1620.      */
  1621.     getStyles : function(){
  1622.     var ret = {};
  1623.     Ext.each(arguments, function(v) {
  1624.    ret[v] = this.getStyle(v);
  1625.     },
  1626.     this);
  1627.     return ret;
  1628.     },
  1629. getStyleSize : function(){
  1630.         var me = this,
  1631.          w,
  1632.          h,
  1633.          d = this.dom,
  1634.          s = d.style;
  1635.         if(s.width && s.width != 'auto'){
  1636.             w = parseInt(s.width, 10);
  1637.             if(me.isBorderBox()){
  1638.                w -= me.getFrameWidth('lr');
  1639.             }
  1640.         }
  1641.         if(s.height && s.height != 'auto'){
  1642.             h = parseInt(s.height, 10);
  1643.             if(me.isBorderBox()){
  1644.                h -= me.getFrameWidth('tb');
  1645.             }
  1646.         }
  1647.         return {width: w || me.getWidth(true), height: h || me.getHeight(true)};
  1648.     },
  1649.     // private  ==> used by ext full
  1650. setOverflow : function(v){
  1651. var dom = this.dom;
  1652.      if(v=='auto' && Ext.isMac && Ext.isGecko2){ // work around stupid FF 2.0/Mac scroll bar bug
  1653.      dom.style.overflow = 'hidden';
  1654.          (function(){dom.style.overflow = 'auto';}).defer(1);
  1655.      }else{
  1656.      dom.style.overflow = v;
  1657.      }
  1658. },
  1659.    /**
  1660. * <p>Wraps the specified element with a special 9 element markup/CSS block that renders by default as
  1661. * a gray container with a gradient background, rounded corners and a 4-way shadow.</p>
  1662. * <p>This special markup is used throughout Ext when box wrapping elements ({@link Ext.Button},
  1663. * {@link Ext.Panel} when <tt>{@link Ext.Panel#frame frame=true}</tt>, {@link Ext.Window}).  The markup
  1664. * is of this form:</p>
  1665. * <pre><code>
  1666. Ext.Element.boxMarkup =
  1667.     &#39;&lt;div class="{0}-tl">&lt;div class="{0}-tr">&lt;div class="{0}-tc">&lt;/div>&lt;/div>&lt;/div>
  1668.      &lt;div class="{0}-ml">&lt;div class="{0}-mr">&lt;div class="{0}-mc">&lt;/div>&lt;/div>&lt;/div>
  1669.      &lt;div class="{0}-bl">&lt;div class="{0}-br">&lt;div class="{0}-bc">&lt;/div>&lt;/div>&lt;/div>&#39;;
  1670. * </code></pre>
  1671. * <p>Example usage:</p>
  1672. * <pre><code>
  1673. // Basic box wrap
  1674. Ext.get("foo").boxWrap();
  1675. // You can also add a custom class and use CSS inheritance rules to customize the box look.
  1676. // 'x-box-blue' is a built-in alternative -- look at the related CSS definitions as an example
  1677. // for how to create a custom box wrap style.
  1678. Ext.get("foo").boxWrap().addClass("x-box-blue");
  1679. * </code></pre>
  1680. * @param {String} class (optional) A base CSS class to apply to the containing wrapper element
  1681. * (defaults to <tt>'x-box'</tt>). Note that there are a number of CSS rules that are dependent on
  1682. * this name to make the overall effect work, so if you supply an alternate base class, make sure you
  1683. * also supply all of the necessary rules.
  1684. * @return {Ext.Element} this
  1685. */
  1686.     boxWrap : function(cls){
  1687.         cls = cls || 'x-box';
  1688.         var el = Ext.get(this.insertHtml("beforeBegin", "<div class='" + cls + "'>" + String.format(Ext.Element.boxMarkup, cls) + "</div>"));        //String.format('<div class="{0}">'+Ext.Element.boxMarkup+'</div>', cls)));
  1689.         Ext.DomQuery.selectNode('.' + cls + '-mc', el.dom).appendChild(this.dom);
  1690.         return el;
  1691.     },
  1692.         /**
  1693.          * Set the size of this Element. If animation is true, both width and height will be animated concurrently.
  1694.          * @param {Mixed} width The new width. This may be one of:<div class="mdetail-params"><ul>
  1695.          * <li>A Number specifying the new width in this Element's {@link #defaultUnit}s (by default, pixels).</li>
  1696.          * <li>A String used to set the CSS width style. Animation may <b>not</b> be used.
  1697.          * <li>A size object in the format <code>{width: widthValue, height: heightValue}</code>.</li>
  1698.          * </ul></div>
  1699.          * @param {Mixed} height The new height. This may be one of:<div class="mdetail-params"><ul>
  1700.          * <li>A Number specifying the new height in this Element's {@link #defaultUnit}s (by default, pixels).</li>
  1701.          * <li>A String used to set the CSS height style. Animation may <b>not</b> be used.</li>
  1702.          * </ul></div>
  1703.          * @param {Boolean/Object} animate (optional) true for the default animation or a standard Element animation config object
  1704.          * @return {Ext.Element} this
  1705.          */
  1706.     setSize : function(width, height, animate){
  1707. var me = this;
  1708. if(Ext.isObject(width)){ // in case of object from getSize()
  1709.     height = width.height;
  1710.     width = width.width;
  1711. }
  1712. width = me.adjustWidth(width);
  1713. height = me.adjustHeight(height);
  1714. if(!animate || !me.anim){
  1715.     me.dom.style.width = me.addUnits(width);
  1716.     me.dom.style.height = me.addUnits(height);
  1717. }else{
  1718.     me.anim({width: {to: width}, height: {to: height}}, me.preanim(arguments, 2));
  1719. }
  1720. return me;
  1721.     },
  1722.     /**
  1723.      * Returns either the offsetHeight or the height of this element based on CSS height adjusted by padding or borders
  1724.      * when needed to simulate offsetHeight when offsets aren't available. This may not work on display:none elements
  1725.      * if a height has not been set using CSS.
  1726.      * @return {Number}
  1727.      */
  1728.     getComputedHeight : function(){
  1729.     var me = this,
  1730.          h = Math.max(me.dom.offsetHeight, me.dom.clientHeight);
  1731.         if(!h){
  1732.             h = parseInt(me.getStyle('height'), 10) || 0;
  1733.             if(!me.isBorderBox()){
  1734.                 h += me.getFrameWidth('tb');
  1735.             }
  1736.         }
  1737.         return h;
  1738.     },
  1739.     /**
  1740.      * Returns either the offsetWidth or the width of this element based on CSS width adjusted by padding or borders
  1741.      * when needed to simulate offsetWidth when offsets aren't available. This may not work on display:none elements
  1742.      * if a width has not been set using CSS.
  1743.      * @return {Number}
  1744.      */
  1745.     getComputedWidth : function(){
  1746.         var w = Math.max(this.dom.offsetWidth, this.dom.clientWidth);
  1747.         if(!w){
  1748.             w = parseInt(this.getStyle('width'), 10) || 0;
  1749.             if(!this.isBorderBox()){
  1750.                 w += this.getFrameWidth('lr');
  1751.             }
  1752.         }
  1753.         return w;
  1754.     },
  1755.     /**
  1756.      * Returns the sum width of the padding and borders for the passed "sides". See getBorderWidth()
  1757.      for more information about the sides.
  1758.      * @param {String} sides
  1759.      * @return {Number}
  1760.      */
  1761.     getFrameWidth : function(sides, onlyContentBox){
  1762.         return onlyContentBox && this.isBorderBox() ? 0 : (this.getPadding(sides) + this.getBorderWidth(sides));
  1763.     },
  1764.     /**
  1765.      * Sets up event handlers to add and remove a css class when the mouse is over this element
  1766.      * @param {String} className
  1767.      * @return {Ext.Element} this
  1768.      */
  1769.     addClassOnOver : function(className){
  1770.         this.hover(
  1771.             function(){
  1772.                 Ext.fly(this, INTERNAL).addClass(className);
  1773.             },
  1774.             function(){
  1775.                 Ext.fly(this, INTERNAL).removeClass(className);
  1776.             }
  1777.         );
  1778.         return this;
  1779.     },
  1780.     /**
  1781.      * Sets up event handlers to add and remove a css class when this element has the focus
  1782.      * @param {String} className
  1783.      * @return {Ext.Element} this
  1784.      */
  1785.     addClassOnFocus : function(className){
  1786.     this.on("focus", function(){
  1787.         Ext.fly(this, INTERNAL).addClass(className);
  1788.     }, this.dom);
  1789.     this.on("blur", function(){
  1790.         Ext.fly(this, INTERNAL).removeClass(className);
  1791.     }, this.dom);
  1792.     return this;
  1793.     },
  1794.     /**
  1795.      * Sets up event handlers to add and remove a css class when the mouse is down and then up on this element (a click effect)
  1796.      * @param {String} className
  1797.      * @return {Ext.Element} this
  1798.      */
  1799.     addClassOnClick : function(className){
  1800.         var dom = this.dom;
  1801.         this.on("mousedown", function(){
  1802.             Ext.fly(dom, INTERNAL).addClass(className);
  1803.             var d = Ext.getDoc(),
  1804.              fn = function(){
  1805.                 Ext.fly(dom, INTERNAL).removeClass(className);
  1806.                 d.removeListener("mouseup", fn);
  1807.             };
  1808.             d.on("mouseup", fn);
  1809.         });
  1810.         return this;
  1811.     },
  1812.     /**
  1813.      * Returns the width and height of the viewport.
  1814.         * <pre><code>
  1815.         var vpSize = Ext.getBody().getViewSize();
  1816.         // all Windows created afterwards will have a default value of 90% height and 95% width
  1817.         Ext.Window.override({
  1818.             width: vpSize.width * 0.9,
  1819.             height: vpSize.height * 0.95
  1820.         });
  1821.         // To handle window resizing you would have to hook onto onWindowResize.
  1822.         </code></pre>
  1823.      * @return {Object} An object containing the viewport's size {width: (viewport width), height: (viewport height)}
  1824.      */
  1825.     getViewSize : function(){
  1826.         var doc = document,
  1827.          d = this.dom,
  1828.          extdom = Ext.lib.Dom,
  1829.          isDoc = (d == doc || d == doc.body);
  1830.         return { width : (isDoc ? extdom.getViewWidth() : d.clientWidth),
  1831.           height : (isDoc ? extdom.getViewHeight() : d.clientHeight) };
  1832.     },
  1833.     /**
  1834.      * Returns the size of the element.
  1835.      * @param {Boolean} contentSize (optional) true to get the width/size minus borders and padding
  1836.      * @return {Object} An object containing the element's size {width: (element width), height: (element height)}
  1837.      */
  1838.     getSize : function(contentSize){
  1839.         return {width: this.getWidth(contentSize), height: this.getHeight(contentSize)};
  1840.     },
  1841.     /**
  1842.      * Forces the browser to repaint this element
  1843.      * @return {Ext.Element} this
  1844.      */
  1845.     repaint : function(){
  1846.         var dom = this.dom;
  1847.         this.addClass("x-repaint");
  1848.         setTimeout(function(){
  1849.             Ext.fly(dom).removeClass("x-repaint");
  1850.         }, 1);
  1851.         return this;
  1852.     },
  1853.     /**
  1854.      * Disables text selection for this element (normalized across browsers)
  1855.      * @return {Ext.Element} this
  1856.      */
  1857.     unselectable : function(){
  1858.         this.dom.unselectable = "on";
  1859.         return this.swallowEvent("selectstart", true).
  1860.              applyStyles("-moz-user-select:none;-khtml-user-select:none;").
  1861.              addClass("x-unselectable");
  1862.     },
  1863.     /**
  1864.      * Returns an object with properties top, left, right and bottom representing the margins of this element unless sides is passed,
  1865.      * then it returns the calculated width of the sides (see getPadding)
  1866.      * @param {String} sides (optional) Any combination of l, r, t, b to get the sum of those sides
  1867.      * @return {Object/Number}
  1868.      */
  1869.     getMargins : function(side){
  1870.     var me = this,
  1871.      key,
  1872.      hash = {t:"top", l:"left", r:"right", b: "bottom"},
  1873.      o = {};
  1874.     if (!side) {
  1875.         for (key in me.margins){
  1876.          o[hash[key]] = parseInt(me.getStyle(me.margins[key]), 10) || 0;
  1877.                 }
  1878.         return o;
  1879.         } else {
  1880.             return me.addStyles.call(me, side, me.margins);
  1881.         }
  1882.     }
  1883.     };
  1884. }());/**
  1885.  * @class Ext.Element
  1886.  */
  1887. (function(){
  1888. var D = Ext.lib.Dom,
  1889.         LEFT = "left",
  1890.         RIGHT = "right",
  1891.         TOP = "top",
  1892.         BOTTOM = "bottom",
  1893.         POSITION = "position",
  1894.         STATIC = "static",
  1895.         RELATIVE = "relative",
  1896.         AUTO = "auto",
  1897.         ZINDEX = "z-index";
  1898. function animTest(args, animate, i) {
  1899. return this.preanim && !!animate ? this.preanim(args, i) : false
  1900. }
  1901. Ext.Element.addMethods({
  1902. /**
  1903.       * Gets the current X position of the element based on page coordinates.  Element must be part of the DOM tree to have page coordinates (display:none or elements not appended return false).
  1904.       * @return {Number} The X position of the element
  1905.       */
  1906.     getX : function(){
  1907.         return D.getX(this.dom);
  1908.     },
  1909.     /**
  1910.       * Gets the current Y position of the element based on page coordinates.  Element must be part of the DOM tree to have page coordinates (display:none or elements not appended return false).
  1911.       * @return {Number} The Y position of the element
  1912.       */
  1913.     getY : function(){
  1914.         return D.getY(this.dom);
  1915.     },
  1916.     /**
  1917.       * Gets the current position of the element based on page coordinates.  Element must be part of the DOM tree to have page coordinates (display:none or elements not appended return false).
  1918.       * @return {Array} The XY position of the element
  1919.       */
  1920.     getXY : function(){
  1921.         return D.getXY(this.dom);
  1922.     },
  1923.     /**
  1924.       * Returns the offsets of this element from the passed element. Both element must be part of the DOM tree and not have display:none to have page coordinates.
  1925.       * @param {Mixed} element The element to get the offsets from.
  1926.       * @return {Array} The XY page offsets (e.g. [100, -200])
  1927.       */
  1928.     getOffsetsTo : function(el){
  1929.         var o = this.getXY(),
  1930.          e = Ext.fly(el, '_internal').getXY();
  1931.         return [o[0]-e[0],o[1]-e[1]];
  1932.     },
  1933.     /**
  1934.      * Sets the X position of the element based on page coordinates.  Element must be part of the DOM tree to have page coordinates (display:none or elements not appended return false).
  1935.      * @param {Number} The X position of the element
  1936.      * @param {Boolean/Object} animate (optional) True for the default animation, or a standard Element animation config object
  1937.      * @return {Ext.Element} this
  1938.      */
  1939.     setX : function(x, animate){     
  1940.     return this.setXY([x, this.getY()], animTest.call(this, arguments, animate, 1));
  1941.     },
  1942.     /**
  1943.      * Sets the Y position of the element based on page coordinates.  Element must be part of the DOM tree to have page coordinates (display:none or elements not appended return false).
  1944.      * @param {Number} The Y position of the element
  1945.      * @param {Boolean/Object} animate (optional) True for the default animation, or a standard Element animation config object
  1946.      * @return {Ext.Element} this
  1947.      */
  1948.     setY : function(y, animate){     
  1949.     return this.setXY([this.getX(), y], animTest.call(this, arguments, animate, 1));
  1950.     },
  1951.     /**
  1952.      * Sets the element's left position directly using CSS style (instead of {@link #setX}).
  1953.      * @param {String} left The left CSS property value
  1954.      * @return {Ext.Element} this
  1955.      */
  1956.     setLeft : function(left){
  1957.         this.setStyle(LEFT, this.addUnits(left));
  1958.         return this;
  1959.     },
  1960.     /**
  1961.      * Sets the element's top position directly using CSS style (instead of {@link #setY}).
  1962.      * @param {String} top The top CSS property value
  1963.      * @return {Ext.Element} this
  1964.      */
  1965.     setTop : function(top){
  1966.         this.setStyle(TOP, this.addUnits(top));
  1967.         return this;
  1968.     },
  1969.     /**
  1970.      * Sets the element's CSS right style.
  1971.      * @param {String} right The right CSS property value
  1972.      * @return {Ext.Element} this
  1973.      */
  1974.     setRight : function(right){
  1975.         this.setStyle(RIGHT, this.addUnits(right));
  1976.         return this;
  1977.     },
  1978.     /**
  1979.      * Sets the element's CSS bottom style.
  1980.      * @param {String} bottom The bottom CSS property value
  1981.      * @return {Ext.Element} this
  1982.      */
  1983.     setBottom : function(bottom){
  1984.         this.setStyle(BOTTOM, this.addUnits(bottom));
  1985.         return this;
  1986.     },
  1987.     /**
  1988.      * Sets the position of the element in page coordinates, regardless of how the element is positioned.
  1989.      * The element must be part of the DOM tree to have page coordinates (display:none or elements not appended return false).
  1990.      * @param {Array} pos Contains X & Y [x, y] values for new position (coordinates are page-based)
  1991.      * @param {Boolean/Object} animate (optional) True for the default animation, or a standard Element animation config object
  1992.      * @return {Ext.Element} this
  1993.      */
  1994.     setXY : function(pos, animate){
  1995.     var me = this;
  1996.         if(!animate || !me.anim){
  1997.             D.setXY(me.dom, pos);
  1998.         }else{
  1999.             me.anim({points: {to: pos}}, me.preanim(arguments, 1), 'motion');
  2000.         }
  2001.         return me;
  2002.     },
  2003.     /**
  2004.      * Sets the position of the element in page coordinates, regardless of how the element is positioned.
  2005.      * The element must be part of the DOM tree to have page coordinates (display:none or elements not appended return false).
  2006.      * @param {Number} x X value for new position (coordinates are page-based)
  2007.      * @param {Number} y Y value for new position (coordinates are page-based)
  2008.      * @param {Boolean/Object} animate (optional) True for the default animation, or a standard Element animation config object
  2009.      * @return {Ext.Element} this
  2010.      */
  2011.     setLocation : function(x, y, animate){
  2012.         return this.setXY([x, y], animTest.call(this, arguments, animate, 2));
  2013.     },
  2014.     /**
  2015.      * Sets the position of the element in page coordinates, regardless of how the element is positioned.
  2016.      * The element must be part of the DOM tree to have page coordinates (display:none or elements not appended return false).
  2017.      * @param {Number} x X value for new position (coordinates are page-based)
  2018.      * @param {Number} y Y value for new position (coordinates are page-based)
  2019.      * @param {Boolean/Object} animate (optional) True for the default animation, or a standard Element animation config object
  2020.      * @return {Ext.Element} this
  2021.      */
  2022.     moveTo : function(x, y, animate){
  2023.         return this.setXY([x, y], animTest.call(this, arguments, animate, 2));        
  2024.     },    
  2025.     
  2026.     /**
  2027.      * Gets the left X coordinate
  2028.      * @param {Boolean} local True to get the local css position instead of page coordinate
  2029.      * @return {Number}
  2030.      */
  2031.     getLeft : function(local){
  2032.     return !local ? this.getX() : parseInt(this.getStyle(LEFT), 10) || 0;
  2033.     },
  2034.     /**
  2035.      * Gets the right X coordinate of the element (element X position + element width)
  2036.      * @param {Boolean} local True to get the local css position instead of page coordinate
  2037.      * @return {Number}
  2038.      */
  2039.     getRight : function(local){
  2040.     var me = this;
  2041.     return !local ? me.getX() + me.getWidth() : (me.getLeft(true) + me.getWidth()) || 0;
  2042.     },
  2043.     /**
  2044.      * Gets the top Y coordinate
  2045.      * @param {Boolean} local True to get the local css position instead of page coordinate
  2046.      * @return {Number}
  2047.      */
  2048.     getTop : function(local) {
  2049.     return !local ? this.getY() : parseInt(this.getStyle(TOP), 10) || 0;
  2050.     },
  2051.     /**
  2052.      * Gets the bottom Y coordinate of the element (element Y position + element height)
  2053.      * @param {Boolean} local True to get the local css position instead of page coordinate
  2054.      * @return {Number}
  2055.      */
  2056.     getBottom : function(local){
  2057.     var me = this;
  2058.     return !local ? me.getY() + me.getHeight() : (me.getTop(true) + me.getHeight()) || 0;
  2059.     },
  2060.     /**
  2061.     * Initializes positioning on this element. If a desired position is not passed, it will make the
  2062.     * the element positioned relative IF it is not already positioned.
  2063.     * @param {String} pos (optional) Positioning to use "relative", "absolute" or "fixed"
  2064.     * @param {Number} zIndex (optional) The zIndex to apply
  2065.     * @param {Number} x (optional) Set the page X position
  2066.     * @param {Number} y (optional) Set the page Y position
  2067.     */
  2068.     position : function(pos, zIndex, x, y){
  2069.     var me = this;
  2070.     
  2071.         if(!pos && me.isStyle(POSITION, STATIC)){           
  2072.             me.setStyle(POSITION, RELATIVE);