Upgrade to ExtJS 4.0.7 - Released 10/19/2011
[extjs.git] / src / Component.js
index 8e032b6..e447bad 100644 (file)
@@ -13,127 +13,122 @@ If you are unsure which license is appropriate for your use, please contact the
 
 */
 /**
- * @class Ext.Component
- * @extends Ext.AbstractComponent
- * <p>Base class for all Ext components.  All subclasses of Component may participate in the automated
- * Ext component lifecycle of creation, rendering and destruction which is provided by the {@link Ext.container.Container Container} class.
- * Components may be added to a Container through the {@link Ext.container.Container#items items} config option at the time the Container is created,
- * or they may be added dynamically via the {@link Ext.container.Container#add add} method.</p>
- * <p>The Component base class has built-in support for basic hide/show and enable/disable and size control behavior.</p>
- * <p>All Components are registered with the {@link Ext.ComponentManager} on construction so that they can be referenced at any time via
- * {@link Ext#getCmp Ext.getCmp}, passing the {@link #id}.</p>
- * <p>All user-developed visual widgets that are required to participate in automated lifecycle and size management should subclass Component.</p>
- * <p>See the <a href="http://sencha.com/learn/Tutorial:Creating_new_UI_controls">Creating new UI controls</a> tutorial for details on how
- * and to either extend or augment ExtJs base classes to create custom Components.</p>
- * <p>Every component has a specific xtype, which is its Ext-specific type name, along with methods for checking the
- * xtype like {@link #getXType} and {@link #isXType}. This is the list of all valid xtypes:</p>
- * <pre>
-xtype            Class
--------------    ------------------
-button           {@link Ext.button.Button}
-buttongroup      {@link Ext.container.ButtonGroup}
-colorpalette     {@link Ext.picker.Color}
-component        {@link Ext.Component}
-container        {@link Ext.container.Container}
-cycle            {@link Ext.button.Cycle}
-dataview         {@link Ext.view.View}
-datepicker       {@link Ext.picker.Date}
-editor           {@link Ext.Editor}
-editorgrid       {@link Ext.grid.plugin.Editing}
-grid             {@link Ext.grid.Panel}
-multislider      {@link Ext.slider.Multi}
-panel            {@link Ext.panel.Panel}
-progress         {@link Ext.ProgressBar}
-slider           {@link Ext.slider.Single}
-spacer           {@link Ext.toolbar.Spacer}
-splitbutton      {@link Ext.button.Split}
-tabpanel         {@link Ext.tab.Panel}
-treepanel        {@link Ext.tree.Panel}
-viewport         {@link Ext.container.Viewport}
-window           {@link Ext.window.Window}
-
-Toolbar components
----------------------------------------
-paging           {@link Ext.toolbar.Paging}
-toolbar          {@link Ext.toolbar.Toolbar}
-tbfill           {@link Ext.toolbar.Fill}
-tbitem           {@link Ext.toolbar.Item}
-tbseparator      {@link Ext.toolbar.Separator}
-tbspacer         {@link Ext.toolbar.Spacer}
-tbtext           {@link Ext.toolbar.TextItem}
-
-Menu components
----------------------------------------
-menu             {@link Ext.menu.Menu}
-menucheckitem    {@link Ext.menu.CheckItem}
-menuitem         {@link Ext.menu.Item}
-menuseparator    {@link Ext.menu.Separator}
-menutextitem     {@link Ext.menu.Item}
-
-Form components
----------------------------------------
-form             {@link Ext.form.Panel}
-checkbox         {@link Ext.form.field.Checkbox}
-combo            {@link Ext.form.field.ComboBox}
-datefield        {@link Ext.form.field.Date}
-displayfield     {@link Ext.form.field.Display}
-field            {@link Ext.form.field.Base}
-fieldset         {@link Ext.form.FieldSet}
-hidden           {@link Ext.form.field.Hidden}
-htmleditor       {@link Ext.form.field.HtmlEditor}
-label            {@link Ext.form.Label}
-numberfield      {@link Ext.form.field.Number}
-radio            {@link Ext.form.field.Radio}
-radiogroup       {@link Ext.form.RadioGroup}
-textarea         {@link Ext.form.field.TextArea}
-textfield        {@link Ext.form.field.Text}
-timefield        {@link Ext.form.field.Time}
-trigger          {@link Ext.form.field.Trigger}
-
-Chart components
----------------------------------------
-chart            {@link Ext.chart.Chart}
-barchart         {@link Ext.chart.series.Bar}
-columnchart      {@link Ext.chart.series.Column}
-linechart        {@link Ext.chart.series.Line}
-piechart         {@link Ext.chart.series.Pie}
-
-</pre><p>
- * It should not usually be necessary to instantiate a Component because there are provided subclasses which implement specialized Component
- * use cases which over most application needs. However it is possible to instantiate a base Component, and it will be renderable,
- * or will particpate in layouts as the child item of a Container:
-{@img Ext.Component/Ext.Component.png Ext.Component component}
-<pre><code>
-    Ext.create('Ext.Component', {
-        html: 'Hello world!',
-        width: 300,
-        height: 200,
-        padding: 20,
-        style: {
-            color: '#FFFFFF',
-            backgroundColor:'#000000'
-        },
-        renderTo: Ext.getBody()
-    });
-</code></pre>
- *</p>
- *<p>The Component above creates its encapsulating <code>div</code> upon render, and use the configured HTML as content. More complex
- * internal structure may be created using the {@link #renderTpl} configuration, although to display database-derived mass
- * data, it is recommended that an ExtJS data-backed Component such as a {@link Ext.view.View View}, or
- * {@link Ext.grid.Panel GridPanel}, or {@link Ext.tree.Panel TreePanel} be used.</p>
- * @constructor
- * Creates new Component.
- * @param {Ext.core.Element/String/Object} config The configuration options may be specified as either:
- * <div class="mdetail-params"><ul>
- * <li><b>an element</b> :
- * <p class="sub-desc">it is set as the internal element and its id used as the component id</p></li>
- * <li><b>a string</b> :
- * <p class="sub-desc">it is assumed to be the id of an existing element and is used as the component id</p></li>
- * <li><b>anything else</b> :
- * <p class="sub-desc">it is assumed to be a standard config object and is applied to the component</p></li>
- * </ul></div>
+ * Base class for all Ext components. All subclasses of Component may participate in the automated Ext component
+ * lifecycle of creation, rendering and destruction which is provided by the {@link Ext.container.Container Container}
+ * class. Components may be added to a Container through the {@link Ext.container.Container#items items} config option
+ * at the time the Container is created, or they may be added dynamically via the
+ * {@link Ext.container.Container#add add} method.
+ *
+ * The Component base class has built-in support for basic hide/show and enable/disable and size control behavior.
+ *
+ * All Components are registered with the {@link Ext.ComponentManager} on construction so that they can be referenced at
+ * any time via {@link Ext#getCmp Ext.getCmp}, passing the {@link #id}.
+ *
+ * All user-developed visual widgets that are required to participate in automated lifecycle and size management should
+ * subclass Component.
+ *
+ * See the [Creating new UI controls][1] tutorial for details on how and to either extend or augment ExtJs base classes
+ * to create custom Components.
+ *
+ * Every component has a specific xtype, which is its Ext-specific type name, along with methods for checking the xtype
+ * like {@link #getXType} and {@link #isXType}. See the [Component Guide][2] for more information on xtypes and the
+ * Component hierarchy.
+ *
+ * This is the list of all valid xtypes:
+ *
+ *     xtype            Class
+ *     -------------    ------------------
+ *     button           {@link Ext.button.Button}
+ *     buttongroup      {@link Ext.container.ButtonGroup}
+ *     colorpalette     {@link Ext.picker.Color}
+ *     component        {@link Ext.Component}
+ *     container        {@link Ext.container.Container}
+ *     cycle            {@link Ext.button.Cycle}
+ *     dataview         {@link Ext.view.View}
+ *     datepicker       {@link Ext.picker.Date}
+ *     editor           {@link Ext.Editor}
+ *     editorgrid       {@link Ext.grid.plugin.Editing}
+ *     grid             {@link Ext.grid.Panel}
+ *     multislider      {@link Ext.slider.Multi}
+ *     panel            {@link Ext.panel.Panel}
+ *     progressbar      {@link Ext.ProgressBar}
+ *     slider           {@link Ext.slider.Single}
+ *     splitbutton      {@link Ext.button.Split}
+ *     tabpanel         {@link Ext.tab.Panel}
+ *     treepanel        {@link Ext.tree.Panel}
+ *     viewport         {@link Ext.container.Viewport}
+ *     window           {@link Ext.window.Window}
+ *
+ *     Toolbar components
+ *     ---------------------------------------
+ *     pagingtoolbar    {@link Ext.toolbar.Paging}
+ *     toolbar          {@link Ext.toolbar.Toolbar}
+ *     tbfill           {@link Ext.toolbar.Fill}
+ *     tbitem           {@link Ext.toolbar.Item}
+ *     tbseparator      {@link Ext.toolbar.Separator}
+ *     tbspacer         {@link Ext.toolbar.Spacer}
+ *     tbtext           {@link Ext.toolbar.TextItem}
+ *
+ *     Menu components
+ *     ---------------------------------------
+ *     menu             {@link Ext.menu.Menu}
+ *     menucheckitem    {@link Ext.menu.CheckItem}
+ *     menuitem         {@link Ext.menu.Item}
+ *     menuseparator    {@link Ext.menu.Separator}
+ *     menutextitem     {@link Ext.menu.Item}
+ *
+ *     Form components
+ *     ---------------------------------------
+ *     form             {@link Ext.form.Panel}
+ *     checkbox         {@link Ext.form.field.Checkbox}
+ *     combo            {@link Ext.form.field.ComboBox}
+ *     datefield        {@link Ext.form.field.Date}
+ *     displayfield     {@link Ext.form.field.Display}
+ *     field            {@link Ext.form.field.Base}
+ *     fieldset         {@link Ext.form.FieldSet}
+ *     hidden           {@link Ext.form.field.Hidden}
+ *     htmleditor       {@link Ext.form.field.HtmlEditor}
+ *     label            {@link Ext.form.Label}
+ *     numberfield      {@link Ext.form.field.Number}
+ *     radio            {@link Ext.form.field.Radio}
+ *     radiogroup       {@link Ext.form.RadioGroup}
+ *     textarea         {@link Ext.form.field.TextArea}
+ *     textfield        {@link Ext.form.field.Text}
+ *     timefield        {@link Ext.form.field.Time}
+ *     trigger          {@link Ext.form.field.Trigger}
+ *
+ *     Chart components
+ *     ---------------------------------------
+ *     chart            {@link Ext.chart.Chart}
+ *     barchart         {@link Ext.chart.series.Bar}
+ *     columnchart      {@link Ext.chart.series.Column}
+ *     linechart        {@link Ext.chart.series.Line}
+ *     piechart         {@link Ext.chart.series.Pie}
+ *
+ * It should not usually be necessary to instantiate a Component because there are provided subclasses which implement
+ * specialized Component use cases which cover most application needs. However it is possible to instantiate a base
+ * Component, and it will be renderable, or will particpate in layouts as the child item of a Container:
+ *
+ *     @example
+ *     Ext.create('Ext.Component', {
+ *         html: 'Hello world!',
+ *         width: 300,
+ *         height: 200,
+ *         padding: 20,
+ *         style: {
+ *             color: '#FFFFFF',
+ *             backgroundColor:'#000000'
+ *         },
+ *         renderTo: Ext.getBody()
+ *     });
+ *
+ * The Component above creates its encapsulating `div` upon render, and use the configured HTML as content. More complex
+ * internal structure may be created using the {@link #renderTpl} configuration, although to display database-derived
+ * mass data, it is recommended that an ExtJS data-backed Component such as a {@link Ext.view.View View}, or {@link
+ * Ext.grid.Panel GridPanel}, or {@link Ext.tree.Panel TreePanel} be used.
+ *
+ * [1]: http://sencha.com/learn/Tutorial:Creating_new_UI_controls
  */
-
 Ext.define('Ext.Component', {
 
     /* Begin Definitions */
@@ -163,119 +158,150 @@ Ext.define('Ext.Component', {
         DIRECTION_BOTTOM: 'bottom',
         DIRECTION_LEFT: 'left',
 
-        VERTICAL_DIRECTION: /^(?:top|bottom)$/
+        VERTICAL_DIRECTION_Re: /^(?:top|bottom)$/,
+
+        // RegExp whih specifies characters in an xtype which must be translated to '-' when generating auto IDs.
+        // This includes dot, comma and whitespace
+        INVALID_ID_CHARS_Re: /[\.,\s]/g
     },
 
     /* End Definitions */
 
     /**
-     * @cfg {Mixed} resizable
-     * <p>Specify as <code>true</code> to apply a {@link Ext.resizer.Resizer Resizer} to this Component
-     * after rendering.</p>
-     * <p>May also be specified as a config object to be passed to the constructor of {@link Ext.resizer.Resizer Resizer}
+     * @cfg {Boolean/Object} resizable
+     * Specify as `true` to apply a {@link Ext.resizer.Resizer Resizer} to this Component after rendering.
+     *
+     * May also be specified as a config object to be passed to the constructor of {@link Ext.resizer.Resizer Resizer}
      * to override any defaults. By default the Component passes its minimum and maximum size, and uses
-     * <code>{@link Ext.resizer.Resizer#dynamic}: false</code></p>
+     * `{@link Ext.resizer.Resizer#dynamic}: false`
      */
 
     /**
      * @cfg {String} resizeHandles
-     * A valid {@link Ext.resizer.Resizer} handles config string (defaults to 'all').  Only applies when resizable = true.
+     * A valid {@link Ext.resizer.Resizer} handles config string. Only applies when resizable = true.
      */
     resizeHandles: 'all',
 
     /**
-     * @cfg {Boolean} autoScroll
-     * <code>true</code> to use overflow:'auto' on the components layout element and show scroll bars automatically when
-     * necessary, <code>false</code> to clip any overflowing content (defaults to <code>false</code>).
+     * @cfg {Boolean} [autoScroll=false]
+     * `true` to use overflow:'auto' on the components layout element and show scroll bars automatically when necessary,
+     * `false` to clip any overflowing content.
      */
 
     /**
      * @cfg {Boolean} floating
-     * <p>Specify as true to float the Component outside of the document flow using CSS absolute positioning.</p>
-     * <p>Components such as {@link Ext.window.Window Window}s and {@link Ext.menu.Menu Menu}s are floating
-     * by default.</p>
-     * <p>Floating Components that are programatically {@link Ext.Component#render rendered} will register themselves with the global
-     * {@link Ext.WindowManager ZIndexManager}</p>
-     * <h3 class="pa">Floating Components as child items of a Container</h3>
-     * <p>A floating Component may be used as a child item of a Container. This just allows the floating Component to seek a ZIndexManager by
-     * examining the ownerCt chain.</p>
-     * <p>When configured as floating, Components acquire, at render time, a {@link Ext.ZIndexManager ZIndexManager} which manages a stack
-     * of related floating Components. The ZIndexManager brings a single floating Component to the top of its stack when
-     * the Component's {@link #toFront} method is called.</p>
-     * <p>The ZIndexManager is found by traversing up the {@link #ownerCt} chain to find an ancestor which itself is floating. This is so that
-     * descendant floating Components of floating <i>Containers</i> (Such as a ComboBox dropdown within a Window) can have its zIndex managed relative
-     * to any siblings, but always <b>above</b> that floating ancestor Container.</p>
-     * <p>If no floating ancestor is found, a floating Component registers itself with the default {@link Ext.WindowManager ZIndexManager}.</p>
-     * <p>Floating components <i>do not participate in the Container's layout</i>. Because of this, they are not rendered until you explicitly
-     * {@link #show} them.</p>
-     * <p>After rendering, the ownerCt reference is deleted, and the {@link #floatParent} property is set to the found floating ancestor Container.
-     * If no floating ancestor Container was found the {@link #floatParent} property will not be set.</p>
+     * Specify as true to float the Component outside of the document flow using CSS absolute positioning.
+     *
+     * Components such as {@link Ext.window.Window Window}s and {@link Ext.menu.Menu Menu}s are floating by default.
+     *
+     * Floating Components that are programatically {@link Ext.Component#render rendered} will register themselves with
+     * the global {@link Ext.WindowManager ZIndexManager}
+     *
+     * ### Floating Components as child items of a Container
+     *
+     * A floating Component may be used as a child item of a Container. This just allows the floating Component to seek
+     * a ZIndexManager by examining the ownerCt chain.
+     *
+     * When configured as floating, Components acquire, at render time, a {@link Ext.ZIndexManager ZIndexManager} which
+     * manages a stack of related floating Components. The ZIndexManager brings a single floating Component to the top
+     * of its stack when the Component's {@link #toFront} method is called.
+     *
+     * The ZIndexManager is found by traversing up the {@link #ownerCt} chain to find an ancestor which itself is
+     * floating. This is so that descendant floating Components of floating _Containers_ (Such as a ComboBox dropdown
+     * within a Window) can have its zIndex managed relative to any siblings, but always **above** that floating
+     * ancestor Container.
+     *
+     * If no floating ancestor is found, a floating Component registers itself with the default {@link Ext.WindowManager
+     * ZIndexManager}.
+     *
+     * Floating components _do not participate in the Container's layout_. Because of this, they are not rendered until
+     * you explicitly {@link #show} them.
+     *
+     * After rendering, the ownerCt reference is deleted, and the {@link #floatParent} property is set to the found
+     * floating ancestor Container. If no floating ancestor Container was found the {@link #floatParent} property will
+     * not be set.
      */
     floating: false,
 
     /**
      * @cfg {Boolean} toFrontOnShow
-     * <p>True to automatically call {@link #toFront} when the {@link #show} method is called
-     * on an already visible, floating component (default is <code>true</code>).</p>
+     * True to automatically call {@link #toFront} when the {@link #show} method is called on an already visible,
+     * floating component.
      */
     toFrontOnShow: true,
 
     /**
-     * <p>Optional. Only present for {@link #floating} Components after they have been rendered.</p>
-     * <p>A reference to the ZIndexManager which is managing this Component's z-index.</p>
-     * <p>The {@link Ext.ZIndexManager ZIndexManager} maintains a stack of floating Component z-indices, and also provides a single modal
-     * mask which is insert just beneath the topmost visible modal floating Component.</p>
-     * <p>Floating Components may be {@link #toFront brought to the front} or {@link #toBack sent to the back} of the z-index stack.</p>
-     * <p>This defaults to the global {@link Ext.WindowManager ZIndexManager} for floating Components that are programatically
-     * {@link Ext.Component#render rendered}.</p>
-     * <p>For {@link #floating} Components which are added to a Container, the ZIndexManager is acquired from the first ancestor Container found
-     * which is floating, or if not found the global {@link Ext.WindowManager ZIndexManager} is used.</p>
-     * <p>See {@link #floating} and {@link #floatParent}</p>
-     * @property zIndexManager
-     * @type Ext.ZIndexManager
+     * @property {Ext.ZIndexManager} zIndexManager
+     * Only present for {@link #floating} Components after they have been rendered.
+     *
+     * A reference to the ZIndexManager which is managing this Component's z-index.
+     *
+     * The {@link Ext.ZIndexManager ZIndexManager} maintains a stack of floating Component z-indices, and also provides
+     * a single modal mask which is insert just beneath the topmost visible modal floating Component.
+     *
+     * Floating Components may be {@link #toFront brought to the front} or {@link #toBack sent to the back} of the
+     * z-index stack.
+     *
+     * This defaults to the global {@link Ext.WindowManager ZIndexManager} for floating Components that are
+     * programatically {@link Ext.Component#render rendered}.
+     *
+     * For {@link #floating} Components which are added to a Container, the ZIndexManager is acquired from the first
+     * ancestor Container found which is floating, or if not found the global {@link Ext.WindowManager ZIndexManager} is
+     * used.
+     *
+     * See {@link #floating} and {@link #floatParent}
      */
 
-     /**
-      * <p>Optional. Only present for {@link #floating} Components which were inserted as descendant items of floating Containers.</p>
-      * <p>Floating Components that are programatically {@link Ext.Component#render rendered} will not have a <code>floatParent</code> property.</p>
-      * <p>For {@link #floating} Components which are child items of a Container, the floatParent will be the floating ancestor Container which is
-      * responsible for the base z-index value of all its floating descendants. It provides a {@link Ext.ZIndexManager ZIndexManager} which provides
-      * z-indexing services for all its descendant floating Components.</p>
-      * <p>For example, the dropdown {@link Ext.view.BoundList BoundList} of a ComboBox which is in a Window will have the Window as its
-      * <code>floatParent</code></p>
-      * <p>See {@link #floating} and {@link #zIndexManager}</p>
-      * @property floatParent
-      * @type Ext.Container
-      */
+    /**
+     * @property {Ext.Container} floatParent
+     * Only present for {@link #floating} Components which were inserted as descendant items of floating Containers.
+     *
+     * Floating Components that are programatically {@link Ext.Component#render rendered} will not have a `floatParent`
+     * property.
+     *
+     * For {@link #floating} Components which are child items of a Container, the floatParent will be the floating
+     * ancestor Container which is responsible for the base z-index value of all its floating descendants. It provides
+     * a {@link Ext.ZIndexManager ZIndexManager} which provides z-indexing services for all its descendant floating
+     * Components.
+     *
+     * For example, the dropdown {@link Ext.view.BoundList BoundList} of a ComboBox which is in a Window will have the
+     * Window as its `floatParent`
+     *
+     * See {@link #floating} and {@link #zIndexManager}
+     */
 
     /**
-     * @cfg {Mixed} draggable
-     * <p>Specify as true to make a {@link #floating} Component draggable using the Component's encapsulating element as the drag handle.</p>
-     * <p>This may also be specified as a config object for the {@link Ext.util.ComponentDragger ComponentDragger} which is instantiated to perform dragging.</p>
-     * <p>For example to create a Component which may only be dragged around using a certain internal element as the drag handle,
-     * use the delegate option:</p>
-     * <code><pre>
-new Ext.Component({
-    constrain: true,
-    floating:true,
-    style: {
-        backgroundColor: '#fff',
-        border: '1px solid black'
-    },
-    html: '&lt;h1 style="cursor:move"&gt;The title&lt;/h1&gt;&lt;p&gt;The content&lt;/p&gt;',
-    draggable: {
-        delegate: 'h1'
-    }
-}).show();
-</pre></code>
+     * @cfg {Boolean/Object} [draggable=false]
+     * Specify as true to make a {@link #floating} Component draggable using the Component's encapsulating element as
+     * the drag handle.
+     *
+     * This may also be specified as a config object for the {@link Ext.util.ComponentDragger ComponentDragger} which is
+     * instantiated to perform dragging.
+     *
+     * For example to create a Component which may only be dragged around using a certain internal element as the drag
+     * handle, use the delegate option:
+     *
+     *     new Ext.Component({
+     *         constrain: true,
+     *         floating: true,
+     *         style: {
+     *             backgroundColor: '#fff',
+     *             border: '1px solid black'
+     *         },
+     *         html: '<h1 style="cursor:move">The title</h1><p>The content</p>',
+     *         draggable: {
+     *             delegate: 'h1'
+     *         }
+     *     }).show();
      */
 
     /**
-     * @cfg {Boolean} maintainFlex
-     * <p><b>Only valid when a sibling element of a {@link Ext.resizer.Splitter Splitter} within a {@link Ext.layout.container.VBox VBox} or
-     * {@link Ext.layout.container.HBox HBox} layout.</b></p>
-     * <p>Specifies that if an immediate sibling Splitter is moved, the Component on the <i>other</i> side is resized, and this
-     * Component maintains its configured {@link Ext.layout.container.Box#flex flex} value.</p>
+     * @cfg {Boolean} [maintainFlex=false]
+     * **Only valid when a sibling element of a {@link Ext.resizer.Splitter Splitter} within a
+     * {@link Ext.layout.container.VBox VBox} or {@link Ext.layout.container.HBox HBox} layout.**
+     *
+     * Specifies that if an immediate sibling Splitter is moved, the Component on the *other* side is resized, and this
+     * Component maintains its configured {@link Ext.layout.container.Box#flex flex} value.
      */
 
     hideMode: 'display',
@@ -295,13 +321,24 @@ new Ext.Component({
     //        disableFormats: true
     //    }
     //),
+
+    /**
+     * Creates new Component.
+     * @param {Ext.Element/String/Object} config The configuration options may be specified as either:
+     *
+     * - **an element** : it is set as the internal element and its id used as the component id
+     * - **a string** : it is assumed to be the id of an existing element and is used as the component id
+     * - **anything else** : it is assumed to be a standard config object and is applied to the component
+     */
     constructor: function(config) {
+        var me = this;
+
         config = config || {};
         if (config.initialConfig) {
 
             // Being initialized from an Ext.Action instance...
             if (config.isAction) {
-                this.baseAction = config;
+                me.baseAction = config;
             }
             config = config.initialConfig;
             // component cloning / action set up
@@ -314,18 +351,49 @@ new Ext.Component({
             };
         }
 
-        this.callParent([config]);
+        me.callParent([config]);
 
         // If we were configured from an instance of Ext.Action, (or configured with a baseAction option),
         // register this Component as one of its items
-        if (this.baseAction){
-            this.baseAction.addComponent(this);
+        if (me.baseAction){
+            me.baseAction.addComponent(me);
         }
     },
 
+    /**
+     * The initComponent template method is an important initialization step for a Component. It is intended to be
+     * implemented by each subclass of Ext.Component to provide any needed constructor logic. The
+     * initComponent method of the class being created is called first, with each initComponent method
+     * up the hierarchy to Ext.Component being called thereafter. This makes it easy to implement and,
+     * if needed, override the constructor logic of the Component at any step in the hierarchy.
+     *
+     * The initComponent method **must** contain a call to {@link Ext.Base#callParent callParent} in order
+     * to ensure that the parent class' initComponent method is also called.
+     *
+     * The following example demonstrates using a dynamic string for the text of a button at the time of
+     * instantiation of the class.
+     *
+     *     Ext.define('DynamicButtonText', {
+     *         extend: 'Ext.button.Button',
+     *
+     *         initComponent: function() {
+     *             this.text = new Date();
+     *             this.renderTo = Ext.getBody();
+     *             this.callParent();
+     *         }
+     *     });
+     *
+     *     Ext.onReady(function() {
+     *         Ext.create('DynamicButtonText');
+     *     });
+     *
+     * @template
+     */
     initComponent: function() {
         var me = this;
 
+        me.callParent();
+
         if (me.listeners) {
             me.on(me.listeners);
             delete me.listeners;
@@ -342,7 +410,7 @@ new Ext.Component({
         if (me.floating) {
             me.makeFloating(me.floating);
         } else {
-            me.el.setVisibilityMode(Ext.core.Element[me.hideMode.toUpperCase()]);
+            me.el.setVisibilityMode(Ext.Element[me.hideMode.toUpperCase()]);
         }
 
         if (Ext.isDefined(me.autoScroll)) {
@@ -401,14 +469,16 @@ new Ext.Component({
     },
 
     initResizable: function(resizable) {
+        var me = this;
+
         resizable = Ext.apply({
-            target: this,
+            target: me,
             dynamic: false,
-            constrainTo: this.constrainTo,
-            handles: this.resizeHandles
+            constrainTo: me.constrainTo || (me.floatParent ? me.floatParent.getTargetEl() : me.el.getScopeParent()),
+            handles: me.resizeHandles
         }, resizable);
-        resizable.target = this;
-        this.resizer = Ext.create('Ext.resizer.Resizer', resizable);
+        resizable.target = me;
+        me.resizer = Ext.create('Ext.resizer.Resizer', resizable);
     },
 
     getDragEl: function() {
@@ -418,9 +488,9 @@ new Ext.Component({
     initDraggable: function() {
         var me = this,
             ddConfig = Ext.applyIf({
-                el: this.getDragEl(),
-                constrainTo: me.constrainTo || (me.floatParent ? me.floatParent.getTargetEl() : me.el.dom.parentNode)
-            }, this.draggable);
+                el: me.getDragEl(),
+                constrainTo: me.constrain ? (me.constrainTo || (me.floatParent ? me.floatParent.getTargetEl() : me.el.getScopeParent())) : undefined
+            }, me.draggable);
 
         // Add extra configs if Component is specified to be constrained
         if (me.constrain || me.constrainDelegate) {
@@ -428,15 +498,16 @@ new Ext.Component({
             ddConfig.constrainDelegate = me.constrainDelegate;
         }
 
-        this.dd = Ext.create('Ext.util.ComponentDragger', this, ddConfig);
+        me.dd = Ext.create('Ext.util.ComponentDragger', me, ddConfig);
     },
 
     /**
-     * Sets the left and top of the component.  To set the page XY position instead, use {@link #setPagePosition}.
-     * This method fires the {@link #move} event.
+     * Sets the left and top of the component. To set the page XY position instead, use {@link #setPagePosition}. This
+     * method fires the {@link #move} event.
      * @param {Number} left The new left
      * @param {Number} top The new top
-     * @param {Mixed} animate If true, the Component is <i>animated</i> into its new position. You may also pass an animation configuration.
+     * @param {Boolean/Object} [animate] If true, the Component is _animated_ into its new position. You may also pass an
+     * animation configuration.
      * @return {Ext.Component} this
      */
     setPosition: function(x, y, animate) {
@@ -498,30 +569,60 @@ new Ext.Component({
     },
 
     /**
-     * @private Template method called after a Component has been positioned.
+     * @private
+     * @template
+     * Template method called after a Component has been positioned.
      */
     afterSetPosition: function(ax, ay) {
         this.onPosition(ax, ay);
         this.fireEvent('move', this, ax, ay);
     },
 
+    /**
+     * Displays component at specific xy position.
+     * A floating component (like a menu) is positioned relative to its ownerCt if any.
+     * Useful for popping up a context menu:
+     *
+     *     listeners: {
+     *         itemcontextmenu: function(view, record, item, index, event, options) {
+     *             Ext.create('Ext.menu.Menu', {
+     *                 width: 100,
+     *                 height: 100,
+     *                 margin: '0 0 10 0',
+     *                 items: [{
+     *                     text: 'regular item 1'
+     *                 },{
+     *                     text: 'regular item 2'
+     *                 },{
+     *                     text: 'regular item 3'
+     *                 }]
+     *             }).showAt(event.getXY());
+     *         }
+     *     }
+     *
+     * @param {Number} x The new x position
+     * @param {Number} y The new y position
+     * @param {Boolean/Object} [animate] True to animate the Component into its new position. You may also pass an
+     * animation configuration.
+     */
     showAt: function(x, y, animate) {
-        // A floating Component is positioned relative to its ownerCt if any.
-        if (this.floating) {
-            this.setPosition(x, y, animate);
+        var me = this;
+
+        if (me.floating) {
+            me.setPosition(x, y, animate);
         } else {
-            this.setPagePosition(x, y, animate);
+            me.setPagePosition(x, y, animate);
         }
-        this.show();
+        me.show();
     },
 
     /**
-     * Sets the page XY position of the component.  To set the left and top instead, use {@link #setPosition}.
+     * Sets the page XY position of the component. To set the left and top instead, use {@link #setPosition}.
      * This method fires the {@link #move} event.
      * @param {Number} x The new x position
      * @param {Number} y The new y position
-     * @param {Mixed} animate If passed, the Component is <i>animated</i> into its new position. If this parameter
-     * is a number, it is used as the animation duration in milliseconds.
+     * @param {Boolean/Object} [animate] True to animate the Component into its new position. You may also pass an
+     * animation configuration.
      * @return {Ext.Component} this
      */
     setPagePosition: function(x, y, animate) {
@@ -554,15 +655,16 @@ new Ext.Component({
 
     /**
      * Gets the current box measurements of the component's underlying element.
-     * @param {Boolean} local (optional) If true the element's left and top are returned instead of page XY (defaults to false)
+     * @param {Boolean} [local=false] If true the element's left and top are returned instead of page XY.
      * @return {Object} box An object in the format {x, y, width, height}
      */
     getBox : function(local){
-        var pos = this.getPosition(local);
-        var s = this.getSize();
-        s.x = pos[0];
-        s.y = pos[1];
-        return s;
+        var pos = this.getPosition(local),
+            size = this.getSize();
+
+        size.x = pos[0];
+        size.y = pos[1];
+        return size;
     },
 
     /**
@@ -585,22 +687,6 @@ new Ext.Component({
         };
     },
 
-    // private
-    adjustSize: function(w, h) {
-        if (this.autoWidth) {
-            w = 'auto';
-        }
-
-        if (this.autoHeight) {
-            h = 'auto';
-        }
-
-        return {
-            width: w,
-            height: h
-        };
-    },
-
     // private
     adjustPosition: function(x, y) {
 
@@ -619,30 +705,40 @@ new Ext.Component({
 
     /**
      * Gets the current XY position of the component's underlying element.
-     * @param {Boolean} local (optional) If true the element's left and top are returned instead of page XY (defaults to false)
-     * @return {Array} The XY position of the element (e.g., [100, 200])
+     * @param {Boolean} [local=false] If true the element's left and top are returned instead of page XY.
+     * @return {Number[]} The XY position of the element (e.g., [100, 200])
      */
     getPosition: function(local) {
-        var el = this.el,
-            xy;
+        var me = this,
+            el = me.el,
+            xy,
+            o;
 
-        if (local === true) {
+        // Floating Components which were just rendered with no ownerCt return local position.
+        if ((local === true) || (me.floating && !me.floatParent)) {
             return [el.getLeft(true), el.getTop(true)];
         }
-        xy = this.xy || el.getXY();
+        xy = me.xy || el.getXY();
 
         // Floating Components in an ownerCt have to have their positions made relative
-        if (this.floating && this.floatParent) {
-            var o = this.floatParent.getTargetEl().getViewRegion();
+        if (me.floating) {
+            o = me.floatParent.getTargetEl().getViewRegion();
             xy[0] -= o.left;
             xy[1] -= o.top;
         }
         return xy;
     },
 
-    // Todo: add in xtype prefix support
     getId: function() {
-        return this.id || (this.id = (this.getXType() || 'ext-comp') + '-' + this.getAutoId());
+        var me = this,
+            xtype;
+
+        if (!me.id) {
+            xtype = me.getXType();
+            xtype = xtype ? xtype.replace(Ext.Component.INVALID_ID_CHARS_Re, '-') : 'ext-comp';
+            me.id = xtype + '-' + me.getAutoId();
+        }
+        return me.id;
     },
 
     onEnable: function() {
@@ -660,42 +756,47 @@ new Ext.Component({
     },
 
     /**
-     * <p>Shows this Component, rendering it first if {@link #autoRender} or {@link #floating} are <code>true</code>.</p>
-     * <p>After being shown, a {@link #floating} Component (such as a {@link Ext.window.Window}), is activated it and brought to the front of
-     * its {@link #zIndexManager z-index stack}.</p>
-     * @param {String/Element} animateTarget Optional, and <b>only valid for {@link #floating} Components such as
-     * {@link Ext.window.Window Window}s or {@link Ext.tip.ToolTip ToolTip}s, or regular Components which have been configured
-     * with <code>floating: true</code>.</b> The target from which the Component should
-     * animate from while opening (defaults to null with no animation)
-     * @param {Function} callback (optional) A callback function to call after the Component is displayed. Only necessary if animation was specified.
-     * @param {Object} scope (optional) The scope (<code>this</code> reference) in which the callback is executed. Defaults to this Component.
-     * @return {Component} this
+     * Shows this Component, rendering it first if {@link #autoRender} or {@link #floating} are `true`.
+     *
+     * After being shown, a {@link #floating} Component (such as a {@link Ext.window.Window}), is activated it and
+     * brought to the front of its {@link #zIndexManager z-index stack}.
+     *
+     * @param {String/Ext.Element} [animateTarget=null] **only valid for {@link #floating} Components such as {@link
+     * Ext.window.Window Window}s or {@link Ext.tip.ToolTip ToolTip}s, or regular Components which have been configured
+     * with `floating: true`.** The target from which the Component should animate from while opening.
+     * @param {Function} [callback] A callback function to call after the Component is displayed.
+     * Only necessary if animation was specified.
+     * @param {Object} [scope] The scope (`this` reference) in which the callback is executed.
+     * Defaults to this Component.
+     * @return {Ext.Component} this
      */
     show: function(animateTarget, cb, scope) {
-        if (this.rendered && this.isVisible()) {
-            if (this.toFrontOnShow && this.floating) {
-                this.toFront();
+        var me = this;
+
+        if (me.rendered && me.isVisible()) {
+            if (me.toFrontOnShow && me.floating) {
+                me.toFront();
             }
-        } else if (this.fireEvent('beforeshow', this) !== false) {
-            this.hidden = false;
+        } else if (me.fireEvent('beforeshow', me) !== false) {
+            me.hidden = false;
 
             // Render on first show if there is an autoRender config, or if this is a floater (Window, Menu, BoundList etc).
-            if (!this.rendered && (this.autoRender || this.floating)) {
-                this.doAutoRender();
+            if (!me.rendered && (me.autoRender || me.floating)) {
+                me.doAutoRender();
             }
-            if (this.rendered) {
-                this.beforeShow();
-                this.onShow.apply(this, arguments);
+            if (me.rendered) {
+                me.beforeShow();
+                me.onShow.apply(me, arguments);
 
                 // Notify any owning Container unless it's suspended.
                 // Floating Components do not participate in layouts.
-                if (this.ownerCt && !this.floating && !(this.ownerCt.suspendLayout || this.ownerCt.layout.layoutBusy)) {
-                    this.ownerCt.doLayout();
+                if (me.ownerCt && !me.floating && !(me.ownerCt.suspendLayout || me.ownerCt.layout.layoutBusy)) {
+                    me.ownerCt.doLayout();
                 }
-                this.afterShow.apply(this, arguments);
+                me.afterShow.apply(me, arguments);
             }
         }
-        return this;
+        return me;
     },
 
     beforeShow: Ext.emptyFn,
@@ -705,10 +806,10 @@ new Ext.Component({
         var me = this;
 
         me.el.show();
-        if (this.floating && this.constrain) {
-            this.doConstrain();
-        }
         me.callParent(arguments);
+        if (me.floating && me.constrain) {
+            me.doConstrain();
+        }
     },
 
     afterShow: function(animateTarget, cb, scope) {
@@ -729,14 +830,13 @@ new Ext.Component({
             animateTarget = animateTarget.el ? animateTarget.el : Ext.get(animateTarget);
             toBox = me.el.getBox();
             fromBox = animateTarget.getBox();
-            fromBox.width += 'px';
-            fromBox.height += 'px';
-            toBox.width += 'px';
-            toBox.height += 'px';
             me.el.addCls(Ext.baseCSSPrefix + 'hide-offsets');
             ghostPanel = me.ghost();
             ghostPanel.el.stopAnimation();
 
+            // Shunting it offscreen immediately, *before* the Animation class grabs it ensure no flicker.
+            ghostPanel.el.setX(-10000);
+
             ghostPanel.el.animate({
                 from: fromBox,
                 to: toBox,
@@ -745,52 +845,55 @@ new Ext.Component({
                         delete ghostPanel.componentLayout.lastComponentSize;
                         me.unghost();
                         me.el.removeCls(Ext.baseCSSPrefix + 'hide-offsets');
-                        if (me.floating) {
-                            me.toFront();
-                        }
-                        Ext.callback(cb, scope || me);
+                        me.onShowComplete(cb, scope);
                     }
                 }
             });
         }
         else {
-            if (me.floating) {
-                me.toFront();
-            }
-            Ext.callback(cb, scope || me);
+            me.onShowComplete(cb, scope);
         }
+    },
+
+    onShowComplete: function(cb, scope) {
+        var me = this;
+        if (me.floating) {
+            me.toFront();
+        }
+        Ext.callback(cb, scope || me);
         me.fireEvent('show', me);
     },
 
     /**
      * Hides this Component, setting it to invisible using the configured {@link #hideMode}.
-     * @param {String/Element/Component} animateTarget Optional, and <b>only valid for {@link #floating} Components such as
-     * {@link Ext.window.Window Window}s or {@link Ext.tip.ToolTip ToolTip}s, or regular Components which have been configured
-     * with <code>floating: true</code>.</b>.
-     * The target to which the Component should animate while hiding (defaults to null with no animation)
-     * @param {Function} callback (optional) A callback function to call after the Component is hidden.
-     * @param {Object} scope (optional) The scope (<code>this</code> reference) in which the callback is executed. Defaults to this Component.
+     * @param {String/Ext.Element/Ext.Component} [animateTarget=null] **only valid for {@link #floating} Components
+     * such as {@link Ext.window.Window Window}s or {@link Ext.tip.ToolTip ToolTip}s, or regular Components which have
+     * been configured with `floating: true`.**. The target to which the Component should animate while hiding.
+     * @param {Function} [callback] A callback function to call after the Component is hidden.
+     * @param {Object} [scope] The scope (`this` reference) in which the callback is executed.
+     * Defaults to this Component.
      * @return {Ext.Component} this
      */
     hide: function() {
+        var me = this;
 
         // Clear the flag which is set if a floatParent was hidden while this is visible.
         // If a hide operation was subsequently called, that pending show must be hidden.
-        this.showOnParentShow = false;
+        me.showOnParentShow = false;
 
-        if (!(this.rendered && !this.isVisible()) && this.fireEvent('beforehide', this) !== false) {
-            this.hidden = true;
-            if (this.rendered) {
-                this.onHide.apply(this, arguments);
+        if (!(me.rendered && !me.isVisible()) && me.fireEvent('beforehide', me) !== false) {
+            me.hidden = true;
+            if (me.rendered) {
+                me.onHide.apply(me, arguments);
 
                 // Notify any owning Container unless it's suspended.
                 // Floating Components do not participate in layouts.
-                if (this.ownerCt && !this.floating && !(this.ownerCt.suspendLayout || this.ownerCt.layout.layoutBusy)) {
-                    this.ownerCt.doLayout();
+                if (me.ownerCt && !me.floating && !(me.ownerCt.suspendLayout || me.ownerCt.layout.layoutBusy)) {
+                    me.ownerCt.doLayout();
                 }
             }
         }
-        return this;
+        return me;
     },
 
     // Possibly animate down to a target element.
@@ -838,6 +941,7 @@ new Ext.Component({
 
     /**
      * @private
+     * @template
      * Template method to contribute functionality at destroy time.
      */
     onDestroy: function() {
@@ -847,6 +951,7 @@ new Ext.Component({
         if (me.rendered) {
             Ext.destroy(
                 me.proxy,
+                me.proxyWrap,
                 me.resizer
             );
             // Different from AbstractComponent
@@ -869,8 +974,8 @@ new Ext.Component({
 
     /**
      * Try to focus this component.
-     * @param {Boolean} selectText (optional) If applicable, true to also select the text in this component
-     * @param {Boolean/Number} delay (optional) Delay the focus this number of milliseconds (true for 10 milliseconds).
+     * @param {Boolean} [selectText] If applicable, true to also select the text in this component
+     * @param {Boolean/Number} [delay] Delay the focus this number of milliseconds (true for 10 milliseconds).
      * @return {Ext.Component} this
      */
     focus: function(selectText, delay) {
@@ -907,7 +1012,7 @@ new Ext.Component({
      * Returns the focus holder element associated with this Component. By default, this is the Component's encapsulating
      * element. Subclasses which use embedded focusable elements (such as Window and Button) should override this for use
      * by the {@link #focus} method.
-     * @returns {Ext.core.Element} the focus holing element.
+     * @returns {Ext.Element} the focus holing element.
      */
     getFocusEl: function() {
         return this.el;
@@ -966,23 +1071,25 @@ new Ext.Component({
      */
     cloneConfig: function(overrides) {
         overrides = overrides || {};
-        var id = overrides.id || Ext.id();
-        var cfg = Ext.applyIf(overrides, this.initialConfig);
+        var id = overrides.id || Ext.id(),
+            cfg = Ext.applyIf(overrides, this.initialConfig),
+            self;
+
         cfg.id = id;
 
-        var self = Ext.getClass(this);
+        self = Ext.getClass(this);
 
         // prevent dup id
         return new self(cfg);
     },
 
     /**
-     * Gets the xtype for this component as registered with {@link Ext.ComponentManager}. For a list of all
-     * available xtypes, see the {@link Ext.Component} header. Example usage:
-     * <pre><code>
-var t = new Ext.form.field.Text();
-alert(t.getXType());  // alerts 'textfield'
-</code></pre>
+     * Gets the xtype for this component as registered with {@link Ext.ComponentManager}. For a list of all available
+     * xtypes, see the {@link Ext.Component} header. Example usage:
+     *
+     *     var t = new Ext.form.field.Text();
+     *     alert(t.getXType());  // alerts 'textfield'
+     *
      * @return {String} The xtype
      */
     getXType: function() {
@@ -990,8 +1097,8 @@ alert(t.getXType());  // alerts 'textfield'
     },
 
     /**
-     * Find a container above this component at any level by a custom function. If the passed function returns
-     * true, the container will be returned.
+     * Find a container above this component at any level by a custom function. If the passed function returns true, the
+     * container will be returned.
      * @param {Function} fn The custom function to call with the arguments (container, this component).
      * @return {Ext.container.Container} The first Container for which the custom function returns true
      */
@@ -1004,9 +1111,11 @@ alert(t.getXType());  // alerts 'textfield'
     },
 
     /**
-     * <p>Find a container above this component at any level by xtype or class</p>
-     * <p>See also the {@link Ext.Component#up up} method.</p>
-     * @param {String/Class} xtype The xtype string for a component, or the class of the component directly
+     * Find a container above this component at any level by xtype or class
+     *
+     * See also the {@link Ext.Component#up up} method.
+     *
+     * @param {String/Ext.Class} xtype The xtype string for a component, or the class of the component directly
      * @return {Ext.container.Container} The first Container which matches the given xtype or class
      */
     findParentByType: function(xtype) {
@@ -1019,13 +1128,13 @@ alert(t.getXType());  // alerts 'textfield'
     },
 
     /**
-     * Bubbles up the component/container heirarchy, calling the specified function with each component. The scope (<i>this</i>) of
-     * function call will be the scope provided or the current component. The arguments to the function
-     * will be the args provided or the current component. If the function returns false at any point,
-     * the bubble is stopped.
+     * Bubbles up the component/container heirarchy, calling the specified function with each component. The scope
+     * (*this*) of function call will be the scope provided or the current component. The arguments to the function will
+     * be the args provided or the current component. If the function returns false at any point, the bubble is stopped.
+     *
      * @param {Function} fn The function to call
-     * @param {Object} scope (optional) The scope of the function (defaults to current node)
-     * @param {Array} args (optional) The args to call the function with (default to passing the current component)
+     * @param {Object} [scope] The scope of the function. Defaults to current node.
+     * @param {Array} [args] The args to call the function with. Defaults to passing the current component.
      * @return {Ext.Component} this
      */
     bubble: function(fn, scope, args) {
@@ -1040,10 +1149,19 @@ alert(t.getXType());  // alerts 'textfield'
     },
 
     getProxy: function() {
-        if (!this.proxy) {
-            this.proxy = this.el.createProxy(Ext.baseCSSPrefix + 'proxy-el', Ext.getBody(), true);
+        var me = this,
+            target;
+
+        if (!me.proxy) {
+            target = Ext.getBody();
+            if (Ext.scopeResetCSS) {
+                me.proxyWrap = target = Ext.getBody().createChild({
+                    cls: Ext.baseCSSPrefix + 'reset'
+                });
+            }
+            me.proxy = me.el.createProxy(Ext.baseCSSPrefix + 'proxy-el', target, true);
         }
-        return this.proxy;
+        return me.proxy;
     }
 
 });