/** * 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 (i = 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) {