/**
 * Base class for all Ext components.
 *
 * The Component base class has built-in support for basic hide/show and enable/disable
 * and size control behavior.
 *
 * ## xtypes
 *
 * 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](../guides/core_concepts/components.html) for more information on xtypes
 * and the Component hierarchy.
 *
 * ## Finding components
 *
 * 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}.
 *
 * Additionally the {@link Ext.ComponentQuery} provides a CSS-selectors-like way to look
 * up components by their xtype and many other attributes.  For example the following code
 * will find all textfield components inside component with `id: 'myform'`:
 *
 *     Ext.ComponentQuery.query('#myform textfield');
 *
 * ## Extending Ext.Component
 *
 * All subclasses of Component may participate in the automated Ext component
 * life cycle 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#cfg-items items} config option at the time
 * the Container is created, or they may be added dynamically via the
 * {@link Ext.container.Container#method-add add} method.
 *
 * All user-developed visual widgets that are required to participate in automated
 * life cycle and size management should subclass Component.
 *
 * See the Creating new UI controls chapter in
 * [Component Guide](../guides/core_concepts/components.html) for details on how and to either
 * extend or augment Ext JS base classes to create custom Components.
 *
 * ## The Ext.Component class by itself
 *
 * Usually one doesn't need to instantiate the Ext.Component class. There are subclasses
 * which implement specialized use cases, covering most application needs. However it is
 * possible to instantiate a base Component, and it can be rendered to document, or handled
 * by 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},
 * {@link Ext.grid.Panel GridPanel}, or {@link Ext.tree.Panel TreePanel} be used.
 */
Ext.define('Ext.Component', {
    alternateClassName: 'Ext.AbstractComponent',
 
    xtype: [
        'component',
        'box'
    ],
 
    requires: [
        'Ext.ComponentQuery',
        'Ext.ComponentManager',
        'Ext.util.ProtoElement',
        'Ext.dom.CompositeElement',
        'Ext.plugin.Abstract',
        'Ext.plugin.Manager',
        'Ext.scroll.Scroller'
    ],
 
    // Note that Floating must be mixed in before Positionable.
    mixins: [
        'Ext.mixin.Inheritable',
        'Ext.util.Floating',
        'Ext.util.Positionable',
        'Ext.util.Observable',
        'Ext.mixin.ComponentDelegation',
        'Ext.mixin.Bindable',
        'Ext.util.Animate',
        'Ext.util.ElementContainer',
        'Ext.util.Renderable',
        'Ext.state.Stateful',
        'Ext.mixin.Focusable',
        'Ext.mixin.Accessible',
        'Ext.mixin.Keyboard'
    ],
 
    uses: [
        'Ext.overrides.*',
        'Ext.Element',
        'Ext.DomHelper',
        'Ext.XTemplate',
        'Ext.ComponentLoader',
        'Ext.layout.Context',
        'Ext.layout.Layout',
        'Ext.layout.component.Auto',
        'Ext.LoadMask',
        'Ext.ZIndexManager',
        'Ext.util.DelayedTask',
        'Ext.resizer.Resizer',
        'Ext.util.ComponentDragger'
    ],
 
    statics: {
        AUTO_ID: 1000,
 
        pendingLayouts: null,
 
        layoutSuspendCount: 0,
 
        // Collapse/expand directions
        DIRECTION_TOP: 'top',
        DIRECTION_RIGHT: 'right',
        DIRECTION_BOTTOM: 'bottom',
        DIRECTION_LEFT: 'left',
 
        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,
 
        /**
         * @property {String} ariaHighContrastModeCls CSS class to be applied
         * to the document body when High Contrast mode is detected in Windows.
         * @private
         */
        ariaHighContrastModeCls: Ext.baseCSSPrefix + 'aria-highcontrast',
 
        /**
         * Cancels layout of a component.
         * @param {Ext.Component} comp 
         * @param isDestroying
         */
        cancelLayout: function(comp, isDestroying) {
            var context = this.runningLayoutContext || this.pendingLayouts;
 
            if (context) {
                context.cancelComponent(comp, false, isDestroying);
            }
        },
 
        /**
         * Find the Widget or Component to which the given event/element belongs.
         *
         * @param {Ext.event.Event/Ext.dom.Element/HTMLElement} el The element or event
         * from which to start to find an owning Component.
         * @param {Ext.dom.Element/HTMLElement} [limit] The element at which to stop upward
         * searching for an owning Component, or the number of Components to traverse
         * before giving up. Defaults to the document's HTML element.
         * @param {String} [selector] An optional {@link Ext.ComponentQuery} selector to
         * filter the target.
         * @return {Ext.Component/null} Component, or null
         *
         * @since 6.5.0
         */
        from: function(el, limit, selector) {
            return Ext.ComponentManager.from(el, limit, selector);
        },
 
        /**
         * Find the Widget or Component to which the given Element belongs.
         *
         * @param {Ext.dom.Element/HTMLElement} el The element from which to start to find an owning
         * Component.
         * @param {Ext.dom.Element/HTMLElement} [limit] The element at which to stop upward
         * searching for an owning Component, or the number of Components to traverse
         * before giving up. Defaults to the document's HTML element.
         * @param {String} [selector] An optional {@link Ext.ComponentQuery} selector to filter
         * the target.
         * @return {Ext.Component/null} Component, or null
         *
         * @deprecated 6.5.0 Use {@link Ext.Component#method!from} instead.
         * @since 6.0.1
         */
        fromElement: function(el, limit, selector) {
            return Ext.ComponentManager.from(el, limit, selector);
        },
 
        /**
         * Performs all pending layouts that were scheduled while
         * {@link Ext.Component#suspendLayouts suspendLayouts} was in effect.
         * @static
         */
        flushLayouts: function() {
            var me = this,
                context = me.pendingLayouts;
 
            if (context && context.invalidQueue.length) {
                me.pendingLayouts = null;
                me.runningLayoutContext = context;
 
                Ext.override(context, {
                    runComplete: function() {
                        var Scroller = Ext.scroll.Scroller,
                            GlobalEvents = Ext.GlobalEvents,
                            result;
 
                        // we need to release the layout queue before running any of the
                        // finishedLayout calls because they call afterComponentLayout
                        // which can re-enter by calling updateLayout/doComponentLayout.
                        me.runningLayoutContext = null;
 
                        if (Scroller.viewport) {
                            Scroller.viewport.restoreState();
                        }
 
                        result = this.callParent(); // not "me" here!
 
                        if (GlobalEvents.hasListeners.afterlayout) {
                            GlobalEvents.fireEvent('afterlayout');
                        }
 
                        return result;
                    }
                });
 
                context.run();
            }
        },
 
        /**
         * Resumes layout activity in the whole framework.
         *
         * {@link Ext#suspendLayouts} is alias of {@link Ext.Component#suspendLayouts}.
         *
         * @param {Boolean} [flush=false] `true` to perform all the pending layouts. This can also
         * be achieved by calling {@link Ext.Component#flushLayouts flushLayouts} directly.
         * @static
         */
        resumeLayouts: function(flush) {
            if (this.layoutSuspendCount && ! --this.layoutSuspendCount) {
                if (flush) {
                    this.flushLayouts();
                }
 
                if (Ext.GlobalEvents.hasListeners.resumelayouts) {
                    Ext.GlobalEvents.fireEvent('resumelayouts');
                }
            }
        },
 
        /**
         * Stops layouts from happening in the whole framework.
         *
         * It's useful to suspend the layout activity while updating multiple components and
         * containers:
         *
         *     Ext.suspendLayouts();
         *     // batch of updates...
         *     Ext.resumeLayouts(true);
         *
         * {@link Ext#suspendLayouts} is alias of {@link Ext.Component#suspendLayouts}.
         *
         * See also {@link Ext#batchLayouts} for more abstract way of doing this.
         *
         * @static
         */
        suspendLayouts: function() {
            ++this.layoutSuspendCount;
        },
 
        /**
         * Updates layout of a component.
         *
         * @param {Ext.Component} comp The component to update.
         * @param {Boolean} [defer=false] `true` to just queue the layout if this component.
         * @static
         */
        updateLayout: function(comp, defer) {
            var me = this,
                running = me.runningLayoutContext,
                pending;
 
            if (running) {
                running.queueInvalidate(comp);
            }
            else {
                pending = me.pendingLayouts || (me.pendingLayouts = new Ext.layout.Context());
                pending.queueInvalidate(comp);
 
                if (!defer && !me.layoutSuspendCount && !comp.isLayoutSuspended()) {
                    me.flushLayouts();
                }
            }
        }
    },
 
    // <editor-fold desc="Config">
    // ***********************************************************************************
    // Begin Config
    // ***********************************************************************************
 
    // We do not want "_hidden" style backing properties.
    $configPrefixed: false,
    // We also want non-config system properties to go to the instance.
    $configStrict: false,
 
    clearPropertiesOnDestroy: 'async',
 
    manageLayoutScroll: true,
 
    config: {
        /**
         * @cfg {Object} data
         * The initial set of data to apply to the `{@link #tpl}` to update the content
         * area of the Component.
         *
         * @accessor
         * @since 3.4.0
         */
        data: null,
 
        /**
         * @cfg {Boolean} modelValidation
         * This config enables binding to your `{@link Ext.data.Model#validators}`. This
         * is only processed by form fields (e.g., `Ext.form.field.Text`) at present, but
         * this setting is inherited and so can be set on a parent container.
         *
         * When set to `true` by a component or not set by a component but inherited from
         * an ancestor container, `Ext.data.Validation` records are used to automatically
         * bind validation results for any form field to which a `value` is bound.
         *
         * While this config can be set arbitrarily high in the component hierarchy, doing
         * so can create a lot overhead if most of your form fields do not actually rely on
         * `validators` in your data model.
         *
         * Using this setting for a form that is bound to an `Ext.data.Model` might look
         * like this:
         *
         *      {
         *          xtype: 'panel',
         *          modelValidation: true,
         *          items: [{
         *              xtype: 'textfield',
         *              bind: '{theUser.firstName}'
         *          },{
         *              xtype: 'textfield',
         *              bind: '{theUser.lastName}'
         *          },{
         *              xtype: 'textfield',
         *              bind: '{theUser.phoneNumber}'
         *          },{
         *              xtype: 'textfield',
         *              bind: '{theUser.email}'
         *          }]
         *      }
         *
         * Notice that "validation" is a pseudo-association defined for all entities. See
         * `{@link Ext.data.Model#getValidation}` for further details.
         */
 
        /**
         * @cfg {Number} maxHeight
         * The maximum value in pixels which this Component will set its height to.
         *
         * **Warning:** This will override any size management applied by layout managers.
         */
        maxHeight: null,
 
        /**
         * @cfg {Number} maxWidth
         * The maximum value in pixels which this Component will set its width to.
         *
         * **Warning:** This will override any size management applied by layout managers.
         */
        maxWidth: null,
 
        /**
         * @cfg {Number} minHeight
         * The minimum value in pixels which this Component will set its height to.
         *
         * **Warning:** This will override any size management applied by layout managers.
         */
        minHeight: null,
 
        /**
         * @cfg {Number} minWidth
         * The minimum value in pixels which this Component will set its width to.
         *
         * **Warning:** This will override any size management applied by layout managers.
         */
        minWidth: null,
 
        /**
         * @cfg {Boolean/String/Object} scrollable
         * Configuration options to make this Component scrollable. Acceptable values are:
         *
         * - `true` to enable auto scrolling.
         * - `false` (or `null`) to disable scrolling - this is the default.
         * - `x` or `horizontal` to enable horizontal scrolling only
         * - `y` or `vertical` to enable vertical scrolling only
         *
         * Also accepts a configuration object for a `{@link Ext.scroll.Scroller}` if
         * if advanced configuration is needed.
         *
         * The getter for this config returns the {@link Ext.scroll.Scroller Scroller}
         * instance.  You can use the Scroller API to read or manipulate the scroll position:
         *
         *     // scrolls the component to 5 on the x axis and 10 on the y axis
         *     component.getScrollable().scrollTo(5, 10);
         */
        scrollable: null
    },
 
    /**
     * @cfg {Object} renderConfig
     * renderConfig wraps configs that do not get applied until after the component is
     * rendered. Unlike normal config system properties, renderConfigs use a special
     * setter method to store values on the instance instead of running the apply and
     * update methods if it is called before the component is rendered. Then, after the
     * component has been rendered, these values are processed by the normal apply and
     * update method for the config.
     *
     * This means that calling the get method for the config prior to render will return
     * whatever raw value has been set, while calling the getter after render will return
     * the value after processing by the config's apply method. If this distinction needs
     * to be made, it is the caller's responsibility to check for the rendered state and
     * handle such intermediate config values.
     */
    renderConfig: {
        /**
         * @cfg {Object} touchAction
         *
         * Emulates the behavior of the CSS
         * [touch-action](https://www.w3.org/TR/pointerevents/#the-touch-action-css-property)
         * property in a cross-browser compatible manner.
         *
         * Keys in this object are touch action names, and values are `false` to disable
         * a touch action or `true` to enable it.  Accepted keys are:
         *
         * - `panX`
         * - `panY`
         * - `pinchZoom`
         * - `doubleTapZoom`
         *
         * All touch actions are enabled (`true`) by default, so it is usually only necessary
         * to specify which touch actions to disable.  For example, the following disables
         * only horizontal scrolling and pinch-to-zoom on the component's main element:
         *
         *     touchAction: {
         *         panX: false,
         *         pinchZoom: false
         *     }
         *
         * Touch actions can be specified on child elements using the child element name,
         * for example:
         *
         *     // disables horizontal scrolling on the main element, and double-tap-zoom
         *     // on the child element named "body"
         *     touchAction: {
         *         panY: false
         *         body: {
         *             doubleTapZoom: false
         *         }
         *     }
         *
         * The primary motivation for setting the touch-action of an element is to prevent
         * the browser's default handling of a gesture such as pinch-to-zoom, or
         * drag-to-scroll, so that the application can implement its own handling of that
         * gesture on the element.  Suppose, for example, a component has a custom drag
         * handler on its element and wishes to prevent horizontal scrolling of its container
         * while it is being dragged:
         *
         *     Ext.create('Ext.Component', {
         *         touchAction: {
         *             panX: false
         *         },
         *         listeners: {
         *             drag: function(e) {
         *                 // implement drag logic
         *             }
         *         }
         *     });
         */
        touchAction: null
    },
 
    /**
     * @property defaultBindProperty
     * @inheritdoc
     */
    defaultBindProperty: 'html',
 
    /**
     * @cfg {String} alignTarget
     * A Component or Element by which to position this component according to the
     * {@link #defaultAlign}. Defaults to the owning Container.
     *
     * *Only applicable if this component is {@link #cfg-floating}*
     *
     * *Used upon first show*.
     */
    alignTarget: null,
 
    /**
     * @cfg anchor
     * @inheritDoc Ext.layout.container.Anchor#cfg-anchor
     */
 
    /**
     * @cfg {String/Object} autoEl
     * A tag name or {@link Ext.dom.Helper DomHelper} spec used to create the {@link #getEl Element}
     * which will encapsulate this Component.
     *
     * You do not normally need to specify this. For the base classes {@link Ext.Component} and
     * {@link Ext.container.Container}, this defaults to **'div'**. The more complex Sencha classes
     * use a more complex DOM structure specified by their own {@link #cfg-renderTpl}s.
     *
     * This is intended to allow the developer to create application-specific utility Components
     * encapsulated by different DOM elements. Example usage:
     *
     *     {
     *         xtype: 'component',
     *         autoEl: {
     *             tag: 'img',
     *             src: 'http://www.example.com/example.jpg'
     *         }
     *     }, {
     *         xtype: 'component',
     *         autoEl: {
     *             tag: 'blockquote',
     *             html: 'autoEl is cool!'
     *         }
     *     }, {
     *         xtype: 'container',
     *         autoEl: 'ul',
     *         cls: 'ux-unordered-list',
     *         items: {
     *             xtype: 'component',
     *             autoEl: 'li',
     *             html: 'First list item'
     *         }
     *     }
     *
     * @since 2.3.0
     */
 
    /**
     * @cfg {Boolean/String/HTMLElement/Ext.dom.Element} autoRender
     * This config is intended mainly for non-{@link #cfg-floating} Components which may or may not
     * be shown. Instead of using {@link #renderTo} in the configuration, and rendering upon
     * construction, this allows a Component to render itself upon first
     * _{@link Ext.Component#method-show show}_. If {@link #cfg-floating} is `true`, the value
     * of this config is omitted as if it is `true`.
     *
     * Specify as `true` to have this Component render to the document body upon first show.
     *
     * Specify as an element, or the ID of an element to have this Component render to a specific
     * element upon first show.
     */
    autoRender: false,
 
    /**
     * @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.
     *
     * This should not be combined with {@link #overflowX} or  {@link #overflowY}.
     * @deprecated 5.1.0 Use {@link #scrollable} instead
     */
 
    /**
     * @cfg {Boolean} autoShow
     * `true` to automatically show the component upon creation. This config option may only be used
     * for {@link #cfg-floating} components or components that use {@link #autoRender}.
     *
     * @since 2.3.0
     */
    autoShow: false,
 
    /**
     * @cfg {String} baseCls
     * The base CSS class to apply to this component's element. This will also be prepended
     * to elements within this component like Panel's body will get a class `x-panel-body`.
     * This means that if you create a subclass of Panel, and you want it to get all the Panels
     * styling for the element and the body, you leave the `baseCls` `x-panel` and use
     * `componentCls` to add specific styling for this component.
     */
    baseCls: Ext.baseCSSPrefix + 'component',
 
    /**
     * @cfg {Number/String/Boolean} border
     * Specifies the border size for this component. The border can be a single numeric value
     * to apply to all sides or it can be a CSS style specification for each style,
     * for example: '10 5 3 10' (top, right, bottom, left).
     *
     * For components that have no border by default, setting this won't make the border appear
     * by itself. You also need to specify border color and style:
     *
     *     border: 5,
     *     style: {
     *         borderColor: 'red',
     *         borderStyle: 'solid'
     *     }
     *
     * To turn off the border, use `border: false`.
     */
 
    /**
     * @cfg childEls
     * @inheritdoc Ext.util.ElementContainer#cfg-childEls
     */
    /* eslint-disable key-spacing */
    childEls: {
        frameTable: { frame: true },
        frameTL:    { frame: 'tl' },
        frameTC:    { frame: 'tc' },
        frameTR:    { frame: 'tr' },
        frameML:    { frame: 'ml' },
        frameBody:  { frame: 'mc' },
        frameMR:    { frame: 'mr' },
        frameBL:    { frame: 'bl' },
        frameBC:    { frame: 'bc' },
        frameBR:    { frame: 'br' }
    },
    /* eslint-enable key-spacing */
 
    /**
     * @cfg {String/String[]} [cls='']
     * An optional extra CSS class that will be added to this component's Element.
     * The value can be a string, a list of strings separated by spaces, or an array of strings.
     * This can be useful for adding customized styles to the component or any of its children
     * using standard CSS rules.
     *
     * @since 1.1.0
     */
 
    /**
     * @cfg {Number} [columnWidth]
     * Defines the column width inside {@link Ext.layout.container.Column column layout}.
     *
     * The columnWidth property is always evaluated as a percentage and must be a decimal value
     * greater than 0 and less than 1 (e.g., .25). See the description at the top of
     * {@link Ext.layout.container.Column column layout} for additional usage details when combining
     * width and columnWidth configs within the layout.
     */
 
    /**
     * @cfg {String} componentCls
     * CSS Class to be added to a components root level element to give distinction to it
     * via styling.
     */
 
    // @cmd-auto-dependency { aliasPrefix : "layout." }
    /**
     * @cfg {String/Object} componentLayout
     * The sizing and positioning of a Component's internal Elements is the responsibility
     * of the Component's layout manager which sizes a Component's internal structure in response
     * to the Component being sized.
     *
     * Generally, developers will not use this configuration as all provided Components which need
     * their internal elements sizing (Such as {@link Ext.form.field.Base input fields}) come with
     * their own componentLayout managers.
     *
     * The {@link Ext.layout.container.Auto default layout manager} will be used on instances of the
     * base Ext.Component class which simply sizes the Component's encapsulating element to the
     * height and width specified in the {@link #setSize} method.
     *
     */
    componentLayout: 'autocomponent',
 
    /**
     * @cfg {Object/String} constraintInsets
     * An object or a string (in TRBL order) specifying insets from the configured
     * {@link #constrainTo constrain region} within which this component must be constrained
     * when positioning or sizing. Example:
     *
     *     constraintInsets: '10 10 10 10' // Constrain with 10px insets from parent
     */
 
    /**
     * @cfg {Ext.util.Region/Ext.dom.Element} constrainTo
     * A {@link Ext.util.Region Region} (or an element from which a Region measurement will be read)
     * which is used to constrain the component. Only applies when the component is floating.
     */
 
    /**
     * @cfg {String} contentEl
     * Specify an existing HTML element, or the `id` of an existing HTML element to use as the
     * content for this component.
     *
     * This config option is used to take an existing HTML element and place it in the layout
     * element of a new component (it simply moves the specified DOM element _after the Component
     * is rendered_ to use as the content.
     *
     * **Notes:**
     *
     * The specified HTML element is appended to the layout element of the component _after any
     * configured {@link #html HTML} has been inserted_, and so the document will not contain
     * this element at the time the {@link #event-render} event is fired.
     *
     * The specified HTML element used will not participate in any
     * **`{@link Ext.container.Container#layout layout}`** scheme that the Component may use.
     * It is just HTML. Layouts operate on child
     * **`{@link Ext.container.Container#cfg-items items}`**.
     *
     * Add either the `x-hidden` or the `x-hidden-display` CSS class to prevent a brief flicker
     * of the content before it is rendered to the panel.
     *
     * @since 3.4.0
     */
 
    /**
     * @cfg {String} defaultAlign
     * The default {@link Ext.util.Positionable#getAlignToXY Ext.dom.Element#getAlignToXY} anchor
     * position value for this component relative to its {@link #alignTarget}
     * (which defaults to its owning Container).
     *
     * _Only applicable if this component is {@link #cfg-floating}_
     *
     * *Used upon first show*.
     */
    defaultAlign: 'c-c',
 
    /**
     * @cfg {Boolean} disabled
     * `true` to disable the component.
     * @since 2.3.0
     */
    disabled: false,
 
    // http://www.w3.org/TR/html5/disabled-elements.html
    disabledRe: /^(?:button|input|select|textarea|optgroup|option|fieldset)$/i,
 
    nonMaskableRe: (function() {
        var re = ['input', 'select', 'textarea', 'optgroup', 'option', 'table'];
 
        // All IE browsers 9 and below except for IE 9 standards.
        if (Ext.isIE9m && !(Ext.isIE9 && !Ext.isIEQuirks)) {
            // <p>.insertAdjacentHTML('BeforeEnd', '<div>...</div>') yields
            // 'Invalid source HTML for this operation' in all IEs not IE 9 standards.
            re.push('p');
        }
 
        return new RegExp('^(?:' + re.join('|') + ')$', 'i');
    }()),
 
    /**
     * @cfg {String} disabledCls
     * CSS class to add when the Component is disabled.
     */
    disabledCls: Ext.baseCSSPrefix + 'item-disabled',
 
    /**
     * @cfg {'top'/'bottom'/'left'/'right'} dock
     * The side of the {@link Ext.panel.Panel panel} where this component is to be
     * docked when specified in the panel's
     * {@link Ext.panel.Panel#dockedItems dockedItems} config.
     *
     * Possible values are:
     *
     *  - top
     *  - bottom
     *  - left
     *  - right
     */
 
    /**
     * @cfg {Boolean/Object} draggable
     * Specify as true to make a {@link #cfg-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();
     */
    draggable: false,
 
    /**
     * @cfg {Number} flex
     * Flex may be applied to **child items** of a box layout
     * ({@link Ext.layout.container.VBox vbox} or {@link Ext.layout.container.HBox hbox}).
     * Each child item with a flex property will fill space (horizontally in `hbox`, vertically
     * in `vbox`) according to that item's **relative** flex value compared to the sum of all items
     * with a flex value specified.
     *
     * Any child items that have either a `flex` of `0` or `undefined`
     * will not be 'flexed' (the initial size will not be changed).
     */
 
    /**
     * @cfg {Boolean} floating
     * 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 programmatically {@link Ext.Component#method-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 sorts its stack according to an incrementing access counter and the
     * {@link Ext.util.Floating#alwaysOnTop alwaysOnTop} config 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 #method-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} [formBind=false]
     * When inside FormPanel, any component configured with `formBind: true` will
     * be enabled/disabled depending on the validity state of the form.
     * See {@link Ext.form.Panel} for more information and example.
     */
 
    /**
     * @cfg {Boolean} frame
     * Specify as `true` to have the Component inject framing elements within the Component
     * at render time to provide a graphical rounded frame around the Component content.
     *
     * This is only necessary when running on outdated, or non standard-compliant browsers
     * such as Microsoft's Internet Explorer prior to version 9 which do not support rounded corners
     * natively.
     *
     * The extra space taken up by this framing is available from the read only property
     * {@link #frameSize}.
     */
 
    /**
     * @cfg {Number|String} height
     * The height of this component. A numeric value will be interpreted as the number of
     * pixels; a string value will be treated as a CSS value with units.
     */
 
    /**
     * @cfg {Boolean} hidden
     * `true` to hide the component.
     * @since 2.3.0
     */
    hidden: false,
 
    /**
     * @cfg {String} hideMode
     * A String which specifies how this Component's encapsulating DOM element will be hidden.
     * Values may be:
     *
     *   - `'display'` : The Component will be hidden using the `display: none` style.
     *   - `'visibility'` : The Component will be hidden using the `visibility: hidden` style.
     *   - `'offsets'` : The Component will be hidden by absolutely positioning it out of the
     *     visible area of the document.
     *     This is useful when a hidden Component must maintain measurable dimensions. Hiding using
     *     `display` results in a Component having zero dimensions.
     *
     * @since 1.1.0
     */
    hideMode: 'display',
 
    /**
     * @cfg {String/Object} [html='']
     * An HTML fragment, or a {@link Ext.dom.Helper DomHelper} specification to use as the layout
     * element content. The HTML content is added after the component is rendered, so the document
     * will not contain this HTML at the time the {@link #event-render} event is fired. This content
     * is inserted into the body _before_ any configured {@link #contentEl} is appended.
     *
     * @since 3.4.0
     */
 
    /**
     * @cfg {String} id
     * The **unique** id of this component instance.
     *
     * Use of this config should be considered carefully as this value must be unique across
     * all existing components. Components created with an `id` may be accessed globally
     * using {@link Ext#getCmp Ext.getCmp}.
     *
     * Instead of using assigned ids, consider a {@link #reference} config and
     * a {@link #cfg-controller ViewController} to respond to events and perform processing
     * upon this Component.
     *
     * Alternatively, {@link #itemId} and {@link Ext.ComponentQuery ComponentQuery} can be
     * used to perform selector-based searching for Components analogous to DOM querying.
     * The {@link Ext.container.Container Container} class contains several helpful
     * {@link Ext.container.Container#down shortcut methods} to query its descendant
     * Components by selector.
     *
     * Note that this `id` will also be used as the element id for the containing HTML
     * element that is rendered to the page for this component. This allows you to write
     * id-based CSS rules to style the specific instance of this component uniquely, and
     * also to select sub-elements using this component's `id` as the parent.
     *
     * Defaults to an {@link #getId auto-assigned id}.
     *
     * **Note**: Valid identifiers start with a letter or underscore and are followed by
     * (optional) additional letters, underscores, digits or hyphens.
     *
     * @since 1.1.0
     */
 
    /**
     * @cfg {String} itemId
     * The **unique** id of this component instance within its container. See also the
     * {@link #reference} config.
     *
     * An `itemId` can be used as an alternative way to get a reference to a component
     * when no object reference is available. Instead of using an `{@link #id}` with
     * {@link Ext#getCmp getCmp}, use `itemId` with
     * {@link Ext.container.Container#getComponent getComponent} which will retrieve `itemId`'s
     * or {@link #id}'s. Since `itemId`'s are an index to the container's internal collection,
     * the `itemId` is scoped locally to the container -- avoiding potential conflicts with
     * {@link Ext.ComponentManager}, which requires a **unique** {@link #id} value.
     *
     *     var c = new Ext.panel.Panel({ //
     *         height: 300,
     *         renderTo: document.body,
     *         layout: 'auto',
     *         items: [{
     *             itemId: 'p1',
     *             title: 'Panel 1',
     *             height: 150
     *         },{
     *             itemId: 'p2',
     *             title: 'Panel 2',
     *             height: 150
     *         }]
     *     });
     *
     *     p1 = c.getComponent('p1'); // not the same as Ext.getCmp()
     *     console.log(p1);
     *     p2 = p1.ownerCt.getComponent('p2'); // reference via a sibling
     *     console.log(p2);
     *
     * Also see {@link #id}, `{@link Ext.container.Container#query}`,
     * `{@link Ext.container.Container#down}` and `{@link Ext.container.Container#child}`.
     *
     * **Note**: Valid identifiers start with a letter or underscore and are followed by
     * (optional) additional letters, underscores, digits or hyphens.
     *
     * **Note**: to access the container of an item see {@link #ownerCt}.
     *
     * @since 3.4.0
     */
 
    /**
     * @cfg {Ext.ComponentLoader/Object} loader
     * A configuration object or an instance of a {@link Ext.ComponentLoader} to load remote content
     * for this Component.
     *
     *     Ext.create('Ext.Component', {
     *         loader: {
     *             url: 'content.html',
     *             autoLoad: true
     *         },
     *         renderTo: Ext.getBody()
     *     });
     */
 
    /**
     * @cfg {Number/String} margin
     * Specifies the margin for this component. The margin can be a single numeric value to apply
     * to all sides or it can be a CSS style specification for each style,
     * for example: '10 5 3 10' (top, right, bottom, left).
     */
 
    /**
     * @cfg {String} maskElement
     * Related to the {@link #cfg-childEls} configuration which specifies named properties
     * which correspond to component sub-elements.
     *
     * The name of the element property in this component to mask when masked by a LoadMask.
     *
     * Defaults to `null` to indicate that Components cannot by default contain a LoadMask,
     * and that any LoadMask should be rendered into the document body.
     *
     * For example, Panels use `"el"` to indicate that the whole panel should be masked.
     * This could be configured to be `"body"` so that only the body is masked and toolbars
     * and the header are still mouse-accessible.
     */
    maskElement: null,
 
    /**
     * @cfg {Object} [maskDefaults] Default LoadMask configuration for {@link #method-setLoading}.
     */
 
    /**
     * @cfg {String} [overCls='']
     * An optional extra CSS class that will be added to this component's Element when the mouse
     * moves over the Element, and removed when the mouse moves out. This can be useful for adding
     * customized 'active' or 'hover' styles to the component or any of its children using standard
     * CSS rules.
     *
     * @since 2.3.0
     */
 
    /**
     * @cfg {String} overflowX
     * Possible values are:
     *
     *  - `'auto'` to enable automatic horizontal scrollbar (Style overflow-x: 'auto').
     *  - `'scroll'` to always enable horizontal scrollbar (Style overflow-x: 'scroll').
     *
     * The default is overflow-x: 'hidden'. This should not be combined with {@link #autoScroll}.
     * @deprecated 5.1.0 Use {@link #scrollable} instead
     */
 
    /**
     * @cfg {String} overflowY
     * Possible values are:
     *
     *  - `'auto'` to enable automatic vertical scrollbar (Style overflow-y: 'auto').
     *  - `'scroll'` to always enable vertical scrollbar (Style overflow-y: 'scroll').
     *
     * The default is overflow-y: 'hidden'. This should not be combined with {@link #autoScroll}.
     * @deprecated 5.1.0 Use {@link #scrollable} instead
     */
 
    /**
     * @cfg {Number/String} padding
     * Specifies the padding for this component. The padding can be a single numeric value to apply
     * to all sides or it can be a CSS style specification for each style,
     * for example: '10 5 3 10' (top, right, bottom, left).
     */
 
    /**
     * @cfg {Array/Ext.enums.Plugin/Object/Ext.plugin.Abstract} plugins
     * This config describes one or more plugin config objects used to create plugin
     * instances for this component.
     *
     * Plugins are a way to bundle and reuse custom functionality. Plugins should extend
     * `Ext.plugin.Abstract` but technically the only requirement for a valid plugin
     * is that it contain an `init` method that accepts a reference to its owner. Once
     * a plugin is created, the owner will call the `init` method, passing a reference
     * to itself. Each plugin can then call methods or respond to events on its owner
     * as needed to provide its functionality.
     *
     * This config's value can take several different forms.
     *
     * The value can be a single string with the plugin's {@link Ext.enums.Plugin alias}:
     *
     *     plugins: 'cellediting',
     *
     * The preferred form for multiple plugins or to configure plugins is the keyed-object
     * form (new in version 6.5):
     *
     *      plugins: {
     *          gridviewdragdrop: true,
     *          cellediting: {
     *              clicksToEdit: 1
     *          }
     *      },
     *
     * The keys are `id`'s as well as the default type alias.
     *
     * The `plugins` config can also be an array of plugin aliases:
     *
     *     plugins: [ 'cellediting', 'gridviewdragdrop' ],
     *
     * An array can also contain elements that are config objects with a `ptype` property
     * holding the type alias:
     *
     *      plugins: ['gridviewdragdrop', {
     *          ptype: 'cellediting',
     *          clicksToEdit: 1
     *      }],
     *
     * @since 2.3.0
     */
 
    /**
     * @cfg {"north"/"south"/"east"/"west"/"center"} [region=undefined]
     * Defines the region inside {@link Ext.layout.container.Border border layout}.
     *
     * Possible values:
     *
     * - north - Positions component at top.
     * - south - Positions component at bottom.
     * - east - Positions component at right.
     * - west - Positions component at left.
     * - center - Positions component at the remaining space.
     *   There **must** be a component with `region: "center"` in every border layout.
     */
 
    /**
     * @cfg {Object} renderData
     *
     * The data used by {@link #renderTpl} in addition to the following property values
     * of the component:
     *
     * - id
     * - ui
     * - uiCls
     * - baseCls
     * - componentCls
     * - frame
     *
     * See {@link #renderSelectors} and {@link #cfg-childEls} for usage examples.
     */
 
    /**
     * @cfg {Object} renderSelectors
     * An object containing properties specifying CSS selectors which identify child elements
     * created by the render process.
     *
     * After the Component's internal structure is rendered according to the {@link #renderTpl},
     * this object is iterated through, and the found Elements are added as properties
     * to the Component using the `renderSelector` property name.
     *
     * For example, a Component which renders a title and description into its element:
     *
     *      Ext.create('Ext.Component', {
     *          renderTo: Ext.getBody(),
     *          renderTpl: [
     *              '<h1 class="title">{title}</h1>',
     *              '<p>{desc}</p>'
     *          ],
     *          renderData: {
     *              title: "Error",
     *              desc: "Something went wrong"
     *          },
     *          renderSelectors: {
     *              titleEl: 'h1.title',
     *              descEl: 'p'
     *          },
     *          listeners: {
     *              afterrender: function(cmp){
     *                  // After rendering the component will have a titleEl and descEl properties
     *                  cmp.titleEl.setStyle({color: "red"});
     *              }
     *          }
     *      });
     *
     * The use of `renderSelectors` is deprecated (for performance reasons). The above
     * code should be refactored into something like this:
     *
     *      Ext.create('Ext.Component', {
     *          renderTo: Ext.getBody(),
     *          renderTpl: [
     *              '<h1 class="title" id="{id}-titleEl" data-ref="titleEl">{title}</h1>',
     *              '<p id="{id}-descEl" data-ref="descEl">{desc}</p>'
     *          ],
     *          renderData: {
     *              title: "Error",
     *              desc: "Something went wrong"
     *          },
     *          childEls: [
     *              'titleEl',
     *              'descEl'
     *          ]
     *      });
     *
     * To use `childEls` yet retain the use of selectors (which remains as expensive as
     * `renderSelectors`):
     *
     *      Ext.create('Ext.Component', {
     *          renderTo: Ext.getBody(),
     *          renderTpl: [
     *              '<h1 class="title">{title}</h1>',
     *              '<p>{desc}</p>'
     *          ],
     *          renderData: {
     *              title: "Error",
     *              desc: "Something went wrong"
     *          },
     *          childEls: {
     *              titleEl: { selectNode: 'h1.title' },
     *              descEl: { selectNode: 'p' }
     *          }
     *      });
     *
     * @deprecated 5.0 Use {@link #cfg-childEls} instead.
     */
 
    /**
     * @cfg {String/HTMLElement/Ext.dom.Element} renderTo
     * Specify the `id` of the element, a DOM element or an existing Element that this component
     * will be rendered into.
     *
     * **Notes:**
     *
     * Do *not* use this option if the Component is to be a child item of a
     * {@link Ext.container.Container Container}. It is the responsibility of the
     * {@link Ext.container.Container Container}'s
     * {@link Ext.container.Container#layout layout manager} to render and manage its child items.
     *
     * When using this config, a call to `render()` is not required.
     *
     * See also: {@link #method-render}.
     *
     * @since 2.3.0
     */
 
    /**
     * @cfg {Ext.XTemplate/String/String[]} renderTpl
     * An {@link Ext.XTemplate XTemplate} used to create the internal structure inside
     * this Component's encapsulating {@link #getEl Element}.
     *
     * You do not normally need to specify this. For the base classes {@link Ext.Component} and
     * {@link Ext.container.Container}, this defaults to **`null`** which means that they will be
     * initially rendered with no internal structure; they render their {@link #getEl Element}
     * empty. The more specialized classes with complex DOM structures provide their own template
     * definitions.
     *
     * This is intended to allow the developer to create application-specific utility Components
     * with customized internal structure.
     *
     * Upon rendering, any created child elements may be automatically imported into object
     * properties using the {@link #renderSelectors} and {@link #cfg-childEls} options.
     * @protected
     */
    renderTpl: '{%this.renderContent(out,values)%}',
 
    /**
     * @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 `{@link Ext.resizer.Resizer#dynamic}: false`
     */
 
    /**
     * @cfg {String} resizeHandles
     * A valid {@link Ext.resizer.Resizer} handles config string. Only applies when
     * resizable = true.
     */
    resizeHandles: 'all',
 
    /**
     * @cfg {Boolean/Number} shrinkWrap
     *
     * The possible values for shrinkWrap are:
     *
     *   - 0 (or `false`): Neither width nor height depend on content.
     *   - 1: Width depends on content (shrink wraps), but height does not.
     *   - 2: Height depends on content (shrink wraps), but width does not.
     *   - 3 (or `true`): Both width and height depend on content (shrink wrap).
     *
     * In CSS terms, shrink-wrap width is analogous to an inline-block element as opposed
     * to a block-level element.
     *
     * @localdoc ##Non-Panel Components
     *
     * The shrinkWrap config is a class-level config and should be used when defining a
     * subclass.
     * It is not intended to be set as a config on instances of a given component.
     *
     * For non-Panel components, shrinkWrap is a descriptive config only.  It should be
     * set when defining your own custom class including the DOM elements used to
     * construct the component.  The shrinkWrap property does not itself apply styling on
     * the component elements.  Rather, it should describe the CSS styling you've applied
     * to your custom component (_refer to the numeric matrix above_).
     *
     * When a component is owned by a container the layout of that container will inspect
     * the component's shrinkWrap property during layout.  The layout then uses the
     * content-wrapping policy described by shrinkWrap to correctly size and position the
     * container's child items.
     */
    shrinkWrap: 2,
 
    /**
     * @cfg stateEvents
     * @inheritdoc Ext.state.Stateful#cfg-stateEvents
     * @localdoc By default the following stateEvents are added:
     *
     *  - {@link #event-resize}
     */
 
    /**
     * @cfg {String/Object} style
     * A custom style specification to be applied to this component's Element.
     * Should be a valid argument to {@link Ext.dom.Element#applyStyles}.
     *
     *     new Ext.panel.Panel({
     *         title: 'Some Title',
     *         renderTo: Ext.getBody(),
     *         width: 400, height: 300,
     *         layout: 'form',
     *         items: [{
     *             xtype: 'textarea',
     *             style: {
     *                 width: '95%',
     *                 marginBottom: '10px'
     *             }
     *         },
     *         new Ext.button.Button({
     *             text: 'Send',
     *             minWidth: '100',
     *             style: {
     *                 marginBottom: '10px'
     *             }
     *         })
     *         ]
     *     });
     *
     * @since 1.1.0
     */
 
    /**
     * @cfg {Boolean} toFrontOnShow
     * True to automatically call {@link #toFront} when the {@link #method-show} method is called
     * on an already visible, floating component.
     */
    toFrontOnShow: true,
 
    /**
     * @cfg {Ext.XTemplate/Ext.Template/String/String[]} tpl
     * An {@link Ext.Template}{@link Ext.XTemplate} or an array of strings to form
     * an Ext.XTemplate. Used in conjunction with the `{@link #data}` and `{@link #tplWriteMode}`
     * configurations.
     *
     * @since 3.4.0
     */
 
    /**
     * @property {Boolean} synthetic
     * This property is `true` if the component was created internally by the framework
     * and is not explicitly user-defined. This is set for such things as `Splitter`
     * instances managed by `border` and `box` layouts.
     * @private
     */
    synthetic: false,
 
    /**
     * @cfg {String} tplWriteMode
     * The Ext.(X)Template method to use when updating the content area of the Component.
     * See `{@link Ext.XTemplate#overwrite}` for information on default mode.
     *
     * @since 3.4.0
     */
    tplWriteMode: 'overwrite',
 
    /**
     * @cfg {String} ui
     * A UI style for a component.
     */
    ui: 'default',
 
    /**
     * @cfg {String[]} uiCls
     * An array of of `classNames` which are currently applied to this component.
     * @private
     */
    uiCls: [],
 
    /**
     * @cfg {String/String[]} userCls
     * One or more CSS classes to add to the component's primary element. This config
     * is intended solely for use by the component instantiator (the "user"), not by
     * derived classes.
     *
     * For example:
     *
     *      items: [{
     *          xtype: 'button',
     *          userCls: 'my-button'
     *      ...
     *      }]
     * @accessor
     */
    userCls: null,
 
    /**
     * @cfg {Number} weight
     * A value to control how Components are laid out in a
     * {@link Ext.layout.container.Border Border} layout or as docked items.
     *
     * In a Border layout, this can control how the regions (not the center) region lay out
     * if the west or east take full height or if the north or south region take full width.
     * Also look at the {@link Ext.layout.container.Border#regionWeights} on the Border layout.
     * An example to show how you can take control of this is:
     *
     *     Ext.create('Ext.container.Viewport', {
     *         layout      : 'border',
     *         defaultType : 'panel',
     *         items       : [
     *             {
     *                 region : 'north',
     *                 title  : 'North',
     *                 height : 100
     *             },
     *             {
     *                 region : 'south',
     *                 title  : 'South',
     *                 height : 100,
     *                 weight : -25
     *             },
     *             {
     *                 region : 'west',
     *                 title  : 'West',
     *                 width  : 200,
     *                 weight : 15
     *             },
     *             {
     *                 region : 'east',
     *                 title  : 'East',
     *                 width  : 200
     *             },
     *             {
     *                 region : 'center',
     *                 title  : 'center'
     *             }
     *         ]
     *     });
     *
     * If docked items, the weight will order how the items are laid out. Here is an example
     * to put a {@link Ext.toolbar.Toolbar} above a {@link Ext.panel.Panel}'s header:
     *
     *     Ext.create('Ext.panel.Panel', {
     *         renderTo    : document.body,
     *         width       : 300,
     *         height      : 300,
     *         title       : 'Panel',
     *         html        : 'Panel Body',
     *         dockedItems : [
     *             {
     *                 xtype : 'toolbar',
     *                 items : [
     *                     {
     *                         text : 'Save'
     *                     }
     *                 ]
     *             },
     *             {
     *                 xtype  : 'toolbar',
     *                 weight : -10,
     *                 items  : [
     *                     {
     *                         text : 'Remove'
     *                     }
     *                 ]
     *             }
     *         ]
     *     });
     */
    weight: null,
 
    /**
     * @cfg {Number|String} width
     * The width of this component. A numeric value will be interpreted as the number of
     * pixels; a string value will be treated as a CSS value with units.
     */
 
    /**
     * @cfg {Ext.enums.Widget} xtype
     * **Note:** Only applies to {@link Ext.Component} derived classes when used as
     * a config in {@link Ext#define Ext.define}.
     *
     * This property provides a shorter alternative to creating objects than using a full
     * class name. Using `xtype` is the most common way to define component instances,
     * especially in a container. For example, the items in a form containing text fields
     * could be created explicitly like so:
     *
     *      items: [
     *          Ext.create('Ext.form.field.Text', {
     *              fieldLabel: 'Foo'
     *          }),
     *          Ext.create('Ext.form.field.Text', {
     *              fieldLabel: 'Bar'
     *          }),
     *          Ext.create('Ext.form.field.Number', {
     *              fieldLabel: 'Num'
     *          })
     *      ]
     *
     * But by using `xtype`, the above becomes:
     *
     *      items: [
     *          {
     *              xtype: 'textfield',
     *              fieldLabel: 'Foo'
     *          },
     *          {
     *              xtype: 'textfield',
     *              fieldLabel: 'Bar'
     *          },
     *          {
     *              xtype: 'numberfield',
     *              fieldLabel: 'Num'
     *          }
     *      ]
     *
     * When the `xtype` is common to many items, {@link Ext.container.Container#defaultType}
     * is another way to specify the `xtype` for all items that don't have an explicit `xtype`:
     *
     *      defaultType: 'textfield',
     *      items: [
     *          { fieldLabel: 'Foo' },
     *          { fieldLabel: 'Bar' },
     *          { fieldLabel: 'Num', xtype: 'numberfield' }
     *      ]
     *
     * Each member of the `items` array is now just a "configuration object". These objects
     * are used to create and configure component instances. A configuration object can be
     * manually used to instantiate a component using {@link Ext#widget}:
     *
     *      var text1 = Ext.create('Ext.form.field.Text', {
     *          fieldLabel: 'Foo'
     *      });
     *
     *      // or alternatively:
     *
     *      var text1 = Ext.widget({
     *          xtype: 'textfield',
     *          fieldLabel: 'Foo'
     *      });
     *
     * This conversion of configuration objects into instantiated components is done when
     * a container is created as part of its {Ext.container.AbstractContainer#initComponent}
     * process. As part of the same process, the `items` array is converted from its raw
     * array form into a {@link Ext.util.MixedCollection} instance.
     *
     * You can define your own `xtype` on a custom {@link Ext.Component component} by specifying
     * the `xtype` property in {@link Ext#define}. For example:
     *
     *     Ext.define('MyApp.PressMeButton', {
     *         extend: 'Ext.button.Button',
     *         xtype: 'pressmebutton',
     *         text: 'Press Me'
     *     });
     *
     * Care should be taken when naming an `xtype` in a custom component because there is
     * a single, shared scope for all xtypes. Third part components should consider using
     * a prefix to avoid collisions.
     *
     *     Ext.define('Foo.form.CoolButton', {
     *         extend: 'Ext.button.Button',
     *         xtype: 'ux-coolbutton',
     *         text: 'Cool!'
     *     });
     *
     * See {@link Ext.enums.Widget} for list of all available xtypes.
     *
     * @since 2.3.0
     */
 
    /**
     * @cfg {Number} tabIndex
     * DOM tabIndex attribute for this component's {@link #focusEl}.
     */
 
    // ***********************************************************************************
    // End Config
    // ***********************************************************************************
    // </editor-fold>
 
    // <editor-fold desc="Properties">
    // ***********************************************************************************
    // Begin Properties
    // ***********************************************************************************
 
    /**
     * @private
     */
    allowDomMove: true,
 
    /**
     * @property {Boolean} autoGenId
     * `true` indicates an `id` was auto-generated rather than provided by configuration.
     * @private
     */
    autoGenId: false,
 
    /**
     * @private
     */
    borderBoxCls: Ext.baseCSSPrefix + 'border-box',
 
    /**
     * @property {Number} componentLayoutCounter
     * @private
     * The number of component layout calls made on this object.
     */
    componentLayoutCounter: 0,
 
    /**
     * @property {String} contentPaddingProperty
     * The name of the padding property that is used by the layout to manage
     * padding.  See {@link Ext.layout.container.Auto#managePadding managePadding}
     */
    contentPaddingProperty: 'padding',
 
    /**
     * @private
     */
    deferLayouts: false,
 
    /**
     * @property {Ext.Container} floatParent
     * **Only present for {@link #cfg-floating} Components which were inserted as child items
     * of Containers.**
     *
     * There are other similar relationships such as the {@link Ext.button.Button button} which
     * activates a {@link Ext.button.Button#cfg-menu menu}, or the
     * {@link Ext.menu.Item menu item} which activated a {@link Ext.menu.Item#cfg-menu submenu},
     * or the {@link Ext.grid.column.Column column header} which activated the column menu.
     *
     * These differences are abstracted away by the {@link #up} method.
     *
     * Floating Components that are programmatically {@link Ext.Component#method-render rendered}
     * will not have a `floatParent` property.
     *
     * See {@link #cfg-floating} and {@link #zIndexManager}
     * @readonly
     */
 
    /**
     * @property {Object} frameSize
     * @readonly
     * Indicates the width of any framing elements which were added within the encapsulating
     * element to provide graphical, rounded borders. See the {@link #frame} config. This
     * property is `null` if the component is not framed.
     *
     * This is an object containing the frame width in pixels for all four sides of the
     * Component containing the following properties:
     *
     * @property {Number} [frameSize.top=0] The width of the top framing element in pixels.
     * @property {Number} [frameSize.right=0] The width of the right framing element in pixels.
     * @property {Number} [frameSize.bottom=0] The width of the bottom framing element in pixels.
     * @property {Number} [frameSize.left=0] The width of the left framing element in pixels.
     * @property {Number} [frameSize.width=0] The total width of the left and right framing elements
     * in pixels.
     * @property {Number} [frameSize.height=0] The total height of the top and right bottom elements
     * in pixels.
     */
    frameSize: null,
 
    /**
     * @private
     */
    horizontalPosProp: 'left',
 
    /**
     * @property {Boolean} isComponent
     * `true` in this class to identify an object as an instantiated Component, or subclass thereof.
     */
    isComponent: true,
 
    /**
     * @property {Boolean} _isLayoutRoot
     * Setting this property to `true` causes the {@link #isLayoutRoot} method to return
     * `true` and stop the search for the top-most component for a layout.
     * @protected
     */
    _isLayoutRoot: false,
 
    /**
     * @private
     */
    layoutSuspendCount: 0,
 
    /**
     * @cfg {Boolean} liquidLayout
     * Components that achieve their internal layout results using solely CSS with no JS
     * intervention must set this to true.  This allows the component to opt out of the
     * layout run when used inside certain container layouts such as {@link
     * Ext.layout.container.Form Form} and {@link Ext.layout.container.Auto Auto}
     * resulting in a performance gain. The following components currently use liquid
     * layout (`liquidLayout: true`):
     *
     * - All Form Fields (subclasses of {@link Ext.form.field.Base})
     * - {@link Ext.button.Button}
     *
     * It is important to keep in mind that components using liquidLayout do not fire
     * the following events:
     *
     * - {@link #event-resize}
     * - {@link #event-boxready}
     *
     * In addition, liquidLayout components do not call the following template methods:
     *
     * - {@link #method!afterComponentLayout}
     * - {@link #method!onBoxReady}
     * - {@link #method!onResize}
     *
     * Any component that needs to fire these events or to have these methods called during
     * its life cycle needs to set `liquidLayout` to `false`.  The following example
     * demonstrates how to enable the resize event for a
     * {@link Ext.form.field.TextArea TextArea Field}:
     *
     *     @example
     *     var win = Ext.create({
     *             xtype: 'window',
     *             title: 'Resize This Window!',
     *             height: 100,
     *             width: 200,
     *             layout: 'anchor',
     *             items: [{
     *                 xtype: 'textarea',
     *                 anchor: '0 0',
     *                 liquidLayout: false // allows the textarea to fire "resize"
     *             }]
     *         }),
     *         textfield = win.items.getAt(0);
     *
     *     win.show();
     *
     *     textfield.on('resize', function(textfield, width, height) {
     *         Ext.Msg.alert('Text Field Resized', 'width: ' + width + ', height: ' + height);
     *     });
     *
     * Use caution when setting `liquidLayout` to `false` as it carries a performance penalty
     * since it means the layout system must perform expensive DOM reads to determine the
     * Component's size.
     */
    liquidLayout: false,
 
    /**
     * @property {Boolean} maskOnDisable
     * This is an internal flag that you use when creating custom components. By default this is set
     * to `true` which means that every component gets a mask when it's disabled. Components like
     * FieldContainer, FieldSet, Field, Button, Tab override this property to `false`
     * since they want to implement custom disable logic.
     */
    maskOnDisable: true,
 
    /**
     * @property {Ext.Container} ownerCt
     * This Component's owner {@link Ext.container.Container Container} (is set automatically
     * when this Component is added to a Container).
     *
     * *Important.* This is not a universal upwards navigation pointer. It indicates the Container
     * which owns and manages this Component if any. There are other similar relationships such as
     * the {@link Ext.button.Button button} which activates a
     * {@link Ext.button.Button#cfg-menu menu}, or the {@link Ext.menu.Item menu item} which
     * activated a {@link Ext.menu.Item#cfg-menu submenu}, or the
     * {@link Ext.grid.column.Column column header} which activated the column menu.
     *
     * These differences are abstracted away by the {@link #up} method.
     *
     * **Note**: to access items within the Container see {@link #itemId}.
     * @readonly
     * @since 2.3.0
     */
 
    /**
     * @property {Boolean} rendered
     * Indicates whether or not the component has been rendered.
     * @readonly
     * @since 1.1.0
     */
    rendered: false,
 
    /**
     * @private
     */
    rootCls: Ext.baseCSSPrefix + 'body',
 
    /**
     * @private
     */
    scrollerCls: Ext.baseCSSPrefix + 'scroll-scroller',
 
    /**
     * @property {Object} scrollFlags
     * An object property which provides unified information as to which dimensions are
     * scrollable based upon the {@link #scrollable} settings (And for *views* of trees and
     * grids, the owning panel's {@link Ext.panel.Table#scroll scroll} setting).
     *
     * Note that if you set overflow styles using the {@link #style} config or
     * {@link Ext.panel.Panel#bodyStyle bodyStyle} config, this object does not include
     * that information. Use {@link #scrollable} if you need to access these flags.
     *
     * This object has the following properties:
     * @property {Boolean} scrollFlags.x `true` if this Component is scrollable
     * horizontally - style setting may be `'auto'` or `'scroll'`.
     * @property {Boolean} scrollFlags.y `true` if this Component is scrollable
     * vertically - style setting may be `'auto'` or `'scroll'`.
     * @property {Boolean} scrollFlags.both `true` if this Component is scrollable both
     * horizontally and vertically.
     * @property {String} scrollFlags.overflowX The `overflow-x` style setting, `'auto'`
     * or `'scroll'` or `''`.
     * @property {String} scrollFlags.overflowY The `overflow-y` style setting, `'auto'`
     * or `'scroll'` or `''`.
     * @readonly
     * @private
     */
    _scrollFlags: {
        auto: {
            // x:auto, y:auto
            auto: {
                overflowX: 'auto',
                overflowY: 'auto',
                x: true,
                y: true,
                both: true
            },
            // x:auto, y:false
            'false': {
                overflowX: 'auto',
                overflowY: 'hidden',
                x: true,
                y: false,
                both: false
            },
            // x:auto, y:scroll
            scroll: {
                overflowX: 'auto',
                overflowY: 'scroll',
                x: true,
                y: true,
                both: true
            }
        },
        'false': {
            // x:false, y:auto
            auto: {
                overflowX: 'hidden',
                overflowY: 'auto',
                x: false,
                y: true,
                both: false
            },
            // x:false, y:false
            'false': {
                overflowX: 'hidden',
                overflowY: 'hidden',
                x: false,
                y: false,
                both: false
            },
            // x:false, y:scroll
            scroll: {
                overflowX: 'hidden',
                overflowY: 'scroll',
                x: false,
                y: true,
                both: false
            }
        },
        scroll: {
            // x:scroll, y:auto
            auto: {
                overflowX: 'scroll',
                overflowY: 'auto',
                x: true,
                y: true,
                both: true
            },
            // x:scroll, y:false
            'false': {
                overflowX: 'scroll',
                overflowY: 'hidden',
                x: true,
                y: false,
                both: false
            },
            // x:scroll, y:scroll
            scroll: {
                overflowX: 'scroll',
                overflowY: 'scroll',
                x: true,
                y: true,
                both: true
            }
        },
        none: {
            overflowX: '',
            overflowY: '',
            x: false,
            y: false,
            both: false
        }
    },
 
    _scrollableCfg: {
        x: {
            x: true,
            y: false
        },
        y: {
            x: false,
            y: true
        },
        horizontal: {
            x: true,
            y: false
        },
        vertical: {
            x: false,
            y: true
        },
        both: {
            x: true,
            y: true
        },
        'true': {
            x: true,
            y: true
        }
    },
 
    validIdRe: Ext.validIdRe,
 
    // ***********************************************************************************
    // End Properties
    // ***********************************************************************************
    // </editor-fold>
 
    // <editor-fold desc="Events">
    // ***********************************************************************************
    // Begin Events
    // ***********************************************************************************
 
    /**
     * @event afterlayoutanimation
     * This event first after a component's layout has been updated by a layout that
     * included animation (e.g., a {@link Ext.panel.Panel panel} in an
     * {@link Ext.layout.container.Accordion accordion} layout).
     * @param {Ext.Component} this 
     * @since 6.0.0
     */
 
    /**
     * @event beforeactivate
     * Fires before a Component has been visually activated. Returning `false` from an event
     * listener can prevent the activate from occurring.
     *
     * **Note** This event is only fired if this Component is a child of a
     * {@link Ext.container.Container} that uses {@link Ext.layout.container.Card} as it's layout.
     * @param {Ext.Component} this 
     */
 
    /**
     * @event activate
     * Fires after a Component has been visually activated.
     *
     * **Note** This event is only fired if this Component is a child of a
     * {@link Ext.container.Container} that uses {@link Ext.layout.container.Card} as it's layout
     * or this Component is a floating Component.
     * @param {Ext.Component} this 
     */
 
    /**
     * @event beforedeactivate
     * Fires before a Component has been visually deactivated. Returning `false` from an event
     * listener can prevent the deactivate from occurring.
     *
     * **Note** This event is only fired if this Component is a child of a
     * {@link Ext.container.Container} that uses {@link Ext.layout.container.Card} as it's layout.
     * @param {Ext.Component} this 
     */
 
    /**
     * @event deactivate
     * Fires after a Component has been visually deactivated.
     *
     * **Note** This event is only fired if this Component is a child of a
     * {@link Ext.container.Container} that uses {@link Ext.layout.container.Card} as it's layout
     * or this Component is a floating Component.
     * @param {Ext.Component} this 
     */
 
    /**
     * @event added
     * Fires after a Component had been added to a Container.
     * @param {Ext.Component} this 
     * @param {Ext.container.Container} container Parent Container
     * @param {Number} pos position of Component
     * @since 3.4.0
     */
 
    /**
     * @event disable
     * Fires after the component is disabled.
     * @param {Ext.Component} this 
     * @since 1.1.0
     */
 
    /**
     * @event enable
     * Fires after the component is enabled.
     * @param {Ext.Component} this 
     * @since 1.1.0
     */
 
    /**
     * @event beforeshow
     * Fires before the component is shown when calling the {@link Ext.Component#method-show show}
     * method. Return `false` from an event handler to stop the show.
     * @param {Ext.Component} this 
     * @since 1.1.0
     */
 
    /**
     * @event show
     * Fires after the component is shown when calling the {@link Ext.Component#method-show show}
     * method.
     * @param {Ext.Component} this 
     * @since 1.1.0
     */
 
    /**
     * @event beforehide
     * Fires before the component is hidden when calling the {@link Ext.Component#method-hide hide}
     * method. Return `false` from an event handler to stop the hide.
     * @param {Ext.Component} this 
     * @since 1.1.0
     */
 
    /**
     * @event hide
     * Fires after the component is hidden. Fires after the component is hidden when calling
     * the {@link Ext.Component#method-hide hide} method.
     * @param {Ext.Component} this 
     * @since 1.1.0
     */
 
    /**
     * @event removed
     * Fires when a component is removed from an Ext.container.Container
     * @param {Ext.Component} this 
     * @param {Ext.container.Container} ownerCt Container which holds the component
     * @since 3.4.0
     */
 
    /**
     * @event beforerender
     * Fires before the component is {@link #rendered}. Return `false` from an event handler
     * to stop the {@link #method-render}.
     * @param {Ext.Component} this 
     * @since 1.1.0
     */
 
    /**
     * @event render
     * Fires after the component markup is {@link #rendered}.
     * @param {Ext.Component} this 
     * @since 1.1.0
     */
 
    /**
     * @event afterrender
     * Fires after the component rendering is finished.
     *
     * The `afterrender` event is fired after this Component has been {@link #rendered},
     * been post-processed by any `afterRender` method defined for the Component.
     * @param {Ext.Component} this 
     * @since 3.4.0
     */
 
    /**
     * @event boxready
     * Fires *one time* - after the component has been laid out for the first time at its initial
     * size.
     *
     * This event does not fire on components that use {@link #cfg-liquidLayout}, such as
     * {@link Ext.button.Button Buttons} and {@link Ext.form.field.Base Form Fields}.
     * @param {Ext.Component} this 
     * @param {Number} width The initial width.
     * @param {Number} height The initial height.
     */
 
    /**
     * @event beforedestroy
     * Fires before the component is destroyed.
     *
     * **Note:** This event should not be used to try to veto the destruction sequence by returning
     *  `false`, even though this is often permitted in other "before" events. Doing so will have
     * unpredictable side-effects and can result in partially destroyed objects. Instead look to
     * other events like {@link Ext.panel.Panel#event!beforeclose beforeclose} that occur prior to
     * the call to the {@link Ext.Base#method!destroy destroy} method.
     *
     * @param {Ext.Component} this 
     * @since 1.1.0
     */
 
    /**
     * @event destroy
     * Fires after the component is {@link #method-destroy}ed.
     * @param {Ext.Component} this 
     * @since 1.1.0
     */
 
    /**
     * @event resize
     * Fires after the component is resized. Note that this does *not* fire when the component
     * is first laid out at its initial size. To hook that point in the life cycle, use the
     * {@link #boxready} event.
     *
     * This event does not fire on components that use {@link #cfg-liquidLayout}, such as
     * {@link Ext.button.Button Buttons} and {@link Ext.form.field.Base Form Fields}.
     * @param {Ext.Component} this 
     * @param {Number} width The new width that was set.
     * @param {Number} height The new height that was set.
     * @param {Number} oldWidth The previous width.
     * @param {Number} oldHeight The previous height.
     */
 
    /**
     * @event move
     * Fires after the component is moved.
     * @param {Ext.Component} this 
     * @param {Number} x The new x position.
     * @param {Number} y The new y position.
     */
 
    // ***********************************************************************************
    // End Events
    // ***********************************************************************************
    // </editor-fold>
 
    /**
     * Creates new Component.
     * @param {Ext.dom.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,
            i, len, xhooks, controller, autoScroll, overflowX, overflowY, scrollable;
 
        config = config || {};
 
        if (config.initialConfig) {
            // Being initialized from an Ext.Action instance...
            if (config.isAction) {
                me.baseAction = config;
            }
 
            config = config.initialConfig;
            // component cloning / action set up
        }
        else if (config.tagName || config.dom || Ext.isString(config)) {
            // element object
            config = {
                applyTo: config,
                id: config.id || config
            };
        }
 
        // Make initialConfig available early so that config getters may access it
        /**
         * @property {Object} initialConfig
         * @readonly
         * The config object passed to the constructor during Component creation.
         */
        me.initialConfig = config;
 
        me.$iid = ++Ext.$nextIid;
 
        // We want to determine very early on whether or not we are a reference holder,
        // so peek at either the incoming config or the class config to see if we have
        // a controller defined.
        if ((config && config.controller) || me.config.controller) {
            me.referenceHolder = true;
        }
 
        // Ensure that we have an id early so that config getters may access it
        me.getId();
        me.protoEl = new Ext.util.ProtoElement();
 
        //<debug>
        me.$calledInitConfig = true;
        //</debug>
 
        me.initConfig(config);
 
        //<debug>
        delete me.$calledInitConfig;
        //</debug>
 
        if (me.scrollable == null) {
            autoScroll = me.autoScroll;
 
            if (autoScroll) {
                scrollable = !!autoScroll;
            }
            else {
                overflowX = me.overflowX;
                overflowY = me.overflowY;
 
                if (overflowX || overflowY) {
                    scrollable = {
                        x: (overflowX && overflowX !== 'hidden') ? overflowX : false,
                        y: (overflowY && overflowY !== 'hidden') ? overflowY : false
                    };
                }
            }
 
            if (scrollable) {
                me.setScrollable(scrollable);
            }
        }
 
        xhooks = me.xhooks;
 
        if (xhooks) {
            delete me.xhooks;
            Ext.override(me, xhooks);
        }
 
        me.mixins.elementCt.constructor.call(me);
 
        //<debug>
        if (!me.validIdRe.test(me.id)) {
            Ext.raise('Invalid component "id": "' + me.id + '"');
        }
 
        if (!me.validIdRe.test(me.itemId)) {
            Ext.raise('Invalid component "itemId": "' + me.itemId + '"');
        }
        //</debug>
 
        me.setupProtoEl();
 
        // initComponent, beforeRender, or event handlers may have set the style
        // or `cls` property since the `protoEl` was set up so we must apply styles
        // and classes here too.
        if (me.cls) {
            me.initialCls = me.cls;
            me.protoEl.addCls(me.cls);
        }
 
        if (me.style) {
            me.initialStyle = me.style;
            me.protoEl.setStyle(me.style);
        }
 
        me.renderData = me.renderData || {};
 
        me.initComponent();
 
        // initComponent gets a chance to change the id property before registering
        if (!me.preventRegister) {
            Ext.ComponentManager.register(me);
        }
 
        me.mixins.state.constructor.call(me);
        me.addStateEvents('resize');
 
        controller = me.getController();
 
        if (controller) {
            controller.init(me);
        }
 
        // Move this into Observable?
        if (me.plugins) {
            for (= 0, len = me.plugins.length; i < len; i++) {
                me.plugins[i] = me.initPlugin(me.plugins[i]);
            }
        }
 
        me.loader = me.getLoader();
 
        if (me.disabled) {
            me.disabled = false;
            me.disable(true);
        }
 
        if (me.renderTo) {
            me.render(me.renderTo);
            // EXTJSIV-1935 - should be a way to do afterShow or something, but that
            // won't work. Likewise, rendering hidden and then showing (w/autoShow) has
            // implications to afterRender so we cannot do that.
        }
 
        // Auto show only works unilaterally on *uncontained* Components.
        // If contained, then it is the Container's responsibility to do the showing
        // at next layout time.
        if (me.autoShow && !me.$initParent) {
            me.show();
        }
 
        //<debug>
        if (Ext.isDefined(me.disabledClass)) {
            if (Ext.isDefined(Ext.global.console)) {
                Ext.global.console.warn('Ext.Component: disabledClass has been deprecated. ' +
                                        'Please use disabledCls.');
            }
 
            me.disabledCls = me.disabledClass;
            delete me.disabledClass;
        }
        //</debug>
 
        // 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 (me.baseAction) {
            me.baseAction.addComponent(me);
        }
    },
 
    beforeInitConfig: function() {
        //<debug>
        if (!this.$calledInitConfig) {
            Ext.raise('initConfig should not be called by subclasses, it will be ' +
                      'called by Ext.Component');
        }
        //</debug>
 
        this.mixins.observable.constructor.call(this);
    },
 
    // <editor-fold desc="Component Methods">
    // ***********************************************************************************
    // Begin Component Methods
    // ***********************************************************************************
 
    /**
     * Adds a CSS class to the top level element representing this component.
     * @param {String/String[]} cls The CSS class name to add.
     * @return {Ext.Component} Returns the Component to allow method chaining.
     */
    addCls: function(cls) {
        var me = this,
            el = me.rendered ? me.el : me.protoEl;
 
        el.addCls.apply(el, arguments);
 
        return me;
    },
 
    /**
     * Adds a `cls` to the `uiCls` array, which will also call {@link #addUIClsToElement}
     * and adds to all elements of this component.
     * @param {String/String[]} classes A string or an array of strings to add to the `uiCls`.
     * @param {Boolean} [skip] `true` to skip adding it to the class and do it later
     * (via the return).
     */
    addClsWithUI: function(classes, skip) {
        var me = this,
            clsArray = [],
            i = 0,
            uiCls = me.uiCls = Ext.Array.clone(me.uiCls),
            activeUI = me.activeUI,
            length,
            cls;
 
        if (typeof classes === "string") {
            classes = (classes.indexOf(' ') < 0) ? [classes] : Ext.String.splitWords(classes);
        }
 
        length = classes.length;
 
        for (; i < length; i++) {
            cls = classes[i];
 
            if (cls && !me.hasUICls(cls)) {
                uiCls.push(cls);
 
                // We can skip this bit if there isn't an activeUI because
                // we'll be called again from setUI
                if (activeUI) {
                    clsArray = clsArray.concat(me.addUIClsToElement(cls));
                }
            }
        }
 
        if (skip !== true && activeUI) {
            me.addCls(clsArray);
        }
 
        return clsArray;
    },
 
    /**
     * Called by the layout system after the Component has been laid out.
     *
     * This method is not called on components that use {@link #cfg-liquidLayout}, such as
     * {@link Ext.button.Button Buttons} and {@link Ext.form.field.Base Form Fields}.
     *
     * @param {Number} width The width that was set
     * @param {Number} height The height that was set
     * @param {Number/undefined} oldWidth The old width, or `undefined` if this was the initial
     * layout.
     * @param {Number/undefined} oldHeight The old height, or `undefined` if this was the initial
     * layout.
     *
     * @template
     * @protected
     */
    afterComponentLayout: function(width, height, oldWidth, oldHeight) {
        var me = this,
            scroller = me.scrollable;
 
        if (++me.componentLayoutCounter === 1) {
            me.afterFirstLayout(width, height);
        }
        else if (me.manageLayoutScroll && scroller) {
            scroller.restoreState();
        }
 
        if (width !== oldWidth || height !== oldHeight) {
            me.onResize(width, height, oldWidth, oldHeight);
        }
 
        if (me.floating) {
            me.onAfterFloatLayout();
        }
    },
 
    /**
     * @protected
     * Adds a plugin. May be called at any time in the component's life cycle.
     */
    addPlugin: function(plugin) {
        var me = this;
 
        plugin = me.constructPlugin(plugin);
 
        if (me.plugins) {
            me.plugins.push(plugin);
        }
        else {
            me.plugins = [ plugin ];
        }
 
        if (me.pluginsInitialized) {
            me.initPlugin(plugin);
        }
 
        return plugin;
    },
 
    /**
     * Save a property to the given state object if it is not its default or configured
     * value.
     *
     * @param {Object} state The state object.
     * @param {String} propName The name of the property on this object to save.
     * @param {String} [value] The value of the state property (defaults to `this[propName]`).
     * @return {Object} The state object or a new object if state was `null` and the property
     * was saved.
     * @protected
     */
    addPropertyToState: function(state, propName, value) {
        var me = this,
            len = arguments.length;
 
        // If the property is inherited, it is a default and we don't want to save it to
        // the state, however if we explicitly specify a value, always save it
        if (len === 3 || me.hasOwnProperty(propName)) {
            if (len < 3) {
                value = me[propName];
            }
 
            // If the property has the same value as was initially configured, again, we
            // don't want to save it.
            if (value !== me.initialConfig[propName]) {
                (state || (state = {}))[propName] = value;
            }
        }
 
        return state;
    },
 
    /**
     * Method which adds a specified UI + `uiCls` to the components element. Can be overridden
     * to add the UI to more than just the component's element.
     * @param {String} uiCls The UI class to add to the element.
     * @protected
     */
    addUIClsToElement: function(uiCls) {
        var me = this,
            baseClsUI = me.baseCls + '-' + me.ui + '-' + uiCls,
            result = [Ext.baseCSSPrefix + uiCls, me.baseCls + '-' + uiCls, baseClsUI],
            childEls, childElName, el, suffix;
 
        if (me.rendered && me.frame && !Ext.supports.CSS3BorderRadius) {
            // Loop through each frame element, and if they are defined add the ui:
            baseClsUI += '-';
            childEls = me.getChildEls();
 
            for (childElName in childEls) {
                suffix = childEls[childElName].frame;
 
                if (suffix && suffix !== true) {
                    el = me[childElName];
 
                    if (el) {
                        el.addCls(baseClsUI + suffix);
                    }
                }
            }
        }
 
        return result;
    },
 
    /**
     * Method which removes a specified UI + `uiCls` from the components element. The `cls`
     * which is added to the element will be: `this.baseCls + '-' + ui + uiCls`.
     * @param {String} uiCls The UI class to remove from the element.
     * @protected
     */
    removeUIClsFromElement: function(uiCls) {