<!DOCTYPE html>
|
<html>
|
<head>
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
<title>The source code</title>
|
<link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" />
|
<script type="text/javascript" src="../resources/prettify/prettify.js"></script>
|
<style type="text/css">
|
.highlight { display: block; background-color: #ddd; }
|
</style>
|
<script type="text/javascript">
|
function highlight() {
|
document.getElementById(location.hash.replace(/#/, "")).className = "highlight";
|
}
|
</script>
|
</head>
|
<body onload="prettyPrint(); highlight();">
|
<pre class="prettyprint lang-js"><span id='Ext-container-AbstractContainer'>/**
|
</span> * An abstract base class which provides shared methods for Containers across the Sencha product line.
|
*
|
* Please refer to sub class's documentation
|
*
|
* @private
|
*/
|
Ext.define('Ext.container.AbstractContainer', {
|
|
/* Begin Definitions */
|
|
extend: 'Ext.Component',
|
|
requires: [
|
'Ext.util.MixedCollection',
|
'Ext.layout.container.Auto',
|
'Ext.ZIndexManager'
|
],
|
|
mixins: {
|
queryable: 'Ext.Queryable'
|
},
|
|
<span id='Ext-container-AbstractContainer-cfg-renderTpl'> /* End Definitions */
|
</span>
|
renderTpl: '{%this.renderContainer(out,values)%}',
|
|
<span id='Ext-container-AbstractContainer-cfg-layout'> /**
|
</span> * @cfg {Ext.enums.Layout/Object} layout
|
* **Important**: In order for child items to be correctly sized and
|
* positioned, typically a layout manager **must** be specified through
|
* the `layout` configuration option.
|
*
|
* The sizing and positioning of child {@link #cfg-items} is the responsibility of
|
* the Container's layout manager which creates and manages the type of layout
|
* you have in mind. For example:
|
*
|
* If the layout configuration is not explicitly specified for
|
* a general purpose container (e.g. Container or Panel) the
|
* {@link Ext.layout.container.Auto default layout manager} will be used
|
* which does nothing but render child components sequentially into the
|
* Container (no sizing or positioning will be performed in this situation).
|
*
|
* **layout** may be specified as either as an Object or as a String:
|
*
|
* ## Specify as an Object
|
*
|
* Example usage:
|
*
|
* layout: {
|
* type: 'vbox',
|
* align: 'left'
|
* }
|
*
|
* - **type**
|
*
|
* The layout type to be used for this container. If not specified,
|
* a default {@link Ext.layout.container.Auto} will be created and used.
|
*
|
* Valid layout <code>type</code> values are listed in {@link Ext.enums.Layout}.
|
*
|
* - Layout specific configuration properties
|
*
|
* Additional layout specific configuration properties may also be
|
* specified. For complete details regarding the valid config options for
|
* each layout type, see the layout class corresponding to the `type`
|
* specified.
|
*
|
* ## Specify as a String
|
*
|
* Example usage:
|
*
|
* layout: 'vbox'
|
*
|
* - **layout**
|
*
|
* The layout `type` to be used for this container (see {@link Ext.enums.Layout}
|
* for list of valid values).
|
*
|
* Additional layout specific configuration properties. For complete
|
* details regarding the valid config options for each layout type, see the
|
* layout class corresponding to the `layout` specified.
|
*
|
* ## Configuring the default layout type
|
*
|
* If a certain Container class has a default layout (For example a {@link Ext.toolbar.Toolbar Toolbar}
|
* with a default `Box` layout), then to simply configure the default layout,
|
* use an object, but without the `type` property:
|
*
|
*
|
* xtype: 'toolbar',
|
* layout: {
|
* pack: 'center'
|
* }
|
*
|
* @since 2.3.0
|
*/
|
|
<span id='Ext-container-AbstractContainer-cfg-activeItem'> /**
|
</span> * @cfg {String/Number} activeItem
|
* A string component id or the numeric index of the component that should be
|
* initially activated within the container's layout on render. For example,
|
* activeItem: 'item-1' or activeItem: 0 (index 0 = the first item in the
|
* container's collection). activeItem only applies to layout styles that can
|
* display items one at a time (like {@link Ext.layout.container.Card} and
|
* {@link Ext.layout.container.Fit}).
|
*
|
* @since 2.3.0
|
*/
|
|
<span id='Ext-container-AbstractContainer-cfg-items'> /**
|
</span> * @cfg {Object/Object[]} items
|
* A single item, or an array of child Components to be added to this container
|
*
|
* **Unless configured with a {@link #layout}, a Container simply renders child
|
* Components serially into its encapsulating element and performs no sizing or
|
* positioning upon them.**
|
*
|
* Example:
|
*
|
* // specifying a single item
|
* items: {...},
|
* layout: 'fit', // The single items is sized to fit
|
*
|
* // specifying multiple items
|
* items: [{...}, {...}],
|
* layout: 'hbox', // The items are arranged horizontally
|
*
|
* Each item may be:
|
*
|
* - A {@link Ext.Component Component}
|
* - A Component configuration object
|
*
|
* If a configuration object is specified, the actual type of Component to be
|
* instantiated my be indicated by using the {@link Ext.Component#xtype xtype} option.
|
*
|
* Every Component class has its own {@link Ext.Component#xtype xtype}.
|
*
|
* If an {@link Ext.Component#xtype xtype} is not explicitly specified, the
|
* {@link #defaultType} for the Container is used, which by default is usually `panel`.
|
*
|
* # Notes:
|
*
|
* Ext uses lazy rendering. Child Components will only be rendered
|
* should it become necessary. Items are automatically laid out when they are first
|
* shown (no sizing is done while hidden), or in response to a {@link #doLayout} call.
|
*
|
* Do not specify {@link Ext.panel.Panel#contentEl contentEl} or
|
* {@link Ext.panel.Panel#html html} with `items`.
|
*
|
* @since 2.3.0
|
*/
|
|
<span id='Ext-container-AbstractContainer-cfg-defaults'> /**
|
</span> * @cfg {Object/Function} defaults
|
* This option is a means of applying default settings to all added items whether added
|
* through the {@link #cfg-items} config or via the {@link #method-add} or {@link #insert} methods.
|
*
|
* Defaults are applied to both config objects and instantiated components conditionally
|
* so as not to override existing properties in the item (see {@link Ext#applyIf}).
|
*
|
* If the defaults option is specified as a function, then the function will be called
|
* using this Container as the scope (`this` reference) and passing the added item as
|
* the first parameter. Any resulting object from that call is then applied to the item
|
* as default properties.
|
*
|
* For example, to automatically apply padding to the body of each of a set of
|
* contained {@link Ext.panel.Panel} items, you could pass:
|
* `defaults: {bodyStyle:'padding:15px'}`.
|
*
|
* Usage:
|
*
|
* defaults: { // defaults are applied to items, not the container
|
* autoScroll: true
|
* },
|
* items: [
|
* // default will not be applied here, panel1 will be autoScroll: false
|
* {
|
* xtype: 'panel',
|
* id: 'panel1',
|
* autoScroll: false
|
* },
|
* // this component will have autoScroll: true
|
* new Ext.panel.Panel({
|
* id: 'panel2'
|
* })
|
* ]
|
*
|
* @since 2.3.0
|
*/
|
|
<span id='Ext-container-AbstractContainer-cfg-suspendLayout'> /**
|
</span> * @cfg {Boolean} suspendLayout
|
* If true, suspend calls to doLayout. Useful when batching multiple adds to a container
|
* and not passing them as multiple arguments or an array.
|
*/
|
suspendLayout : false,
|
|
<span id='Ext-container-AbstractContainer-cfg-autoDestroy'> /**
|
</span> * @cfg {Boolean} [autoDestroy=true]
|
* If true the container will automatically destroy any contained component that is removed
|
* from it, else destruction must be handled manually.
|
* @since 2.3.0
|
*/
|
autoDestroy : true,
|
|
<span id='Ext-container-AbstractContainer-cfg-defaultType'> /**
|
</span> * @cfg {String} [defaultType="panel"]
|
* The default {@link Ext.Component xtype} of child Components to create in this Container when
|
* a child item is specified as a raw configuration object, rather than as an instantiated Component.
|
* @since 2.3.0
|
*/
|
defaultType: 'panel',
|
|
<span id='Ext-container-AbstractContainer-cfg-detachOnRemove'> /**
|
</span> * @cfg {Boolean} [detachOnRemove=true]
|
* True to move any component to the {@link Ext#getDetachedBody detachedBody} when the component is
|
* removed from this container. This option is only applicable when the component is not destroyed while
|
* being removed, see {@link #autoDestroy} and {@link #method-remove}. If this option is set to false, the DOM
|
* of the component will remain in the current place until it is explicitly moved.
|
*/
|
detachOnRemove: true,
|
|
<span id='Ext-container-AbstractContainer-property-isContainer'> /*
|
</span> * @property {Boolean} isContainer
|
* `true` in this class to identify an object as an instantiated Container, or subclass thereof.
|
*/
|
isContainer : true,
|
|
<span id='Ext-container-AbstractContainer-property-layoutCounter'> /**
|
</span> * @property {Number} layoutCounter
|
* The number of container layout calls made on this object.
|
* @private
|
*/
|
layoutCounter : 0,
|
|
<span id='Ext-container-AbstractContainer-cfg-baseCls'> baseCls: Ext.baseCSSPrefix + 'container',
|
</span>
|
<span id='Ext-container-AbstractContainer-cfg-bubbleEvents'> /**
|
</span> * @cfg {String[]} bubbleEvents
|
* An array of events that, when fired, should be bubbled to any parent container.
|
* See {@link Ext.util.Observable#enableBubble}.
|
* @since 3.4.0
|
*/
|
|
defaultLayoutType: 'auto',
|
|
<span id='Ext-container-AbstractContainer-method-initComponent'> // @private
|
</span> initComponent : function(){
|
var me = this;
|
me.addEvents(
|
<span id='Ext-container-AbstractContainer-event-afterlayout'> /**
|
</span> * @event afterlayout
|
* Fires when the components in this container are arranged by the associated layout manager.
|
* @param {Ext.container.Container} this
|
* @param {Ext.layout.container.Container} layout The ContainerLayout implementation for this container
|
* @since 2.3.0
|
*/
|
'afterlayout',
|
<span id='Ext-container-AbstractContainer-event-beforeadd'> /**
|
</span> * @event beforeadd
|
* Fires before any {@link Ext.Component} is added or inserted into the container.
|
* A handler can return false to cancel the add.
|
* @param {Ext.container.Container} this
|
* @param {Ext.Component} component The component being added
|
* @param {Number} index The index at which the component will be added to the container's items collection
|
* @since 2.3.0
|
*/
|
'beforeadd',
|
<span id='Ext-container-AbstractContainer-event-beforeremove'> /**
|
</span> * @event beforeremove
|
* Fires before any {@link Ext.Component} is removed from the container. A handler can return
|
* false to cancel the remove.
|
* @param {Ext.container.Container} this
|
* @param {Ext.Component} component The component being removed
|
* @since 2.3.0
|
*/
|
'beforeremove',
|
<span id='Ext-container-AbstractContainer-event-add'> /**
|
</span> * @event add
|
* Fires after any {@link Ext.Component} is added or inserted into the container.
|
*
|
* **This event bubbles:** 'add' will also be fired when Component is added to any of
|
* the child containers or their childern or ...
|
* @param {Ext.container.Container} this
|
* @param {Ext.Component} component The component that was added
|
* @param {Number} index The index at which the component was added to the container's items collection
|
* @since 2.3.0
|
*/
|
'add',
|
<span id='Ext-container-AbstractContainer-event-remove'> /**
|
</span> * @event remove
|
* Fires after any {@link Ext.Component} is removed from the container.
|
*
|
* **This event bubbles:** 'remove' will also be fired when Component is removed from any of
|
* the child containers or their children or ...
|
* @param {Ext.container.Container} this
|
* @param {Ext.Component} component The component that was removed
|
* @since 2.3.0
|
*/
|
'remove'
|
);
|
|
me.callParent();
|
|
me.getLayout();
|
me.initItems();
|
},
|
|
<span id='Ext-container-AbstractContainer-method-initItems'> // @private
|
</span> initItems : function() {
|
var me = this,
|
items = me.items;
|
|
<span id='Ext-container-AbstractContainer-property-items'> /**
|
</span> * The MixedCollection containing all the child items of this container.
|
* @property items
|
* @type Ext.util.AbstractMixedCollection
|
* @since 2.3.0
|
*/
|
me.items = new Ext.util.AbstractMixedCollection(false, me.getComponentId);
|
me.floatingItems = new Ext.util.MixedCollection(false, me.getComponentId);
|
|
if (items) {
|
if (!Ext.isArray(items)) {
|
items = [items];
|
}
|
|
me.add(items);
|
}
|
},
|
|
<span id='Ext-container-AbstractContainer-method-getFocusEl'> /**
|
</span> * @private
|
* Returns the focus holder element associated with this Container. By default, this is the Container's target
|
* element. Subclasses which use embedded focusable elements (such as Window and Button) should override this for use
|
* by the {@link #method-focus} method.
|
* @returns {Ext.Element} the focus holding element.
|
*/
|
getFocusEl: function() {
|
return this.getTargetEl();
|
},
|
|
<span id='Ext-container-AbstractContainer-method-finishRenderChildren'> finishRenderChildren: function () {
|
</span> this.callParent();
|
|
var layout = this.getLayout();
|
|
if (layout) {
|
layout.finishRender();
|
}
|
},
|
|
<span id='Ext-container-AbstractContainer-method-beforeRender'> beforeRender: function () {
|
</span> var me = this,
|
layout = me.getLayout(),
|
targetCls;
|
|
me.callParent();
|
|
if (!layout.initialized) {
|
layout.initLayout();
|
}
|
|
targetCls = layout.targetCls;
|
|
if (targetCls) {
|
me.applyTargetCls(targetCls);
|
}
|
},
|
|
<span id='Ext-container-AbstractContainer-method-applyTargetCls'> // The targetCls is a CSS class that the layout needs added to the targetEl. The targetEl is where the container's
|
</span> // children are rendered and is usually just the main el. Some containers (e.g. panels) use a body instead.
|
//
|
// In general, if a class overrides getTargetEl it will also need to override this method. This is necessary to
|
// avoid a post-render step to add the targetCls.
|
applyTargetCls: function(targetCls) {
|
this.addCls(targetCls);
|
},
|
|
<span id='Ext-container-AbstractContainer-method-afterComponentLayout'> afterComponentLayout: function() {
|
</span> var floaters = this.floatingItems.items,
|
floaterCount = floaters.length,
|
i, floater
|
|
this.callParent(arguments);
|
|
// Contained, unrendered, autoShow items must be shown upon next layout of the Container
|
for (i = 0; i < floaterCount; i++) {
|
floater = floaters[i];
|
if (!floater.rendered && floater.autoShow) {
|
floater.show();
|
}
|
}
|
},
|
|
<span id='Ext-container-AbstractContainer-method-onPosition'> onPosition: function() {
|
</span> this.callParent(arguments);
|
this.repositionFloatingItems();
|
},
|
|
<span id='Ext-container-AbstractContainer-method-onResize'> onResize: function() {
|
</span> this.callParent(arguments);
|
this.repositionFloatingItems();
|
},
|
|
<span id='Ext-container-AbstractContainer-method-repositionFloatingItems'> repositionFloatingItems: function() {
|
</span> var floaters = this.floatingItems.items,
|
floaterCount = floaters.length,
|
i, floater;
|
|
// Ensure correct positioning of floated children before calling superclass
|
for (i = 0; i < floaterCount; i++) {
|
floater = floaters[i];
|
if (floater.el && !floater.hidden) {
|
floater.setPosition(floater.x, floater.y);
|
}
|
}
|
},
|
|
<span id='Ext-container-AbstractContainer-method-setupRenderTpl'> setupRenderTpl: function (renderTpl) {
|
</span> this.callParent(arguments);
|
this.getLayout().setupRenderTpl(renderTpl);
|
},
|
|
<span id='Ext-container-AbstractContainer-method-getDefaultContentTarget'> // @private
|
</span> getDefaultContentTarget: function() {
|
return this.el;
|
},
|
|
<span id='Ext-container-AbstractContainer-method-getContentTarget'> // @private
|
</span> getContentTarget: function(){
|
return this.getLayout().getContentTarget();
|
},
|
|
<span id='Ext-container-AbstractContainer-method-setLayout'> // @private
|
</span> setLayout : function(layout) {
|
var currentLayout = this.layout;
|
|
if (currentLayout && currentLayout.isLayout && currentLayout != layout) {
|
currentLayout.setOwner(null);
|
}
|
|
this.layout = layout;
|
layout.setOwner(this);
|
},
|
|
<span id='Ext-container-AbstractContainer-method-getLayout'> /**
|
</span> * Returns the {@link Ext.layout.container.Container layout} instance currently associated with this Container.
|
* If a layout has not been instantiated yet, that is done first
|
* @return {Ext.layout.container.Container} The layout
|
*/
|
getLayout : function() {
|
var me = this;
|
if (!me.layout || !me.layout.isLayout) {
|
// Pass any configured in layout property, defaulting to the prototype's layout property, falling back to Auto.
|
me.setLayout(Ext.layout.Layout.create(me.layout, me.self.prototype.layout || me.defaultLayoutType));
|
}
|
|
return me.layout;
|
},
|
|
<span id='Ext-container-AbstractContainer-method-doLayout'> /**
|
</span> * Manually force this container's layout to be recalculated. The framework uses this internally to refresh layouts
|
* form most cases.
|
* @return {Ext.container.Container} this
|
* @since 2.3.0
|
*/
|
doLayout : function() {
|
this.updateLayout();
|
return this;
|
},
|
|
<span id='Ext-container-AbstractContainer-method-afterLayout'> /**
|
</span> * Invoked after the Container has laid out (and rendered if necessary)
|
* its child Components.
|
*
|
* @param {Ext.layout.container.Container} layout
|
*
|
* @template
|
* @protected
|
*/
|
afterLayout : function(layout) {
|
var me = this;
|
++me.layoutCounter;
|
if (me.hasListeners.afterlayout) {
|
me.fireEvent('afterlayout', me, layout);
|
}
|
},
|
|
<span id='Ext-container-AbstractContainer-method-prepareItems'> // @private
|
</span> prepareItems : function(items, applyDefaults) {
|
// Create an Array which does not refer to the passed array.
|
// The passed array is a reference to a user's config object and MUST NOT be mutated.
|
if (Ext.isArray(items)) {
|
items = items.slice();
|
} else {
|
items = [items];
|
}
|
|
// Make sure defaults are applied and item is initialized
|
var me = this,
|
i = 0,
|
len = items.length,
|
item;
|
|
for (; i < len; i++) {
|
item = items[i];
|
if (item == null) {
|
Ext.Array.erase(items, i, 1);
|
--i;
|
--len;
|
} else {
|
if (applyDefaults) {
|
item = this.applyDefaults(item);
|
}
|
|
// Tell the item we're in a container during construction
|
item.isContained = me;
|
items[i] = me.lookupComponent(item);
|
// need to delete both in case item was a config
|
delete item.isContained;
|
delete items[i].isContained;
|
}
|
}
|
|
return items;
|
},
|
|
<span id='Ext-container-AbstractContainer-method-applyDefaults'> // @private
|
</span> applyDefaults : function(config) {
|
var defaults = this.defaults;
|
|
if (defaults) {
|
if (Ext.isFunction(defaults)) {
|
defaults = defaults.call(this, config);
|
}
|
|
if (Ext.isString(config)) {
|
config = Ext.ComponentManager.get(config);
|
}
|
Ext.applyIf(config, defaults);
|
}
|
return config;
|
},
|
|
<span id='Ext-container-AbstractContainer-method-lookupComponent'> // @private
|
</span> lookupComponent : function(comp) {
|
return (typeof comp == 'string') ? Ext.ComponentManager.get(comp)
|
: Ext.ComponentManager.create(comp, this.defaultType);
|
},
|
|
<span id='Ext-container-AbstractContainer-method-getComponentId'> // @private - used as the key lookup function for the items collection
|
</span> getComponentId : function(comp) {
|
return comp.getItemId && comp.getItemId();
|
},
|
|
<span id='Ext-container-AbstractContainer-method-add'> /**
|
</span> * Adds {@link Ext.Component Component}(s) to this Container.
|
*
|
* ## Description:
|
*
|
* - Fires the {@link #beforeadd} event before adding.
|
* - The Container's {@link #defaults default config values} will be applied
|
* accordingly (see `{@link #defaults}` for details).
|
* - Fires the `{@link #event-add}` event after the component has been added.
|
*
|
* ## Notes:
|
*
|
* If the Container is __already rendered__ when `add`
|
* is called, it will render the newly added Component into its content area.
|
*
|
* **If** the Container was configured with a size-managing {@link #layout} manager,
|
* the Container will recalculate its internal layout at this time too.
|
*
|
* Note that the default layout manager simply renders child Components sequentially
|
* into the content area and thereafter performs no sizing.
|
*
|
* If adding multiple new child Components, pass them as an array to the `add` method,
|
* so that only one layout recalculation is performed.
|
*
|
* tb = new {@link Ext.toolbar.Toolbar}({
|
* renderTo: document.body
|
* }); // toolbar is rendered
|
* // add multiple items.
|
* // ({@link #defaultType} for {@link Ext.toolbar.Toolbar Toolbar} is 'button')
|
* tb.add([{text:'Button 1'}, {text:'Button 2'}]);
|
*
|
* To inject components between existing ones, use the {@link #insert} method.
|
*
|
* ## Warning:
|
*
|
* Components directly managed by the BorderLayout layout manager may not be removed
|
* or added. See the Notes for {@link Ext.layout.container.Border BorderLayout} for
|
* more details.
|
*
|
* @param {Ext.Component[]|Object[]/Ext.Component.../Object...} component
|
* Either one or more Components to add or an Array of Components to add.
|
* See `{@link #cfg-items}` for additional information.
|
*
|
* @return {Ext.Component[]/Ext.Component} The Components that were added.
|
*
|
* @since 2.3.0
|
*/
|
add : function() {
|
var me = this,
|
args = Ext.Array.slice(arguments),
|
index = (typeof args[0] == 'number') ? args.shift() : -1,
|
layout = me.getLayout(),
|
addingArray, items, i, length, item, pos, ret;
|
|
if (args.length == 1 && Ext.isArray(args[0])) {
|
items = args[0];
|
addingArray = true;
|
} else {
|
items = args;
|
}
|
|
if (me.rendered) {
|
Ext.suspendLayouts(); // suspend layouts while adding items...
|
}
|
|
ret = items = me.prepareItems(items, true);
|
length = items.length;
|
|
if (!addingArray && length == 1) { // an array of 1 should still return an array...
|
ret = items[0];
|
}
|
|
// loop
|
for (i = 0; i < length; i++) {
|
item = items[i];
|
//<debug>
|
if (!item) {
|
Ext.Error.raise("Cannot add null item to Container with itemId/id: " + me.getItemId());
|
}
|
//</debug>
|
|
pos = (index < 0) ? me.items.length : (index + i);
|
|
// Floating Components are not added into the items collection, but to a separate floatingItems collection
|
if (item.floating) {
|
me.floatingItems.add(item);
|
item.onAdded(me, pos);
|
|
if (me.hasListeners.add) {
|
me.fireEvent('add', me, item, pos);
|
}
|
} else if ((!me.hasListeners.beforeadd || me.fireEvent('beforeadd', me, item, pos) !== false) && me.onBeforeAdd(item) !== false) {
|
me.items.insert(pos, item);
|
item.onAdded(me, pos);
|
me.onAdd(item, pos);
|
layout.onAdd(item, pos);
|
|
if (me.hasListeners.add) {
|
me.fireEvent('add', me, item, pos);
|
}
|
}
|
}
|
|
// We need to update our layout after adding all passed items
|
me.updateLayout();
|
if (me.rendered) {
|
Ext.resumeLayouts(true);
|
}
|
|
return ret;
|
},
|
|
<span id='Ext-container-AbstractContainer-method-onAdd'> /**
|
</span> * This method is invoked after a new Component has been added. It
|
* is passed the Component which has been added. This method may
|
* be used to update any internal structure which may depend upon
|
* the state of the child items.
|
*
|
* @param {Ext.Component} component
|
* @param {Number} position
|
*
|
* @template
|
* @protected
|
*/
|
onAdd : Ext.emptyFn,
|
|
<span id='Ext-container-AbstractContainer-method-onRemove'> /**
|
</span> * This method is invoked after a new Component has been
|
* removed. It is passed the Component which has been
|
* removed. This method may be used to update any internal
|
* structure which may depend upon the state of the child items.
|
*
|
* @param {Ext.Component} component
|
* @param {Boolean} autoDestroy
|
*
|
* @template
|
* @protected
|
*/
|
onRemove : Ext.emptyFn,
|
|
<span id='Ext-container-AbstractContainer-method-insert'> /**
|
</span> * Inserts a Component into this Container at a specified index. Fires the
|
* {@link #beforeadd} event before inserting, then fires the {@link #event-add}
|
* event after the Component has been inserted.
|
*
|
* @param {Number} index The index at which the Component will be inserted
|
* into the Container's items collection
|
*
|
* @param {Ext.Component/Object} component The child Component to insert.
|
*
|
* Ext uses lazy rendering, and will only render the inserted Component should
|
* it become necessary.
|
*
|
* A Component config object may be passed in order to avoid the overhead of
|
* constructing a real Component object if lazy rendering might mean that the
|
* inserted Component will not be rendered immediately. To take advantage of
|
* this 'lazy instantiation', set the {@link Ext.Component#xtype} config
|
* property to the registered type of the Component wanted.
|
*
|
* For a list of all available xtypes, see {@link Ext.enums.Widget}.
|
*
|
* @return {Ext.Component} component The Component (or config object) that was
|
* inserted with the Container's default config values applied.
|
*
|
* @since 2.3.0
|
*/
|
insert : function(index, comp) {
|
var compIdx;
|
if (comp && comp.isComponent) {
|
compIdx = this.items.indexOf(comp);
|
if (compIdx !== -1) {
|
return this.move(compIdx, index);
|
}
|
}
|
return this.add(index, comp);
|
},
|
|
<span id='Ext-container-AbstractContainer-method-move'> /**
|
</span> * Moves a Component within the Container
|
* @param {Number/Ext.Component} fromIdx The index/component to move.
|
* @param {Number} toIdx The new index for the Component.
|
* @return {Ext.Component} component The Component that was moved.
|
*/
|
move : function(fromIdx, toIdx) {
|
var items = this.items,
|
item;
|
|
if (fromIdx.isComponent) {
|
fromIdx = items.indexOf(fromIdx);
|
}
|
item = items.removeAt(fromIdx);
|
if (item === false) {
|
return false;
|
}
|
items.insert(toIdx, item);
|
this.onMove(item, fromIdx, toIdx);
|
this.updateLayout();
|
return item;
|
},
|
|
<span id='Ext-container-AbstractContainer-method-onMove'> onMove: Ext.emptyFn,
|
</span>
|
<span id='Ext-container-AbstractContainer-method-onBeforeAdd'> /**
|
</span> * This method is invoked before adding a new child Component. It
|
* is passed the new Component, and may be used to modify the
|
* Component, or prepare the Container in some way. Returning
|
* false aborts the add operation.
|
*
|
* @param {Ext.Component} item
|
*
|
* @template
|
* @protected
|
*/
|
onBeforeAdd : function(item) {
|
// Remove from current container if it's not us.
|
if (item.ownerCt && item.ownerCt !== this) {
|
item.ownerCt.remove(item, false);
|
}
|
},
|
|
<span id='Ext-container-AbstractContainer-method-remove'> /**
|
</span> * Removes a component from this container. Fires the {@link #beforeremove} event
|
* before removing, then fires the {@link #event-remove} event after the component has
|
* been removed.
|
*
|
* @param {Ext.Component/String} component The component reference or id to remove.
|
*
|
* @param {Boolean} [autoDestroy] True to automatically invoke the removed Component's
|
* {@link Ext.Component#method-destroy} function.
|
*
|
* Defaults to the value of this Container's {@link #autoDestroy} config.
|
*
|
* @return {Ext.Component} component The Component that was removed.
|
* @since 2.3.0
|
*/
|
remove : function(comp, autoDestroy) {
|
var me = this,
|
c = me.getComponent(comp);
|
//<debug>
|
if (Ext.isDefined(Ext.global.console) && !c) {
|
Ext.global.console.warn("Attempted to remove a component that does not exist. Ext.container.Container: remove takes an argument of the component to remove. cmp.remove() is incorrect usage.");
|
}
|
//</debug>
|
|
if (c && (!me.hasListeners.beforeremove || me.fireEvent('beforeremove', me, c) !== false)) {
|
me.doRemove(c, autoDestroy);
|
if (me.hasListeners.remove) {
|
me.fireEvent('remove', me, c);
|
}
|
|
if (!me.destroying && !c.floating) {
|
me.updateLayout();
|
}
|
}
|
|
return c;
|
},
|
|
<span id='Ext-container-AbstractContainer-method-doRemove'> // @private
|
</span> doRemove : function(component, doDestroy) {
|
// Ensure the flag is set correctly
|
doDestroy = doDestroy === true || (doDestroy !== false && this.autoDestroy);
|
|
var me = this,
|
layout = me.layout,
|
hasLayout = layout && me.rendered,
|
|
// isDestroying flag is true if the removal is taking place as part of destruction, OR if removal is intended to *cause* destruction
|
isDestroying = component.destroying || doDestroy,
|
floating = component.floating;
|
|
if (floating) {
|
me.floatingItems.remove(component);
|
} else {
|
me.items.remove(component);
|
}
|
|
// Inform ownerLayout of removal before deleting the ownerLayout & ownerCt references in the onRemoved call
|
if (hasLayout && !floating) {
|
// Removing a component from a running layout has to cancel the layout
|
if (layout.running) {
|
Ext.AbstractComponent.cancelLayout(component, isDestroying);
|
}
|
layout.onRemove(component, isDestroying);
|
}
|
|
component.onRemoved(isDestroying);
|
|
me.onRemove(component, isDestroying);
|
|
// Destroy if we were explicitly told to, or we're defaulting to our autoDestroy configuration
|
if (doDestroy) {
|
component.destroy();
|
}
|
// Only have the layout perform remove postprocessing if the Component is not being destroyed
|
else {
|
if (hasLayout && !floating) {
|
layout.afterRemove(component);
|
}
|
if (me.detachOnRemove && component.rendered) {
|
me.detachComponent(component);
|
}
|
}
|
},
|
|
<span id='Ext-container-AbstractContainer-method-detachComponent'> // Detach a component from the DOM
|
</span> detachComponent: function(component){
|
Ext.getDetachedBody().appendChild(component.getEl());
|
},
|
|
<span id='Ext-container-AbstractContainer-method-removeAll'> /**
|
</span> * Removes all components from this container.
|
* @param {Boolean} [autoDestroy] True to automatically invoke the removed
|
* Component's {@link Ext.Component#method-destroy} function.
|
* Defaults to the value of this Container's {@link #autoDestroy} config.
|
* @return {Ext.Component[]} Array of the removed components
|
* @since 2.3.0
|
*/
|
removeAll : function(autoDestroy) {
|
var me = this,
|
removeItems = me.items.items.slice().concat(me.floatingItems.items),
|
items = [],
|
i = 0,
|
len = removeItems.length,
|
item;
|
|
// Suspend Layouts while we remove multiple items from the container
|
me.suspendLayouts();
|
for (; i < len; i++) {
|
item = removeItems[i];
|
me.remove(item, autoDestroy);
|
|
if (item.ownerCt !== me) {
|
items.push(item);
|
}
|
}
|
|
// Resume Layouts now that all items have been removed and do a single layout (if we removed anything!)
|
me.resumeLayouts(!!len);
|
return items;
|
},
|
|
<span id='Ext-container-AbstractContainer-method-getRefItems'> /**
|
</span> * @protected
|
* Used by {@link Ext.ComponentQuery ComponentQuery}, {@link #child} and {@link #down} to retrieve all of the items
|
* which can potentially be considered a child of this Container.
|
*
|
* This may be overriden by Components which have ownership of Components
|
* that are not contained in the {@link #property-items} collection.
|
*
|
* NOTE: IMPORTANT note for maintainers:
|
* Items are returned in tree traversal order. Each item is appended to the result array
|
* followed by the results of that child's getRefItems call.
|
* Floating child items are appended after internal child items.
|
*/
|
getRefItems : function(deep) {
|
var me = this,
|
items = me.items.items,
|
len = items.length,
|
i = 0,
|
item,
|
result = [];
|
|
for (; i < len; i++) {
|
item = items[i];
|
result[result.length] = item;
|
if (deep && item.getRefItems) {
|
result.push.apply(result, item.getRefItems(true));
|
}
|
}
|
|
// Append floating items to the list.
|
items = me.floatingItems.items;
|
len = items.length;
|
for (i = 0; i < len; i++) {
|
item = items[i];
|
result[result.length] = item;
|
if (deep && item.getRefItems) {
|
result.push.apply(result, item.getRefItems(true));
|
}
|
}
|
|
return result;
|
},
|
|
<span id='Ext-container-AbstractContainer-method-cascade'> /**
|
</span> * Cascades down the component/container heirarchy from this component (passed in
|
* the first call), calling the specified function with each component. The scope
|
* (this reference) of the function call will be the scope provided or the current
|
* component. The arguments to the function will be the args provided or the current
|
* component. If the function returns false at any point, the cascade is stopped on
|
* that branch.
|
* @param {Function} fn The function to call
|
* @param {Object} [scope] The scope of the function (defaults to current component)
|
* @param {Array} [args] The args to call the function with. The current component
|
* always passed as the last argument.
|
* @return {Ext.Container} this
|
* @since 2.3.0
|
*/
|
cascade : function(fn, scope, origArgs){
|
var me = this,
|
cs = me.items ? me.items.items : [],
|
len = cs.length,
|
i = 0,
|
c,
|
args = origArgs ? origArgs.concat(me) : [me],
|
componentIndex = args.length - 1;
|
|
if (fn.apply(scope || me, args) !== false) {
|
for (; i < len; i++){
|
c = cs[i];
|
if (c.cascade) {
|
c.cascade(fn, scope, origArgs);
|
} else {
|
args[componentIndex] = c;
|
fn.apply(scope || cs, args);
|
}
|
}
|
}
|
return this;
|
},
|
|
<span id='Ext-container-AbstractContainer-method-isAncestor'> /**
|
</span> * Determines whether **this Container** is an ancestor of the passed Component.
|
* This will return `true` if the passed Component is anywhere within the subtree
|
* beneath this Container.
|
* @param {Ext.Component} possibleDescendant The Component to test for presence
|
* within this Container's subtree.
|
*/
|
isAncestor: function(possibleDescendant) {
|
while (possibleDescendant) {
|
if (possibleDescendant.ownerCt === this) {
|
return true;
|
}
|
possibleDescendant = possibleDescendant.ownerCt;
|
}
|
},
|
|
<span id='Ext-container-AbstractContainer-method-getComponent'> /**
|
</span> * Examines this container's {@link #property-items} **property** and gets a direct child
|
* component of this container.
|
*
|
* @param {String/Number} comp This parameter may be any of the following:
|
*
|
* - a **String** : representing the {@link Ext.Component#itemId itemId}
|
* or {@link Ext.Component#id id} of the child component.
|
* - a **Number** : representing the position of the child component
|
* within the {@link #property-items} **property**
|
*
|
* For additional information see {@link Ext.util.MixedCollection#get}.
|
*
|
* @return {Ext.Component} The component (if found).
|
*
|
* @since 2.3.0
|
*/
|
getComponent : function(comp) {
|
if (Ext.isObject(comp)) {
|
comp = comp.getItemId();
|
}
|
|
var c = this.items.get(comp);
|
|
// Only allow finding by index on the main items container
|
if (!c && typeof comp != 'number') {
|
c = this.floatingItems.get(comp);
|
}
|
|
return c;
|
},
|
|
<span id='Ext-container-AbstractContainer-method-contains'> /**
|
</span> * Determines whether the passed Component is either an immediate child of this Container,
|
* or whether it is a descendant.
|
*
|
* @param {Ext.Component} comp The Component to test.
|
* @param {Boolean} [deep=false] Pass `true` to test for the Component being a descendant at any level.
|
* @return {Boolean} `true` if the passed Component is contained at the specified level.
|
*/
|
contains: function(comp, deep) {
|
var result = false;
|
if (deep) {
|
this.cascade(function(c) {
|
// Only test if the item is a container
|
if (c.contains && c.contains(comp)) {
|
result = true;
|
return false;
|
}
|
});
|
return result;
|
} else {
|
return this.items.contains(comp) || this.floatingItems.contains(comp);
|
}
|
},
|
|
<span id='Ext-container-AbstractContainer-method-nextChild'> nextChild: function(child, selector) {
|
</span> var me = this,
|
result,
|
childIndex = me.items.indexOf(child);
|
|
if (childIndex !== -1) {
|
result = selector ? Ext.ComponentQuery(selector, me.items.items.slice(childIndex + 1)) : me.items.getAt(childIndex + 1);
|
if (!result && me.ownerCt) {
|
result = me.ownerCt.nextChild(me, selector);
|
}
|
}
|
return result;
|
},
|
|
<span id='Ext-container-AbstractContainer-method-prevChild'> prevChild: function(child, selector) {
|
</span> var me = this,
|
result,
|
childIndex = me.items.indexOf(child);
|
|
if (childIndex !== -1) {
|
result = selector ? Ext.ComponentQuery(selector, me.items.items.slice(childIndex + 1)) : me.items.getAt(childIndex + 1);
|
if (!result && me.ownerCt) {
|
result = me.ownerCt.nextChild(me, selector);
|
}
|
}
|
return result;
|
},
|
|
<span id='Ext-container-AbstractContainer-method-enable'> // @private
|
</span> // Enable all immediate children that was previously disabled
|
// Override enable because onEnable only gets called when rendered
|
enable: function() {
|
this.callParent(arguments);
|
|
var itemsToDisable = this.getChildItemsToDisable(),
|
length = itemsToDisable.length,
|
item, i;
|
|
for (i = 0; i < length; i++) {
|
item = itemsToDisable[i];
|
|
if (item.resetDisable) {
|
item.enable();
|
}
|
}
|
|
return this;
|
},
|
|
<span id='Ext-container-AbstractContainer-method-disable'> // Inherit docs
|
</span> // Disable all immediate children that was previously disabled
|
// Override disable because onDisable only gets called when rendered
|
disable: function() {
|
this.callParent(arguments);
|
|
var itemsToDisable = this.getChildItemsToDisable(),
|
length = itemsToDisable.length,
|
item, i;
|
|
for (i = 0; i < length; i++) {
|
item = itemsToDisable[i];
|
|
if (item.resetDisable !== false && !item.disabled) {
|
item.disable();
|
item.resetDisable = true;
|
}
|
}
|
|
return this;
|
},
|
|
<span id='Ext-container-AbstractContainer-method-getChildItemsToDisable'> /**
|
</span> * Gets a list of child components to enable/disable when the container is
|
* enabled/disabled
|
* @private
|
* @return {Ext.Component[]} Items to be enabled/disabled
|
*/
|
getChildItemsToDisable: function(){
|
return this.query('[isFormField],button');
|
},
|
|
<span id='Ext-container-AbstractContainer-method-beforeDestroy'> // @private
|
</span> // @since 2.3.0
|
beforeDestroy : function() {
|
var me = this,
|
items = me.items,
|
floatingItems = me.floatingItems,
|
c;
|
|
if (items) {
|
while ((c = items.first())) {
|
me.doRemove(c, true);
|
}
|
}
|
|
if (floatingItems) {
|
while ((c = floatingItems.first())) {
|
me.doRemove(c, true);
|
}
|
}
|
|
Ext.destroy(
|
me.layout
|
);
|
me.callParent();
|
}
|
});
|
</pre>
|
</body>
|
</html>
|