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

中间件编程

开发平台:

JavaScript

  1.             t += extraHeight ? extraHeight / 2 : 0;
  2.         }else if(this.pack == 'end'){
  3.             t += extraHeight;
  4.         }
  5.         Ext.each(cs, function(c){
  6.             cm = c.margins;
  7.             t += cm.top;
  8.             c.setPosition(l + cm.left, t);
  9.             if(isStart && c.flex){
  10.                 ch = Math.max(0, heights[idx++] + (leftOver-- > 0 ? 1 : 0));
  11.                 if(isRestore){
  12.                     restore.push(c.getWidth());
  13.                 }
  14.                 c.setSize(availableWidth, ch);
  15.             }else{
  16.                 ch = c.getHeight();
  17.             }
  18.             t += ch + cm.bottom;
  19.         });
  20.         
  21.         idx = 0;
  22.         Ext.each(cs, function(c){
  23.             cm = c.margins;
  24.             if(this.align == 'stretch'){
  25.                 c.setWidth((stretchWidth - (cm.left + cm.right)).constrain(
  26.                     c.minWidth || 0, c.maxWidth || 1000000));
  27.             }else if(this.align == 'stretchmax'){
  28.                 c.setWidth((maxWidth - (cm.left + cm.right)).constrain(
  29.                     c.minWidth || 0, c.maxWidth || 1000000));
  30.             }else{
  31.                 if(this.align == 'center'){
  32.                     var diff = availableWidth - (c.getWidth() + cm.left + cm.right);
  33.                     if(diff > 0){
  34.                         c.setPosition(l + cm.left + (diff/2), c.y);
  35.                     }
  36.                 }
  37.                 if(isStart && c.flex){
  38.                     c.setWidth(restore[idx++]);
  39.                 }
  40.             }
  41.         }, this);
  42.     }
  43.     /**
  44.      * @property activeItem
  45.      * @hide
  46.      */
  47. });
  48. Ext.Container.LAYOUTS.vbox = Ext.layout.VBoxLayout;
  49. /**
  50.  * @class Ext.layout.HBoxLayout
  51.  * @extends Ext.layout.BoxLayout
  52.  * A layout that arranges items horizontally
  53.  */
  54. Ext.layout.HBoxLayout = Ext.extend(Ext.layout.BoxLayout, {
  55.     /**
  56.      * @cfg {String} align
  57.      * Controls how the child items of the container are aligned. Acceptable configuration values for this
  58.      * property are:
  59.      * <div class="mdetail-params"><ul>
  60.      * <li><b><tt>top</tt></b> : <b>Default</b><div class="sub-desc">child items are aligned vertically
  61.      * at the <b>left</b> side of the container</div></li>
  62.      * <li><b><tt>middle</tt></b> : <div class="sub-desc">child items are aligned vertically at the
  63.      * <b>mid-height</b> of the container</div></li>
  64.      * <li><b><tt>stretch</tt></b> : <div class="sub-desc">child items are stretched vertically to fill
  65.      * the height of the container</div></li>
  66.      * <li><b><tt>stretchmax</tt></b> : <div class="sub-desc">child items are stretched vertically to
  67.      * the size of the largest item.</div></li>
  68.      */
  69.     align : 'top', // top, middle, stretch, strechmax
  70.     /**
  71.      * @cfg {String} pack
  72.      * Controls how the child items of the container are packed together. Acceptable configuration values
  73.      * for this property are:
  74.      * <div class="mdetail-params"><ul>
  75.      * <li><b><tt>start</tt></b> : <b>Default</b><div class="sub-desc">child items are packed together at
  76.      * <b>left</b> side of container</div></li>
  77.      * <li><b><tt>center</tt></b> : <div class="sub-desc">child items are packed together at
  78.      * <b>mid-width</b> of container</div></li>
  79.      * <li><b><tt>end</tt></b> : <div class="sub-desc">child items are packed together at <b>right</b>
  80.      * side of container</div></li>
  81.      * </ul></div>
  82.      */
  83.     /**
  84.      * @cfg {Number} flex
  85.      * This configuation option is to be applied to <b>child <tt>items</tt></b> of the container managed
  86.      * by this layout. Each child item with a <tt>flex</tt> property will be flexed <b>horizontally</b>
  87.      * according to each item's <b>relative</b> <tt>flex</tt> value compared to the sum of all items with
  88.      * a <tt>flex</tt> value specified.  Any child items that have either a <tt>flex = 0</tt> or
  89.      * <tt>flex = undefined</tt> will not be 'flexed' (the initial size will not be changed).
  90.      */
  91.     // private
  92.     onLayout : function(ct, target){
  93.         Ext.layout.HBoxLayout.superclass.onLayout.call(this, ct, target);
  94.         
  95.         var cs = this.getItems(ct), cm, cw, margin,
  96.             size = this.getTargetSize(target),
  97.             w = size.width - target.getPadding('lr') - this.scrollOffset,
  98.             h = size.height - target.getPadding('tb'),
  99.             l = this.padding.left, t = this.padding.top,
  100.             isStart = this.pack == 'start',
  101.             isRestore = ['stretch', 'stretchmax'].indexOf(this.align) == -1,
  102.             stretchHeight = h - (this.padding.top + this.padding.bottom),
  103.             extraWidth = 0,
  104.             maxHeight = 0,
  105.             totalFlex = 0,
  106.             flexWidth = 0,
  107.             usedWidth = 0;
  108.         
  109.         Ext.each(cs, function(c){
  110.             cm = c.margins;
  111.             totalFlex += c.flex || 0;
  112.             cw = c.getWidth();
  113.             margin = cm.left + cm.right;
  114.             extraWidth += cw + margin;
  115.             flexWidth += margin + (c.flex ? 0 : cw);
  116.             maxHeight = Math.max(maxHeight, c.getHeight() + cm.top + cm.bottom);
  117.         });
  118.         extraWidth = w - extraWidth - this.padding.left - this.padding.right;
  119.         
  120.         var innerCtHeight = maxHeight + this.padding.top + this.padding.bottom;
  121.         switch(this.align){
  122.             case 'stretch':
  123.                 this.innerCt.setSize(w, h);
  124.                 break;
  125.             case 'stretchmax':
  126.             case 'top':
  127.                 this.innerCt.setSize(w, innerCtHeight);
  128.                 break;
  129.             case 'middle':
  130.                 this.innerCt.setSize(w, h = Math.max(h, innerCtHeight));
  131.                 break;
  132.         }
  133.         
  134.         var availWidth = Math.max(0, w - this.padding.left - this.padding.right - flexWidth),
  135.             leftOver = availWidth,
  136.             widths = [],
  137.             restore = [],
  138.             idx = 0,
  139.             availableHeight = Math.max(0, h - this.padding.top - this.padding.bottom);
  140.             
  141.         Ext.each(cs, function(c){
  142.             if(isStart && c.flex){
  143.                 cw = Math.floor(availWidth * (c.flex / totalFlex));
  144.                 leftOver -= cw;
  145.                 widths.push(cw);
  146.             }
  147.         }); 
  148.         
  149.         if(this.pack == 'center'){
  150.             l += extraWidth ? extraWidth / 2 : 0;
  151.         }else if(this.pack == 'end'){
  152.             l += extraWidth;
  153.         }
  154.         Ext.each(cs, function(c){
  155.             cm = c.margins;
  156.             l += cm.left;
  157.             c.setPosition(l, t + cm.top);
  158.             if(isStart && c.flex){
  159.                 cw = Math.max(0, widths[idx++] + (leftOver-- > 0 ? 1 : 0));
  160.                 if(isRestore){
  161.                     restore.push(c.getHeight());
  162.                 }
  163.                 c.setSize(cw, availableHeight);
  164.             }else{
  165.                 cw = c.getWidth();
  166.             }
  167.             l += cw + cm.right;
  168.         });
  169.         
  170.         idx = 0;
  171.         Ext.each(cs, function(c){
  172.             var cm = c.margins;
  173.             if(this.align == 'stretch'){
  174.                 c.setHeight((stretchHeight - (cm.top + cm.bottom)).constrain(
  175.                     c.minHeight || 0, c.maxHeight || 1000000));
  176.             }else if(this.align == 'stretchmax'){
  177.                 c.setHeight((maxHeight - (cm.top + cm.bottom)).constrain(
  178.                     c.minHeight || 0, c.maxHeight || 1000000));
  179.             }else{
  180.                 if(this.align == 'middle'){
  181.                     var diff = availableHeight - (c.getHeight() + cm.top + cm.bottom);
  182.                     if(diff > 0){
  183.                         c.setPosition(c.x, t + cm.top + (diff/2));
  184.                     }
  185.                 }
  186.                 if(isStart && c.flex){
  187.                     c.setHeight(restore[idx++]);
  188.                 }
  189.             }
  190.         }, this);
  191.     }
  192.     /**
  193.      * @property activeItem
  194.      * @hide
  195.      */
  196. });
  197. Ext.Container.LAYOUTS.hbox = Ext.layout.HBoxLayout; /**
  198.  * @class Ext.Viewport
  199.  * @extends Ext.Container
  200.  * <p>A specialized container representing the viewable application area (the browser viewport).</p>
  201.  * <p>The Viewport renders itself to the document body, and automatically sizes itself to the size of
  202.  * the browser viewport and manages window resizing. There may only be one Viewport created
  203.  * in a page. Inner layouts are available by virtue of the fact that all {@link Ext.Panel Panel}s
  204.  * added to the Viewport, either through its {@link #items}, or through the items, or the {@link #add}
  205.  * method of any of its child Panels may themselves have a layout.</p>
  206.  * <p>The Viewport does not provide scrolling, so child Panels within the Viewport should provide
  207.  * for scrolling if needed using the {@link #autoScroll} config.</p>
  208.  * <p>An example showing a classic application border layout:</p><pre><code>
  209. new Ext.Viewport({
  210.     layout: 'border',
  211.     items: [{
  212.         region: 'north',
  213.         html: '&lt;h1 class="x-panel-header">Page Title&lt;/h1>',
  214.         autoHeight: true,
  215.         border: false,
  216.         margins: '0 0 5 0'
  217.     }, {
  218.         region: 'west',
  219.         collapsible: true,
  220.         title: 'Navigation',
  221.         width: 200
  222.         // the west region might typically utilize a {@link Ext.tree.TreePanel TreePanel} or a Panel with {@link Ext.layout.AccordionLayout Accordion layout} 
  223.     }, {
  224.         region: 'south',
  225.         title: 'Title for Panel',
  226.         collapsible: true,
  227.         html: 'Information goes here',
  228.         split: true,
  229.         height: 100,
  230.         minHeight: 100
  231.     }, {
  232.         region: 'east',
  233.         title: 'Title for the Grid Panel',
  234.         collapsible: true,
  235.         split: true,
  236.         width: 200,
  237.         xtype: 'grid',
  238.         // remaining grid configuration not shown ...
  239.         // notice that the GridPanel is added directly as the region
  240.         // it is not "overnested" inside another Panel
  241.     }, {
  242.         region: 'center',
  243.         xtype: 'tabpanel', // TabPanel itself has no title
  244.         items: {
  245.             title: 'Default Tab',
  246.             html: 'The first tab's content. Others may be added dynamically'
  247.         }
  248.     }]
  249. });
  250. </code></pre>
  251.  * @constructor
  252.  * Create a new Viewport
  253.  * @param {Object} config The config object
  254.  * @xtype viewport
  255.  */
  256. Ext.Viewport = Ext.extend(Ext.Container, {
  257. /*
  258.  * Privatize config options which, if used, would interfere with the
  259.  * correct operation of the Viewport as the sole manager of the
  260.  * layout of the document body.
  261.  */
  262.     /**
  263.      * @cfg {Mixed} applyTo @hide
  264.  */
  265.     /**
  266.      * @cfg {Boolean} allowDomMove @hide
  267.  */
  268.     /**
  269.      * @cfg {Boolean} hideParent @hide
  270.  */
  271.     /**
  272.      * @cfg {Mixed} renderTo @hide
  273.  */
  274.     /**
  275.      * @cfg {Boolean} hideParent @hide
  276.  */
  277.     /**
  278.      * @cfg {Number} height @hide
  279.  */
  280.     /**
  281.      * @cfg {Number} width @hide
  282.  */
  283.     /**
  284.      * @cfg {Boolean} autoHeight @hide
  285.  */
  286.     /**
  287.      * @cfg {Boolean} autoWidth @hide
  288.  */
  289.     /**
  290.      * @cfg {Boolean} deferHeight @hide
  291.  */
  292.     /**
  293.      * @cfg {Boolean} monitorResize @hide
  294.  */
  295.     initComponent : function() {
  296.         Ext.Viewport.superclass.initComponent.call(this);
  297.         document.getElementsByTagName('html')[0].className += ' x-viewport';
  298.         this.el = Ext.getBody();
  299.         this.el.setHeight = Ext.emptyFn;
  300.         this.el.setWidth = Ext.emptyFn;
  301.         this.el.setSize = Ext.emptyFn;
  302.         this.el.dom.scroll = 'no';
  303.         this.allowDomMove = false;
  304.         this.autoWidth = true;
  305.         this.autoHeight = true;
  306.         Ext.EventManager.onWindowResize(this.fireResize, this);
  307.         this.renderTo = this.el;
  308.     },
  309.     fireResize : function(w, h){
  310.         this.fireEvent('resize', this, w, h, w, h);
  311.     }
  312. });
  313. Ext.reg('viewport', Ext.Viewport);/**  * @class Ext.Panel  * @extends Ext.Container  * <p>Panel is a container that has specific functionality and structural components that make  * it the perfect building block for application-oriented user interfaces.</p>  * <p>Panels are, by virtue of their inheritance from {@link Ext.Container}, capable  * of being configured with a {@link Ext.Container#layout layout}, and containing child Components.</p>  * <p>When either specifying child {@link Ext.Component#items items} of a Panel, or dynamically {@link Ext.Container#add adding} Components  * to a Panel, remember to consider how you wish the Panel to arrange those child elements, and whether  * those child elements need to be sized using one of Ext's built-in <tt><b>{@link Ext.Container#layout layout}</b></tt> schemes. By  * default, Panels use the {@link Ext.layout.ContainerLayout ContainerLayout} scheme. This simply 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 Panel may also contain {@link #bbar bottom} and {@link #tbar top} toolbars, along with separate  * {@link #header}, {@link #footer} and {@link #body} sections (see {@link #frame} for additional  * information).</p>  * <p>Panel also provides built-in {@link #collapsible expandable and collapsible behavior}, along with  * a variety of {@link #tools prebuilt tool buttons} that can be wired up to provide other customized  * behavior.  Panels can be easily dropped into any {@link Ext.Container Container} or layout, and the  * layout and rendering pipeline is {@link Ext.Container#add completely managed by the framework}.</p>  * @constructor  * @param {Object} config The config object  * @xtype panel  */ Ext.Panel = Ext.extend(Ext.Container, {     /**      * The Panel's header {@link Ext.Element Element}. Read-only.      * <p>This Element is used to house the {@link #title} and {@link #tools}</p>      * <br><p><b>Note</b>: see the Note for <tt>{@link Ext.Component#el el} also.</p>      * @type Ext.Element      * @property header      */     /**      * The Panel's body {@link Ext.Element Element} which may be used to contain HTML content.      * The content may be specified in the {@link #html} config, or it may be loaded using the      * {@link autoLoad} config, or through the Panel's {@link #getUpdater Updater}. Read-only.      * <p>If this is used to load visible HTML elements in either way, then      * the Panel may not be used as a Layout for hosting nested Panels.</p>      * <p>If this Panel is intended to be used as the host of a Layout (See {@link #layout}      * then the body Element must not be loaded or changed - it is under the control      * of the Panel's Layout.      * <br><p><b>Note</b>: see the Note for <tt>{@link Ext.Component#el el} also.</p>      * @type Ext.Element      * @property body      */     /**      * The Panel's bwrap {@link Ext.Element Element} used to contain other Panel elements      * (tbar, body, bbar, footer). See {@link #bodyCfg}. Read-only.      * @type Ext.Element      * @property bwrap      */     /**      * True if this panel is collapsed. Read-only.      * @type Boolean      * @property collapsed      */     /**      * @cfg {Object} bodyCfg      * <p>A {@link Ext.DomHelper DomHelper} element specification object may be specified for any      * Panel Element.</p>      * <p>By default, the Default element in the table below will be used for the html markup to      * create a child element with the commensurate Default class name (<tt>baseCls</tt> will be      * replaced by <tt>{@link #baseCls}</tt>):</p>      * <pre>      * Panel      Default  Default             Custom      Additional       Additional      * Element    element  class               element     class            style      * ========   ==========================   =========   ==============   ===========      * {@link #header}     div      {@link #baseCls}+'-header'   {@link #headerCfg}   headerCssClass   headerStyle      * {@link #bwrap}      div      {@link #baseCls}+'-bwrap'     {@link #bwrapCfg}    bwrapCssClass    bwrapStyle      * + tbar     div      {@link #baseCls}+'-tbar'       {@link #tbarCfg}     tbarCssClass     tbarStyle      * + {@link #body}     div      {@link #baseCls}+'-body'       {@link #bodyCfg}     {@link #bodyCssClass}     {@link #bodyStyle}      * + bbar     div      {@link #baseCls}+'-bbar'       {@link #bbarCfg}     bbarCssClass     bbarStyle      * + {@link #footer}   div      {@link #baseCls}+'-footer'   {@link #footerCfg}   footerCssClass   footerStyle      * </pre>      * <p>Configuring a Custom element may be used, for example, to force the {@link #body} Element      * to use a different form of markup than is created by default. An example of this might be      * to {@link Ext.Element#createChild create a child} Panel containing a custom content, such as      * a header, or forcing centering of all Panel content by having the body be a &lt;center&gt;      * element:</p>      * <pre><code> new Ext.Panel({     title: 'Message Title',     renderTo: Ext.getBody(),     width: 200, height: 130,     <b>bodyCfg</b>: {         tag: 'center',         cls: 'x-panel-body',  // Default class not applied if Custom element specified         html: 'Message'     },     footerCfg: {         tag: 'h2',         cls: 'x-panel-footer'        // same as the Default class         html: 'footer html'     },     footerCssClass: 'custom-footer', // additional css class, see {@link Ext.element#addClass addClass}     footerStyle:    'background-color:red' // see {@link #bodyStyle} });      * </code></pre>      * <p>The example above also explicitly creates a <tt>{@link #footer}</tt> with custom markup and      * styling applied.</p>      */     /**      * @cfg {Object} headerCfg      * <p>A {@link Ext.DomHelper DomHelper} element specification object specifying the element structure      * of this Panel's {@link #header} Element.  See <tt>{@link #bodyCfg}</tt> also.</p>      */     /**      * @cfg {Object} bwrapCfg      * <p>A {@link Ext.DomHelper DomHelper} element specification object specifying the element structure      * of this Panel's {@link #bwrap} Element.  See <tt>{@link #bodyCfg}</tt> also.</p>      */     /**      * @cfg {Object} tbarCfg      * <p>A {@link Ext.DomHelper DomHelper} element specification object specifying the element structure      * of this Panel's {@link #tbar} Element.  See <tt>{@link #bodyCfg}</tt> also.</p>      */     /**      * @cfg {Object} bbarCfg      * <p>A {@link Ext.DomHelper DomHelper} element specification object specifying the element structure      * of this Panel's {@link #bbar} Element.  See <tt>{@link #bodyCfg}</tt> also.</p>      */     /**      * @cfg {Object} footerCfg      * <p>A {@link Ext.DomHelper DomHelper} element specification object specifying the element structure      * of this Panel's {@link #footer} Element.  See <tt>{@link #bodyCfg}</tt> also.</p>      */     /**      * @cfg {Boolean} closable      * Panels themselves do not directly support being closed, but some Panel subclasses do (like      * {@link Ext.Window}) or a Panel Class within an {@link Ext.TabPanel}.  Specify <tt>true</tt>      * to enable closing in such situations. Defaults to <tt>false</tt>.      */     /**      * The Panel's footer {@link Ext.Element Element}. Read-only.      * <p>This Element is used to house the Panel's <tt>{@link #buttons}</tt> or <tt>{@link #fbar}</tt>.</p>      * <br><p><b>Note</b>: see the Note for <tt>{@link Ext.Component#el el} also.</p>      * @type Ext.Element      * @property footer      */     /**      * @cfg {Mixed} applyTo      * <p>The id of the node, a DOM node or an existing Element corresponding to a DIV that is already present in      * the document that specifies some panel-specific structural markup.  When <tt>applyTo</tt> is used,      * constituent parts of the panel can be specified by CSS class name within the main element, and the panel      * will automatically create those components from that markup. Any required components not specified in the      * markup will be autogenerated if necessary.</p>      * <p>The following class names are supported (baseCls will be replaced by {@link #baseCls}):</p>      * <ul><li>baseCls + '-header'</li>      * <li>baseCls + '-header-text'</li>      * <li>baseCls + '-bwrap'</li>      * <li>baseCls + '-tbar'</li>      * <li>baseCls + '-body'</li>      * <li>baseCls + '-bbar'</li>      * <li>baseCls + '-footer'</li></ul>      * <p>Using this config, a call to render() is not required.  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      * panel's container.</p>      */     /**      * @cfg {Object/Array} tbar      * <p>The top toolbar of the panel. This can be a {@link Ext.Toolbar} object, a toolbar config, or an array of      * buttons/button configs to be added to the toolbar.  Note that this is not available as a property after render.      * To access the top toolbar after render, use {@link #getTopToolbar}.</p>      * <p><b>Note:</b> Although a Toolbar may contain Field components, these will <b>not</b> be updated by a load      * of an ancestor FormPanel. A Panel's toolbars are not part of the standard Container->Component hierarchy, and      * so are not scanned to collect form items. However, the values <b>will</b> be submitted because form      * submission parameters are collected from the DOM tree.</p>      */     /**      * @cfg {Object/Array} bbar      * <p>The bottom toolbar of the panel. This can be a {@link Ext.Toolbar} object, a toolbar config, or an array of      * buttons/button configs to be added to the toolbar.  Note that this is not available as a property after render.      * To access the bottom toolbar after render, use {@link #getBottomToolbar}.</p>      * <p><b>Note:</b> Although a Toolbar may contain Field components, these will <b>not<b> be updated by a load      * of an ancestor FormPanel. A Panel's toolbars are not part of the standard Container->Component hierarchy, and      * so are not scanned to collect form items. However, the values <b>will</b> be submitted because form      * submission parameters are collected from the DOM tree.</p>      */     /** @cfg {Object/Array} fbar      * <p>A {@link Ext.Toolbar Toolbar} object, a Toolbar config, or an array of      * {@link Ext.Button Button}s/{@link Ext.Button Button} configs, describing a {@link Ext.Toolbar Toolbar} to be rendered into this Panel's footer element.</p>      * <p>After render, the <code>fbar</code> property will be an {@link Ext.Toolbar Toolbar} instance.</p>      * <p>If <tt>{@link #buttons}</tt> are specified, they will supersede the <tt>fbar</tt> configuration property.</p>      * The Panel's <tt>{@link #buttonAlign}</tt> configuration affects the layout of these items, for example:      * <pre><code> var w = new Ext.Window({     height: 250,     width: 500,     bbar: new Ext.Toolbar({         items: [{             text: 'bbar Left'         },'->',{             text: 'bbar Right'         }]     }),     {@link #buttonAlign}: 'left', // anything but 'center' or 'right' and you can use "-", and "->"                                   // to control the alignment of fbar items     fbar: [{         text: 'fbar Left'     },'->',{         text: 'fbar Right'     }] }).show();      * </code></pre>      * <p><b>Note:</b> Although a Toolbar may contain Field components, these will <b>not<b> be updated by a load      * of an ancestor FormPanel. A Panel's toolbars are not part of the standard Container->Component hierarchy, and      * so are not scanned to collect form items. However, the values <b>will</b> be submitted because form      * submission parameters are collected from the DOM tree.</p>      */     /**      * @cfg {Boolean} header      * <tt>true</tt> to create the Panel's header element explicitly, <tt>false</tt> to skip creating      * it.  If a <tt>{@link #title}</tt> is set the header will be created automatically, otherwise it will not.      * If a <tt>{@link #title}</tt> is set but <tt>header</tt> is explicitly set to <tt>false</tt>, the header      * will not be rendered.      */     /**      * @cfg {Boolean} footer      * <tt>true</tt> to create the footer element explicitly, false to skip creating it. The footer      * will be created automatically if <tt>{@link #buttons}</tt> or a <tt>{@link #fbar}</tt> have      * been configured.  See <tt>{@link #bodyCfg}</tt> for an example.      */     /**      * @cfg {String} title      * The title text to be used as innerHTML (html tags are accepted) to display in the panel      * <tt>{@link #header}</tt> (defaults to ''). When a <tt>title</tt> is specified the      * <tt>{@link #header}</tt> element will automatically be created and displayed unless      * {@link #header} is explicitly set to <tt>false</tt>.  If you do not want to specify a      * <tt>title</tt> at config time, but you may want one later, you must either specify a non-empty      * <tt>title</tt> (a blank space ' ' will do) or <tt>header:true</tt> so that the container      * element will get created.      */     /**      * @cfg {Array} buttons      * <tt>buttons</tt> will be used as <tt>{@link Ext.Container#items items}</tt> for the toolbar in      * the footer (<tt>{@link #fbar}</tt>). Typically the value of this configuration property will be      * an array of {@link Ext.Button}s or {@link Ext.Button} configuration objects.      * If an item is configured with <tt>minWidth</tt> or the Panel is configured with <tt>minButtonWidth</tt>,      * that width will be applied to the item.      */     /**      * @cfg {Object/String/Function} autoLoad      * A valid url spec according to the Updater {@link Ext.Updater#update} method.      * If autoLoad is not null, the panel will attempt to load its contents      * immediately upon render.<p>      * The URL will become the default URL for this panel's {@link #body} element,      * so it may be {@link Ext.Element#refresh refresh}ed at any time.</p>      */     /**      * @cfg {Boolean} frame      * <tt>false</tt> by default to render with plain 1px square borders. <tt>true</tt> to render with      * 9 elements, complete with custom rounded corners (also see {@link Ext.Element#boxWrap}).      * <p>The template generated for each condition is depicted below:</p><pre><code>      * // frame = false &lt;div id="developer-specified-id-goes-here" class="x-panel">     &lt;div class="x-panel-header">&lt;span class="x-panel-header-text">Title: (frame:false)&lt;/span>&lt;/div>     &lt;div class="x-panel-bwrap">         &lt;div class="x-panel-body">&lt;p>html value goes here&lt;/p>&lt;/div>     &lt;/div> &lt;/div> // frame = true (create 9 elements) &lt;div id="developer-specified-id-goes-here" class="x-panel">     &lt;div class="x-panel-tl">&lt;div class="x-panel-tr">&lt;div class="x-panel-tc">         &lt;div class="x-panel-header">&lt;span class="x-panel-header-text">Title: (frame:true)&lt;/span>&lt;/div>     &lt;/div>&lt;/div>&lt;/div>     &lt;div class="x-panel-bwrap">         &lt;div class="x-panel-ml">&lt;div class="x-panel-mr">&lt;div class="x-panel-mc">             &lt;div class="x-panel-body">&lt;p>html value goes here&lt;/p>&lt;/div>         &lt;/div>&lt;/div>&lt;/div>         &lt;div class="x-panel-bl">&lt;div class="x-panel-br">&lt;div class="x-panel-bc"/>         &lt;/div>&lt;/div>&lt;/div> &lt;/div>      * </code></pre>      */     /**      * @cfg {Boolean} border      * True to display the borders of the panel's body element, false to hide them (defaults to true).  By default,      * the border is a 2px wide inset border, but this can be further altered by setting {@link #bodyBorder} to false.      */     /**      * @cfg {Boolean} bodyBorder      * True to display an interior border on the body element of the panel, false to hide it (defaults to true).      * This only applies when {@link #border} == true.  If border == true and bodyBorder == false, the border will display      * as a 1px wide inset border, giving the entire body element an inset appearance.      */     /**      * @cfg {String/Object/Function} bodyCssClass      * Additional css class selector to be applied to the {@link #body} element in the format expected by      * {@link Ext.Element#addClass} (defaults to null). See {@link #bodyCfg}.      */     /**      * @cfg {String/Object/Function} bodyStyle      * Custom CSS styles to be applied to the {@link #body} element in the format expected by      * {@link Ext.Element#applyStyles} (defaults to null). See {@link #bodyCfg}.      */     /**      * @cfg {String} iconCls      * The CSS class selector that specifies a background image to be used as the header icon (defaults to '').      * <p>An example of specifying a custom icon class would be something like:      * </p><pre><code> // specify the property in the config for the class:      ...      iconCls: 'my-icon' // css class that specifies background image to be used as the icon image: .my-icon { background-image: url(../images/my-icon.gif) 0 6px no-repeat !important; } </code></pre>      */     /**      * @cfg {Boolean} collapsible      * True to make the panel collapsible and have the expand/collapse toggle button automatically rendered into      * the header tool button area, false to keep the panel statically sized with no button (defaults to false).      */     /**      * @cfg {Array} tools      * An array of tool button configs to be added to the header tool area. When rendered, each tool is      * stored as an {@link Ext.Element Element} referenced by a public property called <tt><b></b>tools.<i>&lt;tool-type&gt;</i></tt>      * <p>Each tool config may contain the following properties:      * <div class="mdetail-params"><ul>      * <li><b>id</b> : String<div class="sub-desc"><b>Required.</b> The type      * of tool to create. By default, this assigns a CSS class of the form <tt>x-tool-<i>&lt;tool-type&gt;</i></tt> to the      * resulting tool Element. Ext provides CSS rules, and an icon sprite containing images for the tool types listed below.      * The developer may implement custom tools by supplying alternate CSS rules and background images:      * <ul>      * <div class="x-tool x-tool-toggle" style="float:left; margin-right:5;"> </div><div><tt> toggle</tt> (Created by default when {@link #collapsible} is <tt>true</tt>)</div>      * <div class="x-tool x-tool-close" style="float:left; margin-right:5;"> </div><div><tt> close</tt></div>      * <div class="x-tool x-tool-minimize" style="float:left; margin-right:5;"> </div><div><tt> minimize</tt></div>      * <div class="x-tool x-tool-maximize" style="float:left; margin-right:5;"> </div><div><tt> maximize</tt></div>      * <div class="x-tool x-tool-restore" style="float:left; margin-right:5;"> </div><div><tt> restore</tt></div>      * <div class="x-tool x-tool-gear" style="float:left; margin-right:5;"> </div><div><tt> gear</tt></div>      * <div class="x-tool x-tool-pin" style="float:left; margin-right:5;"> </div><div><tt> pin</tt></div>      * <div class="x-tool x-tool-unpin" style="float:left; margin-right:5;"> </div><div><tt> unpin</tt></div>      * <div class="x-tool x-tool-right" style="float:left; margin-right:5;"> </div><div><tt> right</tt></div>      * <div class="x-tool x-tool-left" style="float:left; margin-right:5;"> </div><div><tt> left</tt></div>      * <div class="x-tool x-tool-up" style="float:left; margin-right:5;"> </div><div><tt> up</tt></div>      * <div class="x-tool x-tool-down" style="float:left; margin-right:5;"> </div><div><tt> down</tt></div>      * <div class="x-tool x-tool-refresh" style="float:left; margin-right:5;"> </div><div><tt> refresh</tt></div>      * <div class="x-tool x-tool-minus" style="float:left; margin-right:5;"> </div><div><tt> minus</tt></div>      * <div class="x-tool x-tool-plus" style="float:left; margin-right:5;"> </div><div><tt> plus</tt></div>      * <div class="x-tool x-tool-help" style="float:left; margin-right:5;"> </div><div><tt> help</tt></div>      * <div class="x-tool x-tool-search" style="float:left; margin-right:5;"> </div><div><tt> search</tt></div>      * <div class="x-tool x-tool-save" style="float:left; margin-right:5;"> </div><div><tt> save</tt></div>      * <div class="x-tool x-tool-print" style="float:left; margin-right:5;"> </div><div><tt> print</tt></div>      * </ul></div></li>      * <li><b>handler</b> : Function<div class="sub-desc"><b>Required.</b> The function to      * call when clicked. Arguments passed are:<ul>      * <li><b>event</b> : Ext.EventObject<div class="sub-desc">The click event.</div></li>      * <li><b>toolEl</b> : Ext.Element<div class="sub-desc">The tool Element.</div></li>      * <li><b>panel</b> : Ext.Panel<div class="sub-desc">The host Panel</div></li>      * <li><b>tc</b> : Ext.Panel<div class="sub-desc">The tool configuration object</div></li>      * </ul></div></li>      * <li><b>stopEvent</b> : Boolean<div class="sub-desc">Defaults to true. Specify as false to allow click event to propagate.</div></li>      * <li><b>scope</b> : Object<div class="sub-desc">The scope in which to call the handler.</div></li>      * <li><b>qtip</b> : String/Object<div class="sub-desc">A tip string, or      * a config argument to {@link Ext.QuickTip#register}</div></li>      * <li><b>hidden</b> : Boolean<div class="sub-desc">True to initially render hidden.</div></li>      * <li><b>on</b> : Object<div class="sub-desc">A listener config object specifiying      * event listeners in the format of an argument to {@link #addListener}</div></li>      * </ul></div>      * <p>Note that, apart from the toggle tool which is provided when a panel is collapsible, these      * tools only provide the visual button. Any required functionality must be provided by adding      * handlers that implement the necessary behavior.</p>      * <p>Example usage:</p>      * <pre><code> tools:[{     id:'refresh',     qtip: 'Refresh form Data',     // hidden:true,     handler: function(event, toolEl, panel){         // refresh logic     } }, {     id:'help',     qtip: 'Get Help',     handler: function(event, toolEl, panel){         // whatever     } }] </code></pre>      * <p>For the custom id of <tt>'help'</tt> define two relevant css classes with a link to      * a 15x15 image:</p>      * <pre><code> .x-tool-help {background-image: url(images/help.png);} .x-tool-help-over {background-image: url(images/help_over.png);} // if using an image sprite: .x-tool-help {background-image: url(images/help.png) no-repeat 0 0;} .x-tool-help-over {background-position:-15px 0;} </code></pre>      */     /**      * @cfg {Ext.Template/Ext.XTemplate} toolTemplate      * <p>A Template used to create {@link #tools} in the {@link #header} Element. Defaults to:</p><pre><code> new Ext.Template('&lt;div class="x-tool x-tool-{id}">&amp;#160;&lt;/div>')</code></pre>      * <p>This may may be overridden to provide a custom DOM structure for tools based upon a more      * complex XTemplate. The template's data is a single tool configuration object (Not the entire Array)      * as specified in {@link #tools}.  In the following example an &lt;a> tag is used to provide a      * visual indication when hovering over the tool:</p><pre><code> var win = new Ext.Window({     tools: [{         id: 'download',         href: '/MyPdfDoc.pdf'     }],     toolTemplate: new Ext.XTemplate(         '&lt;tpl if="id=='download'">',             '&lt;a class="x-tool x-tool-pdf" href="{href}">&lt;/a>',         '&lt;/tpl>',         '&lt;tpl if="id!='download'">',             '&lt;div class="x-tool x-tool-{id}">&amp;#160;&lt;/div>',         '&lt;/tpl>'     ),     width:500,     height:300,     closeAction:'hide' });</code></pre>      * <p>Note that the CSS class "x-tool-pdf" should have an associated style rule which provides an      * appropriate background image, something like:</p>     <pre><code>     a.x-tool-pdf {background-image: url(../shared/extjs/images/pdf.gif)!important;}     </code></pre>      */     /**      * @cfg {Boolean} hideCollapseTool      * <tt>true</tt> to hide the expand/collapse toggle button when <code>{@link #collapsible} == true</code>,      * <tt>false</tt> to display it (defaults to <tt>false</tt>).      */     /**      * @cfg {Boolean} titleCollapse      * <tt>true</tt> to allow expanding and collapsing the panel (when <tt>{@link #collapsible} = true</tt>)      * by clicking anywhere in the header bar, <tt>false</tt>) to allow it only by clicking to tool button      * (defaults to <tt>false</tt>)). If this panel is a child item of a border layout also see the      * {@link Ext.layout.BorderLayout.Region BorderLayout.Region}      * <tt>{@link Ext.layout.BorderLayout.Region#floatable floatable}</tt> config option.      */     /**      * @cfg {Boolean} autoScroll      * <tt>true</tt> to use overflow:'auto' on the panel's body element and show scroll bars automatically when      * necessary, <tt>false</tt> to clip any overflowing content (defaults to <tt>false</tt>).      */     /**      * @cfg {Mixed} floating      * <p>This property is used to configure the underlying {@link Ext.Layer}. Acceptable values for this      * configuration property are:</p><div class="mdetail-params"><ul>      * <li><b><tt>false</tt></b> : <b>Default.</b><div class="sub-desc">Display the panel inline where it is      * rendered.</div></li>      * <li><b><tt>true</tt></b> : <div class="sub-desc">Float the panel (absolute position it with automatic      * shimming and shadow).<ul>      * <div class="sub-desc">Setting floating to true will create an Ext.Layer for this panel and display the      * panel at negative offsets so that it is hidden.</div>      * <div class="sub-desc">Since the panel will be absolute positioned, the position must be set explicitly      * <i>after</i> render (e.g., <tt>myPanel.setPosition(100,100);</tt>).</div>      * <div class="sub-desc"><b>Note</b>: when floating a panel you should always assign a fixed width,      * otherwise it will be auto width and will expand to fill to the right edge of the viewport.</div>      * </ul></div></li>      * <li><b><tt>{@link Ext.Layer object}</tt></b> : <div class="sub-desc">The specified object will be used      * as the configuration object for the {@link Ext.Layer} that will be created.</div></li>      * </ul></div>      */     /**      * @cfg {Boolean/String} shadow      * <tt>true</tt> (or a valid Ext.Shadow {@link Ext.Shadow#mode} value) to display a shadow behind the      * panel, <tt>false</tt> to display no shadow (defaults to <tt>'sides'</tt>).  Note that this option      * only applies when <tt>{@link #floating} = true</tt>.      */     /**      * @cfg {Number} shadowOffset      * The number of pixels to offset the shadow if displayed (defaults to <tt>4</tt>). Note that this      * option only applies when <tt>{@link #floating} = true</tt>.      */     /**      * @cfg {Boolean} shim      * <tt>false</tt> to disable the iframe shim in browsers which need one (defaults to <tt>true</tt>).      * Note that this option only applies when <tt>{@link #floating} = true</tt>.      */     /**      * @cfg {String/Object} html      * An HTML fragment, or a {@link Ext.DomHelper DomHelper} specification to use as the panel's body      * content (defaults to ''). The HTML content is added by the Panel's {@link #afterRender} method,      * and so the document will not contain this HTML at the time the {@link #render} event is fired.      * This content is inserted into the body <i>before</i> any configured {@link #contentEl} is appended.      */     /**      * @cfg {String} contentEl      * <p>Specify the <tt>id</tt> of an existing HTML node to use as the panel's body content      * (defaults to '').</p><div><ul>      * <li><b>Description</b> : <ul>      * <div class="sub-desc">This config option is used to take an existing HTML element and place it in the body      * of a new panel (it simply moves the specified DOM element into the body element of the Panel      * <i>when the Panel is rendered</i> to use as the content (it is not going to be the      * actual panel itself).</div>      * </ul></li>      * <li><b>Notes</b> : <ul>      * <div class="sub-desc">The specified HTML Element is appended to the Panel's {@link #body} Element by the      * Panel's {@link #afterRender} method <i>after any configured {@link #html HTML} has      * been inserted</i>, and so the document will not contain this HTML at the time the      * {@link #render} event is fired.</div>      * <div class="sub-desc">The specified HTML element used will not participate in any layout scheme that the      * Panel may use. It's just HTML. Layouts operate on child items.</div>      * <div class="sub-desc">Add either the <tt>x-hidden</tt> or the <tt>x-hide-display</tt> CSS class to      * prevent a brief flicker of the content before it is rendered to the panel.</div>      * </ul></li>      * </ul></div>      */     /**      * @cfg {Object/Array} keys      * A {@link Ext.KeyMap} config object (in the format expected by {@link Ext.KeyMap#addBinding}      * used to assign custom key handling to this panel (defaults to <tt>null</tt>).      */     /**      * @cfg {Boolean/Object} draggable      * <p><tt>true</tt> to enable dragging of this Panel (defaults to <tt>false</tt>).</p>      * <p>For custom drag/drop implementations, an <b>Ext.Panel.DD</b> config could also be passed      * in this config instead of <tt>true</tt>. Ext.Panel.DD is an internal, undocumented class which      * moves a proxy Element around in place of the Panel's element, but provides no other behaviour      * during dragging or on drop. It is a subclass of {@link Ext.dd.DragSource}, so behaviour may be      * added by implementing the interface methods of {@link Ext.dd.DragDrop} e.g.:      * <pre><code> new Ext.Panel({     title: 'Drag me',     x: 100,     y: 100,     renderTo: Ext.getBody(),     floating: true,     frame: true,     width: 400,     height: 200,     draggable: { //      Config option of Ext.Panel.DD class. //      It&#39;s a floating Panel, so do not show a placeholder proxy in the original position.         insertProxy: false, //      Called for each mousemove event while dragging the DD object.         onDrag : function(e){ //          Record the x,y position of the drag proxy so that we can //          position the Panel at end of drag.             var pel = this.proxy.getEl();             this.x = pel.getLeft(true);             this.y = pel.getTop(true); //          Keep the Shadow aligned if there is one.             var s = this.panel.getEl().shadow;             if (s) {                 s.realign(this.x, this.y, pel.getWidth(), pel.getHeight());             }         }, //      Called on the mouseup event.         endDrag : function(e){             this.panel.setPosition(this.x, this.y);         }     } }).show(); </code></pre>      */     /**      * @cfg {String} tabTip      * A string to be used as innerHTML (html tags are accepted) to show in a tooltip when mousing over      * the tab of a Ext.Panel which is an item of a {@link Ext.TabPanel}. {@link Ext.QuickTips}.init()      * must be called in order for the tips to render.      */     /**      * @cfg {Boolean} disabled      * Render this panel disabled (default is <tt>false</tt>). An important note when using the disabled      * config on panels is that IE will often fail to initialize the disabled mask element correectly if      * the panel's layout has not yet completed by the time the Panel is disabled during the render process.      * If you experience this issue, you may need to instead use the {@link #afterlayout} event to initialize      * the disabled state:      * <pre><code> new Ext.Panel({     ...     listeners: {         'afterlayout': {             fn: function(p){                 p.disable();             },             single: true // important, as many layouts can occur         }     } }); </code></pre>      */     /**      * @cfg {Boolean} autoHeight      * <tt>true</tt> to use height:'auto', <tt>false</tt> to use fixed height (defaults to <tt>false</tt>).      * <b>Note</b>: Setting <tt>autoHeight:true</tt> means that the browser will manage the panel's height      * based on its contents, and that Ext will not manage it at all. If the panel is within a layout that      * manages dimensions (<tt>fit</tt>, <tt>border</tt>, etc.) then setting <tt>autoHeight:true</tt>      * can cause issues with scrolling and will not generally work as expected since the panel will take      * on the height of its contents rather than the height required by the Ext layout.      */     /**      * @cfg {String} baseCls      * The base CSS class to apply to this panel's element (defaults to <tt>'x-panel'</tt>).      * <p>Another option available by default is to specify <tt>'x-plain'</tt> which strips all styling      * except for required attributes for Ext layouts to function (e.g. overflow:hidden).      * See <tt>{@link #unstyled}</tt> also.</p>      */     baseCls : 'x-panel',     /**      * @cfg {String} collapsedCls      * A CSS class to add to the panel's element after it has been collapsed (defaults to      * <tt>'x-panel-collapsed'</tt>).      */     collapsedCls : 'x-panel-collapsed',     /**      * @cfg {Boolean} maskDisabled      * <tt>true</tt> to mask the panel when it is {@link #disabled}, <tt>false</tt> to not mask it (defaults      * to <tt>true</tt>).  Either way, the panel will always tell its contained elements to disable themselves      * when it is disabled, but masking the panel can provide an additional visual cue that the panel is      * disabled.      */     maskDisabled : true,     /**      * @cfg {Boolean} animCollapse      * <tt>true</tt> to animate the transition when the panel is collapsed, <tt>false</tt> to skip the      * animation (defaults to <tt>true</tt> if the {@link Ext.Fx} class is available, otherwise <tt>false</tt>).      */     animCollapse : Ext.enableFx,     /**      * @cfg {Boolean} headerAsText      * <tt>true</tt> to display the panel <tt>{@link #title}</tt> in the <tt>{@link #header}</tt>,      * <tt>false</tt> to hide it (defaults to <tt>true</tt>).      */     headerAsText : true,     /**      * @cfg {String} buttonAlign      * The alignment of any {@link #buttons} added to this panel.  Valid values are <tt>'right'</tt>,      * <tt>'left'</tt> and <tt>'center'</tt> (defaults to <tt>'right'</tt>).      */     buttonAlign : 'right',     /**      * @cfg {Boolean} collapsed      * <tt>true</tt> to render the panel collapsed, <tt>false</tt> to render it expanded (defaults to      * <tt>false</tt>).      */     collapsed : false,     /**      * @cfg {Boolean} collapseFirst      * <tt>true</tt> to make sure the collapse/expand toggle button always renders first (to the left of)      * any other tools in the panel's title bar, <tt>false</tt> to render it last (defaults to <tt>true</tt>).      */     collapseFirst : true,     /**      * @cfg {Number} minButtonWidth      * Minimum width in pixels of all {@link #buttons} in this panel (defaults to <tt>75</tt>)      */     minButtonWidth : 75,     /**      * @cfg {Boolean} unstyled      * Overrides the <tt>{@link #baseCls}</tt> setting to <tt>{@link #baseCls} = 'x-plain'</tt> which renders      * the panel unstyled except for required attributes for Ext layouts to function (e.g. overflow:hidden).      */     /**      * @cfg {String} elements      * A comma-delimited list of panel elements to initialize when the panel is rendered.  Normally, this list will be      * generated automatically based on the items added to the panel at config time, but sometimes it might be useful to      * make sure a structural element is rendered even if not specified at config time (for example, you may want      * to add a button or toolbar dynamically after the panel has been rendered).  Adding those elements to this      * list will allocate the required placeholders in the panel when it is rendered.  Valid values are<div class="mdetail-params"><ul>      * <li><tt>header</tt></li>      * <li><tt>tbar</tt> (top bar)</li>      * <li><tt>body</tt></li>      * <li><tt>bbar</tt> (bottom bar)</li>      * <li><tt>footer</tt></li>      * </ul></div>      * Defaults to '<tt>body</tt>'.      */     elements : 'body',     /**      * @cfg {Boolean} preventBodyReset      * Defaults to <tt>false</tt>.  When set to <tt>true</tt>, an extra css class <tt>'x-panel-normal'</tt>      * will be added to the panel's element, effectively applying css styles suggested by the W3C      * (see http://www.w3.org/TR/CSS21/sample.html) to the Panel's <b>body</b> element (not the header,      * footer, etc.).      */     preventBodyReset : false,     // protected - these could be used to customize the behavior of the window,     // but changing them would not be useful without further mofifications and     // could lead to unexpected or undesirable results.     toolTarget : 'header',     collapseEl : 'bwrap',     slideAnchor : 't',     disabledClass : '',     // private, notify box this class will handle heights     deferHeight : true,     // private     expandDefaults: {         duration : 0.25     },     // private     collapseDefaults : {         duration : 0.25     },     // private     initComponent : function(){         Ext.Panel.superclass.initComponent.call(this);         this.addEvents(             /**              * @event bodyresize              * Fires after the Panel has been resized.              * @param {Ext.Panel} p the Panel which has been resized.              * @param {Number} width The Panel's new width.              * @param {Number} height The Panel's new height.              */             'bodyresize',             /**              * @event titlechange              * Fires after the Panel title has been {@link #title set} or {@link #setTitle changed}.              * @param {Ext.Panel} p the Panel which has had its title changed.              * @param {String} The new title.              */             'titlechange',             /**              * @event iconchange              * Fires after the Panel icon class has been {@link #iconCls set} or {@link #setIconClass changed}.              * @param {Ext.Panel} p the Panel which has had its {@link #iconCls icon class} changed.              * @param {String} The new icon class.              * @param {String} The old icon class.              */             'iconchange',             /**              * @event collapse              * Fires after the Panel has been collapsed.              * @param {Ext.Panel} p the Panel that has been collapsed.              */             'collapse',             /**              * @event expand              * Fires after the Panel has been expanded.              * @param {Ext.Panel} p The Panel that has been expanded.              */             'expand',             /**              * @event beforecollapse              * Fires before the Panel is collapsed.  A handler can return false to cancel the collapse.              * @param {Ext.Panel} p the Panel being collapsed.              * @param {Boolean} animate True if the collapse is animated, else false.              */             'beforecollapse',             /**              * @event beforeexpand              * Fires before the Panel is expanded.  A handler can return false to cancel the expand.              * @param {Ext.Panel} p The Panel being expanded.              * @param {Boolean} animate True if the expand is animated, else false.              */             'beforeexpand',             /**              * @event beforeclose              * Fires before the Panel is closed.  Note that Panels do not directly support being closed, but some              * Panel subclasses do (like {@link Ext.Window}) or a Panel within a Ext.TabPanel.  This event only              * applies to such subclasses.              * A handler can return false to cancel the close.              * @param {Ext.Panel} p The Panel being closed.              */             'beforeclose',             /**              * @event close              * Fires after the Panel is closed.  Note that Panels do not directly support being closed, but some              * Panel subclasses do (like {@link Ext.Window}) or a Panel within a Ext.TabPanel.              * @param {Ext.Panel} p The Panel that has been closed.              */             'close',             /**              * @event activate              * Fires after the Panel has been visually activated.              * Note that Panels do not directly support being activated, but some Panel subclasses              * do (like {@link Ext.Window}). Panels which are child Components of a TabPanel fire the              * activate and deactivate events under the control of the TabPanel.              * @param {Ext.Panel} p The Panel that has been activated.              */             'activate',             /**              * @event deactivate              * Fires after the Panel has been visually deactivated.              * Note that Panels do not directly support being deactivated, but some Panel subclasses              * do (like {@link Ext.Window}). Panels which are child Components of a TabPanel fire the              * activate and deactivate events under the control of the TabPanel.              * @param {Ext.Panel} p The Panel that has been deactivated.              */             'deactivate'         );         if(this.unstyled){             this.baseCls = 'x-plain';         }         // shortcuts         if(this.tbar){             this.elements += ',tbar';             if(Ext.isObject(this.tbar)){                 this.topToolbar = this.tbar;             }             delete this.tbar;         }         if(this.bbar){             this.elements += ',bbar';             if(Ext.isObject(this.bbar)){                 this.bottomToolbar = this.bbar;             }             delete this.bbar;         }         if(this.header === true){             this.elements += ',header';             delete this.header;         }else if(this.headerCfg || (this.title && this.header !== false)){             this.elements += ',header';         }         if(this.footerCfg || this.footer === true){             this.elements += ',footer';             delete this.footer;         }         if(this.buttons){             this.elements += ',footer';             var btns = this.buttons;             /**              * This Panel's Array of buttons as created from the <tt>{@link #buttons}</tt>              * config property. Read only.              * @type Array              * @property buttons              */             this.buttons = [];             for(var i = 0, len = btns.length; i < len; i++) {                 if(btns[i].render){ // button instance                     this.buttons.push(btns[i]);                 }else if(btns[i].xtype){                     this.buttons.push(Ext.create(btns[i], 'button'));                 }else{                     this.addButton(btns[i]);                 }             }         }         if(this.fbar){             this.elements += ',footer';         }         if(this.autoLoad){             this.on('render', this.doAutoLoad, this, {delay:10});         }     },     // private     createElement : function(name, pnode){         if(this[name]){             pnode.appendChild(this[name].dom);             return;         }         if(name === 'bwrap' || this.elements.indexOf(name) != -1){             if(this[name+'Cfg']){                 this[name] = Ext.fly(pnode).createChild(this[name+'Cfg']);             }else{                 var el = document.createElement('div');                 el.className = this[name+'Cls'];                 this[name] = Ext.get(pnode.appendChild(el));             }             if(this[name+'CssClass']){                 this[name].addClass(this[name+'CssClass']);             }             if(this[name+'Style']){                 this[name].applyStyles(this[name+'Style']);             }         }     },     // private     onRender : function(ct, position){         Ext.Panel.superclass.onRender.call(this, ct, position);         this.createClasses();         var el = this.el,             d = el.dom,             bw;         el.addClass(this.baseCls);         if(d.firstChild){ // existing markup             this.header = el.down('.'+this.headerCls);             this.bwrap = el.down('.'+this.bwrapCls);             var cp = this.bwrap ? this.bwrap : el;             this.tbar = cp.down('.'+this.tbarCls);             this.body = cp.down('.'+this.bodyCls);             this.bbar = cp.down('.'+this.bbarCls);             this.footer = cp.down('.'+this.footerCls);             this.fromMarkup = true;         }         if (this.preventBodyReset === true) {             el.addClass('x-panel-reset');         }         if(this.cls){             el.addClass(this.cls);         }         if(this.buttons){             this.elements += ',footer';         }         // This block allows for maximum flexibility and performance when using existing markup         // framing requires special markup         if(this.frame){             el.insertHtml('afterBegin', String.format(Ext.Element.boxMarkup, this.baseCls));             this.createElement('header', d.firstChild.firstChild.firstChild);             this.createElement('bwrap', d);             // append the mid and bottom frame to the bwrap             bw = this.bwrap.dom;             var ml = d.childNodes[1], bl = d.childNodes[2];             bw.appendChild(ml);             bw.appendChild(bl);             var mc = bw.firstChild.firstChild.firstChild;             this.createElement('tbar', mc);             this.createElement('body', mc);             this.createElement('bbar', mc);             this.createElement('footer', bw.lastChild.firstChild.firstChild);             if(!this.footer){                 this.bwrap.dom.lastChild.className += ' x-panel-nofooter';             }         }else{             this.createElement('header', d);             this.createElement('bwrap', d);             // append the mid and bottom frame to the bwrap             bw = this.bwrap.dom;             this.createElement('tbar', bw);             this.createElement('body', bw);             this.createElement('bbar', bw);             this.createElement('footer', bw);             if(!this.header){                 this.body.addClass(this.bodyCls + '-noheader');                 if(this.tbar){                     this.tbar.addClass(this.tbarCls + '-noheader');                 }             }         }         if(this.padding !== undefined) {             this.body.setStyle('padding', this.body.addUnits(this.padding));         }         if(this.border === false){             this.el.addClass(this.baseCls + '-noborder');             this.body.addClass(this.bodyCls + '-noborder');             if(this.header){                 this.header.addClass(this.headerCls + '-noborder');             }             if(this.footer){                 this.footer.addClass(this.footerCls + '-noborder');             }             if(this.tbar){                 this.tbar.addClass(this.tbarCls + '-noborder');             }             if(this.bbar){                 this.bbar.addClass(this.bbarCls + '-noborder');             }         }         if(this.bodyBorder === false){            this.body.addClass(this.bodyCls + '-noborder');         }         this.bwrap.enableDisplayMode('block');         if(this.header){             this.header.unselectable();             // for tools, we need to wrap any existing header markup             if(this.headerAsText){                 this.header.dom.innerHTML =                     '<span class="' + this.headerTextCls + '">'+this.header.dom.innerHTML+'</span>';                 if(this.iconCls){                     this.setIconClass(this.iconCls);                 }             }         }         if(this.floating){             this.makeFloating(this.floating);         }         if(this.collapsible){             this.tools = this.tools ? this.tools.slice(0) : [];             if(!this.hideCollapseTool){                 this.tools[this.collapseFirst?'unshift':'push']({                     id: 'toggle',                     handler : this.toggleCollapse,                     scope: this                 });             }             if(this.titleCollapse && this.header){                 this.mon(this.header, 'click', this.toggleCollapse, this);                 this.header.setStyle('cursor', 'pointer');             }         }         if(this.tools){             var ts = this.tools;             this.tools = {};             this.addTool.apply(this, ts);         }else{             this.tools = {};         }         if(this.buttons && this.buttons.length > 0){             this.fbar = new Ext.Toolbar({                 items: this.buttons,                 toolbarCls: 'x-panel-fbar'             });         }         this.toolbars = [];         if(this.fbar){             this.fbar = Ext.create(this.fbar, 'toolbar');             this.fbar.enableOverflow = false;             if(this.fbar.items){                 this.fbar.items.each(function(c){                     c.minWidth = c.minWidth || this.minButtonWidth;                 }, this);             }             this.fbar.toolbarCls = 'x-panel-fbar';             var bct = this.footer.createChild({cls: 'x-panel-btns x-panel-btns-'+this.buttonAlign});             this.fbar.ownerCt = this;             this.fbar.render(bct);             bct.createChild({cls:'x-clear'});             this.toolbars.push(this.fbar);         }         if(this.tbar && this.topToolbar){             if(Ext.isArray(this.topToolbar)){                 this.topToolbar = new Ext.Toolbar(this.topToolbar);             }else if(!this.topToolbar.events){                 this.topToolbar = Ext.create(this.topToolbar, 'toolbar');             }             this.topToolbar.ownerCt = this;             this.topToolbar.render(this.tbar);             this.toolbars.push(this.topToolbar);         }         if(this.bbar && this.bottomToolbar){             if(Ext.isArray(this.bottomToolbar)){                 this.bottomToolbar = new Ext.Toolbar(this.bottomToolbar);             }else if(!this.bottomToolbar.events){                 this.bottomToolbar = Ext.create(this.bottomToolbar, 'toolbar');             }             this.bottomToolbar.ownerCt = this;             this.bottomToolbar.render(this.bbar);             this.toolbars.push(this.bottomToolbar);         }         Ext.each(this.toolbars, function(tb){             tb.on({                 scope: this,                 afterlayout: this.syncHeight,                 remove: this.syncHeight             });         }, this);     },     /**      * Sets the CSS class that provides the icon image for this panel.  This method will replace any existing      * icon class if one has already been set and fire the {@link #iconchange} event after completion.      * @param {String} cls The new CSS class name      */     setIconClass : function(cls){         var old = this.iconCls;         this.iconCls = cls;         if(this.rendered && this.header){             if(this.frame){                 this.header.addClass('x-panel-icon');                 this.header.replaceClass(old, this.iconCls);             }else{                 var hd = this.header.dom;                 var img = hd.firstChild && String(hd.firstChild.tagName).toLowerCase() == 'img' ? hd.firstChild : null;                 if(img){                     Ext.fly(img).replaceClass(old, this.iconCls);                 }else{                     Ext.DomHelper.insertBefore(hd.firstChild, {                         tag:'img', src: Ext.BLANK_IMAGE_URL, cls:'x-panel-inline-icon '+this.iconCls                     });                  }             }         }         this.fireEvent('iconchange', this, cls, old);     },     // private     makeFloating : function(cfg){         this.floating = true;         this.el = new Ext.Layer(             Ext.isObject(cfg) ? cfg : {                 shadow: this.shadow !== undefined ? this.shadow : 'sides',                 shadowOffset: this.shadowOffset,                 constrain:false,                 shim: this.shim === false ? false : undefined             }, this.el         );     },     /**      * Returns the {@link Ext.Toolbar toolbar} from the top (<tt>{@link #tbar}</tt>) section of the panel.      * @return {Ext.Toolbar} The toolbar      */     getTopToolbar : function(){         return this.topToolbar;     },     /**      * Returns the {@link Ext.Toolbar toolbar} from the bottom (<tt>{@link #bbar}</tt>) section of the panel.      * @return {Ext.Toolbar} The toolbar      */     getBottomToolbar : function(){         return this.bottomToolbar;     },     /**      * Adds a button to this panel.  Note that this method must be called prior to rendering.  The preferred      * approach is to add buttons via the {@link #buttons} config.      * @param {String/Object} config A valid {@link Ext.Button} config.  A string will become the text for a default      * button config, an object will be treated as a button config object.      * @param {Function} handler The function to be called on button {@link Ext.Button#click}      * @param {Object} scope The scope to use for the button handler function      * @return {Ext.Button} The button that was added      */     addButton : function(config, handler, scope){         var bc = {             handler: handler,             scope: scope,             minWidth: this.minButtonWidth,             hideParent:true         };         if(typeof config == "string"){             bc.text = config;         }else{             Ext.apply(bc, config);         }         var btn = new Ext.Button(bc);         if(!this.buttons){             this.buttons = [];         }         this.buttons.push(btn);         return btn;     },     // private     addTool : function(){         if(!this[this.toolTarget]) { // no where to render tools!             return;         }         if(!this.toolTemplate){             // initialize the global tool template on first use             var tt = new Ext.Template(                  '<div class="x-tool x-tool-{id}">&#160;</div>'             );             tt.disableFormats = true;             tt.compile();             Ext.Panel.prototype.toolTemplate = tt;         }         for(var i = 0, a = arguments, len = a.length; i < len; i++) {             var tc = a[i];             if(!this.tools[tc.id]){                 var overCls = 'x-tool-'+tc.id+'-over';                 var t = this.toolTemplate.insertFirst((tc.align !== 'left') ? this[this.toolTarget] : this[this.toolTarget].child('span'), tc, true);                 this.tools[tc.id] = t;                 t.enableDisplayMode('block');                 this.mon(t, 'click',  this.createToolHandler(t, tc, overCls, this));                 if(tc.on){                     this.mon(t, tc.on);                 }                 if(tc.hidden){                     t.hide();                 }                 if(tc.qtip){                     if(Ext.isObject(tc.qtip)){                         Ext.QuickTips.register(Ext.apply({                               target: t.id                         }, tc.qtip));                     } else {                         t.dom.qtip = tc.qtip;                     }                 }                 t.addClassOnOver(overCls);             }         }     },     onLayout : function(){         if(this.toolbars.length > 0){             this.duringLayout = true;             Ext.each(this.toolbars, function(tb){                 tb.doLayout();             });             delete this.duringLayout;             this.syncHeight();         }     },     syncHeight : function(){         if(!(this.autoHeight || this.duringLayout)){             var last = this.lastSize;             if(last && !Ext.isEmpty(last.height)){                 var old = last.height, h = this.el.getHeight();                 if(old != 'auto' && old != h){                     var bd = this.body, bdh = bd.getHeight();                     h = Math.max(bdh + old - h, 0);                     if(bdh > 0 && bdh != h){                         bd.setHeight(h);                         if(Ext.isIE && h <= 0){                             return;                         }                         var sz = bd.getSize();                         this.fireEvent('bodyresize', sz.width, sz.height);                     }                 }             }         }     },     // private     onShow : function(){         if(this.floating){             return this.el.show();         }         Ext.Panel.superclass.onShow.call(this);     },     // private     onHide : function(){         if(this.floating){             return this.el.hide();         }         Ext.Panel.superclass.onHide.call(this);     },     // private     createToolHandler : function(t, tc, overCls, panel){         return function(e){             t.removeClass(overCls);             if(tc.stopEvent !== false){                 e.stopEvent();             }             if(tc.handler){                 tc.handler.call(tc.scope || t, e, t, panel, tc);             }         };     },     // private     afterRender : function(){         if(this.floating && !this.hidden){             this.el.show();         }         if(this.title){             this.setTitle(this.title);         }         this.setAutoScroll();         if(this.html){             this.body.update(Ext.isObject(this.html) ?                              Ext.DomHelper.markup(this.html) :                              this.html);             delete this.html;         }         if(this.contentEl){             var ce = Ext.getDom(this.contentEl);             Ext.fly(ce).removeClass(['x-hidden', 'x-hide-display']);             this.body.dom.appendChild(ce);         }         if(this.collapsed){             this.collapsed = false;             this.collapse(false);         }         Ext.Panel.superclass.afterRender.call(this); // do sizing calcs last         this.initEvents();     },     // private     setAutoScroll : function(){         if(this.rendered && this.autoScroll){             var el = this.body || this.el;             if(el){                 el.setOverflow('auto');             }         }     },     // private     getKeyMap : function(){         if(!this.keyMap){             this.keyMap = new Ext.KeyMap(this.el, this.keys);         }         return this.keyMap;     },     // private     initEvents : function(){         if(this.keys){             this.getKeyMap();         }         if(this.draggable){             this.initDraggable();         }     },     // private     initDraggable : function(){         /**          * <p>If this Panel is configured {@link #draggable}, this property will contain          * an instance of {@link Ext.dd.DragSource} which handles dragging the Panel.</p>          * The developer must provide implementations of the abstract methods of {@link Ext.dd.DragSource}          * in order to supply behaviour for each stage of the drag/drop process. See {@link #draggable}.          * @type Ext.dd.DragSource.          * @property dd          */         this.dd = new Ext.Panel.DD(this, typeof this.draggable == 'boolean' ? null : this.draggable);     },     // private     beforeEffect : function(){         if(this.floating){             this.el.beforeAction();         }         this.el.addClass('x-panel-animated');     },     // private     afterEffect : function(){         this.syncShadow();         this.el.removeClass('x-panel-animated');     },     // private - wraps up an animation param with internal callbacks     createEffect : function(a, cb, scope){         var o = {             scope:scope,             block:true         };         if(a === true){             o.callback = cb;             return o;         }else if(!a.callback){             o.callback = cb;         }else { // wrap it up             o.callback = function(){                 cb.call(scope);                 Ext.callback(a.callback, a.scope);             };         }         return Ext.applyIf(o, a);     },     /**      * Collapses the panel body so that it becomes hidden.  Fires the {@link #beforecollapse} event which will      * cancel the collapse action if it returns false.      * @param {Boolean} animate True to animate the transition, else false (defaults to the value of the      * {@link #animCollapse} panel config)      * @return {Ext.Panel} this      */     collapse : function(animate){         if(this.collapsed || this.el.hasFxBlock() || this.fireEvent('beforecollapse', this, animate) === false){             return;         }         var doAnim = animate === true || (animate !== false && this.animCollapse);         this.beforeEffect();         this.onCollapse(doAnim, animate);         return this;     },     // private     onCollapse : function(doAnim, animArg){         if(doAnim){             this[this.collapseEl].slideOut(this.slideAnchor,                     Ext.apply(this.createEffect(animArg||true, this.afterCollapse, this),                         this.collapseDefaults));         }else{             this[this.collapseEl].hide();             this.afterCollapse();         }     },     // private     afterCollapse : function(){         this.collapsed = true;         this.el.addClass(this.collapsedCls);         this.afterEffect();         this.fireEvent('collapse', this);     },     /**      * Expands the panel body so that it becomes visible.  Fires the {@link #beforeexpand} event which will      * cancel the expand action if it returns false.      * @param {Boolean} animate True to animate the transition, else false (defaults to the value of the      * {@link #animCollapse} panel config)      * @return {Ext.Panel} this      */     expand : function(animate){         if(!this.collapsed || this.el.hasFxBlock() || this.fireEvent('beforeexpand', this, animate) === false){             return;         }         var doAnim = animate === true || (animate !== false && this.animCollapse);         this.el.removeClass(this.collapsedCls);         this.beforeEffect();         this.onExpand(doAnim, animate);         return this;     },     // private     onExpand : function(doAnim, animArg){         if(doAnim){             this[this.collapseEl].slideIn(this.slideAnchor,                     Ext.apply(this.createEffect(animArg||true, this.afterExpand, this),                         this.expandDefaults));         }else{             this[this.collapseEl].show();             this.afterExpand();         }     },     // private     afterExpand : function(){         this.collapsed = false;         this.afterEffect();         if(this.deferLayout !== undefined){             this.doLayout(true);         }         this.fireEvent('expand', this);     },     /**      * Shortcut for performing an {@link #expand} or {@link #collapse} based on the current state of the panel.      * @param {Boolean} animate True to animate the transition, else false (defaults to the value of the      * {@link #animCollapse} panel config)      * @return {Ext.Panel} this      */     toggleCollapse : function(animate){         this[this.collapsed ? 'expand' : 'collapse'](animate);         return this;     },     // private     onDisable : function(){         if(this.rendered && this.maskDisabled){             this.el.mask();         }         Ext.Panel.superclass.onDisable.call(this);     },     // private     onEnable : function(){         if(this.rendered && this.maskDisabled){             this.el.unmask();         }         Ext.Panel.superclass.onEnable.call(this);     },     // private     onResize : function(w, h){         if(w !== undefined || h !== undefined){             if(!this.collapsed){                 if(typeof w == 'number'){                     w = this.adjustBodyWidth(w - this.getFrameWidth());                     if(this.tbar){                         this.tbar.setWidth(w);                         if(this.topToolbar){                             this.topToolbar.setSize(w);                         }                     }                     if(this.bbar){                         this.bbar.setWidth(w);                         if(this.bottomToolbar){                             this.bottomToolbar.setSize(w);                         }                     }                     if(this.fbar){                         var f = this.fbar,                             fWidth = 1,                             strict = Ext.isStrict;                         if(this.buttonAlign == 'left'){                            fWidth = w - f.container.getFrameWidth('lr');                         }else{                             //center/right alignment off in webkit                             if(Ext.isIE || Ext.isWebKit){                                 //center alignment ok on webkit.                                 //right broken in both, center on IE                                 if(!(this.buttonAlign == 'center' && Ext.isWebKit) && (!strict || (!Ext.isIE8 && strict))){                                     (function(){                                         f.setWidth(f.getEl().child('.x-toolbar-ct').getWidth());                                     }).defer(1);                                 }else{                                     fWidth = 'auto';                                 }                             }else{                                 fWidth = 'auto';                             }                         }                         f.setWidth(fWidth);                     }                     this.body.setWidth(w);                 }else if(w == 'auto'){                     this.body.setWidth(w);                 }                 if(typeof h == 'number'){                     h = Math.max(0, this.adjustBodyHeight(h - this.getFrameHeight()));                     this.body.setHeight(h);                 }else if(h == 'auto'){                     this.body.setHeight(h);                 }                 if(this.disabled && this.el._mask){                     this.el._mask.setSize(this.el.dom.clientWidth, this.el.getHeight());                 }             }else{                 this.queuedBodySize = {width: w, height: h};                 if(!this.queuedExpand && this.allowQueuedExpand !== false){                     this.queuedExpand = true;                     this.on('expand', function(){                         delete this.queuedExpand;                         this.onResize(this.queuedBodySize.width, this.queuedBodySize.height);                         this.doLayout();                     }, this, {single:true});                 }             }             this.fireEvent('bodyresize', this, w, h);         }         this.syncShadow();     },     // private     adjustBodyHeight : function(h){         return h;     },     // private     adjustBodyWidth : function(w){         return w;     },     // private     onPosition : function(){         this.syncShadow();     },     /**      * Returns the width in pixels of the framing elements of this panel (not including the body width).  To      * retrieve the body width see {@link #getInnerWidth}.      * @return {Number} The frame width      */     getFrameWidth : function(){         var w = this.el.getFrameWidth('lr')+this.bwrap.getFrameWidth('lr');         if(this.frame){             var l = this.bwrap.dom.firstChild;             w += (Ext.fly(l).getFrameWidth('l') + Ext.fly(l.firstChild).getFrameWidth('r'));             var mc = this.bwrap.dom.firstChild.firstChild.firstChild;             w += Ext.fly(mc).getFrameWidth('lr');         }         return w;     },     /**      * Returns the height in pixels of the framing elements of this panel (including any top and bottom bars and      * header and footer elements, but not including the body height).  To retrieve the body height see {@link #getInnerHeight}.      * @return {Number} The frame height      */     getFrameHeight : function(){         var h  = this.el.getFrameWidth('tb')+this.bwrap.getFrameWidth('tb');         h += (this.tbar ? this.tbar.getHeight() : 0) +              (this.bbar ? this.bbar.getHeight() : 0);         if(this.frame){             var hd = this.el.dom.firstChild;             var ft = this.bwrap.dom.lastChild;             h += (hd.offsetHeight + ft.offsetHeight);             var mc = this.bwrap.dom.firstChild.firstChild.firstChild;             h += Ext.fly(mc).getFrameWidth('tb');         }else{             h += (this.header ? this.header.getHeight() : 0) +                 (this.footer ? this.footer.getHeight() : 0);         }         return h;     },     /**      * Returns the width in pixels of the body element (not including the width of any framing elements).      * For the frame width see {@link #getFrameWidth}.      * @return {Number} The body width      */     getInnerWidth : function(){         return this.getSize().width - this.getFrameWidth();     },     /**      * Returns the height in pixels of the body element (not including the height of any framing elements).      * For the frame height see {@link #getFrameHeight}.      * @return {Number} The body height      */     getInnerHeight : function(){         return this.getSize().height - this.getFrameHeight();     },     // private     syncShadow : function(){         if(this.floating){             this.el.sync(true);         }     },     // private     getLayoutTarget : function(){         return this.body;     },     /**      * <p>Sets the title text for the panel and optionally the {@link #iconCls icon class}.</p>      * <p>In order to be able to set the title, a header element must have been created      * for the Panel. This is triggered either by configuring the Panel with a non-blank <tt>{@link #title}</tt>,      * or configuring it with <tt><b>{@link #header}: true</b></tt>.</p>      * @param {String} title The title text to set      * @param {String} iconCls (optional) {@link #iconCls iconCls} A user-defined CSS class that provides the icon image for this panel      */     setTitle : function(title, iconCls){         this.title = title;         if(this.header && this.headerAsText){             this.header.child('span').update(title);         }         if(iconCls){             this.setIconClass(iconCls);         }         this.fireEvent('titlechange', this, title);         return this;     },     /**      * Get the {@link Ext.Updater} for this panel. Enables you to perform Ajax updates of this panel's body.      * @return {Ext.Updater} The Updater      */     getUpdater : function(){         return this.body.getUpdater();     },      /**      * Loads this content panel immediately with content returned from an XHR call.      * @param {Object/String/Function} config A config object containing any of the following options: <pre><code> panel.load({     url: "your-url.php",     params: {param1: "foo", param2: "bar"}, // or a URL encoded string     callback: yourFunction,     scope: yourObject, // optional scope for the callback     discardUrl: false,     nocache: false,     text: "Loading...",     timeout: 30,     scripts: false }); </code></pre>      * The only required property is url. The optional properties nocache, text and scripts      * are shorthand for disableCaching, indicatorText and loadScripts and are used to set their      * associated property on this panel Updater instance.      * @return {Ext.Panel} this      */     load : function(){         var um = this.body.getUpdater();         um.update.apply(um, arguments);         return this;     },     // private     beforeDestroy : function(){         if(this.header){             this.header.removeAllListeners();             if(this.headerAsText){                 Ext.Element.uncache(this.header.child('span'));             }         }         Ext.Element.uncache(             this.header,             this.tbar,             this.bbar,             this.footer,             this.body,             this.bwrap         );         if(this.tools){             for(var k in this.tools){                 Ext.destroy(this.tools[k]);             }         }         if(this.buttons){             for(var b in this.buttons){                 Ext.destroy(this.buttons[b]);             }         }         Ext.destroy(this.toolbars);         Ext.Panel.superclass.beforeDestroy.call(this);     },     // private     createClasses : function(){         this.headerCls = this.baseCls + '-header';         this.headerTextCls = this.baseCls + '-header-text';         this.bwrapCls = this.baseCls + '-bwrap';         this.tbarCls = this.baseCls + '-tbar';         this.bodyCls = this.baseCls + '-body';         this.bbarCls = this.baseCls + '-bbar';         this.footerCls = this.baseCls + '-footer';     },     // private     createGhost : function(cls, useShim, appendTo){         var el = document.createElement('div');         el.className = 'x-panel-ghost ' + (cls ? cls : '');         if(this.header){             el.appendChild(this.el.dom.firstChild.cloneNode(true));         }         Ext.fly(el.appendChild(document.createElement('ul'))).setHeight(this.bwrap.getHeight());         el.style.width = this.el.dom.offsetWidth + 'px';;         if(!appendTo){             this.container.dom.appendChild(el);         }else{             Ext.getDom(appendTo).appendChild(el);         }         if(useShim !== false && this.el.useShim !== false){             var layer = new Ext.Layer({shadow:false, useDisplay:true, constrain:false}, el);             layer.show();             return layer;         }else{             return new Ext.Element(el);         }     },     // private     doAutoLoad : function(){         var u = this.body.getUpdater();         if(this.renderer){             u.setRenderer(this.renderer);         }         u.update(Ext.isObject(this.autoLoad) ? this.autoLoad : {url: this.autoLoad});     },     /**      * Retrieve a tool by id.      * @param {String} id      * @return {Object} tool      */     getTool : function(id) {         return this.tools[id];     } /**  * @cfg {String} autoEl @hide  */ }); Ext.reg('panel', Ext.Panel); /**  * @class Ext.Editor  * @extends Ext.Component  * A base editor field that handles displaying/hiding on demand and has some built-in sizing and event handling logic.  * @constructor  * Create a new Editor  * @param {Object} config The config object  * @xtype editor  */ Ext.Editor = function(field, config){     if(field.field){         this.field = Ext.create(field.field, 'textfield');         config = Ext.apply({}, field); // copy so we don't disturb original config         delete config.field;     }else{         this.field = field;     }     Ext.Editor.superclass.constructor.call(this, config); }; Ext.extend(Ext.Editor, Ext.Component, {     /**     * @cfg {Ext.form.Field} field     * The Field object (or descendant) or config object for field     */     /**      * @cfg {Boolean} allowBlur      * True to {@link #completeEdit complete the editing process} if in edit mode when the      * field is blurred. Defaults to <tt>false</tt>.      */     /**      * @cfg {Boolean/String} autoSize      * True for the editor to automatically adopt the size of the element being edited, "width" to adopt the width only,      * or "height" to adopt the height only (defaults to false)      */     /**      * @cfg {Boolean} revertInvalid      * True to automatically revert the field value and cancel the edit when the user completes an edit and the field      * validation fails (defaults to true)      */     /**      * @cfg {Boolean} ignoreNoChange      * True to skip the edit completion process (no save, no events fired) if the user completes an edit and      * the value has not changed (defaults to false).  Applies only to string values - edits for other data types      * will never be ignored.      */     /**      * @cfg {Boolean} hideEl      * False to keep the bound element visible while the editor is displayed (defaults to true)      */     /**      * @cfg {Mixed} value      * The data value of the underlying field (defaults to "")      */     value : "",     /**      * @cfg {String} alignment      * The position to align to (see {@link Ext.Element#alignTo} for more details, defaults to "c-c?").      */     alignment: "c-c?",     /**      * @cfg {Boolean/String} shadow "sides" for sides/bottom only, "frame" for 4-way shadow, and "drop"      * for bottom-right shadow (defaults to "frame")      */     shadow : "frame",     /**      * @cfg {Boolean} constrain True to constrain the editor to the viewport      */     constrain : false,     /**      * @cfg {Boolean} swallowKeys Handle the keydown/keypress events so they don't propagate (defaults to true)      */     swallowKeys : true,     /**      * @cfg {Boolean} completeOnEnter True to complete the edit when the enter key is pressed (defaults to false)      */     completeOnEnter : false,     /**      * @cfg {Boolean} cancelOnEsc True to cancel the edit when the escape key is pressed (defaults to false)      */     cancelOnEsc : false,     /**      * @cfg {Boolean} updateEl True to update the innerHTML of the bound element when the update completes (defaults to false)      */     updateEl : false,     initComponent : function(){         Ext.Editor.superclass.initComponent.call(this);         this.addEvents(             /**              * @event beforestartedit              * Fires when editing is initiated, but before the value changes.  Editing can be canceled by returning              * false from the handler of this event.              * @param {Editor} this              * @param {Ext.Element} boundEl The underlying element bound to this editor              * @param {Mixed} value The field value being set              */             "beforestartedit",             /**              * @event startedit              * Fires when this editor is displayed              * @param {Ext.Element} boundEl The underlying element bound to this editor              * @param {Mixed} value The starting field value              */             "startedit",             /**              * @event beforecomplete              * Fires after a change has been made to the field, but before the change is reflected in the underlying              * field.  Saving the change to the field can be canceled by returning false from the handler of this event.              * Note that if the value has not changed and ignoreNoChange = true, the editing will still end but this              * event will not fire since no edit actually occurred.              * @param {Editor} this              * @param {Mixed} value The current field value              * @param {Mixed} startValue The original field value              */             "beforecomplete",             /**              * @event complete              * Fires after editing is complete and any changed value has been written to the underlying field.              * @param {Editor} this              * @param {Mixed} value The current field value              * @param {Mixed} startValue The original field value              */             "complete",             /**              * @event canceledit              * Fires after editing has been canceled and the editor's value has been reset.              * @param {Editor} this              * @param {Mixed} value The user-entered field value that was discarded              * @param {Mixed} startValue The original field value that was set back into the editor after cancel              */             "canceledit",             /**              * @event specialkey              * Fires when any key related to navigation (arrows, tab, enter, esc, etc.) is pressed.  You can check              * {@link Ext.EventObject#getKey} to determine which key was pressed.              * @param {Ext.form.Field} this              * @param {Ext.EventObject} e The event object              */             "specialkey"         );     },     // private     onRender : function(ct, position){         this.el = new Ext.Layer({             shadow: this.shadow,             cls: "x-editor",             parentEl : ct,             shim : this.shim,             shadowOffset: this.shadowOffset || 4,             id: this.id,             constrain: this.constrain         });         if(this.zIndex){             this.el.setZIndex(this.zIndex);         }         this.el.setStyle("overflow", Ext.isGecko ? "auto" : "hidden");         if(this.field.msgTarget != 'title'){             this.field.msgTarget = 'qtip';         }         this.field.inEditor = true;         this.field.render(this.el);         if(Ext.isGecko){             this.field.el.dom.setAttribute('autocomplete', 'off');         }         this.mon(this.field, "specialkey", this.onSpecialKey, this);         if(this.swallowKeys){             this.field.el.swallowEvent(['keydown','keypress']);         }         this.field.show();         this.mon(this.field, "blur", this.onBlur, this);         if(this.field.grow){          this.mon(this.field, "autosize", this.el.sync,  this.el, {delay:1});         }     },     // private     onSpecialKey : function(field, e){         var key = e.getKey();         if(this.completeOnEnter && key == e.ENTER){             e.stopEvent();             this.completeEdit();         }else if(this.cancelOnEsc && key == e.ESC){             this.cancelEdit();         }else{             this.fireEvent('specialkey', field, e);         }         if(this.field.triggerBlur && (key == e.ENTER || key == e.ESC || key == e.TAB)){             this.field.triggerBlur();         }     },     /**      * Starts the editing process and shows the editor.      * @param {Mixed} el The element to edit      * @param {String} value (optional) A value to initialize the editor with. If a value is not provided, it defaults       * to the innerHTML of el.      */     startEdit : function(el, value){         if(this.editing){             this.completeEdit();         }         this.boundEl = Ext.get(el);         var v = value !== undefined ? value : this.boundEl.dom.innerHTML;         if(!this.rendered){             this.render(this.parentEl || document.body);         }         if(this.fireEvent("beforestartedit", this, this.boundEl, v) === false){             return;         }         this.startValue = v;         this.field.setValue(v);         this.doAutoSize();         this.el.alignTo(this.boundEl, this.alignment);         this.editing = true;         this.show();     },     // private     doAutoSize : function(){         if(this.autoSize){             var sz = this.boundEl.getSize();             switch(this.autoSize){                 case "width":                     this.setSize(sz.width,  "");                 break;                 case "height":                     this.setSize("",  sz.height);                 break;                 default:                     this.setSize(sz.width,  sz.height);             }         }     },     /**      * Sets the height and width of this editor.      * @param {Number} width The new width      * @param {Number} height The new height      */     setSize : function(w, h){         delete this.field.lastSize;         this.field.setSize(w, h);         if(this.el){             if(Ext.isGecko2 || Ext.isOpera){                 // prevent layer scrollbars                 this.el.setSize(w, h);             }             this.el.sync();         }     },     /**      * Realigns the editor to the bound field based on the current alignment config value.      */     realign : function(){         this.el.alignTo(this.boundEl, this.alignment);     },     /**      * Ends the editing process, persists the changed value to the underlying field, and hides the editor.      * @param {Boolean} remainVisible Override the default behavior and keep the editor visible after edit (defaults to false)      */     completeEdit : function(remainVisible){         if(!this.editing){             return;         }         var v = this.getValue();         if(!this.field.isValid()){             if(this.revertInvalid !== false){                 this.cancelEdit(remainVisible);             }             return;         }         if(String(v) === String(this.startValue) && this.ignoreNoChange){             this.hideEdit(remainVisible);             return;         }         if(this.fireEvent("beforecomplete", this, v, this.startValue) !== false){             v = this.getValue();             if(this.updateEl && this.boundEl){                 this.boundEl.update(v);             }             this.hideEdit(remainVisible);             this.fireEvent("complete", this, v, this.startValue);         }     },     // private     onShow : function(){         this.el.show();         if(this.hideEl !== false){             this.boundEl.hide();         }         this.field.show();         if(Ext.isIE && !this.fixIEFocus){ // IE has problems with focusing the first time             this.fixIEFocus = true;             this.deferredFocus.defer(50, this);         }else{             this.field.focus();         }         this.fireEvent("startedit", this.boundEl, this.startValue);     },     deferredFocus : function(){         if(this.editing){             this.field.focus();         }     },     /**      * Cancels the editing process and hides the editor without persisting any changes.  The field value will be      * reverted to the original starting value.      * @param {Boolean} remainVisible Override the default behavior and keep the editor visible after      * cancel (defaults to false)      */     cancelEdit : function(remainVisible){         if(this.editing){             var v = this.getValue();             this.setValue(this.startValue);             this.hideEdit(remainVisible);             this.fireEvent("canceledit", this, v, this.startValue);         }     },          // private     hideEdit: function(remainVisible){         if(remainVisible !== true){             this.editing = false;             this.hide();         }     },     // private     onBlur : function(){         if(this.allowBlur !== true && this.editing){             this.completeEdit();         }     },     // private     onHide : function(){         if(this.editing){             this.completeEdit();             return;         }         this.field.blur();         if(this.field.collapse){             this.field.collapse();         }         this.el.hide();         if(this.hideEl !== false){             this.boundEl.show();         }     },     /**      * Sets the data value of the editor      * @param {Mixed} value Any valid value supported by the underlying field      */     setValue : function(v){         this.field.setValue(v);     },     /**      * Gets the data value of the editor      * @return {Mixed} The data value      */     getValue : function(){         return this.field.getValue();     },     beforeDestroy : function(){         Ext.destroy(this.field);         this.field = null;     } }); Ext.reg('editor', Ext.Editor);/**  * @class Ext.ColorPalette  * @extends Ext.Component  * Simple color palette class for choosing colors.  The palette can be rendered to any container.<br />  * Here's an example of typical usage:  * <pre><code> var cp = new Ext.ColorPalette({value:'993300'});  // initial selected color cp.render('my-div'); cp.on('select', function(palette, selColor){     // do something with selColor }); </code></pre>  * @constructor  * Create a new ColorPalette  * @param {Object} config The config object  * @xtype colorpalette  */ Ext.ColorPalette = function(config){     Ext.ColorPalette.superclass.constructor.call(this, config);     this.addEvents(         /**      * @event select      * Fires when a color is selected      * @param {ColorPalette} this      * @param {String} color The 6-digit color hex code (without the # symbol)      */         'select'     );     if(this.handler){         this.on("select", this.handler, this.scope, true);     } }; Ext.extend(Ext.ColorPalette, Ext.Component, { /**  * @cfg {String} tpl An existing XTemplate instance to be used in place of the default template for rendering the component.  */     /**      * @cfg {String} itemCls      * The CSS class to apply to the containing element (defaults to "x-color-palette")      */     itemCls : "x-color-palette",     /**      * @cfg {String} value      * The initial color to highlight (should be a valid 6-digit color hex code without the # symbol).  Note that      * the hex codes are case-sensitive.      */     value : null,     clickEvent:'click',     // private     ctype: "Ext.ColorPalette",     /**      * @cfg {Boolean} allowReselect If set to true then reselecting a color that is already selected fires the {@link #select} event      */     allowReselect : false,     /**      * <p>An array of 6-digit color hex code strings (without the # symbol).  This array can contain any number      * of colors, and each hex code should be unique.  The width of the palette is controlled via CSS by adjusting      * the width property of the 'x-color-palette' class (or assigning a custom class), so you can balance the number      * of colors with the width setting until the box is symmetrical.</p>      * <p>You can override individual colors if needed:</p>      * <pre><code> var cp = new Ext.ColorPalette(); cp.colors[0] = "FF0000";  // change the first box to red </code></pre> Or you can provide a custom array of your own for complete control: <pre><code> var cp = new Ext.ColorPalette(); cp.colors = ["000000", "993300", "333300"]; </code></pre>      * @type Array      */     colors : [         "000000", "993300", "333300", "003300", "003366", "000080", "333399", "333333",         "800000", "FF6600", "808000", "008000", "008080", "0000FF", "666699", "808080",         "FF0000", "FF9900", "99CC00", "339966", "33CCCC", "3366FF", "800080", "969696",         "FF00FF", "FFCC00", "FFFF00", "00FF00", "00FFFF", "00CCFF", "993366", "C0C0C0",         "FF99CC", "FFCC99", "FFFF99", "CCFFCC", "CCFFFF", "99CCFF", "CC99FF", "FFFFFF"     ],     // private     onRender : function(container, position){         var t = this.tpl || new Ext.XTemplate(             '<tpl for="."><a href="#" class="color-{.}" hidefocus="on"><em><span style="background:#{.}" unselectable="on">&#160;</span></em></a></tpl>'         );         var el = document.createElement("div");         el.id = this.getId();         el.className = this.itemCls;         t.overwrite(el, this.colors);         container.dom.insertBefore(el, position);         this.el = Ext.get(el);         this.mon(this.el, this.clickEvent, this.handleClick, this, {delegate: 'a'});         if(this.clickEvent != 'click'){          this.mon(this.el, 'click', Ext.emptyFn, this, {delegate: 'a', preventDefault: true});         }     },     // private     afterRender : function(){         Ext.ColorPalette.superclass.afterRender.call(this);         if(this.value){             var s = this.value;             this.value = null;             this.select(s);         }     },     // private     handleClick : function(e, t){         e.preventDefault();         if(!this.disabled){             var c = t.className.match(/(?:^|s)color-(.{6})(?:s|$)/)[1];             this.select(c.toUpperCase());         }     },     /**      * Selects the specified color in the palette (fires the {@link #select} event)      * @param {String} color A valid 6-digit color hex code (# will be stripped if included)      */     select : function(color){         color = color.replace("#", "");         if(color != this.value || this.allowReselect){             var el = this.el;             if(this.value){                 el.child("a.color-"+this.value).removeClass("x-color-palette-sel");             }             el.child("a.color-"+color).addClass("x-color-palette-sel");             this.value = color;             this.fireEvent("select", this, color);         }     }     /**      * @cfg {String} autoEl @hide      */ }); Ext.reg('colorpalette', Ext.ColorPalette);/**
  314.  * @class Ext.DatePicker
  315.  * @extends Ext.Component
  316.  * Simple date picker class.
  317.  * @constructor
  318.  * Create a new DatePicker
  319.  * @param {Object} config The config object
  320.  * @xtype datepicker
  321.  */
  322. Ext.DatePicker = Ext.extend(Ext.BoxComponent, {
  323.     /**
  324.      * @cfg {String} todayText
  325.      * The text to display on the button that selects the current date (defaults to <tt>'Today'</tt>)
  326.      */
  327.     todayText : 'Today',
  328.     /**
  329.      * @cfg {String} okText
  330.      * The text to display on the ok button (defaults to <tt>'&#160;OK&#160;'</tt> to give the user extra clicking room)
  331.      */
  332.     okText : '&#160;OK&#160;',
  333.     /**
  334.      * @cfg {String} cancelText
  335.      * The text to display on the cancel button (defaults to <tt>'Cancel'</tt>)
  336.      */
  337.     cancelText : 'Cancel',
  338.     /**
  339.      * @cfg {String} todayTip
  340.      * The tooltip to display for the button that selects the current date (defaults to <tt>'{current date} (Spacebar)'</tt>)
  341.      */
  342.     todayTip : '{0} (Spacebar)',
  343.     /**
  344.      * @cfg {String} minText
  345.      * The error text to display if the minDate validation fails (defaults to <tt>'This date is before the minimum date'</tt>)
  346.      */
  347.     minText : 'This date is before the minimum date',
  348.     /**
  349.      * @cfg {String} maxText
  350.      * The error text to display if the maxDate validation fails (defaults to <tt>'This date is after the maximum date'</tt>)
  351.      */
  352.     maxText : 'This date is after the maximum date',
  353.     /**
  354.      * @cfg {String} format
  355.      * The default date format string which can be overriden for localization support.  The format must be
  356.      * valid according to {@link Date#parseDate} (defaults to <tt>'m/d/y'</tt>).
  357.      */
  358.     format : 'm/d/y',
  359.     /**
  360.      * @cfg {String} disabledDaysText
  361.      * The tooltip to display when the date falls on a disabled day (defaults to <tt>'Disabled'</tt>)
  362.      */
  363.     disabledDaysText : 'Disabled',
  364.     /**
  365.      * @cfg {String} disabledDatesText
  366.      * The tooltip text to display when the date falls on a disabled date (defaults to <tt>'Disabled'</tt>)
  367.      */
  368.     disabledDatesText : 'Disabled',
  369.     /**
  370.      * @cfg {Array} monthNames
  371.      * An array of textual month names which can be overriden for localization support (defaults to Date.monthNames)
  372.      */
  373.     monthNames : Date.monthNames,
  374.     /**
  375.      * @cfg {Array} dayNames
  376.      * An array of textual day names which can be overriden for localization support (defaults to Date.dayNames)
  377.      */
  378.     dayNames : Date.dayNames,
  379.     /**
  380.      * @cfg {String} nextText
  381.      * The next month navigation button tooltip (defaults to <tt>'Next Month (Control+Right)'</tt>)
  382.      */
  383.     nextText : 'Next Month (Control+Right)',
  384.     /**
  385.      * @cfg {String} prevText
  386.      * The previous month navigation button tooltip (defaults to <tt>'Previous Month (Control+Left)'</tt>)
  387.      */
  388.     prevText : 'Previous Month (Control+Left)',
  389.     /**
  390.      * @cfg {String} monthYearText
  391.      * The header month selector tooltip (defaults to <tt>'Choose a month (Control+Up/Down to move years)'</tt>)
  392.      */
  393.     monthYearText : 'Choose a month (Control+Up/Down to move years)',
  394.     /**
  395.      * @cfg {Number} startDay
  396.      * Day index at which the week should begin, 0-based (defaults to 0, which is Sunday)
  397.      */
  398.     startDay : 0,
  399.     /**
  400.      * @cfg {Boolean} showToday
  401.      * False to hide the footer area containing the Today button and disable the keyboard handler for spacebar
  402.      * that selects the current date (defaults to <tt>true</tt>).
  403.      */
  404.     showToday : true,
  405.     /**
  406.      * @cfg {Date} minDate
  407.      * Minimum allowable date (JavaScript date object, defaults to null)
  408.      */
  409.     /**
  410.      * @cfg {Date} maxDate
  411.      * Maximum allowable date (JavaScript date object, defaults to null)
  412.      */
  413.     /**
  414.      * @cfg {Array} disabledDays
  415.      * An array of days to disable, 0-based. For example, [0, 6] disables Sunday and Saturday (defaults to null).
  416.      */
  417.     /**
  418.      * @cfg {RegExp} disabledDatesRE
  419.      * JavaScript regular expression used to disable a pattern of dates (defaults to null).  The {@link #disabledDates}
  420.      * config will generate this regex internally, but if you specify disabledDatesRE it will take precedence over the
  421.      * disabledDates value.
  422.      */
  423.     /**
  424.      * @cfg {Array} disabledDates
  425.      * An array of 'dates' to disable, as strings. These strings will be used to build a dynamic regular
  426.      * expression so they are very powerful. Some examples:
  427.      * <ul>
  428.      * <li>['03/08/2003', '09/16/2003'] would disable those exact dates</li>
  429.      * <li>['03/08', '09/16'] would disable those days for every year</li>
  430.      * <li>['^03/08'] would only match the beginning (useful if you are using short years)</li>
  431.      * <li>['03/../2006'] would disable every day in March 2006</li>
  432.      * <li>['^03'] would disable every day in every March</li>
  433.      * </ul>
  434.      * Note that the format of the dates included in the array should exactly match the {@link #format} config.
  435.      * In order to support regular expressions, if you are using a date format that has '.' in it, you will have to
  436.      * escape the dot when restricting dates. For example: ['03\.08\.03'].
  437.      */
  438.     // private
  439.     initComponent : function(){
  440.         Ext.DatePicker.superclass.initComponent.call(this);
  441.         this.value = this.value ?
  442.                  this.value.clearTime() : new Date().clearTime();
  443.         this.addEvents(
  444.             /**
  445.              * @event select
  446.              * Fires when a date is selected
  447.              * @param {DatePicker} this
  448.              * @param {Date} date The selected date
  449.              */
  450.             'select'
  451.         );
  452.         if(this.handler){
  453.             this.on('select', this.handler,  this.scope || this);
  454.         }
  455.         this.initDisabledDays();
  456.     },
  457.     // private
  458.     initDisabledDays : function(){
  459.         if(!this.disabledDatesRE && this.disabledDates){
  460.             var dd = this.disabledDates,
  461.                 len = dd.length - 1,
  462.                 re = '(?:';
  463.                 
  464.             Ext.each(dd, function(d, i){
  465.                 re += Ext.isDate(d) ? '^' + Ext.escapeRe(d.dateFormat(this.format)) + '$' : dd[i];
  466.                 if(i != len){
  467.                     re += '|';
  468.                 }
  469.             }, this);
  470.             this.disabledDatesRE = new RegExp(re + ')');
  471.         }
  472.     },
  473.     /**
  474.      * Replaces any existing disabled dates with new values and refreshes the DatePicker.
  475.      * @param {Array/RegExp} disabledDates An array of date strings (see the {@link #disabledDates} config
  476.      * for details on supported values), or a JavaScript regular expression used to disable a pattern of dates.
  477.      */
  478.     setDisabledDates : function(dd){
  479.         if(Ext.isArray(dd)){
  480.             this.disabledDates = dd;
  481.             this.disabledDatesRE = null;
  482.         }else{
  483.             this.disabledDatesRE = dd;
  484.         }
  485.         this.initDisabledDays();
  486.         this.update(this.value, true);
  487.     },
  488.     /**
  489.      * Replaces any existing disabled days (by index, 0-6) with new values and refreshes the DatePicker.
  490.      * @param {Array} disabledDays An array of disabled day indexes. See the {@link #disabledDays} config
  491.      * for details on supported values.
  492.      */
  493.     setDisabledDays : function(dd){
  494.         this.disabledDays = dd;
  495.         this.update(this.value, true);
  496.     },
  497.     /**
  498.      * Replaces any existing {@link #minDate} with the new value and refreshes the DatePicker.
  499.      * @param {Date} value The minimum date that can be selected
  500.      */
  501.     setMinDate : function(dt){
  502.         this.minDate = dt;
  503.         this.update(this.value, true);
  504.     },
  505.     /**
  506.      * Replaces any existing {@link #maxDate} with the new value and refreshes the DatePicker.
  507.      * @param {Date} value The maximum date that can be selected
  508.      */
  509.     setMaxDate : function(dt){
  510.         this.maxDate = dt;
  511.         this.update(this.value, true);
  512.     },
  513.     /**
  514.      * Sets the value of the date field
  515.      * @param {Date} value The date to set
  516.      */
  517.     setValue : function(value){
  518.         var old = this.value;
  519.         this.value = value.clearTime(true);
  520.         if(this.el){
  521.             this.update(this.value);
  522.         }
  523.     },
  524.     /**
  525.      * Gets the current selected value of the date field
  526.      * @return {Date} The selected date
  527.      */
  528.     getValue : function(){
  529.         return this.value;
  530.     },
  531.     // private
  532.     focus : function(){
  533.         if(this.el){
  534.             this.update(this.activeDate);
  535.         }
  536.     },
  537.     
  538.     // private
  539.     onEnable: function(initial){
  540.         Ext.DatePicker.superclass.onEnable.call(this);    
  541.         this.doDisabled(false);
  542.         this.update(initial ? this.value : this.activeDate);
  543.         if(Ext.isIE){
  544.             this.el.repaint();
  545.         }
  546.         
  547.     },
  548.     
  549.     // private
  550.     onDisable: function(){
  551.         Ext.DatePicker.superclass.onDisable.call(this);   
  552.         this.doDisabled(true);
  553.         if(Ext.isIE && !Ext.isIE8){
  554.             /* Really strange problem in IE6/7, when disabled, have to explicitly
  555.              * repaint each of the nodes to get them to display correctly, simply
  556.              * calling repaint on the main element doesn't appear to be enough.
  557.              */
  558.              Ext.each([].concat(this.textNodes, this.el.query('th span')), function(el){
  559.                  Ext.fly(el).repaint();
  560.              });
  561.         }
  562.     },
  563.     
  564.     // private
  565.     doDisabled: function(disabled){
  566.         this.keyNav.setDisabled(disabled);
  567.         this.prevRepeater.setDisabled(disabled);
  568.         this.nextRepeater.setDisabled(disabled);
  569.         if(this.showToday){
  570.             this.todayKeyListener.setDisabled(disabled);
  571.             this.todayBtn.setDisabled(disabled);
  572.         }
  573.     },
  574.     // private
  575.     onRender : function(container, position){
  576.         var m = [
  577.              '<table cellspacing="0">',
  578.                 '<tr><td class="x-date-left"><a href="#" title="', this.prevText ,'">&#160;</a></td><td class="x-date-middle" align="center"></td><td class="x-date-right"><a href="#" title="', this.nextText ,'">&#160;</a></td></tr>',
  579.                 '<tr><td colspan="3"><table class="x-date-inner" cellspacing="0"><thead><tr>'],
  580.                 dn = this.dayNames,
  581.                 i;
  582.         for(i = 0; i < 7; i++){
  583.             var d = this.startDay+i;
  584.             if(d > 6){
  585.                 d = d-7;
  586.             }
  587.             m.push('<th><span>', dn[d].substr(0,1), '</span></th>');
  588.         }
  589.         m[m.length] = '</tr></thead><tbody><tr>';
  590.         for(i = 0; i < 42; i++) {
  591.             if(i % 7 === 0 && i !== 0){
  592.                 m[m.length] = '</tr><tr>';
  593.             }
  594.             m[m.length] = '<td><a href="#" hidefocus="on" class="x-date-date" tabIndex="1"><em><span></span></em></a></td>';
  595.         }
  596.         m.push('</tr></tbody></table></td></tr>',
  597.                 this.showToday ? '<tr><td colspan="3" class="x-date-bottom" align="center"></td></tr>' : '',
  598.                 '</table><div class="x-date-mp"></div>');
  599.         var el = document.createElement('div');
  600.         el.className = 'x-date-picker';
  601.         el.innerHTML = m.join('');
  602.         container.dom.insertBefore(el, position);
  603.         this.el = Ext.get(el);
  604.         this.eventEl = Ext.get(el.firstChild);
  605.         this.prevRepeater = new Ext.util.ClickRepeater(this.el.child('td.x-date-left a'), {
  606.             handler: this.showPrevMonth,
  607.             scope: this,
  608.             preventDefault:true,
  609.             stopDefault:true
  610.         });
  611.         this.nextRepeater = new Ext.util.ClickRepeater(this.el.child('td.x-date-right a'), {
  612.             handler: this.showNextMonth,
  613.             scope: this,
  614.             preventDefault:true,
  615.             stopDefault:true
  616.         });
  617.         this.monthPicker = this.el.down('div.x-date-mp');
  618.         this.monthPicker.enableDisplayMode('block');
  619.         this.keyNav = new Ext.KeyNav(this.eventEl, {
  620.             'left' : function(e){
  621.                 if(e.ctrlKey){
  622.                     this.showPrevMonth();
  623.                 }else{
  624.                     this.update(this.activeDate.add('d', -1));    
  625.                 }
  626.             },
  627.             'right' : function(e){
  628.                 if(e.ctrlKey){
  629.                     this.showNextMonth();
  630.                 }else{
  631.                     this.update(this.activeDate.add('d', 1));    
  632.                 }
  633.             },
  634.             'up' : function(e){
  635.                 if(e.ctrlKey){
  636.                     this.showNextYear();
  637.                 }else{
  638.                     this.update(this.activeDate.add('d', -7));
  639.                 }
  640.             },
  641.             'down' : function(e){
  642.                 if(e.ctrlKey){
  643.                     this.showPrevYear();
  644.                 }else{
  645.                     this.update(this.activeDate.add('d', 7));
  646.                 }
  647.             },
  648.             'pageUp' : function(e){
  649.                 this.showNextMonth();
  650.             },
  651.             'pageDown' : function(e){
  652.                 this.showPrevMonth();
  653.             },
  654.             'enter' : function(e){
  655.                 e.stopPropagation();
  656.                 return true;
  657.             },
  658.             scope : this
  659.         });
  660.         this.el.unselectable();
  661.         this.cells = this.el.select('table.x-date-inner tbody td');
  662.         this.textNodes = this.el.query('table.x-date-inner tbody span');
  663.         this.mbtn = new Ext.Button({
  664.             text: '&#160;',
  665.             tooltip: this.monthYearText,
  666.             renderTo: this.el.child('td.x-date-middle', true)
  667.         });
  668.         this.mbtn.el.child('em').addClass('x-btn-arrow');
  669.         if(this.showToday){
  670.             this.todayKeyListener = this.eventEl.addKeyListener(Ext.EventObject.SPACE, this.selectToday,  this);
  671.             var today = (new Date()).dateFormat(this.format);
  672.             this.todayBtn = new Ext.Button({
  673.                 renderTo: this.el.child('td.x-date-bottom', true),
  674.                 text: String.format(this.todayText, today),
  675.                 tooltip: String.format(this.todayTip, today),
  676.                 handler: this.selectToday,
  677.                 scope: this
  678.             });
  679.         }
  680.         this.mon(this.eventEl, 'mousewheel', this.handleMouseWheel, this);
  681.         this.mon(this.eventEl, 'click', this.handleDateClick,  this, {delegate: 'a.x-date-date'});
  682.         this.mon(this.mbtn, 'click', this.showMonthPicker, this);
  683.         this.onEnable(true);
  684.     },
  685.     // private
  686.     createMonthPicker : function(){
  687.         if(!this.monthPicker.dom.firstChild){
  688.             var buf = ['<table border="0" cellspacing="0">'];
  689.             for(var i = 0; i < 6; i++){
  690.                 buf.push(
  691.                     '<tr><td class="x-date-mp-month"><a href="#">', Date.getShortMonthName(i), '</a></td>',
  692.                     '<td class="x-date-mp-month x-date-mp-sep"><a href="#">', Date.getShortMonthName(i + 6), '</a></td>',
  693.                     i === 0 ?
  694.                     '<td class="x-date-mp-ybtn" align="center"><a class="x-date-mp-prev"></a></td><td class="x-date-mp-ybtn" align="center"><a class="x-date-mp-next"></a></td></tr>' :
  695.                     '<td class="x-date-mp-year"><a href="#"></a></td><td class="x-date-mp-year"><a href="#"></a></td></tr>'
  696.                 );
  697.             }
  698.             buf.push(
  699.                 '<tr class="x-date-mp-btns"><td colspan="4"><button type="button" class="x-date-mp-ok">',
  700.                     this.okText,
  701.                     '</button><button type="button" class="x-date-mp-cancel">',
  702.                     this.cancelText,
  703.                     '</button></td></tr>',
  704.                 '</table>'
  705.             );
  706.             this.monthPicker.update(buf.join(''));
  707.             this.mon(this.monthPicker, 'click', this.onMonthClick, this);
  708.             this.mon(this.monthPicker, 'dblclick', this.onMonthDblClick, this);
  709.             this.mpMonths = this.monthPicker.select('td.x-date-mp-month');
  710.             this.mpYears = this.monthPicker.select('td.x-date-mp-year');
  711.             this.mpMonths.each(function(m, a, i){
  712.                 i += 1;
  713.                 if((i%2) === 0){
  714.                     m.dom.xmonth = 5 + Math.round(i * 0.5);
  715.                 }else{
  716.                     m.dom.xmonth = Math.round((i-1) * 0.5);
  717.                 }
  718.             });
  719.         }
  720.     },
  721.     // private
  722.     showMonthPicker : function(){
  723.         if(!this.disabled){
  724.             this.createMonthPicker();
  725.             var size = this.el.getSize();
  726.             this.monthPicker.setSize(size);
  727.             this.monthPicker.child('table').setSize(size);
  728.             this.mpSelMonth = (this.activeDate || this.value).getMonth();
  729.             this.updateMPMonth(this.mpSelMonth);
  730.             this.mpSelYear = (this.activeDate || this.value).getFullYear();
  731.             this.updateMPYear(this.mpSelYear);
  732.             this.monthPicker.slideIn('t', {duration:0.2});
  733.         }
  734.     },
  735.     // private
  736.     updateMPYear : function(y){
  737.         this.mpyear = y;
  738.         var ys = this.mpYears.elements;
  739.         for(var i = 1; i <= 10; i++){
  740.             var td = ys[i-1], y2;
  741.             if((i%2) === 0){
  742.                 y2 = y + Math.round(i * 0.5);
  743.                 td.firstChild.innerHTML = y2;
  744.                 td.xyear = y2;
  745.             }else{
  746.                 y2 = y - (5-Math.round(i * 0.5));
  747.                 td.firstChild.innerHTML = y2;
  748.                 td.xyear = y2;
  749.             }
  750.             this.mpYears.item(i-1)[y2 == this.mpSelYear ? 'addClass' : 'removeClass']('x-date-mp-sel');
  751.         }
  752.     },
  753.     // private
  754.     updateMPMonth : function(sm){
  755.         this.mpMonths.each(function(m, a, i){
  756.             m[m.dom.xmonth == sm ? 'addClass' : 'removeClass']('x-date-mp-sel');
  757.         });
  758.     },
  759.     // private
  760.     selectMPMonth : function(m){
  761.     },
  762.     // private
  763.     onMonthClick : function(e, t){
  764.         e.stopEvent();
  765.         var el = new Ext.Element(t), pn;
  766.         if(el.is('button.x-date-mp-cancel')){
  767.             this.hideMonthPicker();
  768.         }
  769.         else if(el.is('button.x-date-mp-ok')){
  770.             var d = new Date(this.mpSelYear, this.mpSelMonth, (this.activeDate || this.value).getDate());
  771.             if(d.getMonth() != this.mpSelMonth){
  772.                 // 'fix' the JS rolling date conversion if needed
  773.                 d = new Date(this.mpSelYear, this.mpSelMonth, 1).getLastDateOfMonth();
  774.             }
  775.             this.update(d);
  776.             this.hideMonthPicker();
  777.         }
  778.         else if((pn = el.up('td.x-date-mp-month', 2))){
  779.             this.mpMonths.removeClass('x-date-mp-sel');
  780.             pn.addClass('x-date-mp-sel');
  781.             this.mpSelMonth = pn.dom.xmonth;
  782.         }
  783.         else if((pn = el.up('td.x-date-mp-year', 2))){
  784.             this.mpYears.removeClass('x-date-mp-sel');
  785.             pn.addClass('x-date-mp-sel');
  786.             this.mpSelYear = pn.dom.xyear;
  787.         }
  788.         else if(el.is('a.x-date-mp-prev')){
  789.             this.updateMPYear(this.mpyear-10);
  790.         }
  791.         else if(el.is('a.x-date-mp-next')){
  792.             this.updateMPYear(this.mpyear+10);
  793.         }
  794.     },
  795.     // private
  796.     onMonthDblClick : function(e, t){
  797.         e.stopEvent();
  798.         var el = new Ext.Element(t), pn;
  799.         if((pn = el.up('td.x-date-mp-month', 2))){
  800.             this.update(new Date(this.mpSelYear, pn.dom.xmonth, (this.activeDate || this.value).getDate()));
  801.             this.hideMonthPicker();
  802.         }
  803.         else if((pn = el.up('td.x-date-mp-year', 2))){
  804.             this.update(new Date(pn.dom.xyear, this.mpSelMonth, (this.activeDate || this.value).getDate()));
  805.             this.hideMonthPicker();
  806.         }
  807.     },
  808.     // private
  809.     hideMonthPicker : function(disableAnim){
  810.         if(this.monthPicker){
  811.             if(disableAnim === true){
  812.                 this.monthPicker.hide();
  813.             }else{
  814.                 this.monthPicker.slideOut('t', {duration:0.2});
  815.             }
  816.         }
  817.     },
  818.     // private
  819.     showPrevMonth : function(e){
  820.         this.update(this.activeDate.add('mo', -1));
  821.     },
  822.     // private
  823.     showNextMonth : function(e){
  824.         this.update(this.activeDate.add('mo', 1));
  825.     },
  826.     // private
  827.     showPrevYear : function(){
  828.         this.update(this.activeDate.add('y', -1));
  829.     },
  830.     // private
  831.     showNextYear : function(){
  832.         this.update(this.activeDate.add('y', 1));
  833.     },
  834.     // private
  835.     handleMouseWheel : function(e){
  836.         e.stopEvent();