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

中间件编程

开发平台:

JavaScript

  1. /*!
  2.  * Ext JS Library 3.0.0
  3.  * Copyright(c) 2006-2009 Ext JS, LLC
  4.  * licensing@extjs.com
  5.  * http://www.extjs.com/license
  6.  */
  7. /**
  8.  * @class Ext.Component
  9.  * @extends Ext.util.Observable
  10.  * <p>Base class for all Ext components.  All subclasses of Component may participate in the automated
  11.  * Ext component lifecycle of creation, rendering and destruction which is provided by the {@link Ext.Container Container} class.
  12.  * Components may be added to a Container through the {@link Ext.Container#items items} config option at the time the Container is created,
  13.  * or they may be added dynamically via the {@link Ext.Container#add add} method.</p>
  14.  * <p>The Component base class has built-in support for basic hide/show and enable/disable behavior.</p>
  15.  * <p>All Components are registered with the {@link Ext.ComponentMgr} on construction so that they can be referenced at any time via
  16.  * {@link Ext#getCmp}, passing the {@link #id}.</p>
  17.  * <p>All user-developed visual widgets that are required to participate in automated lifecycle and size management should subclass Component (or
  18.  * {@link Ext.BoxComponent} if managed box model handling is required, ie height and width management).</p>
  19.  * <p>See the <a href="http://extjs.com/learn/Tutorial:Creating_new_UI_controls">Creating new UI controls</a> tutorial for details on how
  20.  * and to either extend or augment ExtJs base classes to create custom Components.</p>
  21.  * <p>Every component has a specific xtype, which is its Ext-specific type name, along with methods for checking the
  22.  * xtype like {@link #getXType} and {@link #isXType}. This is the list of all valid xtypes:</p>
  23.  * <pre>
  24. xtype            Class
  25. -------------    ------------------
  26. box              {@link Ext.BoxComponent}
  27. button           {@link Ext.Button}
  28. buttongroup      {@link Ext.ButtonGroup}
  29. colorpalette     {@link Ext.ColorPalette}
  30. component        {@link Ext.Component}
  31. container        {@link Ext.Container}
  32. cycle            {@link Ext.CycleButton}
  33. dataview         {@link Ext.DataView}
  34. datepicker       {@link Ext.DatePicker}
  35. editor           {@link Ext.Editor}
  36. editorgrid       {@link Ext.grid.EditorGridPanel}
  37. flash            {@link Ext.FlashComponent}
  38. grid             {@link Ext.grid.GridPanel}
  39. listview         {@link Ext.ListView}
  40. panel            {@link Ext.Panel}
  41. progress         {@link Ext.ProgressBar}
  42. propertygrid     {@link Ext.grid.PropertyGrid}
  43. slider           {@link Ext.Slider}
  44. spacer           {@link Ext.Spacer}
  45. splitbutton      {@link Ext.SplitButton}
  46. tabpanel         {@link Ext.TabPanel}
  47. treepanel        {@link Ext.tree.TreePanel}
  48. viewport         {@link Ext.ViewPort}
  49. window           {@link Ext.Window}
  50. Toolbar components
  51. ---------------------------------------
  52. paging           {@link Ext.PagingToolbar}
  53. toolbar          {@link Ext.Toolbar}
  54. tbbutton         {@link Ext.Toolbar.Button}        (deprecated; use button)
  55. tbfill           {@link Ext.Toolbar.Fill}
  56. tbitem           {@link Ext.Toolbar.Item}
  57. tbseparator      {@link Ext.Toolbar.Separator}
  58. tbspacer         {@link Ext.Toolbar.Spacer}
  59. tbsplit          {@link Ext.Toolbar.SplitButton}   (deprecated; use splitbutton)
  60. tbtext           {@link Ext.Toolbar.TextItem}
  61. Menu components
  62. ---------------------------------------
  63. menu             {@link Ext.menu.Menu}
  64. colormenu        {@link Ext.menu.ColorMenu}
  65. datemenu         {@link Ext.menu.DateMenu}
  66. menubaseitem     {@link Ext.menu.BaseItem}
  67. menucheckitem    {@link Ext.menu.CheckItem}
  68. menuitem         {@link Ext.menu.Item}
  69. menuseparator    {@link Ext.menu.Separator}
  70. menutextitem     {@link Ext.menu.TextItem}
  71. Form components
  72. ---------------------------------------
  73. form             {@link Ext.FormPanel}
  74. checkbox         {@link Ext.form.Checkbox}
  75. checkboxgroup    {@link Ext.form.CheckboxGroup}
  76. combo            {@link Ext.form.ComboBox}
  77. datefield        {@link Ext.form.DateField}
  78. displayfield     {@link Ext.form.DisplayField}
  79. field            {@link Ext.form.Field}
  80. fieldset         {@link Ext.form.FieldSet}
  81. hidden           {@link Ext.form.Hidden}
  82. htmleditor       {@link Ext.form.HtmlEditor}
  83. label            {@link Ext.form.Label}
  84. numberfield      {@link Ext.form.NumberField}
  85. radio            {@link Ext.form.Radio}
  86. radiogroup       {@link Ext.form.RadioGroup}
  87. textarea         {@link Ext.form.TextArea}
  88. textfield        {@link Ext.form.TextField}
  89. timefield        {@link Ext.form.TimeField}
  90. trigger          {@link Ext.form.TriggerField}
  91. Chart components
  92. ---------------------------------------
  93. chart            {@link Ext.chart.Chart}
  94. barchart         {@link Ext.chart.BarChart}
  95. cartesianchart   {@link Ext.chart.CartesianChart}
  96. columnchart      {@link Ext.chart.ColumnChart}
  97. linechart        {@link Ext.chart.LineChart}
  98. piechart         {@link Ext.chart.PieChart}
  99. Store xtypes
  100. ---------------------------------------
  101. arraystore       {@link Ext.data.ArrayStore}
  102. directstore      {@link Ext.data.DirectStore}
  103. groupingstore    {@link Ext.data.GroupingStore}
  104. jsonstore        {@link Ext.data.JsonStore}
  105. simplestore      {@link Ext.data.SimpleStore}      (deprecated; use arraystore)
  106. store            {@link Ext.data.Store}
  107. xmlstore         {@link Ext.data.XmlStore}
  108. </pre>
  109.  * @constructor
  110.  * @param {Ext.Element/String/Object} config The configuration options may be specified as either:
  111.  * <div class="mdetail-params"><ul>
  112.  * <li><b>an element</b> :
  113.  * <p class="sub-desc">it is set as the internal element and its id used as the component id</p></li>
  114.  * <li><b>a string</b> :
  115.  * <p class="sub-desc">it is assumed to be the id of an existing element and is used as the component id</p></li>
  116.  * <li><b>anything else</b> :
  117.  * <p class="sub-desc">it is assumed to be a standard config object and is applied to the component</p></li>
  118.  * </ul></div>
  119.  */
  120. Ext.Component = function(config){
  121.     config = config || {};
  122.     if(config.initialConfig){
  123.         if(config.isAction){           // actions
  124.             this.baseAction = config;
  125.         }
  126.         config = config.initialConfig; // component cloning / action set up
  127.     }else if(config.tagName || config.dom || Ext.isString(config)){ // element object
  128.         config = {applyTo: config, id: config.id || config};
  129.     }
  130.     /**
  131.      * This Component's initial configuration specification. Read-only.
  132.      * @type Object
  133.      * @property initialConfig
  134.      */
  135.     this.initialConfig = config;
  136.     Ext.apply(this, config);
  137.     this.addEvents(
  138.         /**
  139.          * @event disable
  140.          * Fires after the component is disabled.
  141.          * @param {Ext.Component} this
  142.          */
  143.         'disable',
  144.         /**
  145.          * @event enable
  146.          * Fires after the component is enabled.
  147.          * @param {Ext.Component} this
  148.          */
  149.         'enable',
  150.         /**
  151.          * @event beforeshow
  152.          * Fires before the component is shown by calling the {@link #show} method.
  153.          * Return false from an event handler to stop the show.
  154.          * @param {Ext.Component} this
  155.          */
  156.         'beforeshow',
  157.         /**
  158.          * @event show
  159.          * Fires after the component is shown when calling the {@link #show} method.
  160.          * @param {Ext.Component} this
  161.          */
  162.         'show',
  163.         /**
  164.          * @event beforehide
  165.          * Fires before the component is hidden by calling the {@link #hide} method.
  166.          * Return false from an event handler to stop the hide.
  167.          * @param {Ext.Component} this
  168.          */
  169.         'beforehide',
  170.         /**
  171.          * @event hide
  172.          * Fires after the component is hidden.
  173.          * Fires after the component is hidden when calling the {@link #hide} method.
  174.          * @param {Ext.Component} this
  175.          */
  176.         'hide',
  177.         /**
  178.          * @event beforerender
  179.          * Fires before the component is {@link #rendered}. Return false from an
  180.          * event handler to stop the {@link #render}.
  181.          * @param {Ext.Component} this
  182.          */
  183.         'beforerender',
  184.         /**
  185.          * @event render
  186.          * Fires after the component markup is {@link #rendered}.
  187.          * @param {Ext.Component} this
  188.          */
  189.         'render',
  190.         /**
  191.          * @event afterrender
  192.          * <p>Fires after the component rendering is finished.</p>
  193.          * <p>The afterrender event is fired after this Component has been {@link #rendered}, been postprocesed
  194.          * by any afterRender method defined for the Component, and, if {@link #stateful}, after state
  195.          * has been restored.</p>
  196.          * @param {Ext.Component} this
  197.          */
  198.         'afterrender',
  199.         /**
  200.          * @event beforedestroy
  201.          * Fires before the component is {@link #destroy}ed. Return false from an event handler to stop the {@link #destroy}.
  202.          * @param {Ext.Component} this
  203.          */
  204.         'beforedestroy',
  205.         /**
  206.          * @event destroy
  207.          * Fires after the component is {@link #destroy}ed.
  208.          * @param {Ext.Component} this
  209.          */
  210.         'destroy',
  211.         /**
  212.          * @event beforestaterestore
  213.          * Fires before the state of the component is restored. Return false from an event handler to stop the restore.
  214.          * @param {Ext.Component} this
  215.          * @param {Object} state The hash of state values returned from the StateProvider. If this
  216.          * event is not vetoed, then the state object is passed to <b><tt>applyState</tt></b>. By default,
  217.          * that simply copies property values into this Component. The method maybe overriden to
  218.          * provide custom state restoration.
  219.          */
  220.         'beforestaterestore',
  221.         /**
  222.          * @event staterestore
  223.          * Fires after the state of the component is restored.
  224.          * @param {Ext.Component} this
  225.          * @param {Object} state The hash of state values returned from the StateProvider. This is passed
  226.          * to <b><tt>applyState</tt></b>. By default, that simply copies property values into this
  227.          * Component. The method maybe overriden to provide custom state restoration.
  228.          */
  229.         'staterestore',
  230.         /**
  231.          * @event beforestatesave
  232.          * Fires before the state of the component is saved to the configured state provider. Return false to stop the save.
  233.          * @param {Ext.Component} this
  234.          * @param {Object} state The hash of state values. This is determined by calling
  235.          * <b><tt>getState()</tt></b> on the Component. This method must be provided by the
  236.          * developer to return whetever representation of state is required, by default, Ext.Component
  237.          * has a null implementation.
  238.          */
  239.         'beforestatesave',
  240.         /**
  241.          * @event statesave
  242.          * Fires after the state of the component is saved to the configured state provider.
  243.          * @param {Ext.Component} this
  244.          * @param {Object} state The hash of state values. This is determined by calling
  245.          * <b><tt>getState()</tt></b> on the Component. This method must be provided by the
  246.          * developer to return whetever representation of state is required, by default, Ext.Component
  247.          * has a null implementation.
  248.          */
  249.         'statesave'
  250.     );
  251.     this.getId();
  252.     Ext.ComponentMgr.register(this);
  253.     Ext.Component.superclass.constructor.call(this);
  254.     if(this.baseAction){
  255.         this.baseAction.addComponent(this);
  256.     }
  257.     this.initComponent();
  258.     if(this.plugins){
  259.         if(Ext.isArray(this.plugins)){
  260.             for(var i = 0, len = this.plugins.length; i < len; i++){
  261.                 this.plugins[i] = this.initPlugin(this.plugins[i]);
  262.             }
  263.         }else{
  264.             this.plugins = this.initPlugin(this.plugins);
  265.         }
  266.     }
  267.     if(this.stateful !== false){
  268.         this.initState(config);
  269.     }
  270.     if(this.applyTo){
  271.         this.applyToMarkup(this.applyTo);
  272.         delete this.applyTo;
  273.     }else if(this.renderTo){
  274.         this.render(this.renderTo);
  275.         delete this.renderTo;
  276.     }
  277. };
  278. // private
  279. Ext.Component.AUTO_ID = 1000;
  280. Ext.extend(Ext.Component, Ext.util.Observable, {
  281. // Configs below are used for all Components when rendered by FormLayout.
  282.     /**
  283.      * @cfg {String} fieldLabel <p>The label text to display next to this Component (defaults to '').</p>
  284.      * <br><p><b>Note</b>: this config is only used when this Component is rendered by a Container which
  285.      * has been configured to use the <b>{@link Ext.layout.FormLayout FormLayout}</b> layout manager (e.g.
  286.      * {@link Ext.form.FormPanel} or specifying <tt>layout:'form'</tt>).</p><br>
  287.      * <p>Also see <tt>{@link #hideLabel}</tt> and
  288.      * {@link Ext.layout.FormLayout}.{@link Ext.layout.FormLayout#fieldTpl fieldTpl}.</p>
  289.      * Example use:<pre><code>
  290. new Ext.FormPanel({
  291.     height: 100,
  292.     renderTo: Ext.getBody(),
  293.     items: [{
  294.         xtype: 'textfield',
  295.         fieldLabel: 'Name'
  296.     }]
  297. });
  298. </code></pre>
  299.      */
  300.     /**
  301.      * @cfg {String} labelStyle <p>A CSS style specification string to apply directly to this field's
  302.      * label.  Defaults to the container's labelStyle value if set (e.g.,
  303.      * <tt>{@link Ext.layout.FormLayout#labelStyle}</tt> , or '').</p>
  304.      * <br><p><b>Note</b>: see the note for <code>{@link #clearCls}</code>.</p><br>
  305.      * <p>Also see <code>{@link #hideLabel}</code> and
  306.      * <code>{@link Ext.layout.FormLayout}.{@link Ext.layout.FormLayout#fieldTpl fieldTpl}.</code></p>
  307.      * Example use:<pre><code>
  308. new Ext.FormPanel({
  309.     height: 100,
  310.     renderTo: Ext.getBody(),
  311.     items: [{
  312.         xtype: 'textfield',
  313.         fieldLabel: 'Name',
  314.         labelStyle: 'font-weight:bold;'
  315.     }]
  316. });
  317. </code></pre>
  318.      */
  319.     /**
  320.      * @cfg {String} labelSeparator <p>The separator to display after the text of each
  321.      * <tt>{@link #fieldLabel}</tt>.  This property may be configured at various levels.
  322.      * The order of precedence is:
  323.      * <div class="mdetail-params"><ul>
  324.      * <li>field / component level</li>
  325.      * <li>container level</li>
  326.      * <li>{@link Ext.layout.FormLayout#labelSeparator layout level} (defaults to colon <tt>':'</tt>)</li>
  327.      * </ul></div>
  328.      * To display no separator for this field's label specify empty string ''.</p>
  329.      * <br><p><b>Note</b>: see the note for <tt>{@link #clearCls}</tt>.</p><br>
  330.      * <p>Also see <tt>{@link #hideLabel}</tt> and
  331.      * {@link Ext.layout.FormLayout}.{@link Ext.layout.FormLayout#fieldTpl fieldTpl}.</p>
  332.      * Example use:<pre><code>
  333. new Ext.FormPanel({
  334.     height: 100,
  335.     renderTo: Ext.getBody(),
  336.     layoutConfig: {
  337.         labelSeparator: '~'   // layout config has lowest priority (defaults to ':')
  338.     },
  339.     {@link Ext.layout.FormLayout#labelSeparator labelSeparator}: '>>',     // config at container level
  340.     items: [{
  341.         xtype: 'textfield',
  342.         fieldLabel: 'Field 1',
  343.         labelSeparator: '...' // field/component level config supersedes others
  344.     },{
  345.         xtype: 'textfield',
  346.         fieldLabel: 'Field 2' // labelSeparator will be '='
  347.     }]
  348. });
  349. </code></pre>
  350.      */
  351.     /**
  352.      * @cfg {Boolean} hideLabel <p><tt>true</tt> to completely hide the label element
  353.      * ({@link #fieldLabel label} and {@link #labelSeparator separator}). Defaults to <tt>false</tt>.
  354.      * By default, even if you do not specify a <tt>{@link #fieldLabel}</tt> the space will still be
  355.      * reserved so that the field will line up with other fields that do have labels.
  356.      * Setting this to <tt>true</tt> will cause the field to not reserve that space.</p>
  357.      * <br><p><b>Note</b>: see the note for <tt>{@link #clearCls}</tt>.</p><br>
  358.      * Example use:<pre><code>
  359. new Ext.FormPanel({
  360.     height: 100,
  361.     renderTo: Ext.getBody(),
  362.     items: [{
  363.         xtype: 'textfield'
  364.         hideLabel: true
  365.     }]
  366. });
  367. </code></pre>
  368.      */
  369.     /**
  370.      * @cfg {String} clearCls <p>The CSS class used to to apply to the special clearing div rendered
  371.      * directly after each form field wrapper to provide field clearing (defaults to
  372.      * <tt>'x-form-clear-left'</tt>).</p>
  373.      * <br><p><b>Note</b>: this config is only used when this Component is rendered by a Container
  374.      * which has been configured to use the <b>{@link Ext.layout.FormLayout FormLayout}</b> layout
  375.      * manager (e.g. {@link Ext.form.FormPanel} or specifying <tt>layout:'form'</tt>) and either a
  376.      * <tt>{@link #fieldLabel}</tt> is specified or <tt>isFormField=true</tt> is specified.</p><br>
  377.      * <p>See {@link Ext.layout.FormLayout}.{@link Ext.layout.FormLayout#fieldTpl fieldTpl} also.</p>
  378.      */
  379.     /**
  380.      * @cfg {String} itemCls <p>An additional CSS class to apply to the div wrapping the form item
  381.      * element of this field.  If supplied, <tt>itemCls</tt> at the <b>field</b> level will override
  382.      * the default <tt>itemCls</tt> supplied at the <b>container</b> level. The value specified for
  383.      * <tt>itemCls</tt> will be added to the default class (<tt>'x-form-item'</tt>).</p>
  384.      * <p>Since it is applied to the item wrapper (see
  385.      * {@link Ext.layout.FormLayout}.{@link Ext.layout.FormLayout#fieldTpl fieldTpl}), it allows
  386.      * you to write standard CSS rules that can apply to the field, the label (if specified), or
  387.      * any other element within the markup for the field.</p>
  388.      * <br><p><b>Note</b>: see the note for <tt>{@link #fieldLabel}</tt>.</p><br>
  389.      * Example use:<pre><code>
  390. // Apply a style to the field's label:
  391. &lt;style>
  392.     .required .x-form-item-label {font-weight:bold;color:red;}
  393. &lt;/style>
  394. new Ext.FormPanel({
  395. height: 100,
  396. renderTo: Ext.getBody(),
  397. items: [{
  398. xtype: 'textfield',
  399. fieldLabel: 'Name',
  400. itemCls: 'required' //this label will be styled
  401. },{
  402. xtype: 'textfield',
  403. fieldLabel: 'Favorite Color'
  404. }]
  405. });
  406. </code></pre>
  407.      */
  408. // Configs below are used for all Components when rendered by AnchorLayout.
  409.     /**
  410.      * @cfg {String} anchor <p><b>Note</b>: this config is only used when this Component is rendered
  411.      * by a Container which has been configured to use an <b>{@link Ext.layout.AnchorLayout AnchorLayout}</b>
  412.      * based layout manager, for example:<div class="mdetail-params"><ul>
  413.      * <li>{@link Ext.form.FormPanel}</li>
  414.      * <li>specifying <code>layout: 'anchor' // or 'form', or 'absolute'</code></li>
  415.      * </ul></div></p>
  416.      * <p>See {@link Ext.layout.AnchorLayout}.{@link Ext.layout.AnchorLayout#anchor anchor} also.</p>
  417.      */
  418.     /**
  419.      * @cfg {String} id
  420.      * <p>The <b>unique</b> id of this component (defaults to an {@link #getId auto-assigned id}).
  421.      * You should assign an id if you need to be able to access the component later and you do
  422.      * not have an object reference available (e.g., using {@link Ext}.{@link Ext#getCmp getCmp}).</p>
  423.      * <p>Note that this id will also be used as the element id for the containing HTML element
  424.      * that is rendered to the page for this component. This allows you to write id-based CSS
  425.      * rules to style the specific instance of this component uniquely, and also to select
  426.      * sub-elements using this component's id as the parent.</p>
  427.      * <p><b>Note</b>: to avoid complications imposed by a unique <tt>id</tt> also see
  428.      * <code>{@link #itemId}</code> and <code>{@link #ref}</code>.</p>
  429.      * <p><b>Note</b>: to access the container of an item see <code>{@link #ownerCt}</code>.</p>
  430.      */
  431.     /**
  432.      * @cfg {String} itemId
  433.      * <p>An <tt>itemId</tt> can be used as an alternative way to get a reference to a component
  434.      * when no object reference is available.  Instead of using an <code>{@link #id}</code> with
  435.      * {@link Ext}.{@link Ext#getCmp getCmp}, use <code>itemId</code> with
  436.      * {@link Ext.Container}.{@link Ext.Container#getComponent getComponent} which will retrieve
  437.      * <code>itemId</code>'s or <tt>{@link #id}</tt>'s. Since <code>itemId</code>'s are an index to the
  438.      * container's internal MixedCollection, the <code>itemId</code> is scoped locally to the container --
  439.      * avoiding potential conflicts with {@link Ext.ComponentMgr} which requires a <b>unique</b>
  440.      * <code>{@link #id}</code>.</p>
  441.      * <pre><code>
  442. var c = new Ext.Panel({ //
  443.     {@link Ext.BoxComponent#height height}: 300,
  444.     {@link #renderTo}: document.body,
  445.     {@link Ext.Container#layout layout}: 'auto',
  446.     {@link Ext.Container#items items}: [
  447.         {
  448.             itemId: 'p1',
  449.             {@link Ext.Panel#title title}: 'Panel 1',
  450.             {@link Ext.BoxComponent#height height}: 150
  451.         },
  452.         {
  453.             itemId: 'p2',
  454.             {@link Ext.Panel#title title}: 'Panel 2',
  455.             {@link Ext.BoxComponent#height height}: 150
  456.         }
  457.     ]
  458. })
  459. p1 = c.{@link Ext.Container#getComponent getComponent}('p1'); // not the same as {@link Ext#getCmp Ext.getCmp()}
  460. p2 = p1.{@link #ownerCt}.{@link Ext.Container#getComponent getComponent}('p2'); // reference via a sibling
  461.      * </code></pre>
  462.      * <p>Also see <tt>{@link #id}</tt> and <code>{@link #ref}</code>.</p>
  463.      * <p><b>Note</b>: to access the container of an item see <tt>{@link #ownerCt}</tt>.</p>
  464.      */
  465.     /**
  466.      * @cfg {String} xtype
  467.      * The registered <tt>xtype</tt> to create. This config option is not used when passing
  468.      * a config object into a constructor. This config option is used only when
  469.      * lazy instantiation is being used, and a child item of a Container is being
  470.      * specified not as a fully instantiated Component, but as a <i>Component config
  471.      * object</i>. The <tt>xtype</tt> will be looked up at render time up to determine what
  472.      * type of child Component to create.<br><br>
  473.      * The predefined xtypes are listed {@link Ext.Component here}.
  474.      * <br><br>
  475.      * If you subclass Components to create your own Components, you may register
  476.      * them using {@link Ext.ComponentMgr#registerType} in order to be able to
  477.      * take advantage of lazy instantiation and rendering.
  478.      */
  479.     /**
  480.      * @cfg {String} ptype
  481.      * The registered <tt>ptype</tt> to create. This config option is not used when passing
  482.      * a config object into a constructor. This config option is used only when
  483.      * lazy instantiation is being used, and a Plugin is being
  484.      * specified not as a fully instantiated Component, but as a <i>Component config
  485.      * object</i>. The <tt>ptype</tt> will be looked up at render time up to determine what
  486.      * type of Plugin to create.<br><br>
  487.      * If you create your own Plugins, you may register them using
  488.      * {@link Ext.ComponentMgr#registerPlugin} in order to be able to
  489.      * take advantage of lazy instantiation and rendering.
  490.      */
  491.     /**
  492.      * @cfg {String} cls
  493.      * An optional extra CSS class that will be added to this component's Element (defaults to '').  This can be
  494.      * useful for adding customized styles to the component or any of its children using standard CSS rules.
  495.      */
  496.     /**
  497.      * @cfg {String} overCls
  498.      * An optional extra CSS class that will be added to this component's Element when the mouse moves
  499.      * over the Element, and removed when the mouse moves out. (defaults to '').  This can be
  500.      * useful for adding customized 'active' or 'hover' styles to the component or any of its children using standard CSS rules.
  501.      */
  502.     /**
  503.      * @cfg {String} style
  504.      * A custom style specification to be applied to this component's Element.  Should be a valid argument to
  505.      * {@link Ext.Element#applyStyles}.
  506.      * <pre><code>
  507. new Ext.Panel({
  508.     title: 'Some Title',
  509.     renderTo: Ext.getBody(),
  510.     width: 400, height: 300,
  511.     layout: 'form',
  512.     items: [{
  513.         xtype: 'textarea',
  514.         style: {
  515.             width: '95%',
  516.             marginBottom: '10px'
  517.         }
  518.     },
  519.         new Ext.Button({
  520.             text: 'Send',
  521.             minWidth: '100',
  522.             style: {
  523.                 marginBottom: '10px'
  524.             }
  525.         })
  526.     ]
  527. });
  528.      * </code></pre>
  529.      */
  530.     /**
  531.      * @cfg {String} ctCls
  532.      * <p>An optional extra CSS class that will be added to this component's container. This can be useful for
  533.      * adding customized styles to the container or any of its children using standard CSS rules.  See
  534.      * {@link Ext.layout.ContainerLayout}.{@link Ext.layout.ContainerLayout#extraCls extraCls} also.</p>
  535.      * <p><b>Note</b>: <tt>ctCls</tt> defaults to <tt>''</tt> except for the following class
  536.      * which assigns a value by default:
  537.      * <div class="mdetail-params"><ul>
  538.      * <li>{@link Ext.layout.Box Box Layout} : <tt>'x-box-layout-ct'</tt></li>
  539.      * </ul></div>
  540.      * To configure the above Class with an extra CSS class append to the default.  For example,
  541.      * for BoxLayout (Hbox and Vbox):<pre><code>
  542.      * ctCls: 'x-box-layout-ct custom-class'
  543.      * </code></pre>
  544.      * </p>
  545.      */
  546.     /**
  547.      * @cfg {Boolean} disabled
  548.      * Render this component disabled (default is false).
  549.      */
  550.     disabled : false,
  551.     /**
  552.      * @cfg {Boolean} hidden
  553.      * Render this component hidden (default is false). If <tt>true</tt>, the
  554.      * {@link #hide} method will be called internally.
  555.      */
  556.     hidden : false,
  557.     /**
  558.      * @cfg {Object/Array} plugins
  559.      * An object or array of objects that will provide custom functionality for this component.  The only
  560.      * requirement for a valid plugin is that it contain an init method that accepts a reference of type Ext.Component.
  561.      * When a component is created, if any plugins are available, the component will call the init method on each
  562.      * plugin, passing a reference to itself.  Each plugin can then call methods or respond to events on the
  563.      * component as needed to provide its functionality.
  564.      */
  565.     /**
  566.      * @cfg {Mixed} applyTo
  567.      * <p>Specify the id of the element, a DOM element or an existing Element corresponding to a DIV
  568.      * that is already present in the document that specifies some structural markup for this
  569.      * component.</p><div><ul>
  570.      * <li><b>Description</b> : <ul>
  571.      * <div class="sub-desc">When <tt>applyTo</tt> is used, constituent parts of the component can also be specified
  572.      * by id or CSS class name within the main element, and the component being created may attempt
  573.      * to create its subcomponents from that markup if applicable.</div>
  574.      * </ul></li>
  575.      * <li><b>Notes</b> : <ul>
  576.      * <div class="sub-desc">When using this config, a call to render() is not required.</div>
  577.      * <div class="sub-desc">If applyTo is specified, any value passed for {@link #renderTo} will be ignored and the target
  578.      * element's parent node will automatically be used as the component's container.</div>
  579.      * </ul></li>
  580.      * </ul></div>
  581.      */
  582.     /**
  583.      * @cfg {Mixed} renderTo
  584.      * <p>Specify the id of the element, a DOM element or an existing Element that this component
  585.      * will be rendered into.</p><div><ul>
  586.      * <li><b>Notes</b> : <ul>
  587.      * <div class="sub-desc">Do <u>not</u> use this option if the Component is to be a child item of
  588.      * a {@link Ext.Container Container}. It is the responsibility of the
  589.      * {@link Ext.Container Container}'s {@link Ext.Container#layout layout manager}
  590.      * to render and manage its child items.</div>
  591.      * <div class="sub-desc">When using this config, a call to render() is not required.</div>
  592.      * </ul></li>
  593.      * </ul></div>
  594.      * <p>See <tt>{@link #render}</tt> also.</p>
  595.      */
  596.     /**
  597.      * @cfg {Boolean} stateful
  598.      * <p>A flag which causes the Component to attempt to restore the state of
  599.      * internal properties from a saved state on startup. The component must have
  600.      * either a <code>{@link #stateId}</code> or <code>{@link #id}</code> assigned
  601.      * for state to be managed. Auto-generated ids are not guaranteed to be stable
  602.      * across page loads and cannot be relied upon to save and restore the same
  603.      * state for a component.<p>
  604.      * <p>For state saving to work, the state manager's provider must have been
  605.      * set to an implementation of {@link Ext.state.Provider} which overrides the
  606.      * {@link Ext.state.Provider#set set} and {@link Ext.state.Provider#get get}
  607.      * methods to save and recall name/value pairs. A built-in implementation,
  608.      * {@link Ext.state.CookieProvider} is available.</p>
  609.      * <p>To set the state provider for the current page:</p>
  610.      * <pre><code>
  611. Ext.state.Manager.setProvider(new Ext.state.CookieProvider({
  612.     expires: new Date(new Date().getTime()+(1000*60*60*24*7)), //7 days from now
  613. }));
  614.      * </code></pre>
  615.      * <p>A stateful Component attempts to save state when one of the events
  616.      * listed in the <code>{@link #stateEvents}</code> configuration fires.</p>
  617.      * <p>To save state, a stateful Component first serializes its state by
  618.      * calling <b><code>getState</code></b>. By default, this function does
  619.      * nothing. The developer must provide an implementation which returns an
  620.      * object hash which represents the Component's restorable state.</p>
  621.      * <p>The value yielded by getState is passed to {@link Ext.state.Manager#set}
  622.      * which uses the configured {@link Ext.state.Provider} to save the object
  623.      * keyed by the Component's <code>{@link stateId}</code>, or, if that is not
  624.      * specified, its <code>{@link #id}</code>.</p>
  625.      * <p>During construction, a stateful Component attempts to <i>restore</i>
  626.      * its state by calling {@link Ext.state.Manager#get} passing the
  627.      * <code>{@link #stateId}</code>, or, if that is not specified, the
  628.      * <code>{@link #id}</code>.</p>
  629.      * <p>The resulting object is passed to <b><code>applyState</code></b>.
  630.      * The default implementation of <code>applyState</code> simply copies
  631.      * properties into the object, but a developer may override this to support
  632.      * more behaviour.</p>
  633.      * <p>You can perform extra processing on state save and restore by attaching
  634.      * handlers to the {@link #beforestaterestore}, {@link #staterestore},
  635.      * {@link #beforestatesave} and {@link #statesave} events.</p>
  636.      */
  637.     /**
  638.      * @cfg {String} stateId
  639.      * The unique id for this component to use for state management purposes
  640.      * (defaults to the component id if one was set, otherwise null if the
  641.      * component is using a generated id).
  642.      * <p>See <code>{@link #stateful}</code> for an explanation of saving and
  643.      * restoring Component state.</p>
  644.      */
  645.     /**
  646.      * @cfg {Array} stateEvents
  647.      * <p>An array of events that, when fired, should trigger this component to
  648.      * save its state (defaults to none). <code>stateEvents</code> may be any type
  649.      * of event supported by this component, including browser or custom events
  650.      * (e.g., <tt>['click', 'customerchange']</tt>).</p>
  651.      * <p>See <code>{@link #stateful}</code> for an explanation of saving and
  652.      * restoring Component state.</p>
  653.      */
  654.     /**
  655.      * @cfg {Mixed} autoEl
  656.      * <p>A tag name or {@link Ext.DomHelper DomHelper} spec used to create the {@link #getEl Element} which will
  657.      * encapsulate this Component.</p>
  658.      * <p>You do not normally need to specify this. For the base classes {@link Ext.Component}, {@link Ext.BoxComponent},
  659.      * and {@link Ext.Container}, this defaults to <b><tt>'div'</tt></b>. The more complex Ext classes use a more complex
  660.      * DOM structure created by their own onRender methods.</p>
  661.      * <p>This is intended to allow the developer to create application-specific utility Components encapsulated by
  662.      * different DOM elements. Example usage:</p><pre><code>
  663. {
  664.     xtype: 'box',
  665.     autoEl: {
  666.         tag: 'img',
  667.         src: 'http://www.example.com/example.jpg'
  668.     }
  669. }, {
  670.     xtype: 'box',
  671.     autoEl: {
  672.         tag: 'blockquote',
  673.         html: 'autoEl is cool!'
  674.     }
  675. }, {
  676.     xtype: 'container',
  677.     autoEl: 'ul',
  678.     cls: 'ux-unordered-list',
  679.     items: {
  680.         xtype: 'box',
  681.         autoEl: 'li',
  682.         html: 'First list item'
  683.     }
  684. }
  685. </code></pre>
  686.      */
  687.     autoEl : 'div',
  688.     /**
  689.      * @cfg {String} disabledClass
  690.      * CSS class added to the component when it is disabled (defaults to 'x-item-disabled').
  691.      */
  692.     disabledClass : 'x-item-disabled',
  693.     /**
  694.      * @cfg {Boolean} allowDomMove
  695.      * Whether the component can move the Dom node when rendering (defaults to true).
  696.      */
  697.     allowDomMove : true,
  698.     /**
  699.      * @cfg {Boolean} autoShow
  700.      * True if the component should check for hidden classes (e.g. 'x-hidden' or 'x-hide-display') and remove
  701.      * them on render (defaults to false).
  702.      */
  703.     autoShow : false,
  704.     /**
  705.      * @cfg {String} hideMode
  706.      * <p>How this component should be hidden. Supported values are <tt>'visibility'</tt>
  707.      * (css visibility), <tt>'offsets'</tt> (negative offset position) and <tt>'display'</tt>
  708.      * (css display).</p>
  709.      * <br><p><b>Note</b>: the default of <tt>'display'</tt> is generally preferred
  710.      * since items are automatically laid out when they are first shown (no sizing
  711.      * is done while hidden).</p>
  712.      */
  713.     hideMode : 'display',
  714.     /**
  715.      * @cfg {Boolean} hideParent
  716.      * True to hide and show the component's container when hide/show is called on the component, false to hide
  717.      * and show the component itself (defaults to false).  For example, this can be used as a shortcut for a hide
  718.      * button on a window by setting hide:true on the button when adding it to its parent container.
  719.      */
  720.     hideParent : false,
  721.     /**
  722.      * <p>The {@link Ext.Element} which encapsulates this Component. Read-only.</p>
  723.      * <p>This will <i>usually</i> be a &lt;DIV> element created by the class's onRender method, but
  724.      * that may be overridden using the <code>{@link #autoEl}</code> config.</p>
  725.      * <br><p><b>Note</b>: this element will not be available until this Component has been rendered.</p><br>
  726.      * <p>To add listeners for <b>DOM events</b> to this Component (as opposed to listeners
  727.      * for this Component's own Observable events), see the {@link Ext.util.Observable#listeners listeners}
  728.      * config for a suggestion, or use a render listener directly:</p><pre><code>
  729. new Ext.Panel({
  730.     title: 'The Clickable Panel',
  731.     listeners: {
  732.         render: function(p) {
  733.             // Append the Panel to the click handler&#39;s argument list.
  734.             p.getEl().on('click', handlePanelClick.createDelegate(null, [p], true));
  735.         },
  736.         single: true  // Remove the listener after first invocation
  737.     }
  738. });
  739. </code></pre>
  740.      * <p>See also <tt>{@link #getEl getEl}</p>
  741.      * @type Ext.Element
  742.      * @property el
  743.      */
  744.     /**
  745.      * The component's owner {@link Ext.Container} (defaults to undefined, and is set automatically when
  746.      * the component is added to a container).  Read-only.
  747.      * <p><b>Note</b>: to access items within the container see <tt>{@link #itemId}</tt>.</p>
  748.      * @type Ext.Container
  749.      * @property ownerCt
  750.      */
  751.     /**
  752.      * True if this component is hidden. Read-only.
  753.      * @type Boolean
  754.      * @property
  755.      */
  756.     /**
  757.      * True if this component is disabled. Read-only.
  758.      * @type Boolean
  759.      * @property
  760.      */
  761.     /**
  762.      * True if this component has been rendered. Read-only.
  763.      * @type Boolean
  764.      * @property
  765.      */
  766.     rendered : false,
  767.     // private
  768.     ctype : 'Ext.Component',
  769.     // private
  770.     actionMode : 'el',
  771.     // private
  772.     getActionEl : function(){
  773.         return this[this.actionMode];
  774.     },
  775.     initPlugin : function(p){
  776.         if(p.ptype && !Ext.isFunction(p.init)){
  777.             p = Ext.ComponentMgr.createPlugin(p);
  778.         }else if(Ext.isString(p)){
  779.             p = Ext.ComponentMgr.createPlugin({
  780.                 ptype: p
  781.             });
  782.         }
  783.         p.init(this);
  784.         return p;
  785.     },
  786.     /* // protected
  787.      * Function to be implemented by Component subclasses to be part of standard component initialization flow (it is empty by default).
  788.      * <pre><code>
  789. // Traditional constructor:
  790. Ext.Foo = function(config){
  791.     // call superclass constructor:
  792.     Ext.Foo.superclass.constructor.call(this, config);
  793.     this.addEvents({
  794.         // add events
  795.     });
  796. };
  797. Ext.extend(Ext.Foo, Ext.Bar, {
  798.    // class body
  799. }
  800. // initComponent replaces the constructor:
  801. Ext.Foo = Ext.extend(Ext.Bar, {
  802.     initComponent : function(){
  803.         // call superclass initComponent
  804.         Ext.Container.superclass.initComponent.call(this);
  805.         this.addEvents({
  806.             // add events
  807.         });
  808.     }
  809. }
  810. </code></pre>
  811.      */
  812.     initComponent : Ext.emptyFn,
  813.     /**
  814.      * <p>Render this Component into the passed HTML element.</p>
  815.      * <p><b>If you are using a {@link Ext.Container Container} object to house this Component, then
  816.      * do not use the render method.</b></p>
  817.      * <p>A Container's child Components are rendered by that Container's
  818.      * {@link Ext.Container#layout layout} manager when the Container is first rendered.</p>
  819.      * <p>Certain layout managers allow dynamic addition of child components. Those that do
  820.      * include {@link Ext.layout.CardLayout}, {@link Ext.layout.AnchorLayout},
  821.      * {@link Ext.layout.FormLayout}, {@link Ext.layout.TableLayout}.</p>
  822.      * <p>If the Container is already rendered when a new child Component is added, you may need to call
  823.      * the Container's {@link Ext.Container#doLayout doLayout} to refresh the view which causes any
  824.      * unrendered child Components to be rendered. This is required so that you can add multiple
  825.      * child components if needed while only refreshing the layout once.</p>
  826.      * <p>When creating complex UIs, it is important to remember that sizing and positioning
  827.      * of child items is the responsibility of the Container's {@link Ext.Container#layout layout} manager.
  828.      * If you expect child items to be sized in response to user interactions, you must
  829.      * configure the Container with a layout manager which creates and manages the type of layout you
  830.      * have in mind.</p>
  831.      * <p><b>Omitting the Container's {@link Ext.Container#layout layout} config means that a basic
  832.      * layout manager is used which does nothing but render child components sequentially into the
  833.      * Container. No sizing or positioning will be performed in this situation.</b></p>
  834.      * @param {Element/HTMLElement/String} container (optional) The element this Component should be
  835.      * rendered into. If it is being created from existing markup, this should be omitted.
  836.      * @param {String/Number} position (optional) The element ID or DOM node index within the container <b>before</b>
  837.      * which this component will be inserted (defaults to appending to the end of the container)
  838.      */
  839.     render : function(container, position){
  840.         if(!this.rendered && this.fireEvent('beforerender', this) !== false){
  841.             if(!container && this.el){
  842.                 this.el = Ext.get(this.el);
  843.                 container = this.el.dom.parentNode;
  844.                 this.allowDomMove = false;
  845.             }
  846.             this.container = Ext.get(container);
  847.             if(this.ctCls){
  848.                 this.container.addClass(this.ctCls);
  849.             }
  850.             this.rendered = true;
  851.             if(position !== undefined){
  852.                 if(Ext.isNumber(position)){
  853.                     position = this.container.dom.childNodes[position];
  854.                 }else{
  855.                     position = Ext.getDom(position);
  856.                 }
  857.             }
  858.             this.onRender(this.container, position || null);
  859.             if(this.autoShow){
  860.                 this.el.removeClass(['x-hidden','x-hide-' + this.hideMode]);
  861.             }
  862.             if(this.cls){
  863.                 this.el.addClass(this.cls);
  864.                 delete this.cls;
  865.             }
  866.             if(this.style){
  867.                 this.el.applyStyles(this.style);
  868.                 delete this.style;
  869.             }
  870.             if(this.overCls){
  871.                 this.el.addClassOnOver(this.overCls);
  872.             }
  873.             this.fireEvent('render', this);
  874.             this.afterRender(this.container);
  875.             if(this.hidden){
  876.                 // call this so we don't fire initial hide events.
  877.                 this.doHide();
  878.             }
  879.             if(this.disabled){
  880.                 // pass silent so the event doesn't fire the first time.
  881.                 this.disable(true);
  882.             }
  883.             if(this.stateful !== false){
  884.                 this.initStateEvents();
  885.             }
  886.             this.initRef();
  887.             this.fireEvent('afterrender', this);
  888.         }
  889.         return this;
  890.     },
  891.     initRef : function(){
  892.         /**
  893.          * @cfg {String} ref
  894.          * <p>A path specification, relative to the Component's {@link #ownerCt} specifying into which
  895.          * ancestor Container to place a named reference to this Component.</p>
  896.          * <p>The ancestor axis can be traversed by using '/' characters in the path.
  897.          * For example, to put a reference to a Toolbar Button into <i>the Panel which owns the Toolbar</i>:</p><pre><code>
  898. var myGrid = new Ext.grid.EditorGridPanel({
  899.     title: 'My EditorGridPanel',
  900.     store: myStore,
  901.     colModel: myColModel,
  902.     tbar: [{
  903.         text: 'Save',
  904.         handler: saveChanges,
  905.         disabled: true,
  906.         ref: '../saveButton'
  907.     }],
  908.     listeners: {
  909.         afteredit: function() {
  910. //          The button reference is in the GridPanel
  911.             myGrid.saveButton.enable();
  912.         }
  913.     }
  914. });
  915. </code></pre>
  916.          * <p>In the code above, if the ref had been <code>'saveButton'</code> the reference would
  917.          * have been placed into the Toolbar. Each '/' in the ref moves up one level from the
  918.          * Component's {@link #ownerCt}.</p>
  919.          */
  920.         if(this.ref){
  921.             var levels = this.ref.split('/');
  922.             var last = levels.length, i = 0;
  923.             var t = this;
  924.             while(i < last){
  925.                 if(t.ownerCt){
  926.                     t = t.ownerCt;
  927.                 }
  928.                 i++;
  929.             }
  930.             t[levels[--i]] = this;
  931.         }
  932.     },
  933.     // private
  934.     initState : function(config){
  935.         if(Ext.state.Manager){
  936.             var id = this.getStateId();
  937.             if(id){
  938.                 var state = Ext.state.Manager.get(id);
  939.                 if(state){
  940.                     if(this.fireEvent('beforestaterestore', this, state) !== false){
  941.                         this.applyState(state);
  942.                         this.fireEvent('staterestore', this, state);
  943.                     }
  944.                 }
  945.             }
  946.         }
  947.     },
  948.     // private
  949.     getStateId : function(){
  950.         return this.stateId || ((this.id.indexOf('ext-comp-') == 0 || this.id.indexOf('ext-gen') == 0) ? null : this.id);
  951.     },
  952.     // private
  953.     initStateEvents : function(){
  954.         if(this.stateEvents){
  955.             for(var i = 0, e; e = this.stateEvents[i]; i++){
  956.                 this.on(e, this.saveState, this, {delay:100});
  957.             }
  958.         }
  959.     },
  960.     // private
  961.     applyState : function(state, config){
  962.         if(state){
  963.             Ext.apply(this, state);
  964.         }
  965.     },
  966.     // private
  967.     getState : function(){
  968.         return null;
  969.     },
  970.     // private
  971.     saveState : function(){
  972.         if(Ext.state.Manager && this.stateful !== false){
  973.             var id = this.getStateId();
  974.             if(id){
  975.                 var state = this.getState();
  976.                 if(this.fireEvent('beforestatesave', this, state) !== false){
  977.                     Ext.state.Manager.set(id, state);
  978.                     this.fireEvent('statesave', this, state);
  979.                 }
  980.             }
  981.         }
  982.     },
  983.     /**
  984.      * Apply this component to existing markup that is valid. With this function, no call to render() is required.
  985.      * @param {String/HTMLElement} el
  986.      */
  987.     applyToMarkup : function(el){
  988.         this.allowDomMove = false;
  989.         this.el = Ext.get(el);
  990.         this.render(this.el.dom.parentNode);
  991.     },
  992.     /**
  993.      * Adds a CSS class to the component's underlying element.
  994.      * @param {string} cls The CSS class name to add
  995.      * @return {Ext.Component} this
  996.      */
  997.     addClass : function(cls){
  998.         if(this.el){
  999.             this.el.addClass(cls);
  1000.         }else{
  1001.             this.cls = this.cls ? this.cls + ' ' + cls : cls;
  1002.         }
  1003.         return this;
  1004.     },
  1005.     /**
  1006.      * Removes a CSS class from the component's underlying element.
  1007.      * @param {string} cls The CSS class name to remove
  1008.      * @return {Ext.Component} this
  1009.      */
  1010.     removeClass : function(cls){
  1011.         if(this.el){
  1012.             this.el.removeClass(cls);
  1013.         }else if(this.cls){
  1014.             this.cls = this.cls.split(' ').remove(cls).join(' ');
  1015.         }
  1016.         return this;
  1017.     },
  1018.     // private
  1019.     // default function is not really useful
  1020.     onRender : function(ct, position){
  1021.         if(!this.el && this.autoEl){
  1022.             if(Ext.isString(this.autoEl)){
  1023.                 this.el = document.createElement(this.autoEl);
  1024.             }else{
  1025.                 var div = document.createElement('div');
  1026.                 Ext.DomHelper.overwrite(div, this.autoEl);
  1027.                 this.el = div.firstChild;
  1028.             }
  1029.             if (!this.el.id) {
  1030.                 this.el.id = this.getId();
  1031.             }
  1032.         }
  1033.         if(this.el){
  1034.             this.el = Ext.get(this.el);
  1035.             if(this.allowDomMove !== false){
  1036.                 ct.dom.insertBefore(this.el.dom, position);
  1037.             }
  1038.         }
  1039.     },
  1040.     // private
  1041.     getAutoCreate : function(){
  1042.         var cfg = Ext.isObject(this.autoCreate) ?
  1043.                       this.autoCreate : Ext.apply({}, this.defaultAutoCreate);
  1044.         if(this.id && !cfg.id){
  1045.             cfg.id = this.id;
  1046.         }
  1047.         return cfg;
  1048.     },
  1049.     // private
  1050.     afterRender : Ext.emptyFn,
  1051.     /**
  1052.      * Destroys this component by purging any event listeners, removing the component's element from the DOM,
  1053.      * removing the component from its {@link Ext.Container} (if applicable) and unregistering it from
  1054.      * {@link Ext.ComponentMgr}.  Destruction is generally handled automatically by the framework and this method
  1055.      * should usually not need to be called directly.
  1056.      *
  1057.      */
  1058.     destroy : function(){
  1059.         if(this.fireEvent('beforedestroy', this) !== false){
  1060.             this.beforeDestroy();
  1061.             if(this.rendered){
  1062.                 this.el.removeAllListeners();
  1063.                 this.el.remove();
  1064.                 if(this.actionMode == 'container' || this.removeMode == 'container'){
  1065.                     this.container.remove();
  1066.                 }
  1067.             }
  1068.             this.onDestroy();
  1069.             Ext.ComponentMgr.unregister(this);
  1070.             this.fireEvent('destroy', this);
  1071.             this.purgeListeners();
  1072.         }
  1073.     },
  1074.     // private
  1075.     beforeDestroy : Ext.emptyFn,
  1076.     // private
  1077.     onDestroy  : Ext.emptyFn,
  1078.     /**
  1079.      * <p>Returns the {@link Ext.Element} which encapsulates this Component.</p>
  1080.      * <p>This will <i>usually</i> be a &lt;DIV> element created by the class's onRender method, but
  1081.      * that may be overridden using the {@link #autoEl} config.</p>
  1082.      * <br><p><b>Note</b>: this element will not be available until this Component has been rendered.</p><br>
  1083.      * <p>To add listeners for <b>DOM events</b> to this Component (as opposed to listeners
  1084.      * for this Component's own Observable events), see the {@link #listeners} config for a suggestion,
  1085.      * or use a render listener directly:</p><pre><code>
  1086. new Ext.Panel({
  1087.     title: 'The Clickable Panel',
  1088.     listeners: {
  1089.         render: function(p) {
  1090.             // Append the Panel to the click handler&#39;s argument list.
  1091.             p.getEl().on('click', handlePanelClick.createDelegate(null, [p], true));
  1092.         },
  1093.         single: true  // Remove the listener after first invocation
  1094.     }
  1095. });
  1096. </code></pre>
  1097.      * @return {Ext.Element} The Element which encapsulates this Component.
  1098.      */
  1099.     getEl : function(){
  1100.         return this.el;
  1101.     },
  1102.     /**
  1103.      * Returns the <code>id</code> of this component or automatically generates and
  1104.      * returns an <code>id</code> if an <code>id</code> is not defined yet:<pre><code>
  1105.      * 'ext-comp-' + (++Ext.Component.AUTO_ID)
  1106.      * </code></pre>
  1107.      * @return {String} id
  1108.      */
  1109.     getId : function(){
  1110.         return this.id || (this.id = 'ext-comp-' + (++Ext.Component.AUTO_ID));
  1111.     },
  1112.     /**
  1113.      * Returns the <code>{@link #itemId}</code> of this component.  If an
  1114.      * <code>{@link #itemId}</code> was not assigned through configuration the
  1115.      * <code>id</code> is returned using <code>{@link #getId}</code>.
  1116.      * @return {String}
  1117.      */
  1118.     getItemId : function(){
  1119.         return this.itemId || this.getId();
  1120.     },
  1121.     /**
  1122.      * Try to focus this component.
  1123.      * @param {Boolean} selectText (optional) If applicable, true to also select the text in this component
  1124.      * @param {Boolean/Number} delay (optional) Delay the focus this number of milliseconds (true for 10 milliseconds)
  1125.      * @return {Ext.Component} this
  1126.      */
  1127.     focus : function(selectText, delay){
  1128.         if(delay){
  1129.             this.focus.defer(Ext.isNumber(delay) ? delay : 10, this, [selectText, false]);
  1130.             return;
  1131.         }
  1132.         if(this.rendered){
  1133.             this.el.focus();
  1134.             if(selectText === true){
  1135.                 this.el.dom.select();
  1136.             }
  1137.         }
  1138.         return this;
  1139.     },
  1140.     // private
  1141.     blur : function(){
  1142.         if(this.rendered){
  1143.             this.el.blur();
  1144.         }
  1145.         return this;
  1146.     },
  1147.     /**
  1148.      * Disable this component and fire the 'disable' event.
  1149.      * @return {Ext.Component} this
  1150.      */
  1151.     disable : function(/* private */ silent){
  1152.         if(this.rendered){
  1153.             this.onDisable();
  1154.         }
  1155.         this.disabled = true;
  1156.         if(silent !== true){
  1157.             this.fireEvent('disable', this);
  1158.         }
  1159.         return this;
  1160.     },
  1161.     // private
  1162.     onDisable : function(){
  1163.         this.getActionEl().addClass(this.disabledClass);
  1164.         this.el.dom.disabled = true;
  1165.     },
  1166.     /**
  1167.      * Enable this component and fire the 'enable' event.
  1168.      * @return {Ext.Component} this
  1169.      */
  1170.     enable : function(){
  1171.         if(this.rendered){
  1172.             this.onEnable();
  1173.         }
  1174.         this.disabled = false;
  1175.         this.fireEvent('enable', this);
  1176.         return this;
  1177.     },
  1178.     // private
  1179.     onEnable : function(){
  1180.         this.getActionEl().removeClass(this.disabledClass);
  1181.         this.el.dom.disabled = false;
  1182.     },
  1183.     /**
  1184.      * Convenience function for setting disabled/enabled by boolean.
  1185.      * @param {Boolean} disabled
  1186.      * @return {Ext.Component} this
  1187.      */
  1188.     setDisabled : function(disabled){
  1189.         return this[disabled ? 'disable' : 'enable']();
  1190.     },
  1191.     /**
  1192.      * Show this component.  Listen to the '{@link #beforeshow}' event and return
  1193.      * <tt>false</tt> to cancel showing the component.  Fires the '{@link #show}'
  1194.      * event after showing the component.
  1195.      * @return {Ext.Component} this
  1196.      */
  1197.     show : function(){
  1198.         if(this.fireEvent('beforeshow', this) !== false){
  1199.             this.hidden = false;
  1200.             if(this.autoRender){
  1201.                 this.render(Ext.isBoolean(this.autoRender) ? Ext.getBody() : this.autoRender);
  1202.             }
  1203.             if(this.rendered){
  1204.                 this.onShow();
  1205.             }
  1206.             this.fireEvent('show', this);
  1207.         }
  1208.         return this;
  1209.     },
  1210.     // private
  1211.     onShow : function(){
  1212.         this.getVisibiltyEl().removeClass('x-hide-' + this.hideMode);
  1213.     },
  1214.     /**
  1215.      * Hide this component.  Listen to the '{@link #beforehide}' event and return
  1216.      * <tt>false</tt> to cancel hiding the component.  Fires the '{@link #hide}'
  1217.      * event after hiding the component. Note this method is called internally if
  1218.      * the component is configured to be <code>{@link #hidden}</code>.
  1219.      * @return {Ext.Component} this
  1220.      */
  1221.     hide : function(){
  1222.         if(this.fireEvent('beforehide', this) !== false){
  1223.             this.doHide();
  1224.             this.fireEvent('hide', this);
  1225.         }
  1226.         return this;
  1227.     },
  1228.     // private
  1229.     doHide: function(){
  1230.         this.hidden = true;
  1231.         if(this.rendered){
  1232.             this.onHide();
  1233.         }
  1234.     },
  1235.     // private
  1236.     onHide : function(){
  1237.         this.getVisibiltyEl().addClass('x-hide-' + this.hideMode);
  1238.     },
  1239.     // private
  1240.     getVisibiltyEl : function(){
  1241.         return this.hideParent ? this.container : this.getActionEl();
  1242.     },
  1243.     /**
  1244.      * Convenience function to hide or show this component by boolean.
  1245.      * @param {Boolean} visible True to show, false to hide
  1246.      * @return {Ext.Component} this
  1247.      */
  1248.     setVisible : function(visible){
  1249.         return this[visible ? 'show' : 'hide']();
  1250.     },
  1251.     /**
  1252.      * Returns true if this component is visible.
  1253.      * @return {Boolean} True if this component is visible, false otherwise.
  1254.      */
  1255.     isVisible : function(){
  1256.         return this.rendered && this.getVisibiltyEl().isVisible();
  1257.     },
  1258.     /**
  1259.      * Clone the current component using the original config values passed into this instance by default.
  1260.      * @param {Object} overrides A new config containing any properties to override in the cloned version.
  1261.      * An id property can be passed on this object, otherwise one will be generated to avoid duplicates.
  1262.      * @return {Ext.Component} clone The cloned copy of this component
  1263.      */
  1264.     cloneConfig : function(overrides){
  1265.         overrides = overrides || {};
  1266.         var id = overrides.id || Ext.id();
  1267.         var cfg = Ext.applyIf(overrides, this.initialConfig);
  1268.         cfg.id = id; // prevent dup id
  1269.         return new this.constructor(cfg);
  1270.     },
  1271.     /**
  1272.      * Gets the xtype for this component as registered with {@link Ext.ComponentMgr}. For a list of all
  1273.      * available xtypes, see the {@link Ext.Component} header. Example usage:
  1274.      * <pre><code>
  1275. var t = new Ext.form.TextField();
  1276. alert(t.getXType());  // alerts 'textfield'
  1277. </code></pre>
  1278.      * @return {String} The xtype
  1279.      */
  1280.     getXType : function(){
  1281.         return this.constructor.xtype;
  1282.     },
  1283.     /**
  1284.      * <p>Tests whether or not this Component is of a specific xtype. This can test whether this Component is descended
  1285.      * from the xtype (default) or whether it is directly of the xtype specified (shallow = true).</p>
  1286.      * <p><b>If using your own subclasses, be aware that a Component must register its own xtype
  1287.      * to participate in determination of inherited xtypes.</b></p>
  1288.      * <p>For a list of all available xtypes, see the {@link Ext.Component} header.</p>
  1289.      * <p>Example usage:</p>
  1290.      * <pre><code>
  1291. var t = new Ext.form.TextField();
  1292. var isText = t.isXType('textfield');        // true
  1293. var isBoxSubclass = t.isXType('box');       // true, descended from BoxComponent
  1294. var isBoxInstance = t.isXType('box', true); // false, not a direct BoxComponent instance
  1295. </code></pre>
  1296.      * @param {String} xtype The xtype to check for this Component
  1297.      * @param {Boolean} shallow (optional) False to check whether this Component is descended from the xtype (this is
  1298.      * the default), or true to check whether this Component is directly of the specified xtype.
  1299.      * @return {Boolean} True if this component descends from the specified xtype, false otherwise.
  1300.      */
  1301.     isXType : function(xtype, shallow){
  1302.         //assume a string by default
  1303.         if (Ext.isFunction(xtype)){
  1304.             xtype = xtype.xtype; //handle being passed the class, e.g. Ext.Component
  1305.         }else if (Ext.isObject(xtype)){
  1306.             xtype = xtype.constructor.xtype; //handle being passed an instance
  1307.         }
  1308.         return !shallow ? ('/' + this.getXTypes() + '/').indexOf('/' + xtype + '/') != -1 : this.constructor.xtype == xtype;
  1309.     },
  1310.     /**
  1311.      * <p>Returns this Component's xtype hierarchy as a slash-delimited string. For a list of all
  1312.      * available xtypes, see the {@link Ext.Component} header.</p>
  1313.      * <p><b>If using your own subclasses, be aware that a Component must register its own xtype
  1314.      * to participate in determination of inherited xtypes.</b></p>
  1315.      * <p>Example usage:</p>
  1316.      * <pre><code>
  1317. var t = new Ext.form.TextField();
  1318. alert(t.getXTypes());  // alerts 'component/box/field/textfield'
  1319. </code></pre>
  1320.      * @return {String} The xtype hierarchy string
  1321.      */
  1322.     getXTypes : function(){
  1323.         var tc = this.constructor;
  1324.         if(!tc.xtypes){
  1325.             var c = [], sc = this;
  1326.             while(sc && sc.constructor.xtype){
  1327.                 c.unshift(sc.constructor.xtype);
  1328.                 sc = sc.constructor.superclass;
  1329.             }
  1330.             tc.xtypeChain = c;
  1331.             tc.xtypes = c.join('/');
  1332.         }
  1333.         return tc.xtypes;
  1334.     },
  1335.     /**
  1336.      * Find a container above this component at any level by a custom function. If the passed function returns
  1337.      * true, the container will be returned.
  1338.      * @param {Function} fn The custom function to call with the arguments (container, this component).
  1339.      * @return {Ext.Container} The first Container for which the custom function returns true
  1340.      */
  1341.     findParentBy : function(fn) {
  1342.         for (var p = this.ownerCt; (p != null) && !fn(p, this); p = p.ownerCt);
  1343.         return p || null;
  1344.     },
  1345.     /**
  1346.      * Find a container above this component at any level by xtype or class
  1347.      * @param {String/Class} xtype The xtype string for a component, or the class of the component directly
  1348.      * @return {Ext.Container} The first Container which matches the given xtype or class
  1349.      */
  1350.     findParentByType : function(xtype) {
  1351.         return Ext.isFunction(xtype) ?
  1352.             this.findParentBy(function(p){
  1353.                 return p.constructor === xtype;
  1354.             }) :
  1355.             this.findParentBy(function(p){
  1356.                 return p.constructor.xtype === xtype;
  1357.             });
  1358.     },
  1359.     getDomPositionEl : function(){
  1360.         return this.getPositionEl ? this.getPositionEl() : this.getEl();
  1361.     },
  1362.     // private
  1363.     purgeListeners : function(){
  1364.         Ext.Component.superclass.purgeListeners.call(this);
  1365.         if(this.mons){
  1366.             this.on('beforedestroy', this.clearMons, this, {single: true});
  1367.         }
  1368.     },
  1369.     // private
  1370.     clearMons : function(){
  1371.         Ext.each(this.mons, function(m){
  1372.             m.item.un(m.ename, m.fn, m.scope);
  1373.         }, this);
  1374.         this.mons = [];
  1375.     },
  1376.     // internal function for auto removal of assigned event handlers on destruction
  1377.     mon : function(item, ename, fn, scope, opt){
  1378.         if(!this.mons){
  1379.             this.mons = [];
  1380.             this.on('beforedestroy', this.clearMons, this, {single: true});
  1381.         }
  1382.         if(Ext.isObject(ename)){
  1383.          var propRe = /^(?:scope|delay|buffer|single|stopEvent|preventDefault|stopPropagation|normalized|args|delegate)$/;
  1384.             var o = ename;
  1385.             for(var e in o){
  1386.                 if(propRe.test(e)){
  1387.                     continue;
  1388.                 }
  1389.                 if(Ext.isFunction(o[e])){
  1390.                     // shared options
  1391.         this.mons.push({
  1392.             item: item, ename: e, fn: o[e], scope: o.scope
  1393.         });
  1394.         item.on(e, o[e], o.scope, o);
  1395.                 }else{
  1396.                     // individual options
  1397.         this.mons.push({
  1398.             item: item, ename: e, fn: o[e], scope: o.scope
  1399.         });
  1400.         item.on(e, o[e]);
  1401.                 }
  1402.             }
  1403.             return;
  1404.         }
  1405.         this.mons.push({
  1406.             item: item, ename: ename, fn: fn, scope: scope
  1407.         });
  1408.         item.on(ename, fn, scope, opt);
  1409.     },
  1410.     // protected, opposite of mon
  1411.     mun : function(item, ename, fn, scope){
  1412.         var found, mon;
  1413.         for(var i = 0, len = this.mons.length; i < len; ++i){
  1414.             mon = this.mons[i];
  1415.             if(item === mon.item && ename == mon.ename && fn === mon.fn && scope === mon.scope){
  1416.                 this.mons.splice(i, 1);
  1417.                 item.un(ename, fn, scope);
  1418.                 found = true;
  1419.                 break;
  1420.             }
  1421.         }
  1422.         return found;
  1423.     },
  1424.     /**
  1425.      * Returns the next component in the owning container
  1426.      * @return Ext.Component
  1427.      */
  1428.     nextSibling : function(){
  1429.         if(this.ownerCt){
  1430.             var index = this.ownerCt.items.indexOf(this);
  1431.             if(index != -1 && index+1 < this.ownerCt.items.getCount()){
  1432.                 return this.ownerCt.items.itemAt(index+1);
  1433.             }
  1434.         }
  1435.         return null;
  1436.     },
  1437.     /**
  1438.      * Returns the previous component in the owning container
  1439.      * @return Ext.Component
  1440.      */
  1441.     previousSibling : function(){
  1442.         if(this.ownerCt){
  1443.             var index = this.ownerCt.items.indexOf(this);
  1444.             if(index > 0){
  1445.                 return this.ownerCt.items.itemAt(index-1);
  1446.             }
  1447.         }
  1448.         return null;
  1449.     },
  1450.     /**
  1451.      * Provides the link for Observable's fireEvent method to bubble up the ownership hierarchy.
  1452.      * @return {Ext.Container} the Container which owns this Component.
  1453.      */
  1454.     getBubbleTarget : function(){
  1455.         return this.ownerCt;
  1456.     }
  1457. });
  1458. Ext.reg('component', Ext.Component);