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

中间件编程

开发平台:

JavaScript

  1.          * @param {Number} v The number to format.
  2.          * @param {String} format The way you would like to format this text.
  3.          * @return {String} The formatted number.
  4.          */
  5.         number: function(v, format) {
  6.             if(!format){
  7.         return v;
  8.     }
  9.     v = Ext.num(v, NaN);
  10.             if (isNaN(v)){
  11.                 return '';
  12.             }
  13.     var comma = ',',
  14.         dec = '.',
  15.         i18n = false,
  16.         neg = v < 0;
  17.     v = Math.abs(v);
  18.     if(format.substr(format.length - 2) == '/i'){
  19.         format = format.substr(0, format.length - 2);
  20.         i18n = true;
  21.         comma = '.';
  22.         dec = ',';
  23.     }
  24.     var hasComma = format.indexOf(comma) != -1, 
  25.         psplit = (i18n ? format.replace(/[^d,]/g, '') : format.replace(/[^d.]/g, '')).split(dec);
  26.     if(1 < psplit.length){
  27.         v = v.toFixed(psplit[1].length);
  28.     }else if(2 < psplit.length){
  29.         throw ('NumberFormatException: invalid format, formats should have no more than 1 period: ' + format);
  30.     }else{
  31.         v = v.toFixed(0);
  32.     }
  33.     var fnum = v.toString();
  34.     if(hasComma){
  35.         psplit = fnum.split('.');
  36.         var cnum = psplit[0], parr = [], j = cnum.length, m = Math.floor(j / 3), n = cnum.length % 3 || 3;
  37.         for(var i = 0; i < j; i += n){
  38.             if(i != 0){
  39.                 n = 3;
  40.             }
  41.             parr[parr.length] = cnum.substr(i, n);
  42.             m -= 1;
  43.         }
  44.         fnum = parr.join(comma);
  45.         if(psplit[1]){
  46.             fnum += dec + psplit[1];
  47.         }
  48.     }
  49.     return (neg ? '-' : '') + format.replace(/[d,?.?]+/, fnum);
  50.         },
  51.         /**
  52.          * Returns a number rendering function that can be reused to apply a number format multiple times efficiently
  53.          * @param {String} format Any valid number format string for {@link #number}
  54.          * @return {Function} The number formatting function
  55.          */
  56.         numberRenderer : function(format){
  57.             return function(v){
  58.                 return Ext.util.Format.number(v, format);
  59.             };
  60.         },
  61.         /**
  62.          * Selectively do a plural form of a word based on a numeric value. For example, in a template,
  63.          * {commentCount:plural("Comment")}  would result in "1 Comment" if commentCount was 1 or would be "x Comments"
  64.          * if the value is 0 or greater than 1.
  65.          * @param {Number} value The value to compare against
  66.          * @param {String} singular The singular form of the word
  67.          * @param {String} plural (optional) The plural form of the word (defaults to the singular with an "s")
  68.          */
  69.         plural : function(v, s, p){
  70.             return v +' ' + (v == 1 ? s : (p ? p : s+'s'));
  71.         },
  72.         
  73.         /**
  74.          * Converts newline characters to the HTML tag &lt;br/>
  75.          * @param {String} The string value to format.
  76.          * @return {String} The string with embedded &lt;br/> tags in place of newlines.
  77.          */
  78.         nl2br : function(v){
  79.             return v === undefined || v === null ? '' : v.replace(/n/g, '<br/>');
  80.         }
  81.     }
  82. }();/**  * @class Ext.XTemplate  * @extends Ext.Template  * <p>A template class that supports advanced functionality like autofilling arrays, conditional processing with  * basic comparison operators, sub-templates, basic math function support, special built-in template variables,  * inline code execution and more.  XTemplate also provides the templating mechanism built into {@link Ext.DataView}.</p>  * <p>XTemplate supports many special tags and built-in operators that aren't defined as part of the API, but are  * supported in the templates that can be created.  The following examples demonstrate all of the supported features.  * This is the data object used for reference in each code example:</p>  * <pre><code> var data = {     name: 'Jack Slocum',     title: 'Lead Developer',     company: 'Ext JS, LLC',     email: 'jack@extjs.com',     address: '4 Red Bulls Drive',     city: 'Cleveland',     state: 'Ohio',     zip: '44102',     drinks: ['Red Bull', 'Coffee', 'Water'],     kids: [{         name: 'Sara Grace',         age:3     },{         name: 'Zachary',         age:2     },{         name: 'John James',         age:0     }] };  * </code></pre>  * <p><b>Auto filling of arrays</b><br/>The <tt>tpl</tt> tag and the <tt>for</tt> operator are used  * to process the provided data object. If <tt>for="."</tt> is specified, the data object provided  * is examined. If the variable in <tt>for</tt> is an array, it will auto-fill, repeating the template  * block inside the <tt>tpl</tt> tag for each item in the array:</p>  * <pre><code> var tpl = new Ext.XTemplate(     '&lt;p>Kids: ',     '&lt;tpl for=".">',         '&lt;p>{name}&lt;/p>',     '&lt;/tpl>&lt;/p>' ); tpl.overwrite(panel.body, data.kids); // pass the kids property of the data object  * </code></pre>  * <p><b>Scope switching</b><br/>The <tt>for</tt> property can be leveraged to access specified members  * of the provided data object to populate the template:</p>  * <pre><code> var tpl = new Ext.XTemplate(     '&lt;p>Name: {name}&lt;/p>',     '&lt;p>Title: {title}&lt;/p>',     '&lt;p>Company: {company}&lt;/p>',     '&lt;p>Kids: ',     '&lt;tpl <b>for="kids"</b>>', // interrogate the kids property within the data         '&lt;p>{name}&lt;/p>',     '&lt;/tpl>&lt;/p>' ); tpl.overwrite(panel.body, data);  * </code></pre>  * <p><b>Access to parent object from within sub-template scope</b><br/>When processing a sub-template, for example while  * looping through a child array, you can access the parent object's members via the <tt>parent</tt> object:</p>  * <pre><code> var tpl = new Ext.XTemplate(     '&lt;p>Name: {name}&lt;/p>',     '&lt;p>Kids: ',     '&lt;tpl for="kids">',         '&lt;tpl if="age &amp;gt; 1">',  // <-- Note that the &gt; is encoded             '&lt;p>{name}&lt;/p>',             '&lt;p>Dad: {parent.name}&lt;/p>',         '&lt;/tpl>',     '&lt;/tpl>&lt;/p>' ); tpl.overwrite(panel.body, data); </code></pre>  * <p><b>Array item index and basic math support</b> <br/>While processing an array, the special variable <tt>{#}</tt>  * will provide the current array index + 1 (starts at 1, not 0). Templates also support the basic math operators  * + - * and / that can be applied directly on numeric data values:</p>  * <pre><code> var tpl = new Ext.XTemplate(     '&lt;p>Name: {name}&lt;/p>',     '&lt;p>Kids: ',     '&lt;tpl for="kids">',         '&lt;tpl if="age &amp;gt; 1">',  // <-- Note that the &gt; is encoded             '&lt;p>{#}: {name}&lt;/p>',  // <-- Auto-number each item             '&lt;p>In 5 Years: {age+5}&lt;/p>',  // <-- Basic math             '&lt;p>Dad: {parent.name}&lt;/p>',         '&lt;/tpl>',     '&lt;/tpl>&lt;/p>' ); tpl.overwrite(panel.body, data); </code></pre>  * <p><b>Auto-rendering of flat arrays</b> <br/>Flat arrays that contain values (and not objects) can be auto-rendered  * using the special <tt>{.}</tt> variable inside a loop.  This variable will represent the value of  * the array at the current index:</p>  * <pre><code> var tpl = new Ext.XTemplate(     '&lt;p>{name}'s favorite beverages:&lt;/p>',     '&lt;tpl for="drinks">',        '&lt;div> - {.}&lt;/div>',     '&lt;/tpl>' ); tpl.overwrite(panel.body, data); </code></pre>  * <p><b>Basic conditional logic</b> <br/>Using the <tt>tpl</tt> tag and the <tt>if</tt>  * operator you can provide conditional checks for deciding whether or not to render specific parts of the template.  * Note that there is no <tt>else</tt> operator &mdash; if needed, you should use two opposite <tt>if</tt> statements.  * Properly-encoded attributes are required as seen in the following example:</p>  * <pre><code> var tpl = new Ext.XTemplate(     '&lt;p>Name: {name}&lt;/p>',     '&lt;p>Kids: ',     '&lt;tpl for="kids">',         '&lt;tpl if="age &amp;gt; 1">',  // <-- Note that the &gt; is encoded             '&lt;p>{name}&lt;/p>',         '&lt;/tpl>',     '&lt;/tpl>&lt;/p>' ); tpl.overwrite(panel.body, data); </code></pre>  * <p><b>Ability to execute arbitrary inline code</b> <br/>In an XTemplate, anything between {[ ... ]}  is considered  * code to be executed in the scope of the template. There are some special variables available in that code:  * <ul>  * <li><b><tt>values</tt></b>: The values in the current scope. If you are using scope changing sub-templates, you  * can change what <tt>values</tt> is.</li>  * <li><b><tt>parent</tt></b>: The scope (values) of the ancestor template.</li>  * <li><b><tt>xindex</tt></b>: If you are in a looping template, the index of the loop you are in (1-based).</li>  * <li><b><tt>xcount</tt></b>: If you are in a looping template, the total length of the array you are looping.</li>  * <li><b><tt>fm</tt></b>: An alias for <tt>Ext.util.Format</tt>.</li>  * </ul>  * This example demonstrates basic row striping using an inline code block and the <tt>xindex</tt> variable:</p>  * <pre><code> var tpl = new Ext.XTemplate(     '&lt;p>Name: {name}&lt;/p>',     '&lt;p>Company: {[values.company.toUpperCase() + ", " + values.title]}&lt;/p>',     '&lt;p>Kids: ',     '&lt;tpl for="kids">',        '&lt;div class="{[xindex % 2 === 0 ? "even" : "odd"]}">',         '{name}',         '&lt;/div>',     '&lt;/tpl>&lt;/p>' ); tpl.overwrite(panel.body, data); </code></pre>  * <p><b>Template member functions</b> <br/>One or more member functions can be defined directly on the config  * object passed into the XTemplate constructor for more complex processing:</p>  * <pre><code> var tpl = new Ext.XTemplate(     '&lt;p>Name: {name}&lt;/p>',     '&lt;p>Kids: ',     '&lt;tpl for="kids">',         '&lt;tpl if="this.isGirl(name)">',             '&lt;p>Girl: {name} - {age}&lt;/p>',         '&lt;/tpl>',         '&lt;tpl if="this.isGirl(name) == false">',             '&lt;p>Boy: {name} - {age}&lt;/p>',         '&lt;/tpl>',         '&lt;tpl if="this.isBaby(age)">',             '&lt;p>{name} is a baby!&lt;/p>',         '&lt;/tpl>',     '&lt;/tpl>&lt;/p>', {      isGirl: function(name){          return name == 'Sara Grace';      },      isBaby: function(age){         return age < 1;      } }); tpl.overwrite(panel.body, data); </code></pre>  * @constructor  * @param {String/Array/Object} parts The HTML fragment or an array of fragments to join(""), or multiple arguments  * to join("") that can also include a config object  */ Ext.XTemplate = function(){     Ext.XTemplate.superclass.constructor.apply(this, arguments);     var me = this,      s = me.html,      re = /<tplb[^>]*>((?:(?=([^<]+))2|<(?!tplb[^>]*>))*?)</tpl>/,      nameRe = /^<tplb[^>]*?for="(.*?)"/,      ifRe = /^<tplb[^>]*?if="(.*?)"/,      execRe = /^<tplb[^>]*?exec="(.*?)"/,      m,      id = 0,      tpls = [],      VALUES = 'values',      PARENT = 'parent',      XINDEX = 'xindex',      XCOUNT = 'xcount',      RETURN = 'return ',      WITHVALUES = 'with(values){ ';     s = ['<tpl>', s, '</tpl>'].join('');     while((m = s.match(re))){         var m2 = m[0].match(nameRe), m3 = m[0].match(ifRe),         m4 = m[0].match(execRe),         exp = null,         fn = null,         exec = null,         name = m2 && m2[1] ? m2[1] : '';        if (m3) {            exp = m3 && m3[1] ? m3[1] : null;            if(exp){                fn = new Function(VALUES, PARENT, XINDEX, XCOUNT, WITHVALUES + RETURN +(Ext.util.Format.htmlDecode(exp))+'; }');            }        }        if (m4) {            exp = m4 && m4[1] ? m4[1] : null;            if(exp){                exec = new Function(VALUES, PARENT, XINDEX, XCOUNT, WITHVALUES +(Ext.util.Format.htmlDecode(exp))+'; }');            }        }        if(name){            switch(name){                case '.': name = new Function(VALUES, PARENT, WITHVALUES + RETURN + VALUES + '; }'); break;                case '..': name = new Function(VALUES, PARENT, WITHVALUES + RETURN + PARENT + '; }'); break;                default: name = new Function(VALUES, PARENT, WITHVALUES + RETURN + name + '; }');            }        }        tpls.push({             id: id,             target: name,             exec: exec,             test: fn,             body: m[1]||''         });        s = s.replace(m[0], '{xtpl'+ id + '}');        ++id;     } Ext.each(tpls, function(t) {         me.compileTpl(t);     });     me.master = tpls[tpls.length-1];     me.tpls = tpls; }; Ext.extend(Ext.XTemplate, Ext.Template, {     // private     re : /{([w-.#]+)(?::([w.]*)(?:((.*?)?))?)?(s?[+-*\]s?[d.+-*\()]+)?}/g,     // private     codeRe : /{[((?:\]|.|n)*?)]}/g,     // private     applySubTemplate : function(id, values, parent, xindex, xcount){         var me = this,          len,          t = me.tpls[id],          vs,          buf = [];         if ((t.test && !t.test.call(me, values, parent, xindex, xcount)) ||             (t.exec && t.exec.call(me, values, parent, xindex, xcount))) {             return '';         }         vs = t.target ? t.target.call(me, values, parent) : values;         len = vs.length;         parent = t.target ? values : parent;         if(t.target && Ext.isArray(vs)){         Ext.each(vs, function(v, i) {                 buf[buf.length] = t.compiled.call(me, v, parent, i+1, len);             });             return buf.join('');         }         return t.compiled.call(me, vs, parent, xindex, xcount);     },     // private     compileTpl : function(tpl){         var fm = Ext.util.Format,         useF = this.disableFormats !== true,             sep = Ext.isGecko ? "+" : ",",             body;         function fn(m, name, format, args, math){             if(name.substr(0, 4) == 'xtpl'){                 return "'"+ sep +'this.applySubTemplate('+name.substr(4)+', values, parent, xindex, xcount)'+sep+"'";             }             var v;             if(name === '.'){                 v = 'values';             }else if(name === '#'){                 v = 'xindex';             }else if(name.indexOf('.') != -1){                 v = name;             }else{                 v = "values['" + name + "']";             }             if(math){                 v = '(' + v + math + ')';             }             if (format && useF) {                 args = args ? ',' + args : "";                 if(format.substr(0, 5) != "this."){                     format = "fm." + format + '(';                 }else{                     format = 'this.call("'+ format.substr(5) + '", ';                     args = ", values";                 }             } else {                 args= ''; format = "("+v+" === undefined ? '' : ";             }             return "'"+ sep + format + v + args + ")"+sep+"'";         }         function codeFn(m, code){             return "'"+ sep +'('+code+')'+sep+"'";         }         // branched to use + in gecko and [].join() in others         if(Ext.isGecko){             body = "tpl.compiled = function(values, parent, xindex, xcount){ return '" +                    tpl.body.replace(/(rn|n)/g, '\n').replace(/'/g, "\'").replace(this.re, fn).replace(this.codeRe, codeFn) +                     "';};";         }else{             body = ["tpl.compiled = function(values, parent, xindex, xcount){ return ['"];             body.push(tpl.body.replace(/(rn|n)/g, '\n').replace(/'/g, "\'").replace(this.re, fn).replace(this.codeRe, codeFn));             body.push("'].join('');};");             body = body.join('');         }         eval(body);         return this;     },     /**      * Returns an HTML fragment of this template with the specified values applied.      * @param {Object} values The template values. Can be an array if your params are numeric (i.e. {0}) or an object (i.e. {foo: 'bar'})      * @return {String} The HTML fragment      */     applyTemplate : function(values){         return this.master.compiled.call(this, values, {}, 1, 1);     },     /**      * Compile the template to a function for optimized performance.  Recommended if the template will be used frequently.      * @return {Function} The compiled function      */     compile : function(){return this;}     /**      * @property re      * @hide      */     /**      * @property disableFormats      * @hide      */     /**      * @method set      * @hide      */ }); /**  * Alias for {@link #applyTemplate}  * Returns an HTML fragment of this template with the specified values applied.  * @param {Object/Array} values The template values. Can be an array if your params are numeric (i.e. {0}) or an object (i.e. {foo: 'bar'})  * @return {String} The HTML fragment  * @member Ext.XTemplate  * @method apply  */ Ext.XTemplate.prototype.apply = Ext.XTemplate.prototype.applyTemplate; /**  * Creates a template from the passed element's value (<i>display:none</i> textarea, preferred) or innerHTML.  * @param {String/HTMLElement} el A DOM element or its id  * @return {Ext.Template} The created template  * @static  */ Ext.XTemplate.from = function(el){     el = Ext.getDom(el);     return new Ext.XTemplate(el.value || el.innerHTML); };/**
  83.  * @class Ext.util.CSS
  84.  * Utility class for manipulating CSS rules
  85.  * @singleton
  86.  */
  87. Ext.util.CSS = function(){
  88. var rules = null;
  89.     var doc = document;
  90.     var camelRe = /(-[a-z])/gi;
  91.     var camelFn = function(m, a){ return a.charAt(1).toUpperCase(); };
  92.    return {
  93.    /**
  94.     * Creates a stylesheet from a text blob of rules.
  95.     * These rules will be wrapped in a STYLE tag and appended to the HEAD of the document.
  96.     * @param {String} cssText The text containing the css rules
  97.     * @param {String} id An id to add to the stylesheet for later removal
  98.     * @return {StyleSheet}
  99.     */
  100.    createStyleSheet : function(cssText, id){
  101.        var ss;
  102.        var head = doc.getElementsByTagName("head")[0];
  103.        var rules = doc.createElement("style");
  104.        rules.setAttribute("type", "text/css");
  105.        if(id){
  106.            rules.setAttribute("id", id);
  107.        }
  108.        if(Ext.isIE){
  109.            head.appendChild(rules);
  110.            ss = rules.styleSheet;
  111.            ss.cssText = cssText;
  112.        }else{
  113.            try{
  114.                 rules.appendChild(doc.createTextNode(cssText));
  115.            }catch(e){
  116.                rules.cssText = cssText;
  117.            }
  118.            head.appendChild(rules);
  119.            ss = rules.styleSheet ? rules.styleSheet : (rules.sheet || doc.styleSheets[doc.styleSheets.length-1]);
  120.        }
  121.        this.cacheStyleSheet(ss);
  122.        return ss;
  123.    },
  124.    /**
  125.     * Removes a style or link tag by id
  126.     * @param {String} id The id of the tag
  127.     */
  128.    removeStyleSheet : function(id){
  129.        var existing = doc.getElementById(id);
  130.        if(existing){
  131.            existing.parentNode.removeChild(existing);
  132.        }
  133.    },
  134.    /**
  135.     * Dynamically swaps an existing stylesheet reference for a new one
  136.     * @param {String} id The id of an existing link tag to remove
  137.     * @param {String} url The href of the new stylesheet to include
  138.     */
  139.    swapStyleSheet : function(id, url){
  140.        this.removeStyleSheet(id);
  141.        var ss = doc.createElement("link");
  142.        ss.setAttribute("rel", "stylesheet");
  143.        ss.setAttribute("type", "text/css");
  144.        ss.setAttribute("id", id);
  145.        ss.setAttribute("href", url);
  146.        doc.getElementsByTagName("head")[0].appendChild(ss);
  147.    },
  148.    
  149.    /**
  150.     * Refresh the rule cache if you have dynamically added stylesheets
  151.     * @return {Object} An object (hash) of rules indexed by selector
  152.     */
  153.    refreshCache : function(){
  154.        return this.getRules(true);
  155.    },
  156.    // private
  157.    cacheStyleSheet : function(ss){
  158.        if(!rules){
  159.            rules = {};
  160.        }
  161.        try{// try catch for cross domain access issue
  162.            var ssRules = ss.cssRules || ss.rules;
  163.            for(var j = ssRules.length-1; j >= 0; --j){
  164.                rules[ssRules[j].selectorText] = ssRules[j];
  165.            }
  166.        }catch(e){}
  167.    },
  168.    
  169.    /**
  170.     * Gets all css rules for the document
  171.     * @param {Boolean} refreshCache true to refresh the internal cache
  172.     * @return {Object} An object (hash) of rules indexed by selector
  173.     */
  174.    getRules : function(refreshCache){
  175.     if(rules === null || refreshCache){
  176.     rules = {};
  177.     var ds = doc.styleSheets;
  178.     for(var i =0, len = ds.length; i < len; i++){
  179.         try{
  180.              this.cacheStyleSheet(ds[i]);
  181.          }catch(e){} 
  182.         }
  183.     }
  184.     return rules;
  185.     },
  186.    
  187.     /**
  188.     * Gets an an individual CSS rule by selector(s)
  189.     * @param {String/Array} selector The CSS selector or an array of selectors to try. The first selector that is found is returned.
  190.     * @param {Boolean} refreshCache true to refresh the internal cache if you have recently updated any rules or added styles dynamically
  191.     * @return {CSSRule} The CSS rule or null if one is not found
  192.     */
  193.    getRule : function(selector, refreshCache){
  194.     var rs = this.getRules(refreshCache);
  195.     if(!Ext.isArray(selector)){
  196.         return rs[selector];
  197.     }
  198.     for(var i = 0; i < selector.length; i++){
  199. if(rs[selector[i]]){
  200. return rs[selector[i]];
  201. }
  202. }
  203. return null;
  204.     },
  205.    
  206.    
  207.     /**
  208.     * Updates a rule property
  209.     * @param {String/Array} selector If it's an array it tries each selector until it finds one. Stops immediately once one is found.
  210.     * @param {String} property The css property
  211.     * @param {String} value The new value for the property
  212.     * @return {Boolean} true If a rule was found and updated
  213.     */
  214.    updateRule : function(selector, property, value){
  215.     if(!Ext.isArray(selector)){
  216.     var rule = this.getRule(selector);
  217.     if(rule){
  218.     rule.style[property.replace(camelRe, camelFn)] = value;
  219.     return true;
  220.     }
  221.     }else{
  222.     for(var i = 0; i < selector.length; i++){
  223.     if(this.updateRule(selector[i], property, value)){
  224.     return true;
  225.     }
  226.     }
  227.     }
  228.     return false;
  229.     }
  230.    };
  231. }();/**  @class Ext.util.ClickRepeater  @extends Ext.util.Observable  A wrapper class which can be applied to any element. Fires a "click" event while the  mouse is pressed. The interval between firings may be specified in the config but  defaults to 20 milliseconds.  Optionally, a CSS class may be applied to the element during the time it is pressed.  @cfg {Mixed} el The element to act as a button.  @cfg {Number} delay The initial delay before the repeating event begins firing.  Similar to an autorepeat key delay.  @cfg {Number} interval The interval between firings of the "click" event. Default 20 ms.  @cfg {String} pressClass A CSS class name to be applied to the element while pressed.  @cfg {Boolean} accelerate True if autorepeating should start slowly and accelerate.            "interval" and "delay" are ignored.  @cfg {Boolean} preventDefault True to prevent the default click event  @cfg {Boolean} stopDefault True to stop the default click event  @history     2007-02-02 jvs Original code contributed by Nige "Animal" White     2007-02-02 jvs Renamed to ClickRepeater     2007-02-03 jvs Modifications for FF Mac and Safari  @constructor  @param {Mixed} el The element to listen on  @param {Object} config  */ Ext.util.ClickRepeater = function(el, config) {     this.el = Ext.get(el);     this.el.unselectable();     Ext.apply(this, config);     this.addEvents(     /**      * @event mousedown      * Fires when the mouse button is depressed.      * @param {Ext.util.ClickRepeater} this      */         "mousedown",     /**      * @event click      * Fires on a specified interval during the time the element is pressed.      * @param {Ext.util.ClickRepeater} this      */         "click",     /**      * @event mouseup      * Fires when the mouse key is released.      * @param {Ext.util.ClickRepeater} this      */         "mouseup"     );     if(!this.disabled){         this.disabled = true;         this.enable();     }     // allow inline handler     if(this.handler){         this.on("click", this.handler,  this.scope || this);     }     Ext.util.ClickRepeater.superclass.constructor.call(this); }; Ext.extend(Ext.util.ClickRepeater, Ext.util.Observable, {     interval : 20,     delay: 250,     preventDefault : true,     stopDefault : false,     timer : 0,     /**      * Enables the repeater and allows events to fire.      */     enable: function(){         if(this.disabled){             this.el.on('mousedown', this.handleMouseDown, this);             if(this.preventDefault || this.stopDefault){                 this.el.on('click', this.eventOptions, this);             }         }         this.disabled = false;     },          /**      * Disables the repeater and stops events from firing.      */     disable: function(/* private */ force){         if(force || !this.disabled){             clearTimeout(this.timer);             if(this.pressClass){                 this.el.removeClass(this.pressClass);             }             Ext.getDoc().un('mouseup', this.handleMouseUp, this);             this.el.removeAllListeners();         }         this.disabled = true;     },          /**      * Convenience function for setting disabled/enabled by boolean.      * @param {Boolean} disabled      */     setDisabled: function(disabled){         this[disabled ? 'disable' : 'enable']();         },          eventOptions: function(e){         if(this.preventDefault){             e.preventDefault();         }         if(this.stopDefault){             e.stopEvent();         }            },          // private     destroy : function() {         this.disable(true);         Ext.destroy(this.el);         this.purgeListeners();     },          // private     handleMouseDown : function(){         clearTimeout(this.timer);         this.el.blur();         if(this.pressClass){             this.el.addClass(this.pressClass);         }         this.mousedownTime = new Date();         Ext.getDoc().on("mouseup", this.handleMouseUp, this);         this.el.on("mouseout", this.handleMouseOut, this);         this.fireEvent("mousedown", this);         this.fireEvent("click", this); //      Do not honor delay or interval if acceleration wanted.         if (this.accelerate) {             this.delay = 400;     }         this.timer = this.click.defer(this.delay || this.interval, this);     },     // private     click : function(){         this.fireEvent("click", this);         this.timer = this.click.defer(this.accelerate ?             this.easeOutExpo(this.mousedownTime.getElapsed(),                 400,                 -390,                 12000) :             this.interval, this);     },     easeOutExpo : function (t, b, c, d) {         return (t==d) ? b+c : c * (-Math.pow(2, -10 * t/d) + 1) + b;     },     // private     handleMouseOut : function(){         clearTimeout(this.timer);         if(this.pressClass){             this.el.removeClass(this.pressClass);         }         this.el.on("mouseover", this.handleMouseReturn, this);     },     // private     handleMouseReturn : function(){         this.el.un("mouseover", this.handleMouseReturn, this);         if(this.pressClass){             this.el.addClass(this.pressClass);         }         this.click();     },     // private     handleMouseUp : function(){         clearTimeout(this.timer);         this.el.un("mouseover", this.handleMouseReturn, this);         this.el.un("mouseout", this.handleMouseOut, this);         Ext.getDoc().un("mouseup", this.handleMouseUp, this);         this.el.removeClass(this.pressClass);         this.fireEvent("mouseup", this);     } });/**  * @class Ext.KeyNav  * <p>Provides a convenient wrapper for normalized keyboard navigation.  KeyNav allows you to bind  * navigation keys to function calls that will get called when the keys are pressed, providing an easy  * way to implement custom navigation schemes for any UI component.</p>  * <p>The following are all of the possible keys that can be implemented: enter, left, right, up, down, tab, esc,  * pageUp, pageDown, del, home, end.  Usage:</p>  <pre><code> var nav = new Ext.KeyNav("my-element", {     "left" : function(e){         this.moveLeft(e.ctrlKey);     },     "right" : function(e){         this.moveRight(e.ctrlKey);     },     "enter" : function(e){         this.save();     },     scope : this }); </code></pre>  * @constructor  * @param {Mixed} el The element to bind to  * @param {Object} config The config  */ Ext.KeyNav = function(el, config){     this.el = Ext.get(el);     Ext.apply(this, config);     if(!this.disabled){         this.disabled = true;         this.enable();     } }; Ext.KeyNav.prototype = {     /**      * @cfg {Boolean} disabled      * True to disable this KeyNav instance (defaults to false)      */     disabled : false,     /**      * @cfg {String} defaultEventAction      * The method to call on the {@link Ext.EventObject} after this KeyNav intercepts a key.  Valid values are      * {@link Ext.EventObject#stopEvent}, {@link Ext.EventObject#preventDefault} and      * {@link Ext.EventObject#stopPropagation} (defaults to 'stopEvent')      */     defaultEventAction: "stopEvent",     /**      * @cfg {Boolean} forceKeyDown      * Handle the keydown event instead of keypress (defaults to false).  KeyNav automatically does this for IE since      * IE does not propagate special keys on keypress, but setting this to true will force other browsers to also      * handle keydown instead of keypress.      */     forceKeyDown : false,     // private     prepareEvent : function(e){         var k = e.getKey();         var h = this.keyToHandler[k];         if(Ext.isSafari2 && h && k >= 37 && k <= 40){             e.stopEvent();         }     },     // private     relay : function(e){         var k = e.getKey();         var h = this.keyToHandler[k];         if(h && this[h]){             if(this.doRelay(e, this[h], h) !== true){                 e[this.defaultEventAction]();             }         }     },     // private     doRelay : function(e, h, hname){         return h.call(this.scope || this, e);     },     // possible handlers     enter : false,     left : false,     right : false,     up : false,     down : false,     tab : false,     esc : false,     pageUp : false,     pageDown : false,     del : false,     home : false,     end : false,     // quick lookup hash     keyToHandler : {         37 : "left",         39 : "right",         38 : "up",         40 : "down",         33 : "pageUp",         34 : "pageDown",         46 : "del",         36 : "home",         35 : "end",         13 : "enter",         27 : "esc",         9  : "tab"     }, /**  * Enable this KeyNav  */ enable: function(){ if(this.disabled){             // ie won't do special keys on keypress, no one else will repeat keys with keydown             // the EventObject will normalize Safari automatically             if(this.isKeydown()){                 this.el.on("keydown", this.relay,  this);             }else{                 this.el.on("keydown", this.prepareEvent,  this);                 this.el.on("keypress", this.relay,  this);             }     this.disabled = false; } }, /**  * Disable this KeyNav  */ disable: function(){ if(!this.disabled){     if(this.isKeydown()){                 this.el.un("keydown", this.relay, this);             }else{                 this.el.un("keydown", this.prepareEvent, this);                 this.el.un("keypress", this.relay, this);             }     this.disabled = true; } },          /**      * Convenience function for setting disabled/enabled by boolean.      * @param {Boolean} disabled      */     setDisabled : function(disabled){         this[disabled ? "disable" : "enable"]();     },          // private     isKeydown: function(){         return this.forceKeyDown || Ext.EventManager.useKeydown;     } }; /**
  232.  * @class Ext.KeyMap
  233.  * Handles mapping keys to actions for an element. One key map can be used for multiple actions.
  234.  * The constructor accepts the same config object as defined by {@link #addBinding}.
  235.  * If you bind a callback function to a KeyMap, anytime the KeyMap handles an expected key
  236.  * combination it will call the function with this signature (if the match is a multi-key
  237.  * combination the callback will still be called only once): (String key, Ext.EventObject e)
  238.  * A KeyMap can also handle a string representation of keys.<br />
  239.  * Usage:
  240.  <pre><code>
  241. // map one key by key code
  242. var map = new Ext.KeyMap("my-element", {
  243.     key: 13, // or Ext.EventObject.ENTER
  244.     fn: myHandler,
  245.     scope: myObject
  246. });
  247. // map multiple keys to one action by string
  248. var map = new Ext.KeyMap("my-element", {
  249.     key: "arnt",
  250.     fn: myHandler,
  251.     scope: myObject
  252. });
  253. // map multiple keys to multiple actions by strings and array of codes
  254. var map = new Ext.KeyMap("my-element", [
  255.     {
  256.         key: [10,13],
  257.         fn: function(){ alert("Return was pressed"); }
  258.     }, {
  259.         key: "abc",
  260.         fn: function(){ alert('a, b or c was pressed'); }
  261.     }, {
  262.         key: "t",
  263.         ctrl:true,
  264.         shift:true,
  265.         fn: function(){ alert('Control + shift + tab was pressed.'); }
  266.     }
  267. ]);
  268. </code></pre>
  269.  * <b>Note: A KeyMap starts enabled</b>
  270.  * @constructor
  271.  * @param {Mixed} el The element to bind to
  272.  * @param {Object} config The config (see {@link #addBinding})
  273.  * @param {String} eventName (optional) The event to bind to (defaults to "keydown")
  274.  */
  275. Ext.KeyMap = function(el, config, eventName){
  276.     this.el  = Ext.get(el);
  277.     this.eventName = eventName || "keydown";
  278.     this.bindings = [];
  279.     if(config){
  280.         this.addBinding(config);
  281.     }
  282.     this.enable();
  283. };
  284. Ext.KeyMap.prototype = {
  285.     /**
  286.      * True to stop the event from bubbling and prevent the default browser action if the
  287.      * key was handled by the KeyMap (defaults to false)
  288.      * @type Boolean
  289.      */
  290.     stopEvent : false,
  291.     /**
  292.      * Add a new binding to this KeyMap. The following config object properties are supported:
  293.      * <pre>
  294. Property    Type             Description
  295. ----------  ---------------  ----------------------------------------------------------------------
  296. key         String/Array     A single keycode or an array of keycodes to handle
  297. shift       Boolean          True to handle key only when shift is pressed, False to handle the key only when shift is not pressed (defaults to undefined)
  298. ctrl        Boolean          True to handle key only when ctrl is pressed, False to handle the key only when ctrl is not pressed (defaults to undefined)
  299. alt         Boolean          True to handle key only when alt is pressed, False to handle the key only when alt is not pressed (defaults to undefined)
  300. handler     Function         The function to call when KeyMap finds the expected key combination
  301. fn          Function         Alias of handler (for backwards-compatibility)
  302. scope       Object           The scope of the callback function
  303. stopEvent   Boolean          True to stop the event from bubbling and prevent the default browser action if the key was handled by the KeyMap (defaults to false)
  304. </pre>
  305.      *
  306.      * Usage:
  307.      * <pre><code>
  308. // Create a KeyMap
  309. var map = new Ext.KeyMap(document, {
  310.     key: Ext.EventObject.ENTER,
  311.     fn: handleKey,
  312.     scope: this
  313. });
  314. //Add a new binding to the existing KeyMap later
  315. map.addBinding({
  316.     key: 'abc',
  317.     shift: true,
  318.     fn: handleKey,
  319.     scope: this
  320. });
  321. </code></pre>
  322.      * @param {Object/Array} config A single KeyMap config or an array of configs
  323.      */
  324. addBinding : function(config){
  325.         if(Ext.isArray(config)){
  326.             Ext.each(config, function(c){
  327.                 this.addBinding(c);
  328.             }, this);
  329.             return;
  330.         }
  331.         var keyCode = config.key,
  332.             fn = config.fn || config.handler,
  333.             scope = config.scope;
  334. if (config.stopEvent) {
  335.     this.stopEvent = config.stopEvent;    
  336. }
  337.         if(typeof keyCode == "string"){
  338.             var ks = [];
  339.             var keyString = keyCode.toUpperCase();
  340.             for(var j = 0, len = keyString.length; j < len; j++){
  341.                 ks.push(keyString.charCodeAt(j));
  342.             }
  343.             keyCode = ks;
  344.         }
  345.         var keyArray = Ext.isArray(keyCode);
  346.         
  347.         var handler = function(e){
  348.             if(this.checkModifiers(config, e)){
  349.                 var k = e.getKey();
  350.                 if(keyArray){
  351.                     for(var i = 0, len = keyCode.length; i < len; i++){
  352.                         if(keyCode[i] == k){
  353.                           if(this.stopEvent){
  354.                               e.stopEvent();
  355.                           }
  356.                           fn.call(scope || window, k, e);
  357.                           return;
  358.                         }
  359.                     }
  360.                 }else{
  361.                     if(k == keyCode){
  362.                         if(this.stopEvent){
  363.                            e.stopEvent();
  364.                         }
  365.                         fn.call(scope || window, k, e);
  366.                     }
  367.                 }
  368.             }
  369.         };
  370.         this.bindings.push(handler);
  371. },
  372.     
  373.     // private
  374.     checkModifiers: function(config, e){
  375.         var val, key, keys = ['shift', 'ctrl', 'alt'];
  376.         for (var i = 0, len = keys.length; i < len; ++i){
  377.             key = keys[i];
  378.             val = config[key];
  379.             if(!(val === undefined || (val === e[key + 'Key']))){
  380.                 return false;
  381.             }
  382.         }
  383.         return true;
  384.     },
  385.     /**
  386.      * Shorthand for adding a single key listener
  387.      * @param {Number/Array/Object} key Either the numeric key code, array of key codes or an object with the
  388.      * following options:
  389.      * {key: (number or array), shift: (true/false), ctrl: (true/false), alt: (true/false)}
  390.      * @param {Function} fn The function to call
  391.      * @param {Object} scope (optional) The scope of the function
  392.      */
  393.     on : function(key, fn, scope){
  394.         var keyCode, shift, ctrl, alt;
  395.         if(typeof key == "object" && !Ext.isArray(key)){
  396.             keyCode = key.key;
  397.             shift = key.shift;
  398.             ctrl = key.ctrl;
  399.             alt = key.alt;
  400.         }else{
  401.             keyCode = key;
  402.         }
  403.         this.addBinding({
  404.             key: keyCode,
  405.             shift: shift,
  406.             ctrl: ctrl,
  407.             alt: alt,
  408.             fn: fn,
  409.             scope: scope
  410.         });
  411.     },
  412.     // private
  413.     handleKeyDown : function(e){
  414.     if(this.enabled){ //just in case
  415.          var b = this.bindings;
  416.          for(var i = 0, len = b.length; i < len; i++){
  417.              b[i].call(this, e);
  418.          }
  419.     }
  420. },
  421. /**
  422.  * Returns true if this KeyMap is enabled
  423.  * @return {Boolean}
  424.  */
  425. isEnabled : function(){
  426.     return this.enabled;
  427. },
  428. /**
  429.  * Enables this KeyMap
  430.  */
  431. enable: function(){
  432. if(!this.enabled){
  433.     this.el.on(this.eventName, this.handleKeyDown, this);
  434.     this.enabled = true;
  435. }
  436. },
  437. /**
  438.  * Disable this KeyMap
  439.  */
  440. disable: function(){
  441. if(this.enabled){
  442.     this.el.removeListener(this.eventName, this.handleKeyDown, this);
  443.     this.enabled = false;
  444. }
  445. },
  446.     
  447.     /**
  448.      * Convenience function for setting disabled/enabled by boolean.
  449.      * @param {Boolean} disabled
  450.      */
  451.     setDisabled : function(disabled){
  452.         this[disabled ? "disable" : "enable"]();
  453.     }
  454. };/**  * @class Ext.util.TextMetrics  * Provides precise pixel measurements for blocks of text so that you can determine exactly how high and  * wide, in pixels, a given block of text will be. Note that when measuring text, it should be plain text and  * should not contain any HTML, otherwise it may not be measured correctly.  * @singleton  */ Ext.util.TextMetrics = function(){     var shared;     return {         /**          * Measures the size of the specified text          * @param {String/HTMLElement} el The element, dom node or id from which to copy existing CSS styles          * that can affect the size of the rendered text          * @param {String} text The text to measure          * @param {Number} fixedWidth (optional) If the text will be multiline, you have to set a fixed width          * in order to accurately measure the text height          * @return {Object} An object containing the text's size {width: (width), height: (height)}          */         measure : function(el, text, fixedWidth){             if(!shared){                 shared = Ext.util.TextMetrics.Instance(el, fixedWidth);             }             shared.bind(el);             shared.setFixedWidth(fixedWidth || 'auto');             return shared.getSize(text);         },         /**          * Return a unique TextMetrics instance that can be bound directly to an element and reused.  This reduces          * the overhead of multiple calls to initialize the style properties on each measurement.          * @param {String/HTMLElement} el The element, dom node or id that the instance will be bound to          * @param {Number} fixedWidth (optional) If the text will be multiline, you have to set a fixed width          * in order to accurately measure the text height          * @return {Ext.util.TextMetrics.Instance} instance The new instance          */         createInstance : function(el, fixedWidth){             return Ext.util.TextMetrics.Instance(el, fixedWidth);         }     }; }(); Ext.util.TextMetrics.Instance = function(bindTo, fixedWidth){     var ml = new Ext.Element(document.createElement('div'));     document.body.appendChild(ml.dom);     ml.position('absolute');     ml.setLeftTop(-1000, -1000);     ml.hide();     if(fixedWidth){         ml.setWidth(fixedWidth);     }     var instance = {         /**          * Returns the size of the specified text based on the internal element's style and width properties          * @param {String} text The text to measure          * @return {Object} An object containing the text's size {width: (width), height: (height)}          */         getSize : function(text){             ml.update(text);             var s = ml.getSize();             ml.update('');             return s;         },         /**          * Binds this TextMetrics instance to an element from which to copy existing CSS styles          * that can affect the size of the rendered text          * @param {String/HTMLElement} el The element, dom node or id          */         bind : function(el){             ml.setStyle(                 Ext.fly(el).getStyles('font-size','font-style', 'font-weight', 'font-family','line-height', 'text-transform', 'letter-spacing')             );         },         /**          * Sets a fixed width on the internal measurement element.  If the text will be multiline, you have          * to set a fixed width in order to accurately measure the text height.          * @param {Number} width The width to set on the element          */         setFixedWidth : function(width){             ml.setWidth(width);         },         /**          * Returns the measured width of the specified text          * @param {String} text The text to measure          * @return {Number} width The width in pixels          */         getWidth : function(text){             ml.dom.style.width = 'auto';             return this.getSize(text).width;         },         /**          * Returns the measured height of the specified text.  For multiline text, be sure to call          * {@link #setFixedWidth} if necessary.          * @param {String} text The text to measure          * @return {Number} height The height in pixels          */         getHeight : function(text){             return this.getSize(text).height;         }     };     instance.bind(bindTo);     return instance; }; Ext.Element.addMethods({     /**      * Returns the width in pixels of the passed text, or the width of the text in this Element.      * @param {String} text The text to measure. Defaults to the innerHTML of the element.      * @param {Number} min (Optional) The minumum value to return.      * @param {Number} max (Optional) The maximum value to return.      * @return {Number} The text width in pixels.      * @member Ext.Element getTextWidth      */     getTextWidth : function(text, min, max){         return (Ext.util.TextMetrics.measure(this.dom, Ext.value(text, this.dom.innerHTML, true)).width).constrain(min || 0, max || 1000000);     } }); /**
  455.  * @class Ext.util.Cookies
  456.  * Utility class for managing and interacting with cookies.
  457.  * @singleton
  458.  */
  459. Ext.util.Cookies = {
  460.     /**
  461.      * Create a cookie with the specified name and value. Additional settings
  462.      * for the cookie may be optionally specified (for example: expiration,
  463.      * access restriction, SSL).
  464.      * @param {Object} name
  465.      * @param {Object} value
  466.      * @param {Object} expires (Optional) Specify an expiration date the
  467.      * cookie is to persist until.  Note that the specified Date object will
  468.      * be converted to Greenwich Mean Time (GMT). 
  469.      * @param {String} path (Optional) Setting a path on the cookie restricts
  470.      * access to pages that match that path. Defaults to all pages (<tt>'/'</tt>). 
  471.      * @param {String} domain (Optional) Setting a domain restricts access to
  472.      * pages on a given domain (typically used to allow cookie access across
  473.      * subdomains). For example, "extjs.com" will create a cookie that can be
  474.      * accessed from any subdomain of extjs.com, including www.extjs.com,
  475.      * support.extjs.com, etc.
  476.      * @param {Boolean} secure (Optional) Specify true to indicate that the cookie
  477.      * should only be accessible via SSL on a page using the HTTPS protocol.
  478.      * Defaults to <tt>false</tt>. Note that this will only work if the page
  479.      * calling this code uses the HTTPS protocol, otherwise the cookie will be
  480.      * created with default options.
  481.      */
  482.     set : function(name, value){
  483.         var argv = arguments;
  484.         var argc = arguments.length;
  485.         var expires = (argc > 2) ? argv[2] : null;
  486.         var path = (argc > 3) ? argv[3] : '/';
  487.         var domain = (argc > 4) ? argv[4] : null;
  488.         var secure = (argc > 5) ? argv[5] : false;
  489.         document.cookie = name + "=" + escape(value) + ((expires === null) ? "" : ("; expires=" + expires.toGMTString())) + ((path === null) ? "" : ("; path=" + path)) + ((domain === null) ? "" : ("; domain=" + domain)) + ((secure === true) ? "; secure" : "");
  490.     },
  491.     /**
  492.      * Retrieves cookies that are accessible by the current page. If a cookie
  493.      * does not exist, <code>get()</code> returns <tt>null</tt>.  The following
  494.      * example retrieves the cookie called "valid" and stores the String value
  495.      * in the variable <tt>validStatus</tt>.
  496.      * <pre><code>
  497.      * var validStatus = Ext.util.Cookies.get("valid");
  498.      * </code></pre>
  499.      * @param {Object} name The name of the cookie to get
  500.      * @return {Mixed} Returns the cookie value for the specified name;
  501.      * null if the cookie name does not exist.
  502.      */
  503.     get : function(name){
  504.         var arg = name + "=";
  505.         var alen = arg.length;
  506.         var clen = document.cookie.length;
  507.         var i = 0;
  508.         var j = 0;
  509.         while(i < clen){
  510.             j = i + alen;
  511.             if(document.cookie.substring(i, j) == arg){
  512.                 return Ext.util.Cookies.getCookieVal(j);
  513.             }
  514.             i = document.cookie.indexOf(" ", i) + 1;
  515.             if(i === 0){
  516.                 break;
  517.             }
  518.         }
  519.         return null;
  520.     },
  521.     /**
  522.      * Removes a cookie with the provided name from the browser
  523.      * if found.
  524.      * @param {Object} name The name of the cookie to remove
  525.      */
  526.     clear : function(name){
  527.         if(Ext.util.Cookies.get(name)){
  528.             document.cookie = name + "=" + "; expires=Thu, 01-Jan-70 00:00:01 GMT";
  529.         }
  530.     },
  531.     /**
  532.      * @private
  533.      */
  534.     getCookieVal : function(offset){
  535.         var endstr = document.cookie.indexOf(";", offset);
  536.         if(endstr == -1){
  537.             endstr = document.cookie.length;
  538.         }
  539.         return unescape(document.cookie.substring(offset, endstr));
  540.     }
  541. };/**  * Framework-wide error-handler.  Developers can override this method to provide  * custom exception-handling.  Framework errors will often extend from the base  * Ext.Error class.  * @param {Object/Error} e The thrown exception object.  */ Ext.handleError = function(e) {     throw e; }; /**  * @class Ext.Error  * @extends Error  * <p>A base error class. Future implementations are intended to provide more  * robust error handling throughout the framework (<b>in the debug build only</b>)  * to check for common errors and problems. The messages issued by this class  * will aid error checking. Error checks will be automatically removed in the  * production build so that performance is not negatively impacted.</p>  * <p>Some sample messages currently implemented:</p><pre> "DataProxy attempted to execute an API-action but found an undefined url / function. Please review your Proxy url/api-configuration."  * </pre><pre> "Could not locate your "root" property in your server response. Please review your JsonReader config to ensure the config-property "root" matches the property your server-response.  See the JsonReader docs for additional assistance."  * </pre>  * <p>An example of the code used for generating error messages:</p><pre><code> try {     generateError({         foo: 'bar'     }); } catch (e) {     console.error(e); } function generateError(data) {     throw new Ext.Error('foo-error', data); }  * </code></pre>  * @param {String} message  */ Ext.Error = function(message) {     // Try to read the message from Ext.Error.lang     this.message = (this.lang[message]) ? this.lang[message] : message; } Ext.Error.prototype = new Error(); Ext.apply(Ext.Error.prototype, {     // protected.  Extensions place their error-strings here.     lang: {},     name: 'Ext.Error',     /**      * getName      * @return {String}      */     getName : function() {         return this.name;     },     /**      * getMessage      * @return {String}      */     getMessage : function() {         return this.message;     },     /**      * toJson      * @return {String}      */     toJson : function() {         return Ext.encode(this);     } }); /**  * @class Ext.ComponentMgr  * <p>Provides a registry of all Components (instances of {@link Ext.Component} or any subclass  * thereof) on a page so that they can be easily accessed by {@link Ext.Component component}  * {@link Ext.Component#id id} (see {@link #get}, or the convenience method {@link Ext#getCmp Ext.getCmp}).</p>  * <p>This object also provides a registry of available Component <i>classes</i>  * indexed by a mnemonic code known as the Component's {@link Ext.Component#xtype xtype}.  * The <tt>{@link Ext.Component#xtype xtype}</tt> provides a way to avoid instantiating child Components  * when creating a full, nested config object for a complete Ext page.</p>  * <p>A child Component may be specified simply as a <i>config object</i>  * as long as the correct <tt>{@link Ext.Component#xtype xtype}</tt> is specified so that if and when the Component  * needs rendering, the correct type can be looked up for lazy instantiation.</p>  * <p>For a list of all available <tt>{@link Ext.Component#xtype xtypes}</tt>, see {@link Ext.Component}.</p>  * @singleton  */ Ext.ComponentMgr = function(){     var all = new Ext.util.MixedCollection();     var types = {};     var ptypes = {};     return {         /**          * Registers a component.          * @param {Ext.Component} c The component          */         register : function(c){             all.add(c);         },         /**          * Unregisters a component.          * @param {Ext.Component} c The component          */         unregister : function(c){             all.remove(c);         },         /**          * Returns a component by {@link Ext.Component#id id}.          * For additional details see {@link Ext.util.MixedCollection#get}.          * @param {String} id The component {@link Ext.Component#id id}          * @return Ext.Component The Component, <tt>undefined</tt> if not found, or <tt>null</tt> if a          * Class was found.          */         get : function(id){             return all.get(id);         },         /**          * Registers a function that will be called when a specified component is added to ComponentMgr          * @param {String} id The component {@link Ext.Component#id id}          * @param {Function} fn The callback function          * @param {Object} scope The scope of the callback          */         onAvailable : function(id, fn, scope){             all.on("add", function(index, o){                 if(o.id == id){                     fn.call(scope || o, o);                     all.un("add", fn, scope);                 }             });         },         /**          * The MixedCollection used internally for the component cache. An example usage may be subscribing to          * events on the MixedCollection to monitor addition or removal.  Read-only.          * @type {MixedCollection}          */         all : all,                  /**          * Checks if a Component type is registered.          * @param {Ext.Component} xtype The mnemonic string by which the Component class may be looked up          * @return {Boolean} Whether the type is registered.          */         isRegistered : function(xtype){             return types[xtype] !== undefined;             },         /**          * <p>Registers a new Component constructor, keyed by a new          * {@link Ext.Component#xtype}.</p>          * <p>Use this method (or its alias {@link Ext#reg Ext.reg}) to register new          * subclasses of {@link Ext.Component} so that lazy instantiation may be used when specifying          * child Components.          * see {@link Ext.Container#items}</p>          * @param {String} xtype The mnemonic string by which the Component class may be looked up.          * @param {Constructor} cls The new Component class.          */         registerType : function(xtype, cls){             types[xtype] = cls;             cls.xtype = xtype;         },         /**          * Creates a new Component from the specified config object using the          * config object's {@link Ext.component#xtype xtype} to determine the class to instantiate.          * @param {Object} config A configuration object for the Component you wish to create.          * @param {Constructor} defaultType The constructor to provide the default Component type if          * the config object does not contain a <tt>xtype</tt>. (Optional if the config contains a <tt>xtype</tt>).          * @return {Ext.Component} The newly instantiated Component.          */         create : function(config, defaultType){             return config.render ? config : new types[config.xtype || defaultType](config);         },         /**          * <p>Registers a new Plugin constructor, keyed by a new          * {@link Ext.Component#ptype}.</p>          * <p>Use this method (or its alias {@link Ext#preg Ext.preg}) to register new          * plugins for {@link Ext.Component}s so that lazy instantiation may be used when specifying          * Plugins.</p>          * @param {String} ptype The mnemonic string by which the Plugin class may be looked up.          * @param {Constructor} cls The new Plugin class.          */         registerPlugin : function(ptype, cls){             ptypes[ptype] = cls;             cls.ptype = ptype;         },         /**          * Creates a new Plugin from the specified config object using the          * config object's {@link Ext.component#ptype ptype} to determine the class to instantiate.          * @param {Object} config A configuration object for the Plugin you wish to create.          * @param {Constructor} defaultType The constructor to provide the default Plugin type if          * the config object does not contain a <tt>ptype</tt>. (Optional if the config contains a <tt>ptype</tt>).          * @return {Ext.Component} The newly instantiated Plugin.          */         createPlugin : function(config, defaultType){             return new ptypes[config.ptype || defaultType](config);         }     }; }(); /**  * Shorthand for {@link Ext.ComponentMgr#registerType}  * @param {String} xtype The {@link Ext.component#xtype mnemonic string} by which the Component class  * may be looked up.  * @param {Constructor} cls The new Component class.  * @member Ext  * @method reg  */ Ext.reg = Ext.ComponentMgr.registerType; // this will be called a lot internally, shorthand to keep the bytes down /**  * Shorthand for {@link Ext.ComponentMgr#registerPlugin}  * @param {String} ptype The {@link Ext.component#ptype mnemonic string} by which the Plugin class  * may be looked up.  * @param {Constructor} cls The new Plugin class.  * @member Ext  * @method preg  */ Ext.preg = Ext.ComponentMgr.registerPlugin; Ext.create = Ext.ComponentMgr.create; /**  * @class Ext.Component  * @extends Ext.util.Observable  * <p>Base class for all Ext components.  All subclasses of Component may participate in the automated  * Ext component lifecycle of creation, rendering and destruction which is provided by the {@link Ext.Container Container} class.  * Components may be added to a Container through the {@link Ext.Container#items items} config option at the time the Container is created,  * or they may be added dynamically via the {@link Ext.Container#add add} method.</p>  * <p>The Component base class has built-in support for basic hide/show and enable/disable behavior.</p>  * <p>All Components are registered with the {@link Ext.ComponentMgr} on construction so that they can be referenced at any time via  * {@link Ext#getCmp}, passing the {@link #id}.</p>  * <p>All user-developed visual widgets that are required to participate in automated lifecycle and size management should subclass Component (or  * {@link Ext.BoxComponent} if managed box model handling is required, ie height and width management).</p>  * <p>See the <a href="http://extjs.com/learn/Tutorial:Creating_new_UI_controls">Creating new UI controls</a> tutorial for details on how  * and to either extend or augment ExtJs base classes to create custom Components.</p>  * <p>Every component has a specific xtype, which is its Ext-specific type name, along with methods for checking the  * xtype like {@link #getXType} and {@link #isXType}. This is the list of all valid xtypes:</p>  * <pre> xtype            Class -------------    ------------------ box              {@link Ext.BoxComponent} button           {@link Ext.Button} buttongroup      {@link Ext.ButtonGroup} colorpalette     {@link Ext.ColorPalette} component        {@link Ext.Component} container        {@link Ext.Container} cycle            {@link Ext.CycleButton} dataview         {@link Ext.DataView} datepicker       {@link Ext.DatePicker} editor           {@link Ext.Editor} editorgrid       {@link Ext.grid.EditorGridPanel} flash            {@link Ext.FlashComponent} grid             {@link Ext.grid.GridPanel} listview         {@link Ext.ListView} panel            {@link Ext.Panel} progress         {@link Ext.ProgressBar} propertygrid     {@link Ext.grid.PropertyGrid} slider           {@link Ext.Slider} spacer           {@link Ext.Spacer} splitbutton      {@link Ext.SplitButton} tabpanel         {@link Ext.TabPanel} treepanel        {@link Ext.tree.TreePanel} viewport         {@link Ext.ViewPort} window           {@link Ext.Window} Toolbar components --------------------------------------- paging           {@link Ext.PagingToolbar} toolbar          {@link Ext.Toolbar} tbbutton         {@link Ext.Toolbar.Button}        (deprecated; use button) tbfill           {@link Ext.Toolbar.Fill} tbitem           {@link Ext.Toolbar.Item} tbseparator      {@link Ext.Toolbar.Separator} tbspacer         {@link Ext.Toolbar.Spacer} tbsplit          {@link Ext.Toolbar.SplitButton}   (deprecated; use splitbutton) tbtext           {@link Ext.Toolbar.TextItem} Menu components --------------------------------------- menu             {@link Ext.menu.Menu} colormenu        {@link Ext.menu.ColorMenu} datemenu         {@link Ext.menu.DateMenu} menubaseitem     {@link Ext.menu.BaseItem} menucheckitem    {@link Ext.menu.CheckItem} menuitem         {@link Ext.menu.Item} menuseparator    {@link Ext.menu.Separator} menutextitem     {@link Ext.menu.TextItem} Form components --------------------------------------- form             {@link Ext.FormPanel} checkbox         {@link Ext.form.Checkbox} checkboxgroup    {@link Ext.form.CheckboxGroup} combo            {@link Ext.form.ComboBox} datefield        {@link Ext.form.DateField} displayfield     {@link Ext.form.DisplayField} field            {@link Ext.form.Field} fieldset         {@link Ext.form.FieldSet} hidden           {@link Ext.form.Hidden} htmleditor       {@link Ext.form.HtmlEditor} label            {@link Ext.form.Label} numberfield      {@link Ext.form.NumberField} radio            {@link Ext.form.Radio} radiogroup       {@link Ext.form.RadioGroup} textarea         {@link Ext.form.TextArea} textfield        {@link Ext.form.TextField} timefield        {@link Ext.form.TimeField} trigger          {@link Ext.form.TriggerField} Chart components --------------------------------------- chart            {@link Ext.chart.Chart} barchart         {@link Ext.chart.BarChart} cartesianchart   {@link Ext.chart.CartesianChart} columnchart      {@link Ext.chart.ColumnChart} linechart        {@link Ext.chart.LineChart} piechart         {@link Ext.chart.PieChart} Store xtypes --------------------------------------- arraystore       {@link Ext.data.ArrayStore} directstore      {@link Ext.data.DirectStore} groupingstore    {@link Ext.data.GroupingStore} jsonstore        {@link Ext.data.JsonStore} simplestore      {@link Ext.data.SimpleStore}      (deprecated; use arraystore) store            {@link Ext.data.Store} xmlstore         {@link Ext.data.XmlStore} </pre>  * @constructor  * @param {Ext.Element/String/Object} config The configuration options may be specified as either:  * <div class="mdetail-params"><ul>  * <li><b>an element</b> :  * <p class="sub-desc">it is set as the internal element and its id used as the component id</p></li>  * <li><b>a string</b> :  * <p class="sub-desc">it is assumed to be the id of an existing element and is used as the component id</p></li>  * <li><b>anything else</b> :  * <p class="sub-desc">it is assumed to be a standard config object and is applied to the component</p></li>  * </ul></div>  */ Ext.Component = function(config){     config = config || {};     if(config.initialConfig){         if(config.isAction){           // actions             this.baseAction = config;         }         config = config.initialConfig; // component cloning / action set up     }else if(config.tagName || config.dom || Ext.isString(config)){ // element object         config = {applyTo: config, id: config.id || config};     }     /**      * This Component's initial configuration specification. Read-only.      * @type Object      * @property initialConfig      */     this.initialConfig = config;     Ext.apply(this, config);     this.addEvents(         /**          * @event disable          * Fires after the component is disabled.          * @param {Ext.Component} this          */         'disable',         /**          * @event enable          * Fires after the component is enabled.          * @param {Ext.Component} this          */         'enable',         /**          * @event beforeshow          * Fires before the component is shown by calling the {@link #show} method.          * Return false from an event handler to stop the show.          * @param {Ext.Component} this          */         'beforeshow',         /**          * @event show          * Fires after the component is shown when calling the {@link #show} method.          * @param {Ext.Component} this          */         'show',         /**          * @event beforehide          * Fires before the component is hidden by calling the {@link #hide} method.          * Return false from an event handler to stop the hide.          * @param {Ext.Component} this          */         'beforehide',         /**          * @event hide          * Fires after the component is hidden.          * Fires after the component is hidden when calling the {@link #hide} method.          * @param {Ext.Component} this          */         'hide',         /**          * @event beforerender          * Fires before the component is {@link #rendered}. Return false from an          * event handler to stop the {@link #render}.          * @param {Ext.Component} this          */         'beforerender',         /**          * @event render          * Fires after the component markup is {@link #rendered}.          * @param {Ext.Component} this          */         'render',         /**          * @event afterrender          * <p>Fires after the component rendering is finished.</p>          * <p>The afterrender event is fired after this Component has been {@link #rendered}, been postprocesed          * by any afterRender method defined for the Component, and, if {@link #stateful}, after state          * has been restored.</p>          * @param {Ext.Component} this          */         'afterrender',         /**          * @event beforedestroy          * Fires before the component is {@link #destroy}ed. Return false from an event handler to stop the {@link #destroy}.          * @param {Ext.Component} this          */         'beforedestroy',         /**          * @event destroy          * Fires after the component is {@link #destroy}ed.          * @param {Ext.Component} this          */         'destroy',         /**          * @event beforestaterestore          * Fires before the state of the component is restored. Return false from an event handler to stop the restore.          * @param {Ext.Component} this          * @param {Object} state The hash of state values returned from the StateProvider. If this          * event is not vetoed, then the state object is passed to <b><tt>applyState</tt></b>. By default,          * that simply copies property values into this Component. The method maybe overriden to          * provide custom state restoration.          */         'beforestaterestore',         /**          * @event staterestore          * Fires after the state of the component is restored.          * @param {Ext.Component} this          * @param {Object} state The hash of state values returned from the StateProvider. This is passed          * to <b><tt>applyState</tt></b>. By default, that simply copies property values into this          * Component. The method maybe overriden to provide custom state restoration.          */         'staterestore',         /**          * @event beforestatesave          * Fires before the state of the component is saved to the configured state provider. Return false to stop the save.          * @param {Ext.Component} this          * @param {Object} state The hash of state values. This is determined by calling          * <b><tt>getState()</tt></b> on the Component. This method must be provided by the          * developer to return whetever representation of state is required, by default, Ext.Component          * has a null implementation.          */         'beforestatesave',         /**          * @event statesave          * Fires after the state of the component is saved to the configured state provider.          * @param {Ext.Component} this          * @param {Object} state The hash of state values. This is determined by calling          * <b><tt>getState()</tt></b> on the Component. This method must be provided by the          * developer to return whetever representation of state is required, by default, Ext.Component          * has a null implementation.          */         'statesave'     );     this.getId();     Ext.ComponentMgr.register(this);     Ext.Component.superclass.constructor.call(this);     if(this.baseAction){         this.baseAction.addComponent(this);     }     this.initComponent();     if(this.plugins){         if(Ext.isArray(this.plugins)){             for(var i = 0, len = this.plugins.length; i < len; i++){                 this.plugins[i] = this.initPlugin(this.plugins[i]);             }         }else{             this.plugins = this.initPlugin(this.plugins);         }     }     if(this.stateful !== false){         this.initState(config);     }     if(this.applyTo){         this.applyToMarkup(this.applyTo);         delete this.applyTo;     }else if(this.renderTo){         this.render(this.renderTo);         delete this.renderTo;     } }; // private Ext.Component.AUTO_ID = 1000; Ext.extend(Ext.Component, Ext.util.Observable, { // Configs below are used for all Components when rendered by FormLayout.     /**      * @cfg {String} fieldLabel <p>The label text to display next to this Component (defaults to '').</p>      * <br><p><b>Note</b>: this config is only used when this Component is rendered by a Container which      * has been configured to use the <b>{@link Ext.layout.FormLayout FormLayout}</b> layout manager (e.g.      * {@link Ext.form.FormPanel} or specifying <tt>layout:'form'</tt>).</p><br>      * <p>Also see <tt>{@link #hideLabel}</tt> and      * {@link Ext.layout.FormLayout}.{@link Ext.layout.FormLayout#fieldTpl fieldTpl}.</p>      * Example use:<pre><code> new Ext.FormPanel({     height: 100,     renderTo: Ext.getBody(),     items: [{         xtype: 'textfield',         fieldLabel: 'Name'     }] }); </code></pre>      */     /**      * @cfg {String} labelStyle <p>A CSS style specification string to apply directly to this field's      * label.  Defaults to the container's labelStyle value if set (e.g.,      * <tt>{@link Ext.layout.FormLayout#labelStyle}</tt> , or '').</p>      * <br><p><b>Note</b>: see the note for <code>{@link #clearCls}</code>.</p><br>      * <p>Also see <code>{@link #hideLabel}</code> and      * <code>{@link Ext.layout.FormLayout}.{@link Ext.layout.FormLayout#fieldTpl fieldTpl}.</code></p>      * Example use:<pre><code> new Ext.FormPanel({     height: 100,     renderTo: Ext.getBody(),     items: [{         xtype: 'textfield',         fieldLabel: 'Name',         labelStyle: 'font-weight:bold;'     }] }); </code></pre>      */     /**      * @cfg {String} labelSeparator <p>The separator to display after the text of each      * <tt>{@link #fieldLabel}</tt>.  This property may be configured at various levels.      * The order of precedence is:      * <div class="mdetail-params"><ul>      * <li>field / component level</li>      * <li>container level</li>      * <li>{@link Ext.layout.FormLayout#labelSeparator layout level} (defaults to colon <tt>':'</tt>)</li>      * </ul></div>      * To display no separator for this field's label specify empty string ''.</p>      * <br><p><b>Note</b>: see the note for <tt>{@link #clearCls}</tt>.</p><br>      * <p>Also see <tt>{@link #hideLabel}</tt> and      * {@link Ext.layout.FormLayout}.{@link Ext.layout.FormLayout#fieldTpl fieldTpl}.</p>      * Example use:<pre><code> new Ext.FormPanel({     height: 100,     renderTo: Ext.getBody(),     layoutConfig: {         labelSeparator: '~'   // layout config has lowest priority (defaults to ':')     },     {@link Ext.layout.FormLayout#labelSeparator labelSeparator}: '>>',     // config at container level     items: [{         xtype: 'textfield',         fieldLabel: 'Field 1',         labelSeparator: '...' // field/component level config supersedes others     },{         xtype: 'textfield',         fieldLabel: 'Field 2' // labelSeparator will be '='     }] }); </code></pre>      */     /**      * @cfg {Boolean} hideLabel <p><tt>true</tt> to completely hide the label element      * ({@link #fieldLabel label} and {@link #labelSeparator separator}). Defaults to <tt>false</tt>.      * By default, even if you do not specify a <tt>{@link #fieldLabel}</tt> the space will still be      * reserved so that the field will line up with other fields that do have labels.      * Setting this to <tt>true</tt> will cause the field to not reserve that space.</p>      * <br><p><b>Note</b>: see the note for <tt>{@link #clearCls}</tt>.</p><br>      * Example use:<pre><code> new Ext.FormPanel({     height: 100,     renderTo: Ext.getBody(),     items: [{         xtype: 'textfield'         hideLabel: true     }] }); </code></pre>      */     /**      * @cfg {String} clearCls <p>The CSS class used to to apply to the special clearing div rendered      * directly after each form field wrapper to provide field clearing (defaults to      * <tt>'x-form-clear-left'</tt>).</p>      * <br><p><b>Note</b>: this config is only used when this Component is rendered by a Container      * which has been configured to use the <b>{@link Ext.layout.FormLayout FormLayout}</b> layout      * manager (e.g. {@link Ext.form.FormPanel} or specifying <tt>layout:'form'</tt>) and either a      * <tt>{@link #fieldLabel}</tt> is specified or <tt>isFormField=true</tt> is specified.</p><br>      * <p>See {@link Ext.layout.FormLayout}.{@link Ext.layout.FormLayout#fieldTpl fieldTpl} also.</p>      */     /**      * @cfg {String} itemCls <p>An additional CSS class to apply to the div wrapping the form item      * element of this field.  If supplied, <tt>itemCls</tt> at the <b>field</b> level will override      * the default <tt>itemCls</tt> supplied at the <b>container</b> level. The value specified for      * <tt>itemCls</tt> will be added to the default class (<tt>'x-form-item'</tt>).</p>      * <p>Since it is applied to the item wrapper (see      * {@link Ext.layout.FormLayout}.{@link Ext.layout.FormLayout#fieldTpl fieldTpl}), it allows      * you to write standard CSS rules that can apply to the field, the label (if specified), or      * any other element within the markup for the field.</p>      * <br><p><b>Note</b>: see the note for <tt>{@link #fieldLabel}</tt>.</p><br>      * Example use:<pre><code> // Apply a style to the field's label: &lt;style>     .required .x-form-item-label {font-weight:bold;color:red;} &lt;/style> new Ext.FormPanel({ height: 100, renderTo: Ext.getBody(), items: [{ xtype: 'textfield', fieldLabel: 'Name', itemCls: 'required' //this label will be styled },{ xtype: 'textfield', fieldLabel: 'Favorite Color' }] }); </code></pre>      */ // Configs below are used for all Components when rendered by AnchorLayout.     /**      * @cfg {String} anchor <p><b>Note</b>: this config is only used when this Component is rendered      * by a Container which has been configured to use an <b>{@link Ext.layout.AnchorLayout AnchorLayout}</b>      * based layout manager, for example:<div class="mdetail-params"><ul>      * <li>{@link Ext.form.FormPanel}</li>      * <li>specifying <code>layout: 'anchor' // or 'form', or 'absolute'</code></li>      * </ul></div></p>      * <p>See {@link Ext.layout.AnchorLayout}.{@link Ext.layout.AnchorLayout#anchor anchor} also.</p>      */     /**      * @cfg {String} id      * <p>The <b>unique</b> id of this component (defaults to an {@link #getId auto-assigned id}).      * You should assign an id if you need to be able to access the component later and you do      * not have an object reference available (e.g., using {@link Ext}.{@link Ext#getCmp getCmp}).</p>      * <p>Note that this id will also be used as the element id for the containing HTML element      * that is rendered to the page for this component. This allows you to write id-based CSS      * rules to style the specific instance of this component uniquely, and also to select      * sub-elements using this component's id as the parent.</p>      * <p><b>Note</b>: to avoid complications imposed by a unique <tt>id</tt> also see      * <code>{@link #itemId}</code> and <code>{@link #ref}</code>.</p>      * <p><b>Note</b>: to access the container of an item see <code>{@link #ownerCt}</code>.</p>      */     /**      * @cfg {String} itemId      * <p>An <tt>itemId</tt> can be used as an alternative way to get a reference to a component      * when no object reference is available.  Instead of using an <code>{@link #id}</code> with      * {@link Ext}.{@link Ext#getCmp getCmp}, use <code>itemId</code> with      * {@link Ext.Container}.{@link Ext.Container#getComponent getComponent} which will retrieve      * <code>itemId</code>'s or <tt>{@link #id}</tt>'s. Since <code>itemId</code>'s are an index to the      * container's internal MixedCollection, the <code>itemId</code> is scoped locally to the container --      * avoiding potential conflicts with {@link Ext.ComponentMgr} which requires a <b>unique</b>      * <code>{@link #id}</code>.</p>      * <pre><code> var c = new Ext.Panel({ //     {@link Ext.BoxComponent#height height}: 300,     {@link #renderTo}: document.body,     {@link Ext.Container#layout layout}: 'auto',     {@link Ext.Container#items items}: [         {             itemId: 'p1',             {@link Ext.Panel#title title}: 'Panel 1',             {@link Ext.BoxComponent#height height}: 150         },         {             itemId: 'p2',             {@link Ext.Panel#title title}: 'Panel 2',             {@link Ext.BoxComponent#height height}: 150         }     ] }) p1 = c.{@link Ext.Container#getComponent getComponent}('p1'); // not the same as {@link Ext#getCmp Ext.getCmp()} p2 = p1.{@link #ownerCt}.{@link Ext.Container#getComponent getComponent}('p2'); // reference via a sibling      * </code></pre>      * <p>Also see <tt>{@link #id}</tt> and <code>{@link #ref}</code>.</p>      * <p><b>Note</b>: to access the container of an item see <tt>{@link #ownerCt}</tt>.</p>      */     /**      * @cfg {String} xtype      * The registered <tt>xtype</tt> to create. This config option is not used when passing      * a config object into a constructor. This config option is used only when      * lazy instantiation is being used, and a child item of a Container is being      * specified not as a fully instantiated Component, but as a <i>Component config      * object</i>. The <tt>xtype</tt> will be looked up at render time up to determine what      * type of child Component to create.<br><br>      * The predefined xtypes are listed {@link Ext.Component here}.      * <br><br>      * If you subclass Components to create your own Components, you may register      * them using {@link Ext.ComponentMgr#registerType} in order to be able to      * take advantage of lazy instantiation and rendering.      */     /**      * @cfg {String} ptype      * The registered <tt>ptype</tt> to create. This config option is not used when passing      * a config object into a constructor. This config option is used only when      * lazy instantiation is being used, and a Plugin is being      * specified not as a fully instantiated Component, but as a <i>Component config      * object</i>. The <tt>ptype</tt> will be looked up at render time up to determine what      * type of Plugin to create.<br><br>      * If you create your own Plugins, you may register them using      * {@link Ext.ComponentMgr#registerPlugin} in order to be able to      * take advantage of lazy instantiation and rendering.      */     /**      * @cfg {String} cls      * An optional extra CSS class that will be added to this component's Element (defaults to '').  This can be      * useful for adding customized styles to the component or any of its children using standard CSS rules.      */     /**      * @cfg {String} overCls      * An optional extra CSS class that will be added to this component's Element when the mouse moves      * over the Element, and removed when the mouse moves out. (defaults to '').  This can be      * useful for adding customized 'active' or 'hover' styles to the component or any of its children using standard CSS rules.      */     /**      * @cfg {String} style      * A custom style specification to be applied to this component's Element.  Should be a valid argument to      * {@link Ext.Element#applyStyles}.      * <pre><code> new Ext.Panel({     title: 'Some Title',     renderTo: Ext.getBody(),     width: 400, height: 300,     layout: 'form',     items: [{         xtype: 'textarea',         style: {             width: '95%',             marginBottom: '10px'         }     },         new Ext.Button({             text: 'Send',             minWidth: '100',             style: {                 marginBottom: '10px'             }         })     ] });      * </code></pre>      */     /**      * @cfg {String} ctCls      * <p>An optional extra CSS class that will be added to this component's container. This can be useful for      * adding customized styles to the container or any of its children using standard CSS rules.  See      * {@link Ext.layout.ContainerLayout}.{@link Ext.layout.ContainerLayout#extraCls extraCls} also.</p>      * <p><b>Note</b>: <tt>ctCls</tt> defaults to <tt>''</tt> except for the following class      * which assigns a value by default:      * <div class="mdetail-params"><ul>      * <li>{@link Ext.layout.Box Box Layout} : <tt>'x-box-layout-ct'</tt></li>      * </ul></div>      * To configure the above Class with an extra CSS class append to the default.  For example,      * for BoxLayout (Hbox and Vbox):<pre><code>      * ctCls: 'x-box-layout-ct custom-class'      * </code></pre>      * </p>      */     /**      * @cfg {Boolean} disabled      * Render this component disabled (default is false).      */     disabled : false,     /**      * @cfg {Boolean} hidden      * Render this component hidden (default is false). If <tt>true</tt>, the      * {@link #hide} method will be called internally.      */     hidden : false,     /**      * @cfg {Object/Array} plugins      * An object or array of objects that will provide custom functionality for this component.  The only      * requirement for a valid plugin is that it contain an init method that accepts a reference of type Ext.Component.      * When a component is created, if any plugins are available, the component will call the init method on each      * plugin, passing a reference to itself.  Each plugin can then call methods or respond to events on the      * component as needed to provide its functionality.      */     /**      * @cfg {Mixed} applyTo      * <p>Specify the id of the element, a DOM element or an existing Element corresponding to a DIV      * that is already present in the document that specifies some structural markup for this      * component.</p><div><ul>      * <li><b>Description</b> : <ul>      * <div class="sub-desc">When <tt>applyTo</tt> is used, constituent parts of the component can also be specified      * by id or CSS class name within the main element, and the component being created may attempt      * to create its subcomponents from that markup if applicable.</div>      * </ul></li>      * <li><b>Notes</b> : <ul>      * <div class="sub-desc">When using this config, a call to render() is not required.</div>      * <div class="sub-desc">If applyTo is specified, any value passed for {@link #renderTo} will be ignored and the target      * element's parent node will automatically be used as the component's container.</div>      * </ul></li>      * </ul></div>      */     /**      * @cfg {Mixed} renderTo      * <p>Specify the id of the element, a DOM element or an existing Element that this component      * will be rendered into.</p><div><ul>      * <li><b>Notes</b> : <ul>      * <div class="sub-desc">Do <u>not</u> use this option if the Component is to be a child item of      * a {@link Ext.Container Container}. It is the responsibility of the      * {@link Ext.Container Container}'s {@link Ext.Container#layout layout manager}      * to render and manage its child items.</div>      * <div class="sub-desc">When using this config, a call to render() is not required.</div>      * </ul></li>      * </ul></div>      * <p>See <tt>{@link #render}</tt> also.</p>      */     /**      * @cfg {Boolean} stateful      * <p>A flag which causes the Component to attempt to restore the state of      * internal properties from a saved state on startup. The component must have      * either a <code>{@link #stateId}</code> or <code>{@link #id}</code> assigned      * for state to be managed. Auto-generated ids are not guaranteed to be stable      * across page loads and cannot be relied upon to save and restore the same      * state for a component.<p>      * <p>For state saving to work, the state manager's provider must have been      * set to an implementation of {@link Ext.state.Provider} which overrides the      * {@link Ext.state.Provider#set set} and {@link Ext.state.Provider#get get}      * methods to save and recall name/value pairs. A built-in implementation,      * {@link Ext.state.CookieProvider} is available.</p>      * <p>To set the state provider for the current page:</p>      * <pre><code> Ext.state.Manager.setProvider(new Ext.state.CookieProvider({     expires: new Date(new Date().getTime()+(1000*60*60*24*7)), //7 days from now }));      * </code></pre>      * <p>A stateful Component attempts to save state when one of the events      * listed in the <code>{@link #stateEvents}</code> configuration fires.</p>      * <p>To save state, a stateful Component first serializes its state by      * calling <b><code>getState</code></b>. By default, this function does      * nothing. The developer must provide an implementation which returns an      * object hash which represents the Component's restorable state.</p>      * <p>The value yielded by getState is passed to {@link Ext.state.Manager#set}      * which uses the configured {@link Ext.state.Provider} to save the object      * keyed by the Component's <code>{@link stateId}</code>, or, if that is not      * specified, its <code>{@link #id}</code>.</p>      * <p>During construction, a stateful Component attempts to <i>restore</i>      * its state by calling {@link Ext.state.Manager#get} passing the      * <code>{@link #stateId}</code>, or, if that is not specified, the      * <code>{@link #id}</code>.</p>      * <p>The resulting object is passed to <b><code>applyState</code></b>.      * The default implementation of <code>applyState</code> simply copies      * properties into the object, but a developer may override this to support      * more behaviour.</p>      * <p>You can perform extra processing on state save and restore by attaching      * handlers to the {@link #beforestaterestore}, {@link #staterestore},      * {@link #beforestatesave} and {@link #statesave} events.</p>      */     /**      * @cfg {String} stateId      * The unique id for this component to use for state management purposes      * (defaults to the component id if one was set, otherwise null if the      * component is using a generated id).      * <p>See <code>{@link #stateful}</code> for an explanation of saving and      * restoring Component state.</p>      */     /**      * @cfg {Array} stateEvents      * <p>An array of events that, when fired, should trigger this component to      * save its state (defaults to none). <code>stateEvents</code> may be any type      * of event supported by this component, including browser or custom events      * (e.g., <tt>['click', 'customerchange']</tt>).</p>      * <p>See <code>{@link #stateful}</code> for an explanation of saving and      * restoring Component state.</p>      */     /**      * @cfg {Mixed} autoEl      * <p>A tag name or {@link Ext.DomHelper DomHelper} spec used to create the {@link #getEl Element} which will      * encapsulate this Component.</p>      * <p>You do not normally need to specify this. For the base classes {@link Ext.Component}, {@link Ext.BoxComponent},      * and {@link Ext.Container}, this defaults to <b><tt>'div'</tt></b>. The more complex Ext classes use a more complex      * DOM structure created by their own onRender methods.</p>      * <p>This is intended to allow the developer to create application-specific utility Components encapsulated by      * different DOM elements. Example usage:</p><pre><code> {     xtype: 'box',     autoEl: {         tag: 'img',         src: 'http://www.example.com/example.jpg'     } }, {     xtype: 'box',     autoEl: {         tag: 'blockquote',         html: 'autoEl is cool!'     } }, {     xtype: 'container',     autoEl: 'ul',     cls: 'ux-unordered-list',     items: {         xtype: 'box',         autoEl: 'li',         html: 'First list item'     } } </code></pre>      */     autoEl : 'div',     /**      * @cfg {String} disabledClass      * CSS class added to the component when it is disabled (defaults to 'x-item-disabled').      */     disabledClass : 'x-item-disabled',     /**      * @cfg {Boolean} allowDomMove      * Whether the component can move the Dom node when rendering (defaults to true).      */     allowDomMove : true,     /**      * @cfg {Boolean} autoShow      * True if the component should check for hidden classes (e.g. 'x-hidden' or 'x-hide-display') and remove      * them on render (defaults to false).      */     autoShow : false,     /**      * @cfg {String} hideMode      * <p>How this component should be hidden. Supported values are <tt>'visibility'</tt>      * (css visibility), <tt>'offsets'</tt> (negative offset position) and <tt>'display'</tt>      * (css display).</p>      * <br><p><b>Note</b>: the default of <tt>'display'</tt> is generally preferred      * since items are automatically laid out when they are first shown (no sizing      * is done while hidden).</p>      */     hideMode : 'display',     /**      * @cfg {Boolean} hideParent      * True to hide and show the component's container when hide/show is called on the component, false to hide      * and show the component itself (defaults to false).  For example, this can be used as a shortcut for a hide      * button on a window by setting hide:true on the button when adding it to its parent container.      */     hideParent : false,     /**      * <p>The {@link Ext.Element} which encapsulates this Component. Read-only.</p>      * <p>This will <i>usually</i> be a &lt;DIV> element created by the class's onRender method, but      * that may be overridden using the <code>{@link #autoEl}</code> config.</p>      * <br><p><b>Note</b>: this element will not be available until this Component has been rendered.</p><br>      * <p>To add listeners for <b>DOM events</b> to this Component (as opposed to listeners      * for this Component's own Observable events), see the {@link Ext.util.Observable#listeners listeners}      * config for a suggestion, or use a render listener directly:</p><pre><code> new Ext.Panel({     title: 'The Clickable Panel',     listeners: {         render: function(p) {             // Append the Panel to the click handler&#39;s argument list.             p.getEl().on('click', handlePanelClick.createDelegate(null, [p], true));         },         single: true  // Remove the listener after first invocation     } }); </code></pre>      * <p>See also <tt>{@link #getEl getEl}</p>      * @type Ext.Element      * @property el      */     /**      * The component's owner {@link Ext.Container} (defaults to undefined, and is set automatically when      * the component is added to a container).  Read-only.      * <p><b>Note</b>: to access items within the container see <tt>{@link #itemId}</tt>.</p>      * @type Ext.Container      * @property ownerCt      */     /**      * True if this component is hidden. Read-only.      * @type Boolean      * @property      */     /**      * True if this component is disabled. Read-only.      * @type Boolean      * @property      */     /**      * True if this component has been rendered. Read-only.      * @type Boolean      * @property      */     rendered : false,     // private     ctype : 'Ext.Component',     // private     actionMode : 'el',     // private     getActionEl : function(){         return this[this.actionMode];     },     initPlugin : function(p){         if(p.ptype && !Ext.isFunction(p.init)){             p = Ext.ComponentMgr.createPlugin(p);         }else if(Ext.isString(p)){             p = Ext.ComponentMgr.createPlugin({                 ptype: p             });         }         p.init(this);         return p;     },     /* // protected      * Function to be implemented by Component subclasses to be part of standard component initialization flow (it is empty by default).      * <pre><code> // Traditional constructor: Ext.Foo = function(config){     // call superclass constructor:     Ext.Foo.superclass.constructor.call(this, config);     this.addEvents({         // add events     }); }; Ext.extend(Ext.Foo, Ext.Bar, {    // class body } // initComponent replaces the constructor: Ext.Foo = Ext.extend(Ext.Bar, {     initComponent : function(){         // call superclass initComponent         Ext.Container.superclass.initComponent.call(this);         this.addEvents({             // add events         });     } } </code></pre>      */     initComponent : Ext.emptyFn,     /**      * <p>Render this Component into the passed HTML element.</p>      * <p><b>If you are using a {@link Ext.Container Container} object to house this Component, then      * do not use the render method.</b></p>      * <p>A Container's child Components are rendered by that Container's      * {@link Ext.Container#layout layout} manager when the Container is first rendered.</p>      * <p>Certain layout managers allow dynamic addition of child components. Those that do      * include {@link Ext.layout.CardLayout}, {@link Ext.layout.AnchorLayout},      * {@link Ext.layout.FormLayout}, {@link Ext.layout.TableLayout}.</p>      * <p>If the Container is already rendered when a new child Component is added, you may need to call      * the Container's {@link Ext.Container#doLayout doLayout} to refresh the view which causes any      * unrendered child Components to be rendered. This is required so that you can add multiple      * child components if needed while only refreshing the layout once.</p>      * <p>When creating complex UIs, it is important to remember that sizing and positioning      * of child items is the responsibility of the Container's {@link Ext.Container#layout layout} manager.      * If you expect child items to be sized in response to user interactions, you must      * configure the Container with a layout manager which creates and manages the type of layout you      * have in mind.</p>      * <p><b>Omitting the Container's {@link Ext.Container#layout layout} config means that a basic      * layout manager is used which does nothing but render child components sequentially into the      * Container. No sizing or positioning will be performed in this situation.</b></p>      * @param {Element/HTMLElement/String} container (optional) The element this Component should be      * rendered into. If it is being created from existing markup, this should be omitted.      * @param {String/Number} position (optional) The element ID or DOM node index within the container <b>before</b>      * which this component will be inserted (defaults to appending to the end of the container)      */     render : function(container, position){         if(!this.rendered && this.fireEvent('beforerender', this) !== false){             if(!container && this.el){                 this.el = Ext.get(this.el);                 container = this.el.dom.parentNode;                 this.allowDomMove = false;             }             this.container = Ext.get(container);             if(this.ctCls){                 this.container.addClass(this.ctCls);             }             this.rendered = true;             if(position !== undefined){                 if(Ext.isNumber(position)){                     position = this.container.dom.childNodes[position];                 }else{                     position = Ext.getDom(position);                 }             }             this.onRender(this.container, position || null);             if(this.autoShow){                 this.el.removeClass(['x-hidden','x-hide-' + this.hideMode]);             }             if(this.cls){                 this.el.addClass(this.cls);                 delete this.cls;             }             if(this.style){                 this.el.applyStyles(this.style);                 delete this.style;             }             if(this.overCls){                 this.el.addClassOnOver(this.overCls);             }             this.fireEvent('render', this);             this.afterRender(this.container);             if(this.hidden){                 // call this so we don't fire initial hide events.                 this.doHide();             }             if(this.disabled){                 // pass silent so the event doesn't fire the first time.                 this.disable(true);             }             if(this.stateful !== false){                 this.initStateEvents();             }             this.initRef();             this.fireEvent('afterrender', this);         }         return this;     },     initRef : function(){         /**          * @cfg {String} ref          * <p>A path specification, relative to the Component's {@link #ownerCt} specifying into which          * ancestor Container to place a named reference to this Component.</p>          * <p>The ancestor axis can be traversed by using '/' characters in the path.          * For example, to put a reference to a Toolbar Button into <i>the Panel which owns the Toolbar</i>:</p><pre><code> var myGrid = new Ext.grid.EditorGridPanel({     title: 'My EditorGridPanel',     store: myStore,     colModel: myColModel,     tbar: [{         text: 'Save',         handler: saveChanges,         disabled: true,         ref: '../saveButton'     }],     listeners: {         afteredit: function() { //          The button reference is in the GridPanel             myGrid.saveButton.enable();         }     } }); </code></pre>          * <p>In the code above, if the ref had been <code>'saveButton'</code> the reference would          * have been placed into the Toolbar. Each '/' in the ref moves up one level from the          * Component's {@link #ownerCt}.</p>          */         if(this.ref){             var levels = this.ref.split('/');             var last = levels.length, i = 0;             var t = this;             while(i < last){                 if(t.ownerCt){                     t = t.ownerCt;                 }                 i++;             }             t[levels[--i]] = this;         }     },     // private     initState : function(config){         if(Ext.state.Manager){             var id = this.getStateId();             if(id){                 var state = Ext.state.Manager.get(id);                 if(state){                     if(this.fireEvent('beforestaterestore', this, state) !== false){                         this.applyState(state);                         this.fireEvent('staterestore', this, state);                     }                 }             }         }     },     // private     getStateId : function(){         return this.stateId || ((this.id.indexOf('ext-comp-') == 0 || this.id.indexOf('ext-gen') == 0) ? null : this.id);     },     // private     initStateEvents : function(){         if(this.stateEvents){             for(var i = 0, e; e = this.stateEvents[i]; i++){                 this.on(e, this.saveState, this, {delay:100});             }         }     },     // private     applyState : function(state, config){         if(state){             Ext.apply(this, state);         }     },     // private     getState : function(){         return null;     },     // private     saveState : function(){         if(Ext.state.Manager && this.stateful !== false){             var id = this.getStateId();             if(id){                 var state = this.getState();                 if(this.fireEvent('beforestatesave', this, state) !== false){                     Ext.state.Manager.set(id, state);                     this.fireEvent('statesave', this, state);                 }             }         }     },     /**      * Apply this component to existing markup that is valid. With this function, no call to render() is required.      * @param {String/HTMLElement} el      */     applyToMarkup : function(el){         this.allowDomMove = false;         this.el = Ext.get(el);         this.render(this.el.dom.parentNode);     },     /**      * Adds a CSS class to the component's underlying element.      * @param {string} cls The CSS class name to add      * @return {Ext.Component} this      */     addClass : function(cls){         if(this.el){             this.el.addClass(cls);         }else{             this.cls = this.cls ? this.cls + ' ' + cls : cls;         }         return this;     },     /**      * Removes a CSS class from the component's underlying element.      * @param {string} cls The CSS class name to remove      * @return {Ext.Component} this      */     removeClass : function(cls){         if(this.el){             this.el.removeClass(cls);         }else if(this.cls){             this.cls = this.cls.split(' ').remove(cls).join(' ');         }         return this;     },     // private     // default function is not really useful     onRender : function(ct, position){         if(!this.el && this.autoEl){             if(Ext.isString(this.autoEl)){                 this.el = document.createElement(this.autoEl);             }else{                 var div = document.createElement('div');                 Ext.DomHelper.overwrite(div, this.autoEl);                 this.el = div.firstChild;             }             if (!this.el.id) {                 this.el.id = this.getId();             }         }         if(this.el){             this.el = Ext.get(this.el);             if(this.allowDomMove !== false){                 ct.dom.insertBefore(this.el.dom, position);             }         }     },     // private     getAutoCreate : function(){         var cfg = Ext.isObject(this.autoCreate) ?                       this.autoCreate : Ext.apply({}, this.defaultAutoCreate);         if(this.id && !cfg.id){             cfg.id = this.id;         }         return cfg;     },     // private     afterRender : Ext.emptyFn,     /**      * Destroys this component by purging any event listeners, removing the component's element from the DOM,      * removing the component from its {@link Ext.Container} (if applicable) and unregistering it from      * {@link Ext.ComponentMgr}.  Destruction is generally handled automatically by the framework and this method      * should usually not need to be called directly.      *      */     destroy : function(){         if(this.fireEvent('beforedestroy', this) !== false){             this.beforeDestroy();             if(this.rendered){                 this.el.removeAllListeners();                 this.el.remove();                 if(this.actionMode == 'container' || this.removeMode == 'container'){                     this.container.remove();                 }             }             this.onDestroy();             Ext.ComponentMgr.unregister(this);             this.fireEvent('destroy', this);             this.purgeListeners();         }     },     // private     beforeDestroy : Ext.emptyFn,     // private     onDestroy  : Ext.emptyFn,     /**      * <p>Returns the {@link Ext.Element} which encapsulates this Component.</p>      * <p>This will <i>usually</i> be a &lt;DIV> element created by the class's onRender method, but      * that may be overridden using the {@link #autoEl} config.</p>      * <br><p><b>Note</b>: this element will not be available until this Component has been rendered.</p><br>      * <p>To add listeners for <b>DOM events</b> to this Component (as opposed to listeners      * for this Component's own Observable events), see the {@link #listeners} config for a suggestion,      * or use a render listener directly:</p><pre><code> new Ext.Panel({     title: 'The Clickable Panel',     listeners: {         render: function(p) {             // Append the Panel to the click handler&#39;s argument list.             p.getEl().on('click', handlePanelClick.createDelegate(null, [p], true));         },         single: true  // Remove the listener after first invocation     } }); </code></pre>      * @return {Ext.Element} The Element which encapsulates this Component.      */     getEl : function(){         return this.el;     },     /**      * Returns the <code>id</code> of this component or automatically generates and      * returns an <code>id</code> if an <code>id</code> is not defined yet:<pre><code>      * 'ext-comp-' + (++Ext.Component.AUTO_ID)      * </code></pre>      * @return {String} id      */     getId : function(){         return this.id || (this.id = 'ext-comp-' + (++Ext.Component.AUTO_ID));     },     /**      * Returns the <code>{@link #itemId}</code> of this component.  If an      * <code>{@link #itemId}</code> was not assigned through configuration the      * <code>id</code> is returned using <code>{@link #getId}</code>.      * @return {String}      */     getItemId : function(){         return this.itemId || this.getId();     },     /**      * Try to focus this component.      * @param {Boolean} selectText (optional) If applicable, true to also select the text in this component      * @param {Boolean/Number} delay (optional) Delay the focus this number of milliseconds (true for 10 milliseconds)      * @return {Ext.Component} this      */     focus : function(selectText, delay){         if(delay){             this.focus.defer(Ext.isNumber(delay) ? delay : 10, this, [selectText, false]);             return;         }         if(this.rendered){             this.el.focus();             if(selectText === true){                 this.el.dom.select();             }         }         return this;     },     // private     blur : function(){         if(this.rendered){             this.el.blur();         }         return this;     },     /**      * Disable this component and fire the 'disable' event.      * @return {Ext.Component} this      */     disable : function(/* private */ silent){         if(this.rendered){             this.onDisable();         }         this.disabled = true;         if(silent !== true){             this.fireEvent('disable', this);         }         return this;     },     // private     onDisable : function(){         this.getActionEl().addClass(this.disabledClass);         this.el.dom.disabled = true;     },     /**      * Enable this component and fire the 'enable' event.      * @return {Ext.Component} this      */     enable : function(){         if(this.rendered){             this.onEnable();         }         this.disabled = false;         this.fireEvent('enable', this);         return this;     },     // private     onEnable : function(){         this.getActionEl().removeClass(this.disabledClass);         this.el.dom.disabled = false;     },     /**      * Convenience function for setting disabled/enabled by boolean.      * @param {Boolean} disabled      * @return {Ext.Component} this      */     setDisabled : function(disabled){         return this[disabled ? 'disable' : 'enable']();     },     /**      * Show this component.  Listen to the '{@link #beforeshow}' event and return      * <tt>false</tt> to cancel showing the component.  Fires the '{@link #show}'      * event after showing the component.      * @return {Ext.Component} this      */     show : function(){         if(this.fireEvent('beforeshow', this) !== false){             this.hidden = false;             if(this.autoRender){                 this.render(Ext.isBoolean(this.autoRender) ? Ext.getBody() : this.autoRender);             }             if(this.rendered){                 this.onShow();             }             this.fireEvent('show', this);         }         return this;     },     // private     onShow : function(){         this.getVisibiltyEl().removeClass('x-hide-' + this.hideMode);     },     /**      * Hide this component.  Listen to the '{@link #beforehide}' event and return      * <tt>false</tt> to cancel hiding the component.  Fires the '{@link #hide}'      * event after hiding the component. Note this method is called internally if      * the component is configured to be <code>{@link #hidden}</code>.      * @return {Ext.Component} this      */     hide : function(){         if(this.fireEvent('beforehide', this) !== false){             this.doHide();             this.fireEvent('hide', this);         }         return this;     },     // private     doHide: function(){         this.hidden = true;         if(this.rendered){             this.onHide();         }     },     // private     onHide : function(){         this.getVisibiltyEl().addClass('x-hide-' + this.hideMode);     },     // private     getVisibiltyEl : function(){         return this.hideParent ? this.container : this.getActionEl();     },     /**      * Convenience function to hide or show this component by boolean.      * @param {Boolean} visible True to show, false to hide      * @return {Ext.Component} this      */     setVisible : function(visible){         return this[visible ? 'show' : 'hide']();     },     /**      * Returns true if this component is visible.      * @return {Boolean} True if this component is visible, false otherwise.      */     isVisible : function(){         return this.rendered && this.getVisibiltyEl().isVisible();     },     /**      * Clone the current component using the original config values passed into this instance by default.      * @param {Object} overrides A new config containing any properties to override in the cloned version.      * An id property can be passed on this object, otherwise one will be generated to avoid duplicates.      * @return {Ext.Component} clone The cloned copy of this component      */     cloneConfig : function(overrides){         overrides = overrides || {};         var id = overrides.id || Ext.id();         var cfg = Ext.applyIf(overrides, this.initialConfig);         cfg.id = id; // prevent dup id         return new this.constructor(cfg);     },     /**      * Gets the xtype for this component as registered with {@link Ext.ComponentMgr}. For a list of all      * available xtypes, see the {@link Ext.Component} header. Example usage:      * <pre><code> var t = new Ext.form.TextField(); alert(t.getXType());  // alerts 'textfield' </code></pre>      * @return {String} The xtype      */     getXType : function(){         return this.constructor.xtype;     },     /**      * <p>Tests whether or not this Component is of a specific xtype. This can test whether this Component is descended      * from the xtype (default) or whether it is directly of the xtype specified (shallow = true).</p>      * <p><b>If using your own subclasses, be aware that a Component must register its own xtype      * to participate in determination of inherited xtypes.</b></p>      * <p>For a list of all available xtypes, see the {@link Ext.Component} header.</p>      * <p>Example usage:</p>      * <pre><code> var t = new Ext.form.TextField(); var isText = t.isXType('textfield');        // true var isBoxSubclass = t.isXType('box');       // true, descended from BoxComponent var isBoxInstance = t.isXType('box', true); // false, not a direct BoxComponent instance </code></pre>      * @param {String} xtype The xtype to check for this Component      * @param {Boolean} shallow (optional) False to check whether this Component is descended from the xtype (this is      * the default), or true to check whether this Component is directly of the specified xtype.      * @return {Boolean} True if this component descends from the specified xtype, false otherwise.      */     isXType : function(xtype, shallow){         //assume a string by default         if (Ext.isFunction(xtype)){             xtype = xtype.xtype; //handle being passed the class, e.g. Ext.Component         }else if (Ext.isObject(xtype)){             xtype = xtype.constructor.xtype; //handle being passed an instance         }         return !shallow ? ('/' + this.getXTypes() + '/').indexOf('/' + xtype + '/') != -1 : this.constructor.xtype == xtype;     },     /**      * <p>Returns this Component's xtype hierarchy as a slash-delimited string. For a list of all      * available xtypes, see the {@link Ext.Component} header.</p>      * <p><b>If using your own subclasses, be aware that a Component must register its own xtype      * to participate in determination of inherited xtypes.</b></p>      * <p>Example usage:</p>      * <pre><code> var t = new Ext.form.TextField(); alert(t.getXTypes());  // alerts 'component/box/field/textfield' </code></pre>      * @return {String} The xtype hierarchy string      */     getXTypes : function(){         var tc = this.constructor;         if(!tc.xtypes){             var c = [], sc = this;             while(sc && sc.constructor.xtype){                 c.unshift(sc.constructor.xtype);                 sc = sc.constructor.superclass;             }             tc.xtypeChain = c;             tc.xtypes = c.join('/');         }         return tc.xtypes;     },     /**      * Find a container above this component at any level by a custom function. If the passed function returns      * true, the container will be returned.      * @param {Function} fn The custom function to call with the arguments (container, this component).      * @return {Ext.Container} The first Container for which the custom function returns true      */     findParentBy : function(fn) {         for (var p = this.ownerCt; (p != null) && !fn(p, this); p = p.ownerCt);         return p || null;     },     /**      * Find a container above this component at any level by xtype or class      * @param {String/Class} xtype The xtype string for a component, or the class of the component directly      * @return {Ext.Container} The first Container which matches the given xtype or class      */     findParentByType : function(xtype) {         return Ext.isFunction(xtype) ?             this.findParentBy(function(p){                 return p.constructor === xtype;             }) :             this.findParentBy(function(p){                 return p.constructor.xtype === xtype;             });     },     getDomPositionEl : function(){         return this.getPositionEl ? this.getPositionEl() : this.getEl();     },     // private     purgeListeners : function(){         Ext.Component.superclass.purgeListeners.call(this);         if(this.mons){             this.on('beforedestroy', this.clearMons, this, {single: true});         }     },     // private     clearMons : function(){         Ext.each(this.mons, function(m){             m.item.un(m.ename, m.fn, m.scope);         }, this);         this.mons = [];     },     // internal function for auto removal of assigned event handlers on destruction     mon : function(item, ename, fn, scope, opt){         if(!this.mons){             this.mons = [];             this.on('beforedestroy', this.clearMons, this, {single: true});         }         if(Ext.isObject(ename)){          var propRe = /^(?:scope|delay|buffer|single|stopEvent|preventDefault|stopPropagation|normalized|args|delegate)$/;             var o = ename;             for(var e in o){                 if(propRe.test(e)){                     continue;                 }                 if(Ext.isFunction(o[e])){                     // shared options         this.mons.push({             item: item, ename: e, fn: o[e], scope: o.scope         });         item.on(e, o[e], o.scope, o);                 }else{                     // individual options         this.mons.push({             item: item, ename: e, fn: o[e], scope: o.scope         });         item.on(e, o[e]);                 }             }             return;         }         this.mons.push({             item: item, ename: ename, fn: fn, scope: scope         });         item.on(ename, fn, scope, opt);     },     // protected, opposite of mon     mun : function(item, ename, fn, scope){         var found, mon;         for(var i = 0, len = this.mons.length; i < len; ++i){             mon = this.mons[i];             if(item === mon.item && ename == mon.ename && fn === mon.fn && scope === mon.scope){                 this.mons.splice(i, 1);                 item.un(ename, fn, scope);                 found = true;                 break;             }         }         return found;     },     /**      * Returns the next component in the owning container      * @return Ext.Component      */     nextSibling : function(){         if(this.ownerCt){             var index = this.ownerCt.items.indexOf(this);             if(index != -1 && index+1 < this.ownerCt.items.getCount()){                 return this.ownerCt.items.itemAt(index+1);             }         }         return null;     },     /**      * Returns the previous component in the owning container      * @return Ext.Component      */     previousSibling : function(){         if(this.ownerCt){             var index = this.ownerCt.items.indexOf(this);             if(index > 0){                 return this.ownerCt.items.itemAt(index-1);             }         }         return null;     },     /**      * Provides the link for Observable's fireEvent method to bubble up the ownership hierarchy.      * @return {Ext.Container} the Container which owns this Component.      */     getBubbleTarget : function(){         return this.ownerCt;     } }); Ext.reg('component', Ext.Component); /**
  542.  * @class Ext.Action
  543.  * <p>An Action is a piece of reusable functionality that can be abstracted out of any particular component so that it
  544.  * can be usefully shared among multiple components.  Actions let you share handlers, configuration options and UI
  545.  * updates across any components that support the Action interface (primarily {@link Ext.Toolbar}, {@link Ext.Button}
  546.  * and {@link Ext.menu.Menu} components).</p>
  547.  * <p>Aside from supporting the config object interface, any component that needs to use Actions must also support
  548.  * the following method list, as these will be called as needed by the Action class: setText(string), setIconCls(string),
  549.  * setDisabled(boolean), setVisible(boolean) and setHandler(function).</p>
  550.  * Example usage:<br>
  551.  * <pre><code>
  552. // Define the shared action.  Each component below will have the same
  553. // display text and icon, and will display the same message on click.
  554. var action = new Ext.Action({
  555.     {@link #text}: 'Do something',
  556.     {@link #handler}: function(){
  557.         Ext.Msg.alert('Click', 'You did something.');
  558.     },
  559.     {@link #iconCls}: 'do-something',
  560.     {@link #itemId}: 'myAction'
  561. });
  562. var panel = new Ext.Panel({
  563.     title: 'Actions',
  564.     width: 500,
  565.     height: 300,
  566.     tbar: [
  567.         // Add the action directly to a toolbar as a menu button
  568.         action,
  569.         {
  570.             text: 'Action Menu',
  571.             // Add the action to a menu as a text item
  572.             menu: [action]
  573.         }
  574.     ],
  575.     items: [
  576.         // Add the action to the panel body as a standard button
  577.         new Ext.Button(action)
  578.     ],
  579.     renderTo: Ext.getBody()
  580. });
  581. // Change the text for all components using the action
  582. action.setText('Something else');
  583. // Reference an action through a container using the itemId
  584. var btn = panel.getComponent('myAction');
  585. var aRef = btn.baseAction;
  586. aRef.setText('New text');
  587. </code></pre>
  588.  * @constructor
  589.  * @param {Object} config The configuration options
  590.  */
  591. Ext.Action = function(config){
  592.     this.initialConfig = config;
  593.     this.itemId = config.itemId = (config.itemId || config.id || Ext.id());
  594.     this.items = [];
  595. }
  596. Ext.Action.prototype = {
  597.     /**
  598.      * @cfg {String} text The text to set for all components using this action (defaults to '').
  599.      */
  600.     /**
  601.      * @cfg {String} iconCls
  602.      * The CSS class selector that specifies a background image to be used as the header icon for
  603.      * all components using this action (defaults to '').
  604.      * <p>An example of specifying a custom icon class would be something like:
  605.      * </p><pre><code>
  606. // specify the property in the config for the class:
  607.      ...
  608.      iconCls: 'do-something'
  609. // css class that specifies background image to be used as the icon image:
  610. .do-something { background-image: url(../images/my-icon.gif) 0 6px no-repeat !important; }
  611. </code></pre>
  612.      */
  613.     /**
  614.      * @cfg {Boolean} disabled True to disable all components using this action, false to enable them (defaults to false).
  615.      */
  616.     /**
  617.      * @cfg {Boolean} hidden True to hide all components using this action, false to show them (defaults to false).
  618.      */
  619.     /**
  620.      * @cfg {Function} handler The function that will be invoked by each component tied to this action
  621.      * when the component's primary event is triggered (defaults to undefined).
  622.      */
  623.     /**
  624.      * @cfg {String} itemId
  625.      * See {@link Ext.Component}.{@link Ext.Component#itemId itemId}.
  626.      */
  627.     /**
  628.      * @cfg {Object} scope The scope in which the {@link #handler} function will execute.
  629.      */
  630.     // private
  631.     isAction : true,
  632.     /**
  633.      * Sets the text to be displayed by all components using this action.
  634.      * @param {String} text The text to display
  635.      */
  636.     setText : function(text){
  637.         this.initialConfig.text = text;
  638.         this.callEach('setText', [text]);
  639.     },
  640.     /**
  641.      * Gets the text currently displayed by all components using this action.
  642.      */
  643.     getText : function(){
  644.         return this.initialConfig.text;
  645.     },
  646.     /**
  647.      * Sets the icon CSS class for all components using this action.  The class should supply
  648.      * a background image that will be used as the icon image.
  649.      * @param {String} cls The CSS class supplying the icon image
  650.      */
  651.     setIconClass : function(cls){
  652.         this.initialConfig.iconCls = cls;
  653.         this.callEach('setIconClass', [cls]);
  654.     },
  655.     /**
  656.      * Gets the icon CSS class currently used by all components using this action.
  657.      */
  658.     getIconClass : function(){
  659.         return this.initialConfig.iconCls;
  660.     },
  661.     /**
  662.      * Sets the disabled state of all components using this action.  Shortcut method
  663.      * for {@link #enable} and {@link #disable}.
  664.      * @param {Boolean} disabled True to disable the component, false to enable it
  665.      */
  666.     setDisabled : function(v){
  667.         this.initialConfig.disabled = v;
  668.         this.callEach('setDisabled', [v]);
  669.     },
  670.     /**
  671.      * Enables all components using this action.
  672.      */
  673.     enable : function(){
  674.         this.setDisabled(false);
  675.     },
  676.     /**
  677.      * Disables all components using this action.
  678.      */
  679.     disable : function(){
  680.         this.setDisabled(true);
  681.     },
  682.     /**
  683.      * Returns true if the components using this action are currently disabled, else returns false.  
  684.      */
  685.     isDisabled : function(){
  686.         return this.initialConfig.disabled;
  687.     },
  688.     /**
  689.      * Sets the hidden state of all components using this action.  Shortcut method
  690.      * for <code>{@link #hide}</code> and <code>{@link #show}</code>.
  691.      * @param {Boolean} hidden True to hide the component, false to show it
  692.      */
  693.     setHidden : function(v){
  694.         this.initialConfig.hidden = v;
  695.         this.callEach('setVisible', [!v]);
  696.     },
  697.     /**
  698.      * Shows all components using this action.
  699.      */
  700.     show : function(){
  701.         this.setHidden(false);
  702.     },
  703.     /**
  704.      * Hides all components using this action.
  705.      */
  706.     hide : function(){
  707.         this.setHidden(true);
  708.     },
  709.     /**
  710.      * Returns true if the components using this action are currently hidden, else returns false.  
  711.      */
  712.     isHidden : function(){
  713.         return this.initialConfig.hidden;
  714.     },
  715.     /**
  716.      * Sets the function that will be called by each component using this action when its primary event is triggered.
  717.      * @param {Function} fn The function that will be invoked by the action's components.  The function
  718.      * will be called with no arguments.
  719.      * @param {Object} scope The scope in which the function will execute
  720.      */
  721.     setHandler : function(fn, scope){
  722.         this.initialConfig.handler = fn;
  723.         this.initialConfig.scope = scope;
  724.         this.callEach('setHandler', [fn, scope]);
  725.     },
  726.     /**
  727.      * Executes the specified function once for each component currently tied to this action.  The function passed
  728.      * in should accept a single argument that will be an object that supports the basic Action config/method interface.
  729.      * @param {Function} fn The function to execute for each component
  730.      * @param {Object} scope The scope in which the function will execute
  731.      */
  732.     each : function(fn, scope){
  733.         Ext.each(this.items, fn, scope);
  734.     },
  735.     // private
  736.     callEach : function(fnName, args){
  737.         var cs = this.items;
  738.         for(var i = 0, len = cs.length; i < len; i++){
  739.             cs[i][fnName].apply(cs[i], args);
  740.         }
  741.     },
  742.     // private
  743.     addComponent : function(comp){
  744.         this.items.push(comp);
  745.         comp.on('destroy', this.removeComponent, this);
  746.     },
  747.     // private
  748.     removeComponent : function(comp){
  749.         this.items.remove(comp);
  750.     },
  751.     /**
  752.      * Executes this action manually using the handler function specified in the original config object
  753.      * or the handler function set with <code>{@link #setHandler}</code>.  Any arguments passed to this
  754.      * function will be passed on to the handler function.
  755.      * @param {Mixed} arg1 (optional) Variable number of arguments passed to the handler function
  756.      * @param {Mixed} arg2 (optional)
  757.      * @param {Mixed} etc... (optional)
  758.      */
  759.     execute : function(){
  760.         this.initialConfig.handler.apply(this.initialConfig.scope || window, arguments);
  761.     }
  762. }; /**  * @class Ext.Layer  * @extends Ext.Element  * An extended {@link Ext.Element} object that supports a shadow and shim, constrain to viewport and  * automatic maintaining of shadow/shim positions.  * @cfg {Boolean} shim False to disable the iframe shim in browsers which need one (defaults to true)  * @cfg {String/Boolean} shadow True to automatically create an {@link Ext.Shadow}, or a string indicating the  * shadow's display {@link Ext.Shadow#mode}. False to disable the shadow. (defaults to false)  * @cfg {Object} dh DomHelper object config to create element with (defaults to {tag: 'div', cls: 'x-layer'}).  * @cfg {Boolean} constrain False to disable constrain to viewport (defaults to true)  * @cfg {String} cls CSS class to add to the element  * @cfg {Number} zindex Starting z-index (defaults to 11000)  * @cfg {Number} shadowOffset Number of pixels to offset the shadow (defaults to 4)  * @cfg {Boolean} useDisplay  * Defaults to use css offsets to hide the Layer. Specify <tt>true</tt>  * to use css style <tt>'display:none;'</tt> to hide the Layer.  * @constructor  * @param {Object} config An object with config options.  * @param {String/HTMLElement} existingEl (optional) Uses an existing DOM element. If the element is not found it creates it.  */ (function(){ Ext.Layer = function(config, existingEl){     config = config || {};     var dh = Ext.DomHelper;     var cp = config.parentEl, pel = cp ? Ext.getDom(cp) : document.body;     if(existingEl){         this.dom = Ext.getDom(existingEl);     }     if(!this.dom){         var o = config.dh || {tag: 'div', cls: 'x-layer'};         this.dom = dh.append(pel, o);     }     if(config.cls){         this.addClass(config.cls);     }     this.constrain = config.constrain !== false;     this.setVisibilityMode(Ext.Element.VISIBILITY);     if(config.id){         this.id = this.dom.id = config.id;     }else{         this.id = Ext.id(this.dom);     }     this.zindex = config.zindex || this.getZIndex();     this.position('absolute', this.zindex);     if(config.shadow){         this.shadowOffset = config.shadowOffset || 4;         this.shadow = new Ext.Shadow({             offset : this.shadowOffset,             mode : config.shadow         });     }else{         this.shadowOffset = 0;     }     this.useShim = config.shim !== false && Ext.useShims;     this.useDisplay = config.useDisplay;     this.hide(); }; var supr = Ext.Element.prototype; // shims are shared among layer to keep from having 100 iframes var shims = []; Ext.extend(Ext.Layer, Ext.Element, {     getZIndex : function(){         return this.zindex || parseInt((this.getShim() || this).getStyle('z-index'), 10) || 11000;     },     getShim : function(){         if(!this.useShim){             return null;         }         if(this.shim){             return this.shim;         }         var shim = shims.shift();         if(!shim){             shim = this.createShim();             shim.enableDisplayMode('block');             shim.dom.style.display = 'none';             shim.dom.style.visibility = 'visible';         }         var pn = this.dom.parentNode;         if(shim.dom.parentNode != pn){             pn.insertBefore(shim.dom, this.dom);         }         shim.setStyle('z-index', this.getZIndex()-2);         this.shim = shim;         return shim;     },     hideShim : function(){         if(this.shim){             this.shim.setDisplayed(false);             shims.push(this.shim);             delete this.shim;         }     },     disableShadow : function(){         if(this.shadow){             this.shadowDisabled = true;             this.shadow.hide();             this.lastShadowOffset = this.shadowOffset;             this.shadowOffset = 0;         }     },     enableShadow : function(show){         if(this.shadow){             this.shadowDisabled = false;             this.shadowOffset = this.lastShadowOffset;             delete this.lastShadowOffset;             if(show){                 this.sync(true);             }         }     },     // private     // this code can execute repeatedly in milliseconds (i.e. during a drag) so     // code size was sacrificed for effeciency (e.g. no getBox/setBox, no XY calls)     sync : function(doShow){         var sw = this.shadow;         if(!this.updating && this.isVisible() && (sw || this.useShim)){             var sh = this.getShim();             var w = this.getWidth(),                 h = this.getHeight();             var l = this.getLeft(true),                 t = this.getTop(true);             if(sw && !this.shadowDisabled){                 if(doShow && !sw.isVisible()){                     sw.show(this);                 }else{                     sw.realign(l, t, w, h);                 }                 if(sh){                     if(doShow){                        sh.show();                     }                     // fit the shim behind the shadow, so it is shimmed too                     var a = sw.adjusts, s = sh.dom.style;                     s.left = (Math.min(l, l+a.l))+'px';                     s.top = (Math.min(t, t+a.t))+'px';                     s.width = (w+a.w)+'px';                     s.height = (h+a.h)+'px';                 }             }else if(sh){                 if(doShow){                    sh.show();                 }                 sh.setSize(w, h);                 sh.setLeftTop(l, t);             }         }     },     // private     destroy : function(){         this.hideShim();         if(this.shadow){             this.shadow.hide();         }         this.removeAllListeners();         Ext.removeNode(this.dom);         Ext.Element.uncache(this.id);     },     remove : function(){         this.destroy();     },     // private     beginUpdate : function(){         this.updating = true;     },     // private     endUpdate : function(){         this.updating = false;         this.sync(true);     },     // private     hideUnders : function(negOffset){         if(this.shadow){             this.shadow.hide();         }         this.hideShim();     },     // private     constrainXY : function(){         if(this.constrain){             var vw = Ext.lib.Dom.getViewWidth(),                 vh = Ext.lib.Dom.getViewHeight();             var s = Ext.getDoc().getScroll();             var xy = this.getXY();             var x = xy[0], y = xy[1];             var so = this.shadowOffset;             var w = this.dom.offsetWidth+so, h = this.dom.offsetHeight+so;             // only move it if it needs it             var moved = false;             // first validate right/bottom             if((x + w) > vw+s.left){                 x = vw - w - so;                 moved = true;             }             if((y + h) > vh+s.top){                 y = vh - h - so;                 moved = true;             }             // then make sure top/left isn't negative             if(x < s.left){                 x = s.left;                 moved = true;             }             if(y < s.top){                 y = s.top;                 moved = true;             }             if(moved){                 if(this.avoidY){                     var ay = this.avoidY;                     if(y <= ay && (y+h) >= ay){                         y = ay-h-5;                     }                 }                 xy = [x, y];                 this.storeXY(xy);                 supr.setXY.call(this, xy);                 this.sync();             }         }         return this;     },     isVisible : function(){         return this.visible;     },     // private     showAction : function(){         this.visible = true; // track visibility to prevent getStyle calls         if(this.useDisplay === true){             this.setDisplayed('');         }else if(this.lastXY){             supr.setXY.call(this, this.lastXY);         }else if(this.lastLT){             supr.setLeftTop.call(this, this.lastLT[0], this.lastLT[1]);         }     },     // private     hideAction : function(){         this.visible = false;         if(this.useDisplay === true){             this.setDisplayed(false);         }else{             this.setLeftTop(-10000,-10000);         }     },     // overridden Element method     setVisible : function(v, a, d, c, e){         if(v){             this.showAction();         }         if(a && v){             var cb = function(){                 this.sync(true);                 if(c){                     c();                 }             }.createDelegate(this);             supr.setVisible.call(this, true, true, d, cb, e);         }else{             if(!v){                 this.hideUnders(true);             }             var cb = c;             if(a){                 cb = function(){                     this.hideAction();                     if(c){                         c();                     }                 }.createDelegate(this);             }             supr.setVisible.call(this, v, a, d, cb, e);             if(v){                 this.sync(true);             }else if(!a){                 this.hideAction();             }         }         return this;     },     storeXY : function(xy){         delete this.lastLT;         this.lastXY = xy;     },     storeLeftTop : function(left, top){         delete this.lastXY;         this.lastLT = [left, top];     },     // private     beforeFx : function(){         this.beforeAction();         return Ext.Layer.superclass.beforeFx.apply(this, arguments);     },     // private     afterFx : function(){         Ext.Layer.superclass.afterFx.apply(this, arguments);         this.sync(this.isVisible());     },     // private     beforeAction : function(){         if(!this.updating && this.shadow){             this.shadow.hide();         }     },     // overridden Element method     setLeft : function(left){         this.storeLeftTop(left, this.getTop(true));         supr.setLeft.apply(this, arguments);         this.sync();         return this;     },     setTop : function(top){         this.storeLeftTop(this.getLeft(true), top);         supr.setTop.apply(this, arguments);         this.sync();         return this;     },     setLeftTop : function(left, top){         this.storeLeftTop(left, top);         supr.setLeftTop.apply(this, arguments);         this.sync();         return this;     },     setXY : function(xy, a, d, c, e){         this.fixDisplay();         this.beforeAction();         this.storeXY(xy);         var cb = this.createCB(c);         supr.setXY.call(this, xy, a, d, cb, e);         if(!a){             cb();         }         return this;     },     // private     createCB : function(c){         var el = this;         return function(){             el.constrainXY();             el.sync(true);             if(c){                 c();             }         };     },     // overridden Element method     setX : function(x, a, d, c, e){         this.setXY([x, this.getY()], a, d, c, e);         return this;     },     // overridden Element method     setY : function(y, a, d, c, e){         this.setXY([this.getX(), y], a, d, c, e);         return this;     },     // overridden Element method     setSize : function(w, h, a, d, c, e){         this.beforeAction();         var cb = this.createCB(c);         supr.setSize.call(this, w, h, a, d, cb, e);         if(!a){             cb();         }         return this;     },     // overridden Element method     setWidth : function(w, a, d, c, e){         this.beforeAction();         var cb = this.createCB(c);         supr.setWidth.call(this, w, a, d, cb, e);         if(!a){             cb();         }         return this;     },     // overridden Element method     setHeight : function(h, a, d, c, e){         this.beforeAction();         var cb = this.createCB(c);         supr.setHeight.call(this, h, a, d, cb, e);         if(!a){             cb();         }         return this;     },     // overridden Element method     setBounds : function(x, y, w, h, a, d, c, e){         this.beforeAction();         var cb = this.createCB(c);         if(!a){             this.storeXY([x, y]);             supr.setXY.call(this, [x, y]);             supr.setSize.call(this, w, h, a, d, cb, e);             cb();         }else{             supr.setBounds.call(this, x, y, w, h, a, d, cb, e);         }         return this;     },     /**      * Sets the z-index of this layer and adjusts any shadow and shim z-indexes. The layer z-index is automatically      * incremented by two more than the value passed in so that it always shows above any shadow or shim (the shadow      * element, if any, will be assigned z-index + 1, and the shim element, if any, will be assigned the unmodified z-index).      * @param {Number} zindex The new z-index to set      * @return {this} The Layer      */     setZIndex : function(zindex){         this.zindex = zindex;         this.setStyle('z-index', zindex + 2);         if(this.shadow){             this.shadow.setZIndex(zindex + 1);         }         if(this.shim){             this.shim.setStyle('z-index', zindex);         }         return this;     } }); })();/**  * @class Ext.Shadow  * Simple class that can provide a shadow effect for any element.  Note that the element MUST be absolutely positioned,  * and the shadow does not provide any shimming.  This should be used only in simple cases -- for more advanced  * functionality that can also provide the same shadow effect, see the {@link Ext.Layer} class.  * @constructor  * Create a new Shadow  * @param {Object} config The config object  */ Ext.Shadow = function(config){     Ext.apply(this, config);     if(typeof this.mode != "string"){         this.mode = this.defaultMode;     }     var o = this.offset, a = {h: 0};     var rad = Math.floor(this.offset/2);     switch(this.mode.toLowerCase()){ // all this hideous nonsense calculates the various offsets for shadows         case "drop":             a.w = 0;             a.l = a.t = o;             a.t -= 1;             if(Ext.isIE){                 a.l -= this.offset + rad;                 a.t -= this.offset + rad;                 a.w -= rad;                 a.h -= rad;                 a.t += 1;             }         break;         case "sides":             a.w = (o*2);             a.l = -o;             a.t = o-1;             if(Ext.isIE){                 a.l -= (this.offset - rad);                 a.t -= this.offset + rad;                 a.l += 1;                 a.w -= (this.offset - rad)*2;                 a.w -= rad + 1;                 a.h -= 1;             }         break;         case "frame":             a.w = a.h = (o*2);             a.l = a.t = -o;             a.t += 1;             a.h -= 2;             if(Ext.isIE){                 a.l -= (this.offset - rad);                 a.t -= (this.offset - rad);                 a.l += 1;                 a.w -= (this.offset + rad + 1);                 a.h -= (this.offset + rad);                 a.h += 1;             }         break;     };     this.adjusts = a; }; Ext.Shadow.prototype = {     /**      * @cfg {String} mode      * The shadow display mode.  Supports the following options:<div class="mdetail-params"><ul>      * <li><b><tt>sides</tt></b> : Shadow displays on both sides and bottom only</li>      * <li><b><tt>frame</tt></b> : Shadow displays equally on all four sides</li>      * <li><b><tt>drop</tt></b> : Traditional bottom-right drop shadow</li>      * </ul></div>      */     /**      * @cfg {String} offset      * The number of pixels to offset the shadow from the element (defaults to <tt>4</tt>)      */     offset: 4,     // private     defaultMode: "drop",     /**      * Displays the shadow under the target element      * @param {Mixed} targetEl The id or element under which the shadow should display      */     show : function(target){         target = Ext.get(target);         if(!this.el){             this.el = Ext.Shadow.Pool.pull();             if(this.el.dom.nextSibling != target.dom){                 this.el.insertBefore(target);             }         }         this.el.setStyle("z-index", this.zIndex || parseInt(target.getStyle("z-index"), 10)-1);         if(Ext.isIE){             this.el.dom.style.filter="progid:DXImageTransform.Microsoft.alpha(opacity=50) progid:DXImageTransform.Microsoft.Blur(pixelradius="+(this.offset)+")";         }         this.realign(             target.getLeft(true),             target.getTop(true),             target.getWidth(),             target.getHeight()         );         this.el.dom.style.display = "block";     },     /**      * Returns true if the shadow is visible, else false      */     isVisible : function(){         return this.el ? true : false;       },     /**      * Direct alignment when values are already available. Show must be called at least once before      * calling this method to ensure it is initialized.      * @param {Number} left The target element left position      * @param {Number} top The target element top position      * @param {Number} width The target element width      * @param {Number} height The target element height      */     realign : function(l, t, w, h){         if(!this.el){             return;         }         var a = this.adjusts, d = this.el.dom, s = d.style;         var iea = 0;         s.left = (l+a.l)+"px";         s.top = (t+a.t)+"px";         var sw = (w+a.w), sh = (h+a.h), sws = sw +"px", shs = sh + "px";         if(s.width != sws || s.height != shs){             s.width = sws;             s.height = shs;             if(!Ext.isIE){                 var cn = d.childNodes;                 var sww = Math.max(0, (sw-12))+"px";                 cn[0].childNodes[1].style.width = sww;                 cn[1].childNodes[1].style.width = sww;                 cn[2].childNodes[1].style.width = sww;                 cn[1].style.height = Math.max(0, (sh-12))+"px";             }         }     },     /**      * Hides this shadow      */     hide : function(){         if(this.el){             this.el.dom.style.display = "none";             Ext.Shadow.Pool.push(this.el);             delete this.el;         }     },     /**      * Adjust the z-index of this shadow      * @param {Number} zindex The new z-index      */     setZIndex : function(z){         this.zIndex = z;         if(this.el){             this.el.setStyle("z-index", z);         }     } }; // Private utility class that manages the internal Shadow cache Ext.Shadow.Pool = function(){     var p = [];     var markup = Ext.isIE ?                  '<div class="x-ie-shadow"></div>' :                  '<div class="x-shadow"><div class="xst"><div class="xstl"></div><div class="xstc"></div><div class="xstr"></div></div><div class="xsc"><div class="xsml"></div><div class="xsmc"></div><div class="xsmr"></div></div><div class="xsb"><div class="xsbl"></div><div class="xsbc"></div><div class="xsbr"></div></div></div>';     return {         pull : function(){             var sh = p.shift();             if(!sh){                 sh = Ext.get(Ext.DomHelper.insertHtml("beforeBegin", document.body.firstChild, markup));                 sh.autoBoxAdjust = false;             }             return sh;         },         push : function(sh){             p.push(sh);         }     }; }();/**  * @class Ext.BoxComponent  * @extends Ext.Component  * <p>Base class for any {@link Ext.Component Component} that is to be sized as a box, using width and height.</p>  * <p>BoxComponent provides automatic box model adjustments for sizing and positioning and will work correctly  * within the Component rendering model.</p>  * <p>A BoxComponent may be created as a custom Component which encapsulates any HTML element, either a pre-existing  * element, or one that is created to your specifications at render time. Usually, to participate in layouts,  * a Component will need to be a <b>Box</b>Component in order to have its width and height managed.</p>  * <p>To use a pre-existing element as a BoxComponent, configure it so that you preset the <b>el</b> property to the  * element to reference:<pre><code> var pageHeader = new Ext.BoxComponent({     el: 'my-header-div' });</code></pre>  * This may then be {@link Ext.Container#add added} to a {@link Ext.Container Container} as a child item.</p>  * <p>To create a BoxComponent based around a HTML element to be created at render time, use the  * {@link Ext.Component#autoEl autoEl} config option which takes the form of a  * {@link Ext.DomHelper DomHelper} specification:<pre><code> var myImage = new Ext.BoxComponent({     autoEl: {         tag: 'img',         src: '/images/my-image.jpg'     } });</code></pre></p>  * @constructor  * @param {Ext.Element/String/Object} config The configuration options.  * @xtype box  */ Ext.BoxComponent = Ext.extend(Ext.Component, {     // Configs below are used for all Components when rendered by BorderLayout.     /**      * @cfg {String} region <p><b>Note</b>: this config is only used when this BoxComponent is rendered      * by a Container which has been configured to use the <b>{@link Ext.layout.BorderLayout BorderLayout}</b>      * layout manager (e.g. specifying <tt>layout:'border'</tt>).</p><br>      * <p>See {@link Ext.layout.BorderLayout} also.</p>      */     // margins config is used when a BoxComponent is rendered by BorderLayout or BoxLayout.     /**      * @cfg {Object} margins <p><b>Note</b>: this config is only used when this BoxComponent is rendered      * by a Container which has been configured to use the <b>{@link Ext.layout.BorderLayout BorderLayout}</b>      * or one of the two <b>{@link Ext.layout.BoxLayout BoxLayout} subclasses.</b></p>      * <p>An object containing margins to apply to this BoxComponent in the      * format:</p><pre><code> {     top: (top margin),     right: (right margin),     bottom: (bottom margin),     left: (left margin) }</code></pre>      * <p>May also be a string containing space-separated, numeric margin values. The order of the      * sides associated with each value matches the way CSS processes margin values:</p>      * <p><div class="mdetail-params"><ul>      * <li>If there is only one value, it applies to all sides.</li>      * <li>If there are two values, the top and bottom borders are set to the first value and the      * right and left are set to the second.</li>      * <li>If there are three values, the top is set to the first value, the left and right are set      * to the second, and the bottom is set to the third.</li>      * <li>If there are four values, they apply to the top, right, bottom, and left, respectively.</li>      * </ul></div></p>      * <p>Defaults to:</p><pre><code>      * {top:0, right:0, bottom:0, left:0}      * </code></pre>      */     /**      * @cfg {Number} x      * The local x (left) coordinate for this component if contained within a positioning container.      */     /**      * @cfg {Number} y      * The local y (top) coordinate for this component if contained within a positioning container.      */     /**      * @cfg {Number} pageX      * The page level x coordinate for this component if contained within a positioning container.      */     /**      * @cfg {Number} pageY      * The page level y coordinate for this component if contained within a positioning container.      */     /**      * @cfg {Number} height      * The height of this component in pixels (defaults to auto).      * <b>Note</b> to express this dimension as a percentage or offset see {@link Ext.Component#anchor}.      */     /**      * @cfg {Number} width      * The width of this component in pixels (defaults to auto).      * <b>Note</b> to express this dimension as a percentage or offset see {@link Ext.Component#anchor}.      */     /**      * @cfg {Boolean} autoHeight      * <p>True to use height:'auto', false to use fixed height (or allow it to be managed by its parent      * Container's {@link Ext.Container#layout layout manager}. Defaults to false.</p>      * <p><b>Note</b>: Although many components inherit this config option, not all will      * function as expected with a height of 'auto'. Setting autoHeight:true means that the      * browser will manage height based on the element's contents, and that Ext will not manage it at all.</p>      * <p>If the <i>browser</i> is managing the height, be aware that resizes performed by the browser in response      * to changes within the structure of the Component cannot be detected. Therefore changes to the height might      * result in elements needing to be synchronized with the new height. Example:</p><pre><code> var w = new Ext.Window({     title: 'Window',     width: 600,     autoHeight: true,     items: {         title: 'Collapse Me',         height: 400,         collapsible: true,         border: false,         listeners: {             beforecollapse: function() {                 w.el.shadow.hide();             },             beforeexpand: function() {                 w.el.shadow.hide();             },             collapse: function() {                 w.syncShadow();             },             expand: function() {                 w.syncShadow();             }         }     } }).show(); </code></pre>      */     /**      * @cfg {Boolean} autoWidth      * <p>True to use width:'auto', false to use fixed width (or allow it to be managed by its parent      * Container's {@link Ext.Container#layout layout manager}. Defaults to false.</p>      * <p><b>Note</b>: Although many components  inherit this config option, not all will      * function as expected with a width of 'auto'. Setting autoWidth:true means that the      * browser will manage width based on the element's contents, and that Ext will not manage it at all.</p>      * <p>If the <i>browser</i> is managing the width, be aware that resizes performed by the browser in response      * to changes within the structure of the Component cannot be detected. Therefore changes to the width might      * result in elements needing to be synchronized with the new width. For example, where the target element is:</p><pre><code> &lt;div id='grid-container' style='margin-left:25%;width:50%'>&lt;/div> </code></pre>      * A Panel rendered into that target element must listen for browser window resize in order to relay its       * child items when the browser changes its width:<pre><code> var myPanel = new Ext.Panel({     renderTo: 'grid-container',     monitorResize: true, // relay on browser resize     title: 'Panel',     height: 400,     autoWidth: true,     layout: 'hbox',     layoutConfig: {         align: 'stretch'     },     defaults: {         flex: 1     },     items: [{         title: 'Box 1',     }, {         title: 'Box 2'     }, {         title: 'Box 3'     }], }); </code></pre>      */     /* // private internal config      * {Boolean} deferHeight      * True to defer height calculations to an external component, false to allow this component to set its own      * height (defaults to false).      */     // private     initComponent : function(){         Ext.BoxComponent.superclass.initComponent.call(this);         this.addEvents(             /**              * @event resize              * Fires after the component is resized.              * @param {Ext.Component} this              * @param {Number} adjWidth The box-adjusted width that was set              * @param {Number} adjHeight The box-adjusted height that was set              * @param {Number} rawWidth The width that was originally specified              * @param {Number} rawHeight The height that was originally specified              */             'resize',             /**              * @event move              * Fires after the component is moved.              * @param {Ext.Component} this              * @param {Number} x The new x position              * @param {Number} y The new y position              */             'move'         );     },     // private, set in afterRender to signify that the component has been rendered     boxReady : false,     // private, used to defer height settings to subclasses     deferHeight: false,     /**      * Sets the width and height of this BoxComponent. This method fires the {@link #resize} event. This method can accept      * either width and height as separate arguments, or you can pass a size object like <code>{width:10, height:20}</code>.      * @param {Mixed} width The new width to set. This may be one of:<div class="mdetail-params"><ul>      * <li>A Number specifying the new width in the {@link #getEl Element}'s {@link Ext.Element#defaultUnit}s (by default, pixels).</li>      * <li>A String used to set the CSS width style.</li>      * <li>A size object in the format <code>{width: widthValue, height: heightValue}</code>.</li>      * <li><code>undefined</code> to leave the width unchanged.</li>      * </ul></div>      * @param {Mixed} height The new height to set (not required if a size object is passed as the first arg).      * This may be one of:<div class="mdetail-params"><ul>      * <li>A Number specifying the new height in the {@link #getEl Element}'s {@link Ext.Element#defaultUnit}s (by default, pixels).</li>      * <li>A String used to set the CSS height style. Animation may <b>not</b> be used.</li>      * <li><code>undefined</code> to leave the height unchanged.</li>      * </ul></div>      * @return {Ext.BoxComponent} this      */     setSize : function(w, h){         // support for standard size objects         if(typeof w == 'object'){             h = w.height;             w = w.width;         }         // not rendered         if(!this.boxReady){             this.width = w;             this.height = h;             return this;         }         // prevent recalcs when not needed         if(this.cacheSizes !== false && this.lastSize && this.lastSize.width == w && this.lastSize.height == h){             return this;         }         this.lastSize = {width: w, height: h};         var adj = this.adjustSize(w, h);         var aw = adj.width, ah = adj.height;         if(aw !== undefined || ah !== undefined){ // this code is nasty but performs better with floaters             var rz = this.getResizeEl();             if(!this.deferHeight && aw !== undefined && ah !== undefined){                 rz.setSize(aw, ah);             }else if(!this.deferHeight && ah !== undefined){                 rz.setHeight(ah);             }else if(aw !== undefined){                 rz.setWidth(aw);             }             this.onResize(aw, ah, w, h);             this.fireEvent('resize', this, aw, ah, w, h);         }         return this;     },     /**      * Sets the width of the component.  This method fires the {@link #resize} event.      * @param {Number} width The new width to setThis may be one of:<div class="mdetail-params"><ul>      * <li>A Number specifying the new width in the {@link #getEl Element}'s {@link Ext.Element#defaultUnit}s (by default, pixels).</li>      * <li>A String used to set the CSS width style.</li>      * </ul></div>      * @return {Ext.BoxComponent} this      */     setWidth : function(width){         return this.setSize(width);     },     /**      * Sets the height of the component.  This method fires the {@link #resize} event.      * @param {Number} height The new height to set. This may be one of:<div class="mdetail-params"><ul>      * <li>A Number specifying the new height in the {@link #getEl Element}'s {@link Ext.Element#defaultUnit}s (by default, pixels).</li>      * <li>A String used to set the CSS height style.</li>      * <li><i>undefined</i> to leave the height unchanged.</li>      * </ul></div>      * @return {Ext.BoxComponent} this      */     setHeight : function(height){         return this.setSize(undefined, height);     },     /**      * Gets the current size of the component's underlying element.      * @return {Object} An object containing the element's size {width: (element width), height: (element height)}      */     getSize : function(){         return this.getResizeEl().getSize();     },     /**      * Gets the current width of the component's underlying element.      * @return {Number}      */     getWidth : function(){         return this.getResizeEl().getWidth();     },     /**      * Gets the current height of the component's underlying element.      * @return {Number}      */     getHeight : function(){         return this.getResizeEl().getHeight();     },     /**      * Gets the current size of the component's underlying element, including space taken by its margins.      * @return {Object} An object containing the element's size {width: (element width + left/right margins), height: (element height + top/bottom margins)}      */     getOuterSize : function(){         var el = this.getResizeEl();         return {width: el.getWidth() + el.getMargins('lr'),                 height: el.getHeight() + el.getMargins('tb')};     },     /**      * Gets the current XY position of the component's underlying element.      * @param {Boolean} local (optional) If true the element's left and top are returned instead of page XY (defaults to false)      * @return {Array} The XY position of the element (e.g., [100, 200])      */     getPosition : function(local){         var el = this.getPositionEl();         if(local === true){             return [el.getLeft(true), el.getTop(true)];         }         return this.xy || el.getXY();     },     /**      * Gets the current box measurements of the component's underlying element.      * @param {Boolean} local (optional) If true the element's left and top are returned instead of page XY (defaults to false)      * @return {Object} box An object in the format {x, y, width, height}      */     getBox : function(local){         var pos = this.getPosition(local);         var s = this.getSize();         s.x = pos[0];         s.y = pos[1];         return s;     },     /**      * Sets the current box measurements of the component's underlying element.      * @param {Object} box An object in the format {x, y, width, height}      * @return {Ext.BoxComponent} this      */     updateBox : function(box){         this.setSize(box.width, box.height);         this.setPagePosition(box.x, box.y);         return this;     },     /**      * <p>Returns the outermost Element of this Component which defines the Components overall size.</p>      * <p><i>Usually</i> this will return the same Element as <code>{@link #getEl}</code>,      * but in some cases, a Component may have some more wrapping Elements around its main      * active Element.</p>      * <p>An example is a ComboBox. It is encased in a <i>wrapping</i> Element which      * contains both the <code>&lt;input></code> Element (which is what would be returned      * by its <code>{@link #getEl}</code> method, <i>and</i> the trigger button Element.      * This Element is returned as the <code>resizeEl</code>.      */     getResizeEl : function(){         return this.resizeEl || this.el;     },     // protected     getPositionEl : function(){         return this.positionEl || this.el;     },     /**      * Sets the left and top of the component.  To set the page XY position instead, use {@link #setPagePosition}.      * This method fires the {@link #move} event.      * @param {Number} left The new left      * @param {Number} top The new top      * @return {Ext.BoxComponent} this      */     setPosition : function(x, y){         if(x && typeof x[1] == 'number'){             y = x[1];             x = x[0];         }         this.x = x;         this.y = y;         if(!this.boxReady){             return this;         }         var adj = this.adjustPosition(x, y);         var ax = adj.x, ay = adj.y;         var el = this.getPositionEl();         if(ax !== undefined || ay !== undefined){             if(ax !== undefined && ay !== undefined){                 el.setLeftTop(ax, ay);             }else if(ax !== undefined){                 el.setLeft(ax);             }else if(ay !== undefined){                 el.setTop(ay);             }             this.onPosition(ax, ay);             this.fireEvent('move', this, ax, ay);         }         return this;     },     /**      * Sets the page XY position of the component.  To set the left and top instead, use {@link #setPosition}.      * This method fires the {@link #move} event.      * @param {Number} x The new x position      * @param {Number} y The new y position      * @return {Ext.BoxComponent} this      */     setPagePosition : function(x, y){         if(x && typeof x[1] == 'number'){             y = x[1];             x = x[0];         }         this.pageX = x;         this.pageY = y;         if(!this.boxReady){             return;         }         if(x === undefined || y === undefined){ // cannot translate undefined points             return;         }         var p = this.getPositionEl().translatePoints(x, y);         this.setPosition(p.left, p.top);         return this;     },     // private     onRender : function(ct, position){         Ext.BoxComponent.superclass.onRender.call(this, ct, position);         if(this.resizeEl){             this.resizeEl = Ext.get(this.resizeEl);         }         if(this.positionEl){             this.positionEl = Ext.get(this.positionEl);         }     },     // private     afterRender : function(){         Ext.BoxComponent.superclass.afterRender.call(this);         this.boxReady = true;         this.setSize(this.width, this.height);         if(this.x || this.y){             this.setPosition(this.x, this.y);         }else if(this.pageX || this.pageY){             this.setPagePosition(this.pageX, this.pageY);         }     },     /**      * Force the component's size to recalculate based on the underlying element's current height and width.      * @return {Ext.BoxComponent} this      */     syncSize : function(){         delete this.lastSize;         this.setSize(this.autoWidth ? undefined : this.getResizeEl().getWidth(), this.autoHeight ? undefined : this.getResizeEl().getHeight());         return this;     },     /* // protected      * Called after the component is resized, this method is empty by default but can be implemented by any      * subclass that needs to perform custom logic after a resize occurs.      * @param {Number} adjWidth The box-adjusted width that was set      * @param {Number} adjHeight The box-adjusted height that was set      * @param {Number} rawWidth The width that was originally specified      * @param {Number} rawHeight The height that was originally specified      */     onResize : function(adjWidth, adjHeight, rawWidth, rawHeight){     },     /* // protected      * Called after the component is moved, this method is empty by default but can be implemented by any      * subclass that needs to perform custom logic after a move occurs.      * @param {Number} x The new x position      * @param {Number} y The new y position      */     onPosition : function(x, y){     },     // private     adjustSize : function(w, h){         if(this.autoWidth){             w = 'auto';         }         if(this.autoHeight){             h = 'auto';         }         return {width : w, height: h};     },     // private     adjustPosition : function(x, y){         return {x : x, y: y};     } }); Ext.reg('box', Ext.BoxComponent); /**  * @class Ext.Spacer  * @extends Ext.BoxComponent  * <p>Used to provide a sizable space in a layout.</p>  * @constructor  * @param {Object} config  */ Ext.Spacer = Ext.extend(Ext.BoxComponent, {     autoEl:'div' }); Ext.reg('spacer', Ext.Spacer);/**
  763.  * @class Ext.SplitBar
  764.  * @extends Ext.util.Observable
  765.  * Creates draggable splitter bar functionality from two elements (element to be dragged and element to be resized).
  766.  * <br><br>
  767.  * Usage:
  768.  * <pre><code>
  769. var split = new Ext.SplitBar("elementToDrag", "elementToSize",
  770.                    Ext.SplitBar.HORIZONTAL, Ext.SplitBar.LEFT);
  771. split.setAdapter(new Ext.SplitBar.AbsoluteLayoutAdapter("container"));
  772. split.minSize = 100;
  773. split.maxSize = 600;
  774. split.animate = true;
  775. split.on('moved', splitterMoved);
  776. </code></pre>
  777.  * @constructor
  778.  * Create a new SplitBar
  779.  * @param {Mixed} dragElement The element to be dragged and act as the SplitBar.
  780.  * @param {Mixed} resizingElement The element to be resized based on where the SplitBar element is dragged
  781.  * @param {Number} orientation (optional) Either Ext.SplitBar.HORIZONTAL or Ext.SplitBar.VERTICAL. (Defaults to HORIZONTAL)
  782.  * @param {Number} placement (optional) Either Ext.SplitBar.LEFT or Ext.SplitBar.RIGHT for horizontal or  
  783.                         Ext.SplitBar.TOP or Ext.SplitBar.BOTTOM for vertical. (By default, this is determined automatically by the initial
  784.                         position of the SplitBar).
  785.  */
  786. Ext.SplitBar = function(dragElement, resizingElement, orientation, placement, existingProxy){
  787.     
  788.     /** @private */
  789.     this.el = Ext.get(dragElement, true);
  790.     this.el.dom.unselectable = "on";
  791.     /** @private */
  792.     this.resizingEl = Ext.get(resizingElement, true);
  793.     /**
  794.      * @private
  795.      * The orientation of the split. Either Ext.SplitBar.HORIZONTAL or Ext.SplitBar.VERTICAL. (Defaults to HORIZONTAL)
  796.      * Note: If this is changed after creating the SplitBar, the placement property must be manually updated
  797.      * @type Number
  798.      */
  799.     this.orientation = orientation || Ext.SplitBar.HORIZONTAL;
  800.     
  801.     /**
  802.      * The increment, in pixels by which to move this SplitBar. When <i>undefined</i>, the SplitBar moves smoothly.
  803.      * @type Number
  804.      * @property tickSize
  805.      */
  806.     /**
  807.      * The minimum size of the resizing element. (Defaults to 0)
  808.      * @type Number
  809.      */
  810.     this.minSize = 0;
  811.     
  812.     /**
  813.      * The maximum size of the resizing element. (Defaults to 2000)
  814.      * @type Number
  815.      */
  816.     this.maxSize = 2000;
  817.     
  818.     /**
  819.      * Whether to animate the transition to the new size
  820.      * @type Boolean
  821.      */
  822.     this.animate = false;
  823.     
  824.     /**
  825.      * Whether to create a transparent shim that overlays the page when dragging, enables dragging across iframes.
  826.      * @type Boolean
  827.      */
  828.     this.useShim = false;
  829.     
  830.     /** @private */
  831.     this.shim = null;
  832.     
  833.     if(!existingProxy){
  834.         /** @private */
  835.         this.proxy = Ext.SplitBar.createProxy(this.orientation);
  836.     }else{
  837.         this.proxy = Ext.get(existingProxy).dom;
  838.     }
  839.     /** @private */
  840.     this.dd = new Ext.dd.DDProxy(this.el.dom.id, "XSplitBars", {dragElId : this.proxy.id});
  841.     
  842.     /** @private */
  843.     this.dd.b4StartDrag = this.onStartProxyDrag.createDelegate(this);
  844.     
  845.     /** @private */
  846.     this.dd.endDrag = this.onEndProxyDrag.createDelegate(this);
  847.     
  848.     /** @private */
  849.     this.dragSpecs = {};
  850.     
  851.     /**
  852.      * @private The adapter to use to positon and resize elements
  853.      */
  854.     this.adapter = new Ext.SplitBar.BasicLayoutAdapter();
  855.     this.adapter.init(this);
  856.     
  857.     if(this.orientation == Ext.SplitBar.HORIZONTAL){
  858.         /** @private */
  859.         this.placement = placement || (this.el.getX() > this.resizingEl.getX() ? Ext.SplitBar.LEFT : Ext.SplitBar.RIGHT);
  860.         this.el.addClass("x-splitbar-h");
  861.     }else{
  862.         /** @private */
  863.         this.placement = placement || (this.el.getY() > this.resizingEl.getY() ? Ext.SplitBar.TOP : Ext.SplitBar.BOTTOM);
  864.         this.el.addClass("x-splitbar-v");
  865.     }
  866.     
  867.     this.addEvents(
  868.         /**
  869.          * @event resize
  870.          * Fires when the splitter is moved (alias for {@link #moved})
  871.          * @param {Ext.SplitBar} this
  872.          * @param {Number} newSize the new width or height
  873.          */
  874.         "resize",
  875.         /**
  876.          * @event moved
  877.          * Fires when the splitter is moved
  878.          * @param {Ext.SplitBar} this
  879.          * @param {Number} newSize the new width or height
  880.          */
  881.         "moved",
  882.         /**
  883.          * @event beforeresize
  884.          * Fires before the splitter is dragged
  885.          * @param {Ext.SplitBar} this
  886.          */
  887.         "beforeresize",
  888.         "beforeapply"
  889.     );
  890.     Ext.SplitBar.superclass.constructor.call(this);
  891. };
  892. Ext.extend(Ext.SplitBar, Ext.util.Observable, {
  893.     onStartProxyDrag : function(x, y){
  894.         this.fireEvent("beforeresize", this);
  895.         this.overlay =  Ext.DomHelper.append(document.body,  {cls: "x-drag-overlay", html: "&#160;"}, true);
  896.         this.overlay.unselectable();
  897.         this.overlay.setSize(Ext.lib.Dom.getViewWidth(true), Ext.lib.Dom.getViewHeight(true));
  898.         this.overlay.show();
  899.         Ext.get(this.proxy).setDisplayed("block");
  900.         var size = this.adapter.getElementSize(this);
  901.         this.activeMinSize = this.getMinimumSize();
  902.         this.activeMaxSize = this.getMaximumSize();
  903.         var c1 = size - this.activeMinSize;
  904.         var c2 = Math.max(this.activeMaxSize - size, 0);
  905.         if(this.orientation == Ext.SplitBar.HORIZONTAL){
  906.             this.dd.resetConstraints();
  907.             this.dd.setXConstraint(
  908.                 this.placement == Ext.SplitBar.LEFT ? c1 : c2, 
  909.                 this.placement == Ext.SplitBar.LEFT ? c2 : c1,
  910.                 this.tickSize
  911.             );
  912.             this.dd.setYConstraint(0, 0);
  913.         }else{
  914.             this.dd.resetConstraints();
  915.             this.dd.setXConstraint(0, 0);
  916.             this.dd.setYConstraint(
  917.                 this.placement == Ext.SplitBar.TOP ? c1 : c2, 
  918.                 this.placement == Ext.SplitBar.TOP ? c2 : c1,
  919.                 this.tickSize
  920.             );
  921.          }
  922.         this.dragSpecs.startSize = size;
  923.         this.dragSpecs.startPoint = [x, y];
  924.         Ext.dd.DDProxy.prototype.b4StartDrag.call(this.dd, x, y);
  925.     },
  926.     
  927.     /** 
  928.      * @private Called after the drag operation by the DDProxy
  929.      */
  930.     onEndProxyDrag : function(e){
  931.         Ext.get(this.proxy).setDisplayed(false);
  932.         var endPoint = Ext.lib.Event.getXY(e);
  933.         if(this.overlay){
  934.             Ext.destroy(this.overlay);
  935.             delete this.overlay;
  936.         }
  937.         var newSize;
  938.         if(this.orientation == Ext.SplitBar.HORIZONTAL){
  939.             newSize = this.dragSpecs.startSize + 
  940.                 (this.placement == Ext.SplitBar.LEFT ?
  941.                     endPoint[0] - this.dragSpecs.startPoint[0] :
  942.                     this.dragSpecs.startPoint[0] - endPoint[0]
  943.                 );
  944.         }else{
  945.             newSize = this.dragSpecs.startSize + 
  946.                 (this.placement == Ext.SplitBar.TOP ?
  947.                     endPoint[1] - this.dragSpecs.startPoint[1] :
  948.                     this.dragSpecs.startPoint[1] - endPoint[1]
  949.                 );
  950.         }
  951.         newSize = Math.min(Math.max(newSize, this.activeMinSize), this.activeMaxSize);
  952.         if(newSize != this.dragSpecs.startSize){
  953.             if(this.fireEvent('beforeapply', this, newSize) !== false){
  954.                 this.adapter.setElementSize(this, newSize);
  955.                 this.fireEvent("moved", this, newSize);
  956.                 this.fireEvent("resize", this, newSize);
  957.             }
  958.         }
  959.     },
  960.     
  961.     /**
  962.      * Get the adapter this SplitBar uses
  963.      * @return The adapter object
  964.      */
  965.     getAdapter : function(){
  966.         return this.adapter;
  967.     },
  968.     
  969.     /**
  970.      * Set the adapter this SplitBar uses
  971.      * @param {Object} adapter A SplitBar adapter object
  972.      */
  973.     setAdapter : function(adapter){
  974.         this.adapter = adapter;
  975.         this.adapter.init(this);
  976.     },
  977.     
  978.     /**
  979.      * Gets the minimum size for the resizing element
  980.      * @return {Number} The minimum size
  981.      */
  982.     getMinimumSize : function(){
  983.         return this.minSize;
  984.     },
  985.     
  986.     /**
  987.      * Sets the minimum size for the resizing element
  988.      * @param {Number} minSize The minimum size
  989.      */
  990.     setMinimumSize : function(minSize){
  991.         this.minSize = minSize;
  992.     },
  993.     
  994.     /**
  995.      * Gets the maximum size for the resizing element
  996.      * @return {Number} The maximum size
  997.      */
  998.     getMaximumSize : function(){
  999.         return this.maxSize;
  1000.     },
  1001.     
  1002.     /**
  1003.      * Sets the maximum size for the resizing element
  1004.      * @param {Number} maxSize The maximum size
  1005.      */
  1006.     setMaximumSize : function(maxSize){
  1007.         this.maxSize = maxSize;
  1008.     },
  1009.     
  1010.     /**
  1011.      * Sets the initialize size for the resizing element
  1012.      * @param {Number} size The initial size
  1013.      */
  1014.     setCurrentSize : function(size){
  1015.         var oldAnimate = this.animate;
  1016.         this.animate = false;
  1017.         this.adapter.setElementSize(this, size);
  1018.         this.animate = oldAnimate;
  1019.     },
  1020.     
  1021.     /**
  1022.      * Destroy this splitbar. 
  1023.      * @param {Boolean} removeEl True to remove the element
  1024.      */
  1025.     destroy : function(removeEl){
  1026. Ext.destroy(this.shim, Ext.get(this.proxy));
  1027.         this.dd.unreg();
  1028.         if(removeEl){
  1029.             this.el.remove();
  1030.         }
  1031. this.purgeListeners();
  1032.     }
  1033. });
  1034. /**
  1035.  * @private static Create our own proxy element element. So it will be the same same size on all browsers, we won't use borders. Instead we use a background color.
  1036.  */
  1037. Ext.SplitBar.createProxy = function(dir){
  1038.     var proxy = new Ext.Element(document.createElement("div"));
  1039.     proxy.unselectable();
  1040.     var cls = 'x-splitbar-proxy';
  1041.     proxy.addClass(cls + ' ' + (dir == Ext.SplitBar.HORIZONTAL ? cls +'-h' : cls + '-v'));
  1042.     document.body.appendChild(proxy.dom);
  1043.     return proxy.dom;
  1044. };
  1045. /** 
  1046.  * @class Ext.SplitBar.BasicLayoutAdapter
  1047.  * Default Adapter. It assumes the splitter and resizing element are not positioned
  1048.  * elements and only gets/sets the width of the element. Generally used for table based layouts.
  1049.  */
  1050. Ext.SplitBar.BasicLayoutAdapter = function(){
  1051. };
  1052. Ext.SplitBar.BasicLayoutAdapter.prototype = {
  1053.     // do nothing for now
  1054.     init : function(s){
  1055.     
  1056.     },
  1057.     /**
  1058.      * Called before drag operations to get the current size of the resizing element. 
  1059.      * @param {Ext.SplitBar} s The SplitBar using this adapter
  1060.      */
  1061.      getElementSize : function(s){
  1062.         if(s.orientation == Ext.SplitBar.HORIZONTAL){
  1063.             return s.resizingEl.getWidth();
  1064.         }else{
  1065.             return s.resizingEl.getHeight();
  1066.         }
  1067.     },
  1068.     
  1069.     /**
  1070.      * Called after drag operations to set the size of the resizing element.
  1071.      * @param {Ext.SplitBar} s The SplitBar using this adapter
  1072.      * @param {Number} newSize The new size to set
  1073.      * @param {Function} onComplete A function to be invoked when resizing is complete
  1074.      */
  1075.     setElementSize : function(s, newSize, onComplete){
  1076.         if(s.orientation == Ext.SplitBar.HORIZONTAL){
  1077.             if(!s.animate){
  1078.                 s.resizingEl.setWidth(newSize);
  1079.                 if(onComplete){
  1080.                     onComplete(s, newSize);
  1081.                 }
  1082.             }else{
  1083.                 s.resizingEl.setWidth(newSize, true, .1, onComplete, 'easeOut');
  1084.             }
  1085.         }else{
  1086.             
  1087.             if(!s.animate){
  1088.                 s.resizingEl.setHeight(newSize);
  1089.                 if(onComplete){
  1090.                     onComplete(s, newSize);
  1091.                 }
  1092.             }else{
  1093.                 s.resizingEl.setHeight(newSize, true, .1, onComplete, 'easeOut');
  1094.             }
  1095.         }
  1096.     }
  1097. };
  1098. /** 
  1099.  *@class Ext.SplitBar.AbsoluteLayoutAdapter
  1100.  * @extends Ext.SplitBar.BasicLayoutAdapter
  1101.  * Adapter that  moves the splitter element to align with the resized sizing element. 
  1102.  * Used with an absolute positioned SplitBar.
  1103.  * @param {Mixed} container The container that wraps around the absolute positioned content. If it's
  1104.  * document.body, make sure you assign an id to the body element.
  1105.  */
  1106. Ext.SplitBar.AbsoluteLayoutAdapter = function(container){
  1107.     this.basic = new Ext.SplitBar.BasicLayoutAdapter();
  1108.     this.container = Ext.get(container);
  1109. };
  1110. Ext.SplitBar.AbsoluteLayoutAdapter.prototype = {
  1111.     init : function(s){
  1112.         this.basic.init(s);
  1113.     },
  1114.     
  1115.     getElementSize : function(s){
  1116.         return this.basic.getElementSize(s);
  1117.     },
  1118.     
  1119.     setElementSize : function(s, newSize, onComplete){
  1120.         this.basic.setElementSize(s, newSize, this.moveSplitter.createDelegate(this, [s]));
  1121.     },
  1122.     
  1123.     moveSplitter : function(s){
  1124.         var yes = Ext.SplitBar;
  1125.         switch(s.placement){
  1126.             case yes.LEFT:
  1127.                 s.el.setX(s.resizingEl.getRight());
  1128.                 break;
  1129.             case yes.RIGHT:
  1130.                 s.el.setStyle("right", (this.container.getWidth() - s.resizingEl.getLeft()) + "px");
  1131.                 break;
  1132.             case yes.TOP:
  1133.                 s.el.setY(s.resizingEl.getBottom());
  1134.                 break;
  1135.             case yes.BOTTOM:
  1136.                 s.el.setY(s.resizingEl.getTop() - s.el.getHeight());
  1137.                 break;
  1138.         }
  1139.     }
  1140. };
  1141. /**
  1142.  * Orientation constant - Create a vertical SplitBar
  1143.  * @static
  1144.  * @type Number
  1145.  */
  1146. Ext.SplitBar.VERTICAL = 1;
  1147. /**
  1148.  * Orientation constant - Create a horizontal SplitBar
  1149.  * @static
  1150.  * @type Number
  1151.  */
  1152. Ext.SplitBar.HORIZONTAL = 2;
  1153. /**
  1154.  * Placement constant - The resizing element is to the left of the splitter element
  1155.  * @static
  1156.  * @type Number
  1157.  */
  1158. Ext.SplitBar.LEFT = 1;
  1159. /**
  1160.  * Placement constant - The resizing element is to the right of the splitter element
  1161.  * @static
  1162.  * @type Number
  1163.  */
  1164. Ext.SplitBar.RIGHT = 2;
  1165. /**
  1166.  * Placement constant - The resizing element is positioned above the splitter element
  1167.  * @static
  1168.  * @type Number
  1169.  */
  1170. Ext.SplitBar.TOP = 3;
  1171. /**
  1172.  * Placement constant - The resizing element is positioned under splitter element
  1173.  * @static
  1174.  * @type Number
  1175.  */
  1176. Ext.SplitBar.BOTTOM = 4;
  1177. /**  * @class Ext.Container  * @extends Ext.BoxComponent  * <p>Base class for any {@link Ext.BoxComponent} that may contain other Components. Containers handle the  * basic behavior of containing items, namely adding, inserting and removing items.</p>  *  * <p>The most commonly used Container classes are {@link Ext.Panel}, {@link Ext.Window} and {@link Ext.TabPanel}.  * If you do not need the capabilities offered by the aforementioned classes you can create a lightweight  * Container to be encapsulated by an HTML element to your specifications by using the  * <tt><b>{@link Ext.Component#autoEl autoEl}</b></tt> config option. This is a useful technique when creating  * embedded {@link Ext.layout.ColumnLayout column} layouts inside {@link Ext.form.FormPanel FormPanels}  * for example.</p>  *  * <p>The code below illustrates both how to explicitly create a Container, and how to implicitly  * create one using the <b><tt>'container'</tt></b> xtype:<pre><code> // explicitly create a Container var embeddedColumns = new Ext.Container({     autoEl: 'div',  // This is the default     layout: 'column',     defaults: {         // implicitly create Container by specifying xtype         xtype: 'container',         autoEl: 'div', // This is the default.         layout: 'form',         columnWidth: 0.5,         style: {             padding: '10px'         }     }, //  The two items below will be Ext.Containers, each encapsulated by a &lt;DIV> element.     items: [{         items: {             xtype: 'datefield',             name: 'startDate',             fieldLabel: 'Start date'         }     }, {         items: {             xtype: 'datefield',             name: 'endDate',             fieldLabel: 'End date'         }     }] });</code></pre></p>  *  * <p><u><b>Layout</b></u></p>  * <p>Container classes delegate the rendering of child Components to a layout  * manager class which must be configured into the Container using the  * <code><b>{@link #layout}</b></code> configuration property.</p>  * <p>When either specifying child <code>{@link #items}</code> of a Container,  * or dynamically {@link #add adding} Components to a Container, remember to  * consider how you wish the Container to arrange those child elements, and  * whether those child elements need to be sized using one of Ext's built-in  * <b><code>{@link #layout}</code></b> schemes. By default, Containers use the  * {@link Ext.layout.ContainerLayout ContainerLayout} scheme which only  * renders child components, appending them one after the other inside the  * Container, and <b>does not apply any sizing</b> at all.</p>  * <p>A common mistake is when a developer neglects to specify a  * <b><code>{@link #layout}</code></b> (e.g. widgets like GridPanels or  * TreePanels are added to Containers for which no <tt><b>{@link #layout}</b></tt>  * has been specified). If a Container is left to use the default  * {@link Ext.layout.ContainerLayout ContainerLayout} scheme, none of its  * child components will be resized, or changed in any way when the Container  * is resized.</p>  * <p>Certain layout managers allow dynamic addition of child components.  * Those that do include {@link Ext.layout.CardLayout},  * {@link Ext.layout.AnchorLayout}, {@link Ext.layout.FormLayout}, and  * {@link Ext.layout.TableLayout}. For example:<pre><code> //  Create the GridPanel. var myNewGrid = new Ext.grid.GridPanel({     store: myStore,     columns: myColumnModel,     title: 'Results', // the title becomes the title of the tab }); myTabPanel.add(myNewGrid); // {@link Ext.TabPanel} implicitly uses {@link Ext.layout.CardLayout CardLayout} myTabPanel.{@link Ext.TabPanel#setActiveTab setActiveTab}(myNewGrid);  * </code></pre></p>  * <p>The example above adds a newly created GridPanel to a TabPanel. Note that  * a TabPanel uses {@link Ext.layout.CardLayout} as its layout manager which  * means all its child items are sized to {@link Ext.layout.FitLayout fit}  * exactly into its client area.  * <p><b><u>Overnesting is a common problem</u></b>.  * An example of overnesting occurs when a GridPanel is added to a TabPanel  * by wrapping the GridPanel <i>inside</i> a wrapping Panel (that has no  * <tt><b>{@link #layout}</b></tt> specified) and then add that wrapping Panel  * to the TabPanel. The point to realize is that a GridPanel <b>is</b> a  * Component which can be added directly to a Container. If the wrapping Panel  * has no <tt><b>{@link #layout}</b></tt> configuration, then the overnested  * GridPanel will not be sized as expected.<p> </code></pre>  *  * <p><u><b>Adding via remote configuration</b></u></p>  *  * <p>A server side script can be used to add Components which are generated dynamically on the server.  * An example of adding a GridPanel to a TabPanel where the GridPanel is generated by the server  * based on certain parameters:  * </p><pre><code> // execute an Ajax request to invoke server side script: Ext.Ajax.request({     url: 'gen-invoice-grid.php',     // send additional parameters to instruct server script     params: {         startDate: Ext.getCmp('start-date').getValue(),         endDate: Ext.getCmp('end-date').getValue()     },     // process the response object to add it to the TabPanel:     success: function(xhr) {         var newComponent = eval(xhr.responseText); // see discussion below         myTabPanel.add(newComponent); // add the component to the TabPanel         myTabPanel.setActiveTab(newComponent);     },     failure: function() {         Ext.Msg.alert("Grid create failed", "Server communication failure");     } }); </code></pre>  * <p>The server script needs to return an executable Javascript statement which, when processed  * using <tt>eval()</tt>, will return either a config object with an {@link Ext.Component#xtype xtype},  * or an instantiated Component. The server might return this for example:</p><pre><code> (function() {     function formatDate(value){         return value ? value.dateFormat('M d, Y') : '';     };     var store = new Ext.data.Store({         url: 'get-invoice-data.php',         baseParams: {             startDate: '01/01/2008',             endDate: '01/31/2008'         },         reader: new Ext.data.JsonReader({             record: 'transaction',             idProperty: 'id',             totalRecords: 'total'         }, [            'customer',            'invNo',            {name: 'date', type: 'date', dateFormat: 'm/d/Y'},            {name: 'value', type: 'float'}         ])     });     var grid = new Ext.grid.GridPanel({         title: 'Invoice Report',         bbar: new Ext.PagingToolbar(store),         store: store,         columns: [             {header: "Customer", width: 250, dataIndex: 'customer', sortable: true},             {header: "Invoice Number", width: 120, dataIndex: 'invNo', sortable: true},             {header: "Invoice Date", width: 100, dataIndex: 'date', renderer: formatDate, sortable: true},             {header: "Value", width: 120, dataIndex: 'value', renderer: 'usMoney', sortable: true}         ],     });     store.load();     return grid;  // return instantiated component })(); </code></pre>  * <p>When the above code fragment is passed through the <tt>eval</tt> function in the success handler  * of the Ajax request, the code is executed by the Javascript processor, and the anonymous function  * runs, and returns the instantiated grid component.</p>  * <p>Note: since the code above is <i>generated</i> by a server script, the <tt>baseParams</tt> for  * the Store, the metadata to allow generation of the Record layout, and the ColumnModel  * can all be generated into the code since these are all known on the server.</p>  *  * @xtype container  */ Ext.Container = Ext.extend(Ext.BoxComponent, {     /**      * @cfg {Boolean} monitorResize      * True to automatically monitor window resize events to handle anything that is sensitive to the current size      * of the viewport.  This value is typically managed by the chosen <code>{@link #layout}</code> and should not need      * to be set manually.      */     /**      * @cfg {String/Object} layout      * When creating complex UIs, it is important to remember that sizing and      * positioning of child items is the responsibility of the Container's      * layout manager. If you expect child items to be sized in response to      * user interactions, <b>you must specify a layout manager</b> which      * creates and manages the type of layout you have in mind.  For example:<pre><code> new Ext.Window({     width:300, height: 300,     layout: 'fit', // explicitly set layout manager: override the default (layout:'auto')     items: [{         title: 'Panel inside a Window'     }] }).show();      * </code></pre>      * <p>Omitting the {@link #layout} config means that the      * {@link Ext.layout.ContainerLayout default layout manager} will be used which does      * nothing but render child components sequentially into the Container (no sizing or      * positioning will be performed in this situation).</p>      * <p>The layout manager class for this container may be specified as either as an      * Object or as a String:</p>      * <div><ul class="mdetail-params">      *      * <li><u>Specify as an Object</u></li>      * <div><ul class="mdetail-params">      * <li>Example usage:</li> <pre><code> layout: {     type: 'vbox',     padding: '5',     align: 'left' } </code></pre>      *      * <li><tt><b>type</b></tt></li>      * <br/><p>The layout type to be used for this container.  If not specified,      * a default {@link Ext.layout.ContainerLayout} will be created and used.</p>      * <br/><p>Valid layout <tt>type</tt> values are:</p>      * <div class="sub-desc"><ul class="mdetail-params">      * <li><tt><b>{@link Ext.layout.AbsoluteLayout absolute}</b></tt></li>      * <li><tt><b>{@link Ext.layout.AccordionLayout accordion}</b></tt></li>      * <li><tt><b>{@link Ext.layout.AnchorLayout anchor}</b></tt></li>      * <li><tt><b>{@link Ext.layout.ContainerLayout auto}</b></tt> &nbsp;&nbsp;&nbsp; <b>Default</b></li>      * <li><tt><b>{@link Ext.layout.BorderLayout border}</b></tt></li>      * <li><tt><b>{@link Ext.layout.CardLayout card}</b></tt></li>      * <li><tt><b>{@link Ext.layout.ColumnLayout column}</b></tt></li>      * <li><tt><b>{@link Ext.layout.FitLayout fit}</b></tt></li>      * <li><tt><b>{@link Ext.layout.FormLayout form}</b></tt></li>      * <li><tt><b>{@link Ext.layout.HBoxLayout hbox}</b></tt></li>      * <li><tt><b>{@link Ext.layout.MenuLayout menu}</b></tt></li>      * <li><tt><b>{@link Ext.layout.TableLayout table}</b></tt></li>      * <li><tt><b>{@link Ext.layout.ToolbarLayout toolbar}</b></tt></li>      * <li><tt><b>{@link Ext.layout.VBoxLayout vbox}</b></tt></li>      * </ul></div>      *      * <li>Layout specific configuration properties</li>      * <br/><p>Additional layout specific configuration properties may also be      * specified. For complete details regarding the valid config options for      * each layout type, see the layout class corresponding to the <tt>type</tt>      * specified.</p>      *      * </ul></div>      *      * <li><u>Specify as a String</u></li>      * <div><ul class="mdetail-params">      * <li>Example usage:</li> <pre><code> layout: 'vbox', layoutConfig: {     padding: '5',     align: 'left' } </code></pre>      * <li><tt><b>layout</b></tt></li>      * <br/><p>The layout <tt>type</tt> to be used for this container (see list      * of valid layout type values above).</p><br/>      * <li><tt><b>{@link #layoutConfig}</b></tt></li>      * <br/><p>Additional layout specific configuration properties. For complete      * details regarding the valid config options for each layout type, see the      * layout class corresponding to the <tt>layout</tt> specified.</p>      * </ul></div></ul></div>      */     /**      * @cfg {Object} layoutConfig      * This is a config object containing properties specific to the chosen      * <b><code>{@link #layout}</code></b> if <b><code>{@link #layout}</code></b>      * has been specified as a <i>string</i>.</p>      */     /**      * @cfg {Boolean/Number} bufferResize      * When set to true (100 milliseconds) or a number of milliseconds, the layout assigned for this container will buffer      * the frequency it calculates and does a re-layout of components. This is useful for heavy containers or containers      * with a large quantity of sub-components for which frequent layout calls would be expensive.      */     bufferResize: 100,          /**      * @cfg {String/Number} activeItem      * A string component id or the numeric index of the component that should be initially activated within the      * container's layout on render.  For example, activeItem: 'item-1' or activeItem: 0 (index 0 = the first      * item in the container's collection).  activeItem only applies to layout styles that can display      * items one at a time (like {@link Ext.layout.AccordionLayout}, {@link Ext.layout.CardLayout} and      * {@link Ext.layout.FitLayout}).  Related to {@link Ext.layout.ContainerLayout#activeItem}.      */     /**      * @cfg {Object/Array} items      * <pre><b>** IMPORTANT</b>: be sure to specify a <b><code>{@link #layout}</code> ! **</b></pre>      * <p>A single item, or an array of child Components to be added to this container,      * for example:</p>      * <pre><code> // specifying a single item items: {...}, layout: 'fit',    // specify a layout! // specifying multiple items items: [{...}, {...}], layout: 'anchor', // specify a layout!      * </code></pre>      * <p>Each item may be:</p>      * <div><ul class="mdetail-params">      * <li>any type of object based on {@link Ext.Component}</li>      * <li>a fully instanciated object or</li>      * <li>an object literal that:</li>      * <div><ul class="mdetail-params">      * <li>has a specified <code>{@link Ext.Component#xtype xtype}</code></li>      * <li>the {@link Ext.Component#xtype} specified is associated with the Component      * desired and should be chosen from one of the available xtypes as listed      * in {@link Ext.Component}.</li>      * <li>If an <code>{@link Ext.Component#xtype xtype}</code> is not explicitly      * specified, the {@link #defaultType} for that Container is used.</li>      * <li>will be "lazily instanciated", avoiding the overhead of constructing a fully      * instanciated Component object</li>      * </ul></div></ul></div>      * <p><b>Notes</b>:</p>      * <div><ul class="mdetail-params">      * <li>Ext uses lazy rendering. Child Components will only be rendered      * should it become necessary. Items are automatically laid out when they are first      * shown (no sizing is done while hidden), or in response to a {@link #doLayout} call.</li>      * <li>Do not specify <code>{@link Ext.Panel#contentEl contentEl}</code>/      * <code>{@link Ext.Panel#html html}</code> with <code>items</code>.</li>      * </ul></div>      */     /**      * @cfg {Object} defaults      * <p>A config object that will be applied to all components added to this container either via the {@link #items}      * config or via the {@link #add} or {@link #insert} methods.  The <tt>defaults</tt> config can contain any      * number of name/value property pairs to be added to each item, and should be valid for the types of items      * being added to the container.  For example, to automatically apply padding to the body of each of a set of      * contained {@link Ext.Panel} items, you could pass: <tt>defaults: {bodyStyle:'padding:15px'}</tt>.</p><br/>      * <p><b>Note</b>: <tt>defaults</tt> will not be applied to config objects if the option is already specified.      * For example:</p><pre><code> defaults: {               // defaults are applied to items, not the container     autoScroll:true }, items: [     {         xtype: 'panel',   // defaults <b>do not</b> have precedence over         id: 'panel1',     // options in config objects, so the defaults         autoScroll: false // will not be applied here, panel1 will be autoScroll:false     },     new Ext.Panel({       // defaults <b>do</b> have precedence over options         id: 'panel2',     // options in components, so the defaults         autoScroll: false // will be applied here, panel2 will be autoScroll:true.     }) ]      * </code></pre>      */     /** @cfg {Boolean} autoDestroy      * If true the container will automatically destroy any contained component that is removed from it, else      * destruction must be handled manually (defaults to true).      */     autoDestroy : true,     /** @cfg {Boolean} forceLayout      * If true the container will force a layout initially even if hidden or collapsed. This option      * is useful for forcing forms to render in collapsed or hidden containers. (defaults to false).      */     forceLayout: false,     /** @cfg {Boolean} hideBorders      * True to hide the borders of each contained component, false to defer to the component's existing      * border settings (defaults to false).      */     /** @cfg {String} defaultType      * <p>The default {@link Ext.Component xtype} of child Components to create in this Container when      * a child item is specified as a raw configuration object, rather than as an instantiated Component.</p>      * <p>Defaults to <tt>'panel'</tt>, except {@link Ext.menu.Menu} which defaults to <tt>'menuitem'</tt>,      * and {@link Ext.Toolbar} and {@link Ext.ButtonGroup} which default to <tt>'button'</tt>.</p>      */     defaultType : 'panel',     // private     initComponent : function(){         Ext.Container.superclass.initComponent.call(this);         this.addEvents(             /**              * @event afterlayout              * Fires when the components in this container are arranged by the associated layout manager.              * @param {Ext.Container} this              * @param {ContainerLayout} layout The ContainerLayout implementation for this container              */             'afterlayout',             /**              * @event beforeadd              * Fires before any {@link Ext.Component} is added or inserted into the container.              * A handler can return false to cancel the add.              * @param {Ext.Container} this              * @param {Ext.Component} component The component being added              * @param {Number} index The index at which the component will be added to the container's items collection              */             'beforeadd',             /**              * @event beforeremove              * Fires before any {@link Ext.Component} is removed from the container.  A handler can return              * false to cancel the remove.              * @param {Ext.Container} this              * @param {Ext.Component} component The component being removed              */             'beforeremove',             /**              * @event add              * @bubbles              * Fires after any {@link Ext.Component} is added or inserted into the container.              * @param {Ext.Container} this              * @param {Ext.Component} component The component that was added              * @param {Number} index The index at which the component was added to the container's items collection              */             'add',             /**              * @event remove              * @bubbles              * Fires after any {@link Ext.Component} is removed from the container.              * @param {Ext.Container} this              * @param {Ext.Component} component The component that was removed              */             'remove'         ); this.enableBubble('add', 'remove');         /**          * The collection of components in this container as a {@link Ext.util.MixedCollection}          * @type MixedCollection          * @property items          */         var items = this.items;         if(items){             delete this.items;             if(Ext.isArray(items) && items.length > 0){                 this.add.apply(this, items);             }else{                 this.add(items);             }         }     },     // private     initItems : function(){         if(!this.items){             this.items = new Ext.util.MixedCollection(false, this.getComponentId);             this.getLayout(); // initialize the layout         }     },     // private     setLayout : function(layout){         if(this.layout && this.layout != layout){             this.layout.setContainer(null);         }         this.initItems();         this.layout = layout;         layout.setContainer(this);     },     // private     render : function(){         Ext.Container.superclass.render.apply(this, arguments);         if(this.layout){             if(Ext.isObject(this.layout) && !this.layout.layout){                 this.layoutConfig = this.layout;                 this.layout = this.layoutConfig.type;             }             if(typeof this.layout == 'string'){                 this.layout = new Ext.Container.LAYOUTS[this.layout.toLowerCase()](this.layoutConfig);             }             this.setLayout(this.layout);             if(this.activeItem !== undefined){                 var item = this.activeItem;                 delete this.activeItem;                 this.layout.setActiveItem(item);             }         }         if(!this.ownerCt){             // force a layout if no ownerCt is set             this.doLayout(false, true);         }         if(this.monitorResize === true){             Ext.EventManager.onWindowResize(this.doLayout, this, [false]);         }     },     /**      * <p>Returns the Element to be used to contain the child Components of this Container.</p>      * <p>An implementation is provided which returns the Container's {@link #getEl Element}, but      * if there is a more complex structure to a Container, this may be overridden to return      * the element into which the {@link #layout layout} renders child Components.</p>      * @return {Ext.Element} The Element to render child Components into.      */     getLayoutTarget : function(){         return this.el;     },     // private - used as the key lookup function for the items collection     getComponentId : function(comp){         return comp.getItemId();     },     /**      * <p>Adds {@link Ext.Component Component}(s) to this Container.</p>      * <br><p><b>Description</b></u> :      * <div><ul class="mdetail-params">      * <li>Fires the {@link #beforeadd} event before adding</li>      * <li>The Container's {@link #defaults default config values} will be applied      * accordingly (see <code>{@link #defaults}</code> for details).</li>      * <li>Fires the {@link #add} event after the component has been added.</li>      * </ul></div>      * <br><p><b>Notes</b></u> :      * <div><ul class="mdetail-params">      * <li>If the Container is <i>already rendered</i> when <tt>add</tt>      * is called, you may need to call {@link #doLayout} to refresh the view which causes      * any unrendered child Components to be rendered. This is required so that you can      * <tt>add</tt> multiple child components if needed while only refreshing the layout      * once. For example:<pre><code> var tb = new {@link Ext.Toolbar}(); tb.render(document.body);  // toolbar is rendered tb.add({text:'Button 1'}); // add multiple items ({@link #defaultType} for {@link Ext.Toolbar Toolbar} is 'button') tb.add({text:'Button 2'}); tb.{@link #doLayout}();             // refresh the layout      * </code></pre></li>      * <li><i>Warning:</i> Containers directly managed by the BorderLayout layout manager      * may not be removed or added.  See the Notes for {@link Ext.layout.BorderLayout BorderLayout}      * for more details.</li>      * </ul></div>      * @param {Object/Array} component      * <p>Either a single component or an Array of components to add.  See      * <code>{@link #items}</code> for additional information.</p>      * @param {Object} (Optional) component_2      * @param {Object} (Optional) component_n      * @return {Ext.Component} component The Component (or config object) that was added.      */     add : function(comp){         this.initItems();         var args = arguments.length > 1;         if(args || Ext.isArray(comp)){             Ext.each(args ? arguments : comp, function(c){                 this.add(c);             }, this);             return;         }         var c = this.lookupComponent(this.applyDefaults(comp));         var pos = this.items.length;         if(this.fireEvent('beforeadd', this, c, pos) !== false && this.onBeforeAdd(c) !== false){             this.items.add(c);             c.ownerCt = this;             this.fireEvent('add', this, c, pos);         }         return c;     },     /**      * Inserts a Component into this Container at a specified index. Fires the      * {@link #beforeadd} event before inserting, then fires the {@link #add} event after the      * Component has been inserted.      * @param {Number} index The index at which the Component will be inserted      * into the Container's items collection      * @param {Ext.Component} component The child Component to insert.<br><br>      * Ext uses lazy rendering, and will only render the inserted Component should      * it become necessary.<br><br>      * A Component config object may be passed in order to avoid the overhead of      * constructing a real Component object if lazy rendering might mean that the      * inserted Component will not be rendered immediately. To take advantage of      * this 'lazy instantiation', set the {@link Ext.Component#xtype} config      * property to the registered type of the Component wanted.<br><br>      * For a list of all available xtypes, see {@link Ext.Component}.      * @return {Ext.Component} component The Component (or config object) that was      * inserted with the Container's default config values applied.      */     insert : function(index, comp){         this.initItems();         var a = arguments, len = a.length;         if(len > 2){             for(var i = len-1; i >= 1; --i) {                 this.insert(index, a[i]);             }             return;         }         var c = this.lookupComponent(this.applyDefaults(comp));         if(c.ownerCt == this && this.items.indexOf(c) < index){             --index;         }         if(this.fireEvent('beforeadd', this, c, index) !== false && this.onBeforeAdd(c) !== false){             this.items.insert(index, c);             c.ownerCt = this;             this.fireEvent('add', this, c, index);         }         return c;     },     // private     applyDefaults : function(c){         if(this.defaults){             if(typeof c == 'string'){                 c = Ext.ComponentMgr.get(c);                 Ext.apply(c, this.defaults);             }else if(!c.events){                 Ext.applyIf(c, this.defaults);             }else{                 Ext.apply(c, this.defaults);             }         }         return c;     },     // private     onBeforeAdd : function(item){         if(item.ownerCt){             item.ownerCt.remove(item, false);         }         if(this.hideBorders === true){             item.border = (item.border === true);         }     },     /**      * Removes a component from this container.  Fires the {@link #beforeremove} event before removing, then fires      * the {@link #remove} event after the component has been removed.      * @param {Component/String} component The component reference or id to remove.      * @param {Boolean} autoDestroy (optional) True to automatically invoke the removed Component's {@link Ext.Component#destroy} function.      * Defaults to the value of this Container's {@link #autoDestroy} config.      * @return {Ext.Component} component The Component that was removed.      */     remove : function(comp, autoDestroy){         this.initItems();         var c = this.getComponent(comp);         if(c && this.fireEvent('beforeremove', this, c) !== false){             this.items.remove(c);             delete c.ownerCt;             if(autoDestroy === true || (autoDestroy !== false && this.autoDestroy)){                 c.destroy();             }             if(this.layout && this.layout.activeItem == c){                 delete this.layout.activeItem;             }             this.fireEvent('remove', this, c);         }         return c;     },     /**      * Removes all components from this container.      * @param {Boolean} autoDestroy (optional) True to automatically invoke the removed Component's {@link Ext.Component#destroy} function.      * Defaults to the value of this Container's {@link #autoDestroy} config.      * @return {Array} Array of the destroyed components      */     removeAll: function(autoDestroy){         this.initItems();         var item, rem = [], items = [];         this.items.each(function(i){             rem.push(i);         });         for (var i = 0, len = rem.length; i < len; ++i){             item = rem[i];             this.remove(item, autoDestroy);             if(item.ownerCt !== this){                 items.push(item);             }         }         return items;     },     /**      * Examines this container's <code>{@link #items}</code> <b>property</b>      * and gets a direct child component of this container.      * @param {String/Number} comp This parameter may be any of the following:      * <div><ul class="mdetail-params">      * <li>a <b><tt>String</tt></b> : representing the <code>{@link Ext.Component#itemId itemId}</code>      * or <code>{@link Ext.Component#id id}</code> of the child component </li>      * <li>a <b><tt>Number</tt></b> : representing the position of the child component      * within the <code>{@link #items}</code> <b>property</b></li>      * </ul></div>      * <p>For additional information see {@link Ext.util.MixedCollection#get}.      * @return Ext.Component The component (if found).      */     getComponent : function(comp){         if(Ext.isObject(comp)){             return comp;         }         return this.items.get(comp);     },     // private     lookupComponent : function(comp){         if(typeof comp == 'string'){             return Ext.ComponentMgr.get(comp);         }else if(!comp.events){             return this.createComponent(comp);         }         return comp;     },     // private     createComponent : function(config){         return Ext.create(config, this.defaultType);     },     /**      * Force this container's layout to be recalculated. A call to this function is required after adding a new component      * to an already rendered container, or possibly after changing sizing/position properties of child components.      * @param {Boolean} shallow (optional) True to only calc the layout of this component, and let child components auto      * calc layouts as required (defaults to false, which calls doLayout recursively for each subcontainer)      * @param {Boolean} force (optional) True to force a layout to occur, even if the item is hidden.      * @return {Ext.Container} this      */     doLayout: function(shallow, force){         var rendered = this.rendered,             forceLayout = this.forceLayout;         if(!this.isVisible() || this.collapsed){             this.deferLayout = this.deferLayout || !shallow;             if(!(force || forceLayout)){                 return;             }             shallow = shallow && !this.deferLayout;         } else {             delete this.deferLayout;         }         if(rendered && this.layout){             this.layout.layout();         }         if(shallow !== true && this.items){             var cs = this.items.items;             for(var i = 0, len = cs.length; i < len; i++){                 var c = cs[i];                 if(c.doLayout){                     c.forceLayout = forceLayout;                     c.doLayout();                 }             }         }         if(rendered){             this.onLayout(shallow, force);         }         delete this.forceLayout;     },     //private     onLayout : Ext.emptyFn,     onShow : function(){         Ext.Container.superclass.onShow.call(this);         if(this.deferLayout !== undefined){             this.doLayout(true);         }     },     /**      * Returns the layout currently in use by the container.  If the container does not currently have a layout      * set, a default {@link Ext.layout.ContainerLayout} will be created and set as the container's layout.      * @return {ContainerLayout} layout The container's layout      */     getLayout : function(){         if(!this.layout){             var layout = new Ext.layout.ContainerLayout(this.layoutConfig);             this.setLayout(layout);         }         return this.layout;     },     // private     beforeDestroy : function(){         if(this.items){             Ext.destroy.apply(Ext, this.items.items);         }         if(this.monitorResize){             Ext.EventManager.removeResizeListener(this.doLayout, this);         }         Ext.destroy(this.layout);         Ext.Container.superclass.beforeDestroy.call(this);     },     /**      * Bubbles up the component/container heirarchy, calling the specified function with each component. The scope (<i>this</i>) of      * function call will be the scope provided or the current component. The arguments to the function      * will be the args provided or the current component. If the function returns false at any point,      * the bubble is stopped.      * @param {Function} fn The function to call      * @param {Object} scope (optional) The scope of the function (defaults to current node)      * @param {Array} args (optional) The args to call the function with (default to passing the current component)      * @return {Ext.Container} this      */     bubble : function(fn, scope, args){         var p = this;         while(p){             if(fn.apply(scope || p, args || [p]) === false){                 break;             }             p = p.ownerCt;         }         return this;     },     /**      * Cascades down the component/container heirarchy from this component (called first), calling the specified function with      * each component. The scope (<i>this</i>) of      * function call will be the scope provided or the current component. The arguments to the function      * will be the args provided or the current component. If the function returns false at any point,      * the cascade is stopped on that branch.      * @param {Function} fn The function to call      * @param {Object} scope (optional) The scope of the function (defaults to current component)      * @param {Array} args (optional) The args to call the function with (defaults to passing the current component)      * @return {Ext.Container} this      */     cascade : function(fn, scope, args){         if(fn.apply(scope || this, args || [this]) !== false){             if(this.items){                 var cs = this.items.items;                 for(var i = 0, len = cs.length; i < len; i++){                     if(cs[i].cascade){                         cs[i].cascade(fn, scope, args);                     }else{                         fn.apply(scope || cs[i], args || [cs[i]]);                     }                 }             }         }         return this;     },     /**      * Find a component under this container at any level by id      * @param {String} id      * @return Ext.Component      */     findById : function(id){         var m, ct = this;         this.cascade(function(c){             if(ct != c && c.id === id){                 m = c;                 return false;             }         });         return m || null;     },     /**      * Find a component under this container at any level by xtype or class      * @param {String/Class} xtype The xtype string for a component, or the class of the component directly      * @param {Boolean} shallow (optional) False to check whether this Component is descended from the xtype (this is      * the default), or true to check whether this Component is directly of the specified xtype.      * @return {Array} Array of Ext.Components      */     findByType : function(xtype, shallow){         return this.findBy(function(c){             return c.isXType(xtype, shallow);         });     },     /**      * Find a component under this container at any level by property      * @param {String} prop      * @param {String} value      * @return {Array} Array of Ext.Components      */     find : function(prop, value){         return this.findBy(function(c){             return c[prop] === value;         });     },     /**      * Find a component under this container at any level by a custom function. If the passed function returns      * true, the component will be included in the results. The passed function is called with the arguments (component, this container).      * @param {Function} fn The function to call      * @param {Object} scope (optional)      * @return {Array} Array of Ext.Components      */     findBy : function(fn, scope){         var m = [], ct = this;         this.cascade(function(c){             if(ct != c && fn.call(scope || c, c, ct) === true){                 m.push(c);             }         });         return m;     },     /**      * Get a component contained by this container (alias for items.get(key))      * @param {String/Number} key The index or id of the component      * @return {Ext.Component} Ext.Component      */     get : function(key){         return this.items.get(key);     } }); Ext.Container.LAYOUTS = {}; Ext.reg('container', Ext.Container); /**  * @class Ext.layout.ContainerLayout  * <p>The ContainerLayout class is the default layout manager delegated by {@link Ext.Container} to  * render any child Components when no <tt>{@link Ext.Container#layout layout}</tt> is configured into  * a {@link Ext.Container Container}. ContainerLayout provides the basic foundation for all other layout  * classes in Ext. It simply renders all child Components into the Container, performing no sizing or  * positioning services. To utilize a layout that provides sizing and positioning of child Components,  * specify an appropriate <tt>{@link Ext.Container#layout layout}</tt>.</p>  * <p>This class is intended to be extended or created via the <tt><b>{@link Ext.Container#layout layout}</b></tt>  * configuration property.  See <tt><b>{@link Ext.Container#layout}</b></tt> for additional details.</p>  */ Ext.layout.ContainerLayout = function(config){     Ext.apply(this, config); }; Ext.layout.ContainerLayout.prototype = {     /**      * @cfg {String} extraCls      * <p>An optional extra CSS class that will be added to the container. This can be useful for adding      * customized styles to the container or any of its children using standard CSS rules. See      * {@link Ext.Component}.{@link Ext.Component#ctCls ctCls} also.</p>      * <p><b>Note</b>: <tt>extraCls</tt> defaults to <tt>''</tt> except for the following classes      * which assign a value by default:      * <div class="mdetail-params"><ul>      * <li>{@link Ext.layout.AbsoluteLayout Absolute Layout} : <tt>'x-abs-layout-item'</tt></li>      * <li>{@link Ext.layout.Box Box Layout} : <tt>'x-box-item'</tt></li>      * <li>{@link Ext.layout.ColumnLayout Column Layout} : <tt>'x-column'</tt></li>      * </ul></div>      * To configure the above Classes with an extra CSS class append to the default.  For example,      * for ColumnLayout:<pre><code>      * extraCls: 'x-column custom-class'      * </code></pre>      * </p>      */     /**      * @cfg {Boolean} renderHidden      * True to hide each contained item on render (defaults to false).      */     /**      * A reference to the {@link Ext.Component} that is active.  For example, <pre><code>      * if(myPanel.layout.activeItem.id == 'item-1') { ... }      * </code></pre>      * <tt>activeItem</tt> only applies to layout styles that can display items one at a time      * (like {@link Ext.layout.AccordionLayout}, {@link Ext.layout.CardLayout}      * and {@link Ext.layout.FitLayout}).  Read-only.  Related to {@link Ext.Container#activeItem}.      * @type {Ext.Component}      * @property activeItem      */     // private     monitorResize:false,     // private     activeItem : null,     // private     layout : function(){         var target = this.container.getLayoutTarget();         this.onLayout(this.container, target);         this.container.fireEvent('afterlayout', this.container, this);     },     // private     onLayout : function(ct, target){         this.renderAll(ct, target);     },     // private     isValidParent : function(c, target){ return target && c.getDomPositionEl().dom.parentNode == (target.dom || target);     },     // private     renderAll : function(ct, target){         var items = ct.items.items;         for(var i = 0, len = items.length; i < len; i++) {             var c = items[i];             if(c && (!c.rendered || !this.isValidParent(c, target))){                 this.renderItem(c, i, target);             }         }     },     // private     renderItem : function(c, position, target){         if(c && !c.rendered){             c.render(target, position);             this.configureItem(c, position);         }else if(c && !this.isValidParent(c, target)){             if(typeof position == 'number'){                 position = target.dom.childNodes[position];             }             target.dom.insertBefore(c.getDomPositionEl().dom, position || null);             c.container = target;             this.configureItem(c, position);         }     },          // private     configureItem: function(c, position){         if(this.extraCls){             var t = c.getPositionEl ? c.getPositionEl() : c;             t.addClass(this.extraCls);         }         if (this.renderHidden && c != this.activeItem) {             c.hide();         }         if(c.doLayout){             c.doLayout(false, this.forceLayout);         }     },     // private     onResize: function(){         if(this.container.collapsed){             return;         }         var b = this.container.bufferResize;         if(b){             if(!this.resizeTask){                 this.resizeTask = new Ext.util.DelayedTask(this.runLayout, this);                 this.resizeBuffer = typeof b == 'number' ? b : 100;             }             this.resizeTask.delay(this.resizeBuffer);         }else{             this.runLayout();         }     },          // private     runLayout: function(){         this.layout();         this.container.onLayout();     },     // private     setContainer : function(ct){         if(this.monitorResize && ct != this.container){             if(this.container){                 this.container.un('resize', this.onResize, this);                 this.container.un('bodyresize', this.onResize, this);             }             if(ct){                 ct.on({                     scope: this,                     resize: this.onResize,                     bodyresize: this.onResize                 });             }         }         this.container = ct;     },     // private     parseMargins : function(v){         if(typeof v == 'number'){             v = v.toString();         }         var ms = v.split(' ');         var len = ms.length;         if(len == 1){             ms[1] = ms[0];             ms[2] = ms[0];             ms[3] = ms[0];         }         if(len == 2){             ms[2] = ms[0];             ms[3] = ms[1];         }         if(len == 3){             ms[3] = ms[1];         }         return {             top:parseInt(ms[0], 10) || 0,             right:parseInt(ms[1], 10) || 0,             bottom:parseInt(ms[2], 10) || 0,             left:parseInt(ms[3], 10) || 0         };     },     /**      * The {@link Template Ext.Template} used by Field rendering layout classes (such as      * {@link Ext.layout.FormLayout}) to create the DOM structure of a fully wrapped,      * labeled and styled form Field. A default Template is supplied, but this may be      * overriden to create custom field structures. The template processes values returned from      * {@link Ext.layout.FormLayout#getTemplateArgs}.      * @property fieldTpl      * @type Ext.Template      */     fieldTpl: (function() {         var t = new Ext.Template(             '<div class="x-form-item {itemCls}" tabIndex="-1">',                 '<label for="{id}" style="{labelStyle}" class="x-form-item-label">{label}{labelSeparator}</label>',                 '<div class="x-form-element" id="x-form-el-{id}" style="{elementStyle}">',                 '</div><div class="{clearCls}"></div>',             '</div>'         );         t.disableFormats = true;         return t.compile();     })(),     /*      * Destroys this layout. This is a template method that is empty by default, but should be implemented      * by subclasses that require explicit destruction to purge event handlers or remove DOM nodes.      * @protected      */     destroy : Ext.emptyFn }; Ext.Container.LAYOUTS['auto'] = Ext.layout.ContainerLayout;/**
  1178.  * @class Ext.layout.FitLayout
  1179.  * @extends Ext.layout.ContainerLayout
  1180.  * <p>This is a base class for layouts that contain <b>a single item</b> that automatically expands to fill the layout's
  1181.  * container.  This class is intended to be extended or created via the <tt>layout:'fit'</tt> {@link Ext.Container#layout}
  1182.  * config, and should generally not need to be created directly via the new keyword.</p>
  1183.  * <p>FitLayout does not have any direct config options (other than inherited ones).  To fit a panel to a container
  1184.  * using FitLayout, simply set layout:'fit' on the container and add a single panel to it.  If the container has
  1185.  * multiple panels, only the first one will be displayed.  Example usage:</p>
  1186.  * <pre><code>
  1187. var p = new Ext.Panel({
  1188.     title: 'Fit Layout',
  1189.     layout:'fit',
  1190.     items: {
  1191.         title: 'Inner Panel',
  1192.         html: '&lt;p&gt;This is the inner panel content&lt;/p&gt;',
  1193.         border: false
  1194.     }
  1195. });
  1196. </code></pre>
  1197.  */
  1198. Ext.layout.FitLayout = Ext.extend(Ext.layout.ContainerLayout, {
  1199.     // private
  1200.     monitorResize:true,
  1201.     // private
  1202.     onLayout : function(ct, target){
  1203.         Ext.layout.FitLayout.superclass.onLayout.call(this, ct, target);
  1204.         if(!this.container.collapsed){
  1205.             var sz = (Ext.isIE6 && Ext.isStrict && target.dom == document.body) ? target.getViewSize() : target.getStyleSize();
  1206.             this.setItemSize(this.activeItem || ct.items.itemAt(0), sz);
  1207.         }
  1208.     },
  1209.     // private
  1210.     setItemSize : function(item, size){
  1211.         if(item && size.height > 0){ // display none?
  1212.             item.setSize(size);
  1213.         }
  1214.     }
  1215. });
  1216. Ext.Container.LAYOUTS['fit'] = Ext.layout.FitLayout;/**
  1217.  * @class Ext.layout.CardLayout
  1218.  * @extends Ext.layout.FitLayout
  1219.  * <p>This layout manages multiple child Components, each fitted to the Container, where only a single child Component can be
  1220.  * visible at any given time.  This layout style is most commonly used for wizards, tab implementations, etc.
  1221.  * This class is intended to be extended or created via the layout:'card' {@link Ext.Container#layout} config,
  1222.  * and should generally not need to be created directly via the new keyword.</p>
  1223.  * <p>The CardLayout's focal method is {@link #setActiveItem}.  Since only one panel is displayed at a time,
  1224.  * the only way to move from one Component to the next is by calling setActiveItem, passing the id or index of
  1225.  * the next panel to display.  The layout itself does not provide a user interface for handling this navigation,
  1226.  * so that functionality must be provided by the developer.</p>
  1227.  * <p>In the following example, a simplistic wizard setup is demonstrated.  A button bar is added
  1228.  * to the footer of the containing panel to provide navigation buttons.  The buttons will be handled by a
  1229.  * common navigation routine -- for this example, the implementation of that routine has been ommitted since
  1230.  * it can be any type of custom logic.  Note that other uses of a CardLayout (like a tab control) would require a
  1231.  * completely different implementation.  For serious implementations, a better approach would be to extend
  1232.  * CardLayout to provide the custom functionality needed.  Example usage:</p>
  1233.  * <pre><code>
  1234. var navHandler = function(direction){
  1235.     // This routine could contain business logic required to manage the navigation steps.
  1236.     // It would call setActiveItem as needed, manage navigation button state, handle any
  1237.     // branching logic that might be required, handle alternate actions like cancellation
  1238.     // or finalization, etc.  A complete wizard implementation could get pretty
  1239.     // sophisticated depending on the complexity required, and should probably be
  1240.     // done as a subclass of CardLayout in a real-world implementation.
  1241. };
  1242. var card = new Ext.Panel({
  1243.     title: 'Example Wizard',
  1244.     layout:'card',
  1245.     activeItem: 0, // make sure the active item is set on the container config!
  1246.     bodyStyle: 'padding:15px',
  1247.     defaults: {
  1248.         // applied to each contained panel
  1249.         border:false
  1250.     },
  1251.     // just an example of one possible navigation scheme, using buttons
  1252.     bbar: [
  1253.         {
  1254.             id: 'move-prev',
  1255.             text: 'Back',
  1256.             handler: navHandler.createDelegate(this, [-1]),
  1257.             disabled: true
  1258.         },
  1259.         '->', // greedy spacer so that the buttons are aligned to each side
  1260.         {
  1261.             id: 'move-next',
  1262.             text: 'Next',
  1263.             handler: navHandler.createDelegate(this, [1])
  1264.         }
  1265.     ],
  1266.     // the panels (or "cards") within the layout
  1267.     items: [{
  1268.         id: 'card-0',
  1269.         html: '&lt;h1&gt;Welcome to the Wizard!&lt;/h1&gt;&lt;p&gt;Step 1 of 3&lt;/p&gt;'
  1270.     },{
  1271.         id: 'card-1',
  1272.         html: '&lt;p&gt;Step 2 of 3&lt;/p&gt;'
  1273.     },{
  1274.         id: 'card-2',
  1275.         html: '&lt;h1&gt;Congratulations!&lt;/h1&gt;&lt;p&gt;Step 3 of 3 - Complete&lt;/p&gt;'
  1276.     }]
  1277. });
  1278. </code></pre>
  1279.  */
  1280. Ext.layout.CardLayout = Ext.extend(Ext.layout.FitLayout, {
  1281.     /**
  1282.      * @cfg {Boolean} deferredRender
  1283.      * True to render each contained item at the time it becomes active, false to render all contained items
  1284.      * as soon as the layout is rendered (defaults to false).  If there is a significant amount of content or
  1285.      * a lot of heavy controls being rendered into panels that are not displayed by default, setting this to
  1286.      * true might improve performance.
  1287.      */
  1288.     deferredRender : false,
  1289.     
  1290.     /**
  1291.      * @cfg {Boolean} layoutOnCardChange
  1292.      * True to force a layout of the active item when the active card is changed. Defaults to false.
  1293.      */
  1294.     layoutOnCardChange : false,
  1295.     /**
  1296.      * @cfg {Boolean} renderHidden @hide
  1297.      */
  1298.     // private
  1299.     renderHidden : true,
  1300.     
  1301.     constructor: function(config){
  1302.         Ext.layout.CardLayout.superclass.constructor.call(this, config);
  1303.         this.forceLayout = (this.deferredRender === false);
  1304.     },
  1305.     /**
  1306.      * Sets the active (visible) item in the layout.
  1307.      * @param {String/Number} item The string component id or numeric index of the item to activate
  1308.      */
  1309.     setActiveItem : function(item){
  1310.         item = this.container.getComponent(item);
  1311.         if(this.activeItem != item){
  1312.             if(this.activeItem){
  1313.                 this.activeItem.hide();
  1314.             }
  1315.             this.activeItem = item;
  1316.             item.show();
  1317.             this.container.doLayout();
  1318.             if(this.layoutOnCardChange && item.doLayout){
  1319.                 item.doLayout();
  1320.             }
  1321.         }
  1322.     },
  1323.     // private
  1324.     renderAll : function(ct, target){
  1325.         if(this.deferredRender){
  1326.             this.renderItem(this.activeItem, undefined, target);
  1327.         }else{
  1328.             Ext.layout.CardLayout.superclass.renderAll.call(this, ct, target);
  1329.         }
  1330.     }
  1331. });
  1332. Ext.Container.LAYOUTS['card'] = Ext.layout.CardLayout;/**
  1333.  * @class Ext.layout.AnchorLayout
  1334.  * @extends Ext.layout.ContainerLayout
  1335.  * <p>This is a layout that enables anchoring of contained elements relative to the container's dimensions.
  1336.  * If the container is resized, all anchored items are automatically rerendered according to their
  1337.  * <b><tt>{@link #anchor}</tt></b> rules.</p>
  1338.  * <p>This class is intended to be extended or created via the layout:'anchor' {@link Ext.Container#layout}
  1339.  * config, and should generally not need to be created directly via the new keyword.</p>
  1340.  * <p>AnchorLayout does not have any direct config options (other than inherited ones). By default,
  1341.  * AnchorLayout will calculate anchor measurements based on the size of the container itself. However, the
  1342.  * container using the AnchorLayout can supply an anchoring-specific config property of <b>anchorSize</b>.
  1343.  * If anchorSize is specifed, the layout will use it as a virtual container for the purposes of calculating
  1344.  * anchor measurements based on it instead, allowing the container to be sized independently of the anchoring
  1345.  * logic if necessary.  For example:</p>
  1346.  * <pre><code>
  1347. var viewport = new Ext.Viewport({
  1348.     layout:'anchor',
  1349.     anchorSize: {width:800, height:600},
  1350.     items:[{
  1351.         title:'Item 1',
  1352.         html:'Content 1',
  1353.         width:800,
  1354.         anchor:'right 20%'
  1355.     },{
  1356.         title:'Item 2',
  1357.         html:'Content 2',
  1358.         width:300,
  1359.         anchor:'50% 30%'
  1360.     },{
  1361.         title:'Item 3',
  1362.         html:'Content 3',
  1363.         width:600,
  1364.         anchor:'-100 50%'
  1365.     }]
  1366. });
  1367.  * </code></pre>
  1368.  */
  1369. Ext.layout.AnchorLayout = Ext.extend(Ext.layout.ContainerLayout, {
  1370.     /**
  1371.      * @cfg {String} anchor
  1372.      * <p>This configuation option is to be applied to <b>child <tt>items</tt></b> of a container managed by
  1373.      * this layout (ie. configured with <tt>layout:'anchor'</tt>).</p><br/>
  1374.      * 
  1375.      * <p>This value is what tells the layout how an item should be anchored to the container. <tt>items</tt>
  1376.      * added to an AnchorLayout accept an anchoring-specific config property of <b>anchor</b> which is a string
  1377.      * containing two values: the horizontal anchor value and the vertical anchor value (for example, '100% 50%').
  1378.      * The following types of anchor values are supported:<div class="mdetail-params"><ul>
  1379.      * 
  1380.      * <li><b>Percentage</b> : Any value between 1 and 100, expressed as a percentage.<div class="sub-desc">
  1381.      * The first anchor is the percentage width that the item should take up within the container, and the
  1382.      * second is the percentage height.  For example:<pre><code>
  1383. // two values specified
  1384. anchor: '100% 50%' // render item complete width of the container and
  1385.                    // 1/2 height of the container
  1386. // one value specified
  1387. anchor: '100%'     // the width value; the height will default to auto
  1388.      * </code></pre></div></li>
  1389.      * 
  1390.      * <li><b>Offsets</b> : Any positive or negative integer value.<div class="sub-desc">
  1391.      * This is a raw adjustment where the first anchor is the offset from the right edge of the container,
  1392.      * and the second is the offset from the bottom edge. For example:<pre><code>
  1393. // two values specified
  1394. anchor: '-50 -100' // render item the complete width of the container
  1395.                    // minus 50 pixels and
  1396.                    // the complete height minus 100 pixels.
  1397. // one value specified
  1398. anchor: '-50'      // anchor value is assumed to be the right offset value
  1399.                    // bottom offset will default to 0
  1400.      * </code></pre></div></li>
  1401.      * 
  1402.      * <li><b>Sides</b> : Valid values are <tt>'right'</tt> (or <tt>'r'</tt>) and <tt>'bottom'</tt>
  1403.      * (or <tt>'b'</tt>).<div class="sub-desc">
  1404.      * Either the container must have a fixed size or an anchorSize config value defined at render time in
  1405.      * order for these to have any effect.</div></li>
  1406.      *
  1407.      * <li><b>Mixed</b> : <div class="sub-desc">
  1408.      * Anchor values can also be mixed as needed.  For example, to render the width offset from the container
  1409.      * right edge by 50 pixels and 75% of the container's height use:
  1410.      * <pre><code>
  1411. anchor: '-50 75%' 
  1412.      * </code></pre></div></li>
  1413.      * 
  1414.      * 
  1415.      * </ul></div>
  1416.      */
  1417.     
  1418.     // private
  1419.     monitorResize:true,
  1420.     // private
  1421.     getAnchorViewSize : function(ct, target){
  1422.         return target.dom == document.body ?
  1423.                    target.getViewSize() : target.getStyleSize();
  1424.     },
  1425.     // private
  1426.     onLayout : function(ct, target){
  1427.         Ext.layout.AnchorLayout.superclass.onLayout.call(this, ct, target);
  1428.         var size = this.getAnchorViewSize(ct, target);
  1429.         var w = size.width, h = size.height;
  1430.         if(w < 20 && h < 20){
  1431.             return;
  1432.         }
  1433.         // find the container anchoring size
  1434.         var aw, ah;
  1435.         if(ct.anchorSize){
  1436.             if(typeof ct.anchorSize == 'number'){
  1437.                 aw = ct.anchorSize;
  1438.             }else{
  1439.                 aw = ct.anchorSize.width;
  1440.                 ah = ct.anchorSize.height;
  1441.             }
  1442.         }else{
  1443.             aw = ct.initialConfig.width;
  1444.             ah = ct.initialConfig.height;
  1445.         }
  1446.         var cs = ct.items.items, len = cs.length, i, c, a, cw, ch;
  1447.         for(i = 0; i < len; i++){
  1448.             c = cs[i];
  1449.             if(c.anchor){
  1450.                 a = c.anchorSpec;
  1451.                 if(!a){ // cache all anchor values
  1452.                     var vs = c.anchor.split(' ');
  1453.                     c.anchorSpec = a = {
  1454.                         right: this.parseAnchor(vs[0], c.initialConfig.width, aw),
  1455.                         bottom: this.parseAnchor(vs[1], c.initialConfig.height, ah)
  1456.                     };
  1457.                 }
  1458.                 cw = a.right ? this.adjustWidthAnchor(a.right(w), c) : undefined;
  1459.                 ch = a.bottom ? this.adjustHeightAnchor(a.bottom(h), c) : undefined;
  1460.                 if(cw || ch){
  1461.                     c.setSize(cw || undefined, ch || undefined);
  1462.                 }
  1463.             }
  1464.         }
  1465.     },
  1466.     // private
  1467.     parseAnchor : function(a, start, cstart){
  1468.         if(a && a != 'none'){
  1469.             var last;
  1470.             if(/^(r|right|b|bottom)$/i.test(a)){   // standard anchor
  1471.                 var diff = cstart - start;
  1472.                 return function(v){
  1473.                     if(v !== last){
  1474.                         last = v;
  1475.                         return v - diff;
  1476.                     }
  1477.                 }
  1478.             }else if(a.indexOf('%') != -1){
  1479.                 var ratio = parseFloat(a.replace('%', ''))*.01;   // percentage
  1480.                 return function(v){
  1481.                     if(v !== last){
  1482.                         last = v;
  1483.                         return Math.floor(v*ratio);
  1484.                     }
  1485.                 }
  1486.             }else{
  1487.                 a = parseInt(a, 10);
  1488.                 if(!isNaN(a)){                            // simple offset adjustment
  1489.                     return function(v){
  1490.                         if(v !== last){
  1491.                             last = v;
  1492.                             return v + a;
  1493.                         }
  1494.                     }
  1495.                 }
  1496.             }
  1497.         }
  1498.         return false;
  1499.     },
  1500.     // private
  1501.     adjustWidthAnchor : function(value, comp){
  1502.         return value;
  1503.     },
  1504.     // private
  1505.     adjustHeightAnchor : function(value, comp){
  1506.         return value;
  1507.     }
  1508.     
  1509.     /**
  1510.      * @property activeItem
  1511.      * @hide
  1512.      */
  1513. });
  1514. Ext.Container.LAYOUTS['anchor'] = Ext.layout.AnchorLayout;/**
  1515.  * @class Ext.layout.ColumnLayout
  1516.  * @extends Ext.layout.ContainerLayout
  1517.  * <p>This is the layout style of choice for creating structural layouts in a multi-column format where the width of
  1518.  * each column can be specified as a percentage or fixed width, but the height is allowed to vary based on the content.
  1519.  * This class is intended to be extended or created via the layout:'column' {@link Ext.Container#layout} config,
  1520.  * and should generally not need to be created directly via the new keyword.</p>
  1521.  * <p>ColumnLayout does not have any direct config options (other than inherited ones), but it does support a
  1522.  * specific config property of <b><tt>columnWidth</tt></b> that can be included in the config of any panel added to it.  The
  1523.  * layout will use the columnWidth (if present) or width of each panel during layout to determine how to size each panel.
  1524.  * If width or columnWidth is not specified for a given panel, its width will default to the panel's width (or auto).</p>
  1525.  * <p>The width property is always evaluated as pixels, and must be a number greater than or equal to 1.
  1526.  * The columnWidth property is always evaluated as a percentage, and must be a decimal value greater than 0 and
  1527.  * less than 1 (e.g., .25).</p>
  1528.  * <p>The basic rules for specifying column widths are pretty simple.  The logic makes two passes through the
  1529.  * set of contained panels.  During the first layout pass, all panels that either have a fixed width or none
  1530.  * specified (auto) are skipped, but their widths are subtracted from the overall container width.  During the second
  1531.  * pass, all panels with columnWidths are assigned pixel widths in proportion to their percentages based on
  1532.  * the total <b>remaining</b> container width.  In other words, percentage width panels are designed to fill the space
  1533.  * left over by all the fixed-width and/or auto-width panels.  Because of this, while you can specify any number of columns
  1534.  * with different percentages, the columnWidths must always add up to 1 (or 100%) when added together, otherwise your
  1535.  * layout may not render as expected.  Example usage:</p>
  1536.  * <pre><code>
  1537. // All columns are percentages -- they must add up to 1
  1538. var p = new Ext.Panel({
  1539.     title: 'Column Layout - Percentage Only',
  1540.     layout:'column',
  1541.     items: [{
  1542.         title: 'Column 1',
  1543.         columnWidth: .25 
  1544.     },{
  1545.         title: 'Column 2',
  1546.         columnWidth: .6
  1547.     },{
  1548.         title: 'Column 3',
  1549.         columnWidth: .15
  1550.     }]
  1551. });
  1552. // Mix of width and columnWidth -- all columnWidth values must add up
  1553. // to 1. The first column will take up exactly 120px, and the last two
  1554. // columns will fill the remaining container width.
  1555. var p = new Ext.Panel({
  1556.     title: 'Column Layout - Mixed',
  1557.     layout:'column',