X-Git-Url: http://git.ithinksw.org/extjs.git/blobdiff_plain/3789b528d8dd8aad4558e38e22d775bcab1cbd36..6746dc89c47ed01b165cc1152533605f97eb8e8d:/pkgs/classes.js
diff --git a/pkgs/classes.js b/pkgs/classes.js
index c08d63df..36e5f3c3 100644
--- a/pkgs/classes.js
+++ b/pkgs/classes.js
@@ -1,47 +1,53 @@
/*
-Ext JS - JavaScript Library
-Copyright (c) 2006-2011, Sencha Inc.
-All rights reserved.
-licensing@sencha.com
+
+This file is part of Ext JS 4
+
+Copyright (c) 2011 Sencha Inc
+
+Contact: http://www.sencha.com/contact
+
+GNU General Public License Usage
+This file may be used under the terms of the GNU General Public License version 3.0 as published by the Free Software Foundation and appearing in the file LICENSE included in the packaging of this file. Please review the following information to ensure the GNU General Public License version 3.0 requirements will be met: http://www.gnu.org/copyleft/gpl.html.
+
+If you are unsure which license is appropriate for your use, please contact the sales department at http://www.sencha.com/contact.
+
*/
/**
- * @class Ext.util.Observable
- * Base class that provides a common interface for publishing events. Subclasses are expected to
- * to have a property "events" with all the events defined, and, optionally, a property "listeners"
- * with configured listeners defined.
+ * Base class that provides a common interface for publishing events. Subclasses are expected to to have a property
+ * "events" with all the events defined, and, optionally, a property "listeners" with configured listeners defined.
+ *
* For example:
- *
-Ext.define('Employee', {
- extend: 'Ext.util.Observable',
- constructor: function(config){
- this.name = config.name;
- this.addEvents({
- "fired" : true,
- "quit" : true
- });
-
- // Copy configured listeners into *this* object so that the base class's
- // constructor will add them.
- this.listeners = config.listeners;
-
- // Call our superclass constructor to complete construction process.
- Employee.superclass.constructor.call(this, config)
- }
-});
-
- * This could then be used like this:
-var newEmployee = new Employee({
- name: employeeName,
- listeners: {
- quit: function() {
- // By default, "this" will be the object that fired the event.
- alert(this.name + " has quit!");
- }
- }
-});
-
+ *
+ * Ext.define('Employee', {
+ * extend: 'Ext.util.Observable',
+ * constructor: function(config){
+ * this.name = config.name;
+ * this.addEvents({
+ * "fired" : true,
+ * "quit" : true
+ * });
+ *
+ * // Copy configured listeners into *this* object so that the base class's
+ * // constructor will add them.
+ * this.listeners = config.listeners;
+ *
+ * // Call our superclass constructor to complete construction process.
+ * Employee.superclass.constructor.call(this, config)
+ * }
+ * });
+ *
+ * This could then be used like this:
+ *
+ * var newEmployee = new Employee({
+ * name: employeeName,
+ * listeners: {
+ * quit: function() {
+ * // By default, "this" will be the object that fired the event.
+ * alert(this.name + " has quit!");
+ * }
+ * }
+ * });
*/
-
Ext.define('Ext.util.Observable', {
/* Begin Definitions */
@@ -50,7 +56,8 @@ Ext.define('Ext.util.Observable', {
statics: {
/**
- * Removes all added captures from the Observable.
+ * Removes **all** added captures from the Observable.
+ *
* @param {Observable} o The Observable to release
* @static
*/
@@ -59,13 +66,14 @@ Ext.define('Ext.util.Observable', {
},
/**
- * Starts capture on the specified Observable. All events will be passed
- * to the supplied function with the event name + standard signature of the event
- * before the event is fired. If the supplied function returns false,
+ * Starts capture on the specified Observable. All events will be passed to the supplied function with the event
+ * name + standard signature of the event **before** the event is fired. If the supplied function returns false,
* the event will not fire.
+ *
* @param {Observable} o The Observable to capture events from.
* @param {Function} fn The function to call when an event is fired.
- * @param {Object} scope (optional) The scope (this
reference) in which the function is executed. Defaults to the Observable firing the event.
+ * @param {Object} scope (optional) The scope (`this` reference) in which the function is executed. Defaults to
+ * the Observable firing the event.
* @static
*/
capture: function(o, fn, scope) {
@@ -73,22 +81,21 @@ Ext.define('Ext.util.Observable', {
},
/**
-Sets observability on the passed class constructor.
-
-This makes any event fired on any instance of the passed class also fire a single event through
-the __class__ allowing for central handling of events on many instances at once.
-
-Usage:
-
- Ext.util.Observable.observe(Ext.data.Connection);
- Ext.data.Connection.on('beforerequest', function(con, options) {
- console.log('Ajax request made to ' + options.url);
- });
-
+ * Sets observability on the passed class constructor.
+ *
+ * This makes any event fired on any instance of the passed class also fire a single event through
+ * the **class** allowing for central handling of events on many instances at once.
+ *
+ * Usage:
+ *
+ * Ext.util.Observable.observe(Ext.data.Connection);
+ * Ext.data.Connection.on('beforerequest', function(con, options) {
+ * console.log('Ajax request made to ' + options.url);
+ * });
+ *
* @param {Function} c The class constructor to make observable.
* @param {Object} listeners An object containing a series of listeners to add. See {@link #addListener}.
* @static
- * @markdown
*/
observe: function(cls, listeners) {
if (cls) {
@@ -107,36 +114,38 @@ Usage:
/* End Definitions */
/**
- * @cfg {Object} listeners (optional) A config object containing one or more event handlers to be added to this - * object during initialization. This should be a valid listeners config object as specified in the - * {@link #addListener} example for attaching multiple handlers at once.
- *DOM events from ExtJs {@link Ext.Component Components}
- *While some ExtJs Component classes export selected DOM events (e.g. "click", "mouseover" etc), this
- * is usually only done when extra value can be added. For example the {@link Ext.view.View DataView}'s
- * {@link Ext.view.View#click click}
event passing the node clicked on. To access DOM
- * events directly from a child element of a Component, we need to specify the element
option to
- * identify the Component property to add a DOM listener to:
- *
-new Ext.panel.Panel({
- width: 400,
- height: 200,
- dockedItems: [{
- xtype: 'toolbar'
- }],
- listeners: {
- click: {
- element: 'el', //bind to the underlying el property on the panel
- fn: function(){ console.log('click el'); }
- },
- dblclick: {
- element: 'body', //bind to the underlying body property on the panel
- fn: function(){ console.log('dblclick body'); }
- }
- }
-});
-
- *
- */
+ * @cfg {Object} listeners
+ *
+ * A config object containing one or more event handlers to be added to this object during initialization. This
+ * should be a valid listeners config object as specified in the {@link #addListener} example for attaching multiple
+ * handlers at once.
+ *
+ * **DOM events from ExtJS {@link Ext.Component Components}**
+ *
+ * While _some_ ExtJs Component classes export selected DOM events (e.g. "click", "mouseover" etc), this is usually
+ * only done when extra value can be added. For example the {@link Ext.view.View DataView}'s **`{@link
+ * Ext.view.View#itemclick itemclick}`** event passing the node clicked on. To access DOM events directly from a
+ * child element of a Component, we need to specify the `element` option to identify the Component property to add a
+ * DOM listener to:
+ *
+ * new Ext.panel.Panel({
+ * width: 400,
+ * height: 200,
+ * dockedItems: [{
+ * xtype: 'toolbar'
+ * }],
+ * listeners: {
+ * click: {
+ * element: 'el', //bind to the underlying el property on the panel
+ * fn: function(){ console.log('click el'); }
+ * },
+ * dblclick: {
+ * element: 'body', //bind to the underlying body property on the panel
+ * fn: function(){ console.log('dblclick body'); }
+ * }
+ * }
+ * });
+ */
// @private
isObservable: true,
@@ -159,23 +168,23 @@ new Ext.panel.Panel({
eventOptionsRe : /^(?:scope|delay|buffer|single|stopEvent|preventDefault|stopPropagation|normalized|args|delegate|element|vertical|horizontal)$/,
/**
- * Adds listeners to any Observable object (or Element) which are automatically removed when this Component
- * is destroyed.
+ * Adds listeners to any Observable object (or Element) which are automatically removed when this Component is
+ * destroyed.
+ *
* @param {Observable/Element} item The item to which to add a listener/listeners.
* @param {Object/String} ename The event name, or an object containing event name properties.
- * @param {Function} fn Optional. If the ename
parameter was an event name, this
- * is the handler function.
- * @param {Object} scope Optional. If the ename
parameter was an event name, this
- * is the scope (this
reference) in which the handler function is executed.
- * @param {Object} opt Optional. If the ename
parameter was an event name, this
- * is the {@link Ext.util.Observable#addListener addListener} options.
+ * @param {Function} fn (optional) If the `ename` parameter was an event name, this is the handler function.
+ * @param {Object} scope (optional) If the `ename` parameter was an event name, this is the scope (`this` reference)
+ * in which the handler function is executed.
+ * @param {Object} opt (optional) If the `ename` parameter was an event name, this is the
+ * {@link Ext.util.Observable#addListener addListener} options.
*/
addManagedListener : function(item, ename, fn, scope, options) {
var me = this,
managedListeners = me.managedListeners = me.managedListeners || [],
config;
- if (Ext.isObject(ename)) {
+ if (typeof ename !== 'string') {
options = ename;
for (ename in options) {
if (options.hasOwnProperty(ename)) {
@@ -201,14 +210,14 @@ new Ext.panel.Panel({
/**
* Removes listeners that were added by the {@link #mon} method.
+ *
* @param {Observable|Element} item The item from which to remove a listener/listeners.
* @param {Object|String} ename The event name, or an object containing event name properties.
- * @param {Function} fn Optional. If the ename
parameter was an event name, this
- * is the handler function.
- * @param {Object} scope Optional. If the ename
parameter was an event name, this
- * is the scope (this
reference) in which the handler function is executed.
+ * @param {Function} fn Optional. If the `ename` parameter was an event name, this is the handler function.
+ * @param {Object} scope Optional. If the `ename` parameter was an event name, this is the scope (`this` reference)
+ * in which the handler function is executed.
*/
- removeManagedListener : function(item, ename, fn, scope) {
+ removeManagedListener : function(item, ename, fn, scope) {
var me = this,
options,
config,
@@ -216,7 +225,7 @@ new Ext.panel.Panel({
length,
i;
- if (Ext.isObject(ename)) {
+ if (typeof ename !== 'string') {
options = ename;
for (ename in options) {
if (options.hasOwnProperty(ename)) {
@@ -236,9 +245,12 @@ new Ext.panel.Panel({
},
/**
- *
Fires the specified event with the passed parameters (minus the event name).
- *An event may be set to bubble up an Observable parent hierarchy (See {@link Ext.Component#getBubbleTarget}) - * by calling {@link #enableBubble}.
+ * Fires the specified event with the passed parameters (minus the event name, plus the `options` object passed + * to {@link #addListener}). + * + * An event may be set to bubble up an Observable parent hierarchy (See {@link Ext.Component#getBubbleTarget}) by + * calling {@link #enableBubble}. + * * @param {String} eventName The name of the event to fire. * @param {Object...} args Variable number of parameters are passed to handlers. * @return {Boolean} returns false if any of the handlers return false otherwise it returns true. @@ -256,84 +268,120 @@ new Ext.panel.Panel({ if (queue) { queue.push(args); } - } else if (event && Ext.isObject(event) && event.bubble) { - if (event.fire.apply(event, args.slice(1)) === false) { - return false; - } - parent = me.getBubbleTarget && me.getBubbleTarget(); - if (parent && parent.isObservable) { - if (!parent.events[ename] || !Ext.isObject(parent.events[ename]) || !parent.events[ename].bubble) { - parent.enableBubble(ename); + } else if (event && event !== true) { + if (event.bubble) { + if (event.fire.apply(event, args.slice(1)) === false) { + return false; } - return parent.fireEvent.apply(parent, args); + parent = me.getBubbleTarget && me.getBubbleTarget(); + if (parent && parent.isObservable) { + if (!parent.events[ename] || parent.events[ename] === true || !parent.events[ename].bubble) { + parent.enableBubble(ename); + } + return parent.fireEvent.apply(parent, args); + } + } + else { + args.shift(); + ret = event.fire.apply(event, args); } - } else if (event && Ext.isObject(event)) { - args.shift(); - ret = event.fire.apply(event, args); } return ret; }, /** * Appends an event handler to this object. - * @param {String} eventName The name of the event to listen for. May also be an object who's property names are event names. See - * @param {Function} handler The method the event invokes. - * @param {Object} scope (optional) The scope (this
reference) in which the handler function is executed.
- * If omitted, defaults to the object which fired the event.
- * @param {Object} options (optional) An object containing handler configuration.
- * properties. This may contain any of the following properties:this
reference) in which the handler function is executed.
- * If omitted, defaults to the object which fired the event.This option is useful during Component construction to add DOM event listeners to elements of {@link Ext.Component Components} which - * will exist only after the Component is rendered. For example, to add a click listener to a Panel's body:
-new Ext.panel.Panel({
- title: 'The title',
- listeners: {
- click: this.handlePanelClick,
- element: 'body'
- }
-});
-
- * When added in this way, the options available are the options applicable to {@link Ext.core.Element#addListener}
- * Combining Options
- * Using the options argument, it is possible to combine different types of listeners:
- *
+ *
+ * @param {String} eventName The name of the event to listen for. May also be an object who's property names are
+ * event names.
+ * @param {Function} handler The method the event invokes. Will be called with arguments given to
+ * {@link #fireEvent} plus the `options` parameter described below.
+ * @param {Object} scope (optional) The scope (`this` reference) in which the handler function is executed. **If
+ * omitted, defaults to the object which fired the event.**
+ * @param {Object} options (optional) An object containing handler configuration.
+ *
+ * **Note:** Unlike in ExtJS 3.x, the options object will also be passed as the last argument to every event handler.
+ *
+ * This object may contain any of the following properties:
+ *
+ * - **scope** : Object
+ *
+ * The scope (`this` reference) in which the handler function is executed. **If omitted, defaults to the object
+ * which fired the event.**
+ *
+ * - **delay** : Number
+ *
+ * The number of milliseconds to delay the invocation of the handler after the event fires.
+ *
+ * - **single** : Boolean
+ *
+ * True to add a handler to handle just the next firing of the event, and then remove itself.
+ *
+ * - **buffer** : Number
+ *
+ * Causes the handler to be scheduled to run in an {@link Ext.util.DelayedTask} delayed by the specified number of
+ * milliseconds. If the event fires again within that time, the original handler is _not_ invoked, but the new
+ * handler is scheduled in its place.
+ *
+ * - **target** : Observable
+ *
+ * Only call the handler if the event was fired on the target Observable, _not_ if the event was bubbled up from a
+ * child Observable.
+ *
+ * - **element** : String
+ *
+ * **This option is only valid for listeners bound to {@link Ext.Component Components}.** The name of a Component
+ * property which references an element to add a listener to.
+ *
+ * This option is useful during Component construction to add DOM event listeners to elements of
+ * {@link Ext.Component Components} which will exist only after the Component is rendered.
+ * For example, to add a click listener to a Panel's body:
+ *
+ * new Ext.panel.Panel({
+ * title: 'The title',
+ * listeners: {
+ * click: this.handlePanelClick,
+ * element: 'body'
+ * }
+ * });
+ *
+ * **Combining Options**
+ *
+ * Using the options argument, it is possible to combine different types of listeners:
+ *
* A delayed, one-time listener.
- *
-myPanel.on('hide', this.handleClick, this, {
-single: true,
-delay: 100
-});
- *
- * Attaching multiple handlers in 1 call
- * The method also allows for a single argument to be passed which is a config object containing properties
- * which specify multiple events. For example:
-myGridPanel.on({
- cellClick: this.onCellClick,
- mouseover: this.onMouseOver,
- mouseout: this.onMouseOut,
- scope: this // Important. Ensure "this" is correct during handler execution
-});
-
.
- *
+ *
+ * myPanel.on('hide', this.handleClick, this, {
+ * single: true,
+ * delay: 100
+ * });
+ *
+ * **Attaching multiple handlers in 1 call**
+ *
+ * The method also allows for a single argument to be passed which is a config object containing properties which
+ * specify multiple events. For example:
+ *
+ * myGridPanel.on({
+ * cellClick: this.onCellClick,
+ * mouseover: this.onMouseOver,
+ * mouseout: this.onMouseOut,
+ * scope: this // Important. Ensure "this" is correct during handler execution
+ * });
+ *
+ * One can also specify options for each event handler separately:
+ *
+ * myGridPanel.on({
+ * cellClick: {fn: this.onCellClick, scope: this, single: true},
+ * mouseover: {fn: panel.onMouseOver, scope: panel}
+ * });
+ *
*/
addListener: function(ename, fn, scope, options) {
var me = this,
config,
event;
- if (Ext.isObject(ename)) {
+ if (typeof ename !== 'string') {
options = ename;
for (ename in options) {
if (options.hasOwnProperty(ename)) {
@@ -357,9 +405,11 @@ myGridPanel.on({
/**
* Removes an event handler.
- * @param {String} eventName The type of event the handler was associated with.
- * @param {Function} handler The handler to remove. This must be a reference to the function passed into the {@link #addListener} call.
- * @param {Object} scope (optional) The scope originally specified for the handler.
+ *
+ * @param {String} eventName The type of event the handler was associated with.
+ * @param {Function} handler The handler to remove. **This must be a reference to the function passed into the
+ * {@link #addListener} call.**
+ * @param {Object} scope (optional) The scope originally specified for the handler.
*/
removeListener: function(ename, fn, scope) {
var me = this,
@@ -367,7 +417,7 @@ myGridPanel.on({
event,
options;
- if (Ext.isObject(ename)) {
+ if (typeof ename !== 'string') {
options = ename;
for (ename in options) {
if (options.hasOwnProperty(ename)) {
@@ -457,12 +507,20 @@ myGridPanel.on({
/**
* Adds the specified events to the list of events which this Observable may fire.
- * @param {Object/String} o Either an object with event names as properties with a value of true
- * or the first event name string if multiple event names are being passed as separate parameters.
- * @param {String} [additional] Optional additional event names if multiple event names are being passed as separate parameters.
- * Usage:
-this.addEvents('storeloaded', 'storecleared');
-
+ *
+ * @param {Object/String} o Either an object with event names as properties with a value of `true` or the first
+ * event name string if multiple event names are being passed as separate parameters. Usage:
+ *
+ * this.addEvents({
+ * storeloaded: true,
+ * storecleared: true
+ * });
+ *
+ * @param {String...} more Optional additional event names if multiple event names are being passed as separate
+ * parameters. Usage:
+ *
+ * this.addEvents('storeloaded', 'storecleared');
+ *
*/
addEvents: function(o) {
var me = this,
@@ -485,6 +543,7 @@ this.addEvents('storeloaded', 'storecleared');
/**
* Checks to see if this object has any listeners for a specified event
+ *
* @param {String} eventName The name of the event to check for
* @return {Boolean} True if the event is being listened for, else false
*/
@@ -494,9 +553,10 @@ this.addEvents('storeloaded', 'storecleared');
},
/**
- * Suspend the firing of all events. (see {@link #resumeEvents})
+ * Suspends the firing of all events. (see {@link #resumeEvents})
+ *
* @param {Boolean} queueSuspended Pass as true to queue up suspended events to be fired
- * after the {@link #resumeEvents} call instead of discarding all suspended events;
+ * after the {@link #resumeEvents} call instead of discarding all suspended events.
*/
suspendEvents: function(queueSuspended) {
this.eventsSuspended = true;
@@ -506,9 +566,10 @@ this.addEvents('storeloaded', 'storecleared');
},
/**
- * Resume firing events. (see {@link #suspendEvents})
- * If events were suspended using the queueSuspended
parameter, then all
- * events fired during event suspension will be sent to any listeners now.
+ * Resumes firing events (see {@link #suspendEvents}).
+ *
+ * If events were suspended using the `**queueSuspended**` parameter, then all events fired
+ * during event suspension will be sent to any listeners now.
*/
resumeEvents: function() {
var me = this,
@@ -524,9 +585,11 @@ this.addEvents('storeloaded', 'storecleared');
},
/**
- * Relays selected events from the specified Observable as if the events were fired by this
.
+ * Relays selected events from the specified Observable as if the events were fired by `this`.
+ *
* @param {Object} origin The Observable whose events this object is to relay.
- * @param {Array} events Array of event names to relay.
+ * @param {[String]} events Array of event names to relay.
+ * @param {Object} prefix
*/
relayEvents : function(origin, events, prefix) {
prefix = prefix || '';
@@ -558,41 +621,45 @@ this.addEvents('storeloaded', 'storecleared');
},
/**
- * Enables events fired by this Observable to bubble up an owner hierarchy by calling
- * this.getBubbleTarget()
if present. There is no implementation in the Observable base class.
This is commonly used by Ext.Components to bubble events to owner Containers. See {@link Ext.Component#getBubbleTarget}. The default - * implementation in Ext.Component returns the Component's immediate owner. But if a known target is required, this can be overridden to - * access the required target more quickly.
- *Example:
-Ext.override(Ext.form.field.Base, {
-// Add functionality to Field's initComponent to enable the change event to bubble
-initComponent : Ext.Function.createSequence(Ext.form.field.Base.prototype.initComponent, function() {
- this.enableBubble('change');
-}),
-
-// We know that we want Field's events to bubble directly to the FormPanel.
-getBubbleTarget : function() {
- if (!this.formPanel) {
- this.formPanel = this.findParentByType('form');
- }
- return this.formPanel;
-}
-});
-
-var myForm = new Ext.formPanel({
-title: 'User Details',
-items: [{
- ...
-}],
-listeners: {
- change: function() {
- // Title goes red if form has been modified.
- myForm.header.setStyle('color', 'red');
- }
-}
-});
-
- * @param {String/Array} events The event name to bubble, or an Array of event names.
+ * Enables events fired by this Observable to bubble up an owner hierarchy by calling `this.getBubbleTarget()` if
+ * present. There is no implementation in the Observable base class.
+ *
+ * This is commonly used by Ext.Components to bubble events to owner Containers.
+ * See {@link Ext.Component#getBubbleTarget}. The default implementation in Ext.Component returns the
+ * Component's immediate owner. But if a known target is required, this can be overridden to access the
+ * required target more quickly.
+ *
+ * Example:
+ *
+ * Ext.override(Ext.form.field.Base, {
+ * // Add functionality to Field's initComponent to enable the change event to bubble
+ * initComponent : Ext.Function.createSequence(Ext.form.field.Base.prototype.initComponent, function() {
+ * this.enableBubble('change');
+ * }),
+ *
+ * // We know that we want Field's events to bubble directly to the FormPanel.
+ * getBubbleTarget : function() {
+ * if (!this.formPanel) {
+ * this.formPanel = this.findParentByType('form');
+ * }
+ * return this.formPanel;
+ * }
+ * });
+ *
+ * var myForm = new Ext.formPanel({
+ * title: 'User Details',
+ * items: [{
+ * ...
+ * }],
+ * listeners: {
+ * change: function() {
+ * // Title goes red if form has been modified.
+ * myForm.header.setStyle('color', 'red');
+ * }
+ * }
+ * });
+ *
+ * @param {String/[String]} events The event name to bubble, or an Array of event names.
*/
enableBubble: function(events) {
var me = this;
@@ -611,28 +678,31 @@ listeners: {
}
}
}, function() {
- /**
- * Removes an event handler (shorthand for {@link #removeListener}.)
- * @param {String} eventName The type of event the handler was associated with.
- * @param {Function} handler The handler to remove. This must be a reference to the function passed into the {@link #addListener} call.
- * @param {Object} scope (optional) The scope originally specified for the handler.
- * @method un
- */
-
- /**
- * Appends an event handler to this object (shorthand for {@link #addListener}.)
- * @param {String} eventName The type of event to listen for
- * @param {Function} handler The method the event invokes
- * @param {Object} scope (optional) The scope (this
reference) in which the handler function is executed.
- * If omitted, defaults to the object which fired the event.
- * @param {Object} options (optional) An object containing handler configuration.
- * @method on
- */
this.createAlias({
+ /**
+ * @method
+ * Shorthand for {@link #addListener}.
+ * @alias Ext.util.Observable#addListener
+ */
on: 'addListener',
+ /**
+ * @method
+ * Shorthand for {@link #removeListener}.
+ * @alias Ext.util.Observable#removeListener
+ */
un: 'removeListener',
+ /**
+ * @method
+ * Shorthand for {@link #addManagedListener}.
+ * @alias Ext.util.Observable#addManagedListener
+ */
mon: 'addManagedListener',
+ /**
+ * @method
+ * Shorthand for {@link #removeManagedListener}.
+ * @alias Ext.util.Observable#removeManagedListener
+ */
mun: 'removeManagedListener'
});
@@ -732,13 +802,13 @@ listeners: {
i, len;
for(i = 0, len = e.before.length; i < len; i++){
if(e.before[i].fn == fn && e.before[i].scope == scope){
- e.before.splice(i, 1);
+ Ext.Array.erase(e.before, i, 1);
return;
}
}
for(i = 0, len = e.after.length; i < len; i++){
if(e.after[i].fn == fn && e.after[i].scope == scope){
- e.after.splice(i, 1);
+ Ext.Array.erase(e.after, i, 1);
return;
}
}
@@ -963,7 +1033,7 @@ Ext.define('Ext.util.Animate', {
/**
* Perform custom animation on this object.
- *
This method is applicable to both the the {@link Ext.Component Component} class and the {@link Ext.core.Element Element} class. + *
This method is applicable to both the {@link Ext.Component Component} class and the {@link Ext.core.Element Element} class. * It performs animated transitions of certain properties of this object over a specified timeline.
*The sole parameter is an object which specifies start property values, end property values, and properties which
* describe the timeline. Of the properties listed below, only to
is mandatory.
Abstract base class for state provider implementations. The provider is responsible @@ -1336,8 +1408,6 @@ map.each(function(key, value, length){ * there is no guarantee when iterating over the items that they will be in any particular * order. If this is required, then use a {@link Ext.util.MixedCollection}. *
- * @constructor - * @param {Object} config The configuration options */ Ext.define('Ext.util.HashMap', { @@ -1351,8 +1421,15 @@ Ext.define('Ext.util.HashMap', { observable: 'Ext.util.Observable' }, + /** + * Creates new HashMap. + * @param {Object} config (optional) Config object. + */ constructor: function(config) { - var me = this; + config = config || {}; + + var me = this, + keyFn = config.keyFn; me.addEvents( /** @@ -1390,6 +1467,10 @@ Ext.define('Ext.util.HashMap', { me.mixins.observable.constructor.call(me, config); me.clear(true); + + if (keyFn) { + me.getKey = keyFn; + } }, /** @@ -1420,7 +1501,6 @@ Ext.define('Ext.util.HashMap', { /** * Extracts the key from an object. This is a default implementation, it may be overridden - * @private * @param {Object} o The object to get the key from * @return {String} The key to use. */ @@ -1778,7 +1858,6 @@ Ext.define('Ext.Template', { * Returns an HTML fragment of this template with the specified values applied. * @param {Object/Array} values The template values. Can be an array if your params are numeric (i.e. {0}) or an object (i.e. {foo: 'bar'}) * @return {String} The HTML fragment - * @hide repeat doc */ applyTemplate: function(values) { var me = this, @@ -1829,7 +1908,6 @@ Ext.define('Ext.Template', { /** * Compiles the template into an internal function, eliminating the RegEx overhead. * @return {Ext.Template} this - * @hide repeat doc */ compile: function() { var me = this, @@ -1944,78 +2022,73 @@ Ext.define('Ext.Template', { /** * @class Ext.ComponentQuery * @extends Object + * @singleton * * Provides searching of Components within Ext.ComponentManager (globally) or a specific * Ext.container.Container on the document with a similar syntax to a CSS selector. * * Components can be retrieved by using their {@link Ext.Component xtype} with an optional . prefix -
-var disabledFields = myFormPanel.query("{isDisabled()}");
-
*
- * Pseudo classes may be used to filter results in the same way as in {@link Ext.DomQuery DomQuery}:
-// Function receives array and returns a filtered array.
-Ext.ComponentQuery.pseudos.invalid = function(items) {
- var i = 0, l = items.length, c, result = [];
- for (; i < l; i++) {
- if (!(c = items[i]).isValid()) {
- result.push(c);
- }
- }
- return result;
-};
-
-var invalidFields = myFormPanel.query('field:invalid');
-if (invalidFields.length) {
- invalidFields[0].getEl().scrollIntoView(myFormPanel.body);
- for (var i = 0, l = invalidFields.length; i < l; i++) {
- invalidFields[i].getEl().frame("red");
- }
-}
-
- *
- * Default pseudos include:
+ * - `component[autoScroll]`
+ * - `panel[title="Test"]`
+ *
+ * Member expressions from candidate Components may be tested. If the expression returns a *truthy* value,
+ * the candidate Component will be included in the query:
+ *
+ * var disabledFields = myFormPanel.query("{isDisabled()}");
+ *
+ * Pseudo classes may be used to filter results in the same way as in {@link Ext.DomQuery DomQuery}:
+ *
+ * // Function receives array and returns a filtered array.
+ * Ext.ComponentQuery.pseudos.invalid = function(items) {
+ * var i = 0, l = items.length, c, result = [];
+ * for (; i < l; i++) {
+ * if (!(c = items[i]).isValid()) {
+ * result.push(c);
+ * }
+ * }
+ * return result;
+ * };
+ *
+ * var invalidFields = myFormPanel.query('field:invalid');
+ * if (invalidFields.length) {
+ * invalidFields[0].getEl().scrollIntoView(myFormPanel.body);
+ * for (var i = 0, l = invalidFields.length; i < l; i++) {
+ * invalidFields[i].getEl().frame("red");
+ * }
+ * }
+ *
+ * Default pseudos include:
+ *
* - not
- *
- // retrieve all Ext.Panels in the document by xtype
- var panelsArray = Ext.ComponentQuery.query('panel');
-
- // retrieve all Ext.Panels within the container with an id myCt
- var panelsWithinmyCt = Ext.ComponentQuery.query('#myCt panel');
-
- // retrieve all direct children which are Ext.Panels within myCt
- var directChildPanel = Ext.ComponentQuery.query('#myCt > panel');
-
- // retrieve all gridpanels and listviews
- var gridsAndLists = Ext.ComponentQuery.query('gridpanel, listview');
-
-
-For easy access to queries based from a particular Container see the {@link Ext.container.Container#query},
-{@link Ext.container.Container#down} and {@link Ext.container.Container#child} methods. Also see
-{@link Ext.Component#up}.
- * @singleton
+ *
+ * // retrieve all Ext.Panels in the document by xtype
+ * var panelsArray = Ext.ComponentQuery.query('panel');
+ *
+ * // retrieve all Ext.Panels within the container with an id myCt
+ * var panelsWithinmyCt = Ext.ComponentQuery.query('#myCt panel');
+ *
+ * // retrieve all direct children which are Ext.Panels within myCt
+ * var directChildPanel = Ext.ComponentQuery.query('#myCt > panel');
+ *
+ * // retrieve all grids and trees
+ * var gridsAndTrees = Ext.ComponentQuery.query('gridpanel, treepanel');
+ *
+ * For easy access to queries based from a particular Container see the {@link Ext.container.Container#query},
+ * {@link Ext.container.Container#down} and {@link Ext.container.Container#child} methods. Also see
+ * {@link Ext.Component#up}.
*/
Ext.define('Ext.ComponentQuery', {
singleton: true,
@@ -2294,15 +2367,20 @@ Ext.define('Ext.ComponentQuery', {
},
/**
- * Returns an array of matched Components from within the passed root object.
- *This method filters returned Components in a similar way to how CSS selector based DOM - * queries work using a textual selector string.
- *See class summary for details.
- * @param selector The selector string to filter returned Components - * @param rootThe Container within which to perform the query. If omitted, all Components - * within the document are included in the search.
- *This parameter may also be an array of Components to filter according to the selector.
- * @returns {Array} The matched Components. + * Returns an array of matched Components from within the passed root object. + * + * This method filters returned Components in a similar way to how CSS selector based DOM + * queries work using a textual selector string. + * + * See class summary for details. + * + * @param {String} selector The selector string to filter returned Components + * @param {Ext.container.Container} root The Container within which to perform the query. + * If omitted, all Components within the document are included in the search. + * + * This parameter may also be an array of Components to filter according to the selector. + * @returns {[Ext.Component]} The matched Components. + * * @member Ext.ComponentQuery */ query: function(selector, root) { @@ -2341,8 +2419,8 @@ Ext.define('Ext.ComponentQuery', { /** * Tests whether the passed Component matches the selector string. - * @param component The Component to test - * @param selector The selector string to test against. + * @param {Ext.Component} component The Component to test + * @param {String} selector The selector string to test against. * @return {Boolean} True if the Component matches the selector. * @member Ext.ComponentQuery */ @@ -2498,8 +2576,6 @@ var longNames = allNames.filter(longNameFilter); //a new MixedCollection with the 2 people of age 24: var youngFolk = allNames.filter(ageFilter); - * @constructor - * @param {Object} config Config object */ Ext.define('Ext.util.Filter', { @@ -2507,7 +2583,7 @@ Ext.define('Ext.util.Filter', { /* End Definitions */ /** - * @cfg {String} property The property to filter on. Required unless a {@link #filter} is passed + * @cfg {String} property The property to filter on. Required unless a {@link #filterFn} is passed */ /** @@ -2535,7 +2611,11 @@ Ext.define('Ext.util.Filter', { * @cfg {String} root Optional root property. This is mostly useful when filtering a Store, in which case we set the * root to 'data' to make the filter pull the {@link #property} out of the data object of each item */ - + + /** + * Creates new Filter. + * @param {Object} config (optional) Config object + */ constructor: function(config) { Ext.apply(this, config); @@ -2613,16 +2693,76 @@ Ext.define('Ext.util.Filter', { /** * @class Ext.util.Sorter * @extends Object - * Represents a single sorter that can be applied to a Store + +Represents a single sorter that can be applied to a Store. The sorter is used +to compare two values against each other for the purpose of ordering them. Ordering +is achieved by specifying either: +- {@link #property A sorting property} +- {@link #sorterFn A sorting function} + +As a contrived example, we can specify a custom sorter that sorts by rank: + + Ext.define('Person', { + extend: 'Ext.data.Model', + fields: ['name', 'rank'] + }); + + Ext.create('Ext.data.Store', { + model: 'Person', + proxy: 'memory', + sorters: [{ + sorterFn: function(o1, o2){ + var getRank = function(o){ + var name = o.get('rank'); + if (name === 'first') { + return 1; + } else if (name === 'second') { + return 2; + } else { + return 3; + } + }, + rank1 = getRank(o1), + rank2 = getRank(o2); + + if (rank1 === rank2) { + return 0; + } + + return rank1 < rank2 ? -1 : 1; + } + }], + data: [{ + name: 'Person1', + rank: 'second' + }, { + name: 'Person2', + rank: 'third' + }, { + name: 'Person3', + rank: 'first' + }] + }); + + * @markdown */ Ext.define('Ext.util.Sorter', { /** - * @cfg {String} property The property to sort by. Required unless {@link #sorter} is provided + * @cfg {String} property The property to sort by. Required unless {@link #sorterFn} is provided. + * The property is extracted from the object directly and compared for sorting using the built in + * comparison operators. */ /** - * @cfg {Function} sorterFn A specific sorter function to execute. Can be passed instead of {@link #property} + * @cfg {Function} sorterFn A specific sorter function to execute. Can be passed instead of {@link #property}. + * This sorter function allows for any kind of custom/complex comparisons. + * The sorterFn receives two arguments, the objects being compared. The function should return: + *A flag which causes the object to attempt to restore the state of
* internal properties from a saved state on startup. The object must have
- * a {@link #stateId}
for state to be managed.
- * Auto-generated ids are not guaranteed to be stable across page loads and
+ * a {@link #stateId}
for state to be managed.
+ * Auto-generated ids are not guaranteed to be stable across page loads and
* cannot be relied upon to save and restore the same state for a object.
*
For state saving to work, the state manager's provider must have been * set to an implementation of {@link Ext.state.Provider} which overrides the @@ -3671,7 +3842,7 @@ Ext.state.Manager.setProvider(new Ext.state.CookieProvider({ * object hash which represents the restorable state of the object.
*The value yielded by getState is passed to {@link Ext.state.Manager#set}
* which uses the configured {@link Ext.state.Provider} to save the object
- * keyed by the {@link stateId}
{@link #stateId}
.
* During construction, a stateful object attempts to restore
* its state by calling {@link Ext.state.Manager#get} passing the
* {@link #stateId}
See {@link #stateful} for an explanation of saving and restoring state.
*/ - + /** * @cfg {Array} stateEvents *An array of events that, when fired, should trigger this object to @@ -3700,18 +3871,18 @@ Ext.state.Manager.setProvider(new Ext.state.CookieProvider({ *
See {@link #stateful}
for an explanation of saving and
* restoring object state.
An abstract base class which provides shared methods for Components across the Sencha product line.
*Please refer to sub class's documentation
- * @constructor */ Ext.define('Ext.AbstractComponent', { @@ -6562,6 +6732,7 @@ Ext.define('Ext.AbstractComponent', { return ++Ext.AbstractComponent.AUTO_ID; }, + /** * @cfg {String} id *The unique id of this component instance (defaults to an {@link #getId auto-assigned id}).
@@ -6609,7 +6780,8 @@ var c = new Ext.panel.Panel({ // p1 = c.{@link Ext.container.Container#getComponent getComponent}('p1'); // not the same as {@link Ext#getCmp Ext.getCmp()} p2 = p1.{@link #ownerCt}.{@link Ext.container.Container#getComponent getComponent}('p2'); // reference via a sibling * - *Also see {@link #id}, {@link #query}
, {@link #down}
and {@link #child}
.
Also see {@link #id}, {@link Ext.container.Container#query}
,
+ * {@link Ext.container.Container#down}
and {@link Ext.container.Container#child}
.
Note: to access the container of an item see {@link #ownerCt}.
*/ @@ -6621,6 +6793,26 @@ p2 = p1.{@link #ownerCt}.{@link Ext.container.Container#getComponent getComponen * @property ownerCt */ + /** + * @private + * Flag set by the container layout to which this Component is added. + * If the layout manages this Component's width, it sets the value to 1. + * If it does NOT manage the width, it sets it to 2. + * If the layout MAY affect the width, but only if the owning Container has a fixed width, this is set to 0. + * @type boolean + * @property layoutManagedWidth + */ + + /** + * @private + * Flag set by the container layout to which this Component is added. + * If the layout manages this Component's height, it sets the value to 1. + * If it does NOT manage the height, it sets it to 2. + * If the layout MAY affect the height, but only if the owning Container has a fixed height, this is set to 0. + * @type boolean + * @property layoutManagedHeight + */ + /** * @cfg {Mixed} autoEl *A tag name or {@link Ext.core.DomHelper DomHelper} spec used to create the {@link #getEl Element} which will
@@ -6804,14 +6996,14 @@ and a property `descEl` referencing the `div` Element which contains the descrip
* A set style for a component. Can be a string or an Array of multiple strings (UIs)
*/
ui: 'default',
-
+
/**
* @cfg {Array} uiCls
* An array of of classNames which are currently applied to this component
* @private
*/
uiCls: [],
-
+
/**
* @cfg {String} style
* A custom style specification to be applied to this component's Element. Should be a valid argument to
@@ -7023,8 +7215,8 @@ and a property `descEl` referencing the `div` Element which contains the descrip
trimRe: /^\s+|\s+$/g,
spacesRe: /\s+/,
-
-
+
+
/**
* 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 its disabled.
@@ -7032,9 +7224,13 @@ and a property `descEl` referencing the `div` Element which contains the descrip
* since they want to implement custom disable logic.
* @property maskOnDisable
* @type {Boolean}
- */
+ */
maskOnDisable: true,
+ /**
+ * Creates new Component.
+ * @param {Object} config (optional) Config object.
+ */
constructor : function(config) {
var me = this,
i, len;
@@ -7190,7 +7386,7 @@ and a property `descEl` referencing the `div` Element which contains the descrip
me.plugins[i] = me.constructPlugin(me.plugins[i]);
}
}
-
+
me.initComponent();
// ititComponent gets a chance to change the id property before registering
@@ -7200,6 +7396,9 @@ and a property `descEl` referencing the `div` Element which contains the descrip
me.mixins.observable.constructor.call(me);
me.mixins.state.constructor.call(me, config);
+ // Save state on resize.
+ this.addStateEvents('resize');
+
// Move this into Observable?
if (me.plugins) {
me.plugins = [].concat(me.plugins);
@@ -7220,7 +7419,7 @@ and a property `descEl` referencing the `div` Element which contains the descrip
if (me.autoShow) {
me.show();
}
-
+
//
flex
, anchor
, width
+ * and height
along with collapsed
state.
+ * Subclasses which implement more complex state should call the superclass's implementation, and apply their state + * to the result if this basic state is to be saved.
+ *Note that Component state will only be saved if the Component has a {@link #stateId} and there as a StateProvider + * configured for the document.
+ */ + getState: function() { + var me = this, + layout = me.ownerCt ? (me.shadowOwnerCt || me.ownerCt).getLayout() : null, + state = { + collapsed: me.collapsed + }, + width = me.width, + height = me.height, + cm = me.collapseMemento, + anchors; + + // If a Panel-local collapse has taken place, use remembered values as the dimensions. + // TODO: remove this coupling with Panel's privates! All collapse/expand logic should be refactored into one place. + if (me.collapsed && cm) { + if (Ext.isDefined(cm.data.width)) { + width = cm.width; + } + if (Ext.isDefined(cm.data.height)) { + height = cm.height; + } + } + + // If we have flex, only store the perpendicular dimension. + if (layout && me.flex) { + state.flex = me.flex; + state[layout.perpendicularPrefix] = me['get' + layout.perpendicularPrefixCap](); + } + // If we have anchor, only store dimensions which are *not* being anchored + else if (layout && me.anchor) { + state.anchor = me.anchor; + anchors = me.anchor.split(' ').concat(null); + if (!anchors[0]) { + if (me.width) { + state.width = width; + } + } + if (!anchors[1]) { + if (me.height) { + state.height = height; + } + } + } + // Store dimensions. + else { + if (me.width) { + state.width = width; + } + if (me.height) { + state.height = height; + } + } + + // Don't save dimensions if they are unchanged from the original configuration. + if (state.width == me.initialConfig.width) { + delete state.width; + } + if (state.height == me.initialConfig.height) { + delete state.height; + } + + // If a Box layout was managing the perpendicular dimension, don't save that dimension + if (layout && layout.align && (layout.align.indexOf('stretch') !== -1)) { + delete state[layout.perpendicularPrefix]; + } + return state; + }, + show: Ext.emptyFn, animate: function(animObj) { @@ -7398,7 +7673,6 @@ and a property `descEl` referencing the `div` Element which contains the descrip onRender : function(container, position) { var me = this, el = me.el, - cls = me.initCls(), styles = me.initStyles(), renderTpl, renderData, i; @@ -7433,7 +7707,9 @@ and a property `descEl` referencing the `div` Element which contains the descrip } } - el.addCls(cls); + me.setUI(me.ui); + + el.addCls(me.initCls()); el.setStyle(styles); // Here we check if the component has a height set through style or css. @@ -7448,14 +7724,7 @@ and a property `descEl` referencing the `div` Element which contains the descrip // } me.el = el; - - me.rendered = true; - me.addUIToElement(true); - //loop through all exisiting uiCls and update the ui in them - for (i = 0; i < me.uiCls.length; i++) { - me.addUIClsToElement(me.uiCls[i], true); - } - me.rendered = false; + me.initFrame(); renderTpl = me.initRenderTpl(); @@ -7465,10 +7734,8 @@ and a property `descEl` referencing the `div` Element which contains the descrip } me.applyRenderSelectors(); - + me.rendered = true; - - me.setUI(me.ui); }, // @private @@ -7485,7 +7752,7 @@ and a property `descEl` referencing the `div` Element which contains the descrip } // For floaters, calculate x and y if they aren't defined by aligning - // the sized element to the center of either the the container or the ownerCt + // the sized element to the center of either the container or the ownerCt if (me.floating && (me.x === undefined || me.y === undefined)) { if (me.floatParent) { xy = me.el.getAlignToXY(me.floatParent.getTargetEl(), 'c-c'); @@ -7509,6 +7776,18 @@ and a property `descEl` referencing the `div` Element which contains the descrip frameCls: Ext.baseCSSPrefix + 'frame', + frameElementCls: { + tl: [], + tc: [], + tr: [], + ml: [], + mc: [], + mr: [], + bl: [], + bc: [], + br: [] + }, + frameTpl: [ 'Returns the next node in the Component tree in tree traversal order.
*Note that this is not limited to siblings, and if invoked upon a node with no matching siblings, will - * walk the tree to attempt to find a match. Contrast with {@link #pnextSibling}.
+ * walk the tree to attempt to find a match. Contrast with {@link #nextSibling}. * @param {String} selector Optional A {@link Ext.ComponentQuery ComponentQuery} selector to filter the following nodes. * @returns The next node (or the next node which matches the selector). Returns null if there is no matching node. */ @@ -8608,12 +8950,12 @@ alert(t.getXTypes()); // alerts 'component/field/textfield' return me; }, - + // @private onEnable: function() { if (this.maskOnDisable) { this.el.unmask(); - } + } }, // @private @@ -8622,7 +8964,7 @@ alert(t.getXTypes()); // alerts 'component/field/textfield' this.el.mask(); } }, - + /** * Method to determine whether this Component is currently disabled. * @return {Boolean} the disabled state of this Component. @@ -8754,18 +9096,21 @@ alert(t.getXTypes()); // alerts 'component/field/textfield' me.mon(me[element], listeners); } else { me.afterRenderEvents = me.afterRenderEvents || {}; - me.afterRenderEvents[element] = listeners; + if (!me.afterRenderEvents[element]) { + me.afterRenderEvents[element] = []; + } + me.afterRenderEvents[element].push(listeners); } } return me.mixins.observable.addListener.apply(me, arguments); }, - + // inherit docs removeManagedListenerItem: function(isClear, managedListener, item, ename, fn, scope){ var me = this, element = managedListener.options ? managedListener.options.element : null; - + if (element) { element = me[element]; if (element && element.un) { @@ -8903,13 +9248,39 @@ alert(t.getXTypes()); // alerts 'component/field/textfield' return me; }, - setCalculatedSize : function(width, height, ownerCt) { + isFixedWidth: function() { + var me = this, + layoutManagedWidth = me.layoutManagedWidth; + + if (Ext.isDefined(me.width) || layoutManagedWidth == 1) { + return true; + } + if (layoutManagedWidth == 2) { + return false; + } + return (me.ownerCt && me.ownerCt.isFixedWidth()); + }, + + isFixedHeight: function() { + var me = this, + layoutManagedHeight = me.layoutManagedHeight; + + if (Ext.isDefined(me.height) || layoutManagedHeight == 1) { + return true; + } + if (layoutManagedHeight == 2) { + return false; + } + return (me.ownerCt && me.ownerCt.isFixedHeight()); + }, + + setCalculatedSize : function(width, height, callingContainer) { var me = this, layoutCollection; // support for standard size objects if (Ext.isObject(width)) { - ownerCt = width.ownerCt; + callingContainer = width.ownerCt; height = width.height; width = width.width; } @@ -8933,11 +9304,11 @@ alert(t.getXTypes()); // alerts 'component/field/textfield' width: width, height: height, isSetSize: false, - ownerCt: ownerCt + ownerCt: callingContainer }; return me; } - me.doComponentLayout(width, height, false, ownerCt); + me.doComponentLayout(width, height, false, callingContainer); return me; }, @@ -8947,26 +9318,51 @@ alert(t.getXTypes()); // alerts 'component/field/textfield' * layout to be recalculated. * @return {Ext.container.Container} this */ - doComponentLayout : function(width, height, isSetSize, ownerCt) { + doComponentLayout : function(width, height, isSetSize, callingContainer) { var me = this, - componentLayout = me.getComponentLayout(); + componentLayout = me.getComponentLayout(), + lastComponentSize = componentLayout.lastComponentSize || { + width: undefined, + height: undefined + }; // collapsed state is not relevant here, so no testing done. // Only Panels have a collapse method, and that just sets the width/height such that only // a single docked Header parallel to the collapseTo side are visible, and the Panel body is hidden. if (me.rendered && componentLayout) { - width = (width !== undefined) ? width : me.width; - height = (height !== undefined) ? height : me.height; + + + // If no width passed, then only insert a value if the Component is NOT ALLOWED to autowidth itself. + if (!Ext.isDefined(width)) { + if (me.isFixedWidth()) { + width = Ext.isDefined(me.width) ? me.width : lastComponentSize.width; + } + } + + // If no height passed, then only insert a value if the Component is NOT ALLOWED to autoheight itself. + if (!Ext.isDefined(height)) { + if (me.isFixedHeight()) { + height = Ext.isDefined(me.height) ? me.height : lastComponentSize.height; + } + } + if (isSetSize) { me.width = width; me.height = height; } - componentLayout.layout(width, height, isSetSize, ownerCt); + componentLayout.layout(width, height, isSetSize, callingContainer); } return me; }, + /** + * Forces this component to redo its componentLayout. + */ + forceComponentLayout: function () { + this.doComponentLayout(); + }, + // @private setComponentLayout : function(layout) { var currentLayout = this.componentLayout; @@ -8990,9 +9386,9 @@ alert(t.getXTypes()); // alerts 'component/field/textfield' * @param {Number} adjWidth The box-adjusted width that was set * @param {Number} adjHeight The box-adjusted height that was set * @param {Boolean} isSetSize Whether or not the height/width are stored on the component permanently - * @param {Ext.Component} layoutOwner Component which sent the layout. Only used when isSetSize is false. + * @param {Ext.Component} callingContainer Container requesting the layout. Only used when isSetSize is false. */ - afterComponentLayout: function(width, height, isSetSize, layoutOwner) { + afterComponentLayout: function(width, height, isSetSize, callingContainer) { this.fireEvent('resize', this, width, height); }, @@ -9002,14 +9398,15 @@ alert(t.getXTypes()); // alerts 'component/field/textfield' * @param {Number} adjWidth The box-adjusted width that was set * @param {Number} adjHeight The box-adjusted height that was set * @param {Boolean} isSetSize Whether or not the height/width are stored on the component permanently - * @param {Ext.Component} layoutOwner Component which sent the layout. Only used when isSetSize is false. + * @param {Ext.Component} callingContainer Container requesting sent the layout. Only used when isSetSize is false. */ - beforeComponentLayout: function(width, height, isSetSize, layoutOwner) { + beforeComponentLayout: function(width, height, isSetSize, callingContainer) { return true; }, /** - * Sets the left and top of the component. To set the page XY position instead, use {@link #setPagePosition}. + * Sets the left and top of the component. To set the page XY position instead, use + * {@link Ext.Component#setPagePosition setPagePosition}. * This method fires the {@link #move} event. * @param {Number} left The new left * @param {Number} top The new top @@ -9199,15 +9596,15 @@ alert(t.getXTypes()); // alerts 'component/field/textfield' me.ownerCt.remove(me, false); } - if (me.rendered) { - me.el.remove(); - } - me.onDestroy(); // Attempt to destroy all plugins Ext.destroy(me.plugins); + if (me.rendered) { + me.el.remove(); + } + Ext.ComponentManager.unregister(me); me.fireEvent('destroy', me); @@ -9235,7 +9632,7 @@ alert(t.getXTypes()); // alerts 'component/field/textfield' } } }, - + /** * Determines whether this component is the descendant of a particular container. * @param {Ext.Container} container @@ -9258,11 +9655,21 @@ alert(t.getXTypes()); // alerts 'component/field/textfield' * @class Ext.AbstractPlugin * @extends Object * - * Plugins are injected + *The AbstractPlugin class is the base class from which user-implemented plugins should inherit.
+ *This class defines the essential API of plugins as used by Components by defining the following methods:
+ *init
: The plugin initialization method which the owning Component calls at Component initialization
+ * time.The Component passes itself as the sole parameter.
Subclasses should set up bidirectional + * links between the plugin and its client Component here.
destroy
: The plugin cleanup method which the owning Component calls at Component destruction time.enable
: The base implementation just sets the plugin's disabled
flag to false
disable
: The base implementation just sets the plugin's disabled
flag to true
The init method is invoked after {@link Ext.Component#initComponent initComponent} has been run for the client Component.
+ *The supplied implementation is empty. Subclasses should perform plugin initialization, and set up bidirectional + * links between the plugin and its client Component in their own implementation of this method.
+ * @param {Component} client The client Component which owns this plugin. * @method */ init: Ext.emptyFn, /** - * The destroy method is invoked by the owning Component at the time the Component is being destroyed. - * Use this method to clean up an resources. + *The destroy method is invoked by the owning Component at the time the Component is being destroyed.
+ *The supplied implementation is empty. Subclasses should perform plugin cleanup in their own implementation of this method.
* @method */ destroy: Ext.emptyFn, /** - * Enable the plugin and set the disabled flag to false. + *The base implementation just sets the plugin's disabled
flag to false
Plugin subclasses which need more complex processing may implement an overriding implementation.
*/ enable: function() { this.disabled = false; }, /** - * Disable the plugin and set the disabled flag to true. + *The base implementation just sets the plugin's disabled
flag to true
Plugin subclasses which need more complex processing may implement an overriding implementation.
*/ disable: function() { this.disabled = true; } }); - /** * @class Ext.data.Connection * The Connection class encapsulates a connection to the page's originating domain, allowing requests to be made either @@ -10014,9 +10424,20 @@ failure: function(response, opts) { onComplete : function(request) { var me = this, options = request.options, - result = me.parseStatus(request.xhr.status), - success = result.success, + result, + success, response; + + try { + result = me.parseStatus(request.xhr.status); + } catch (e) { + // in some browsers we can't access the status if the readyState is not 4, so the request has failed + result = { + success : false, + isException : false + }; + } + success = result.success; if (success) { response = me.createResponse(request); @@ -10354,8 +10775,6 @@ Ext.onReady(function(){ }); * * - * @constructor - * @param {Object} config Optional config object */ Ext.define('Ext.data.Association', { /** @@ -10410,6 +10829,10 @@ Ext.define('Ext.data.Association', { } }, + /** + * Creates the Association object. + * @param {Object} config (optional) Config object. + */ constructor: function(config) { Ext.apply(this, config); @@ -10772,21 +11195,21 @@ Ext.define('Ext.ModelManager', { * * Further Reading * - * For more information about writing Ext JS 4 applications, please see the - * application architecture guide. Also see the {@link Ext.app.Application} documentation. + * For more information about writing Ext JS 4 applications, please see the + * [application architecture guide](#/guide/application_architecture). Also see the {@link Ext.app.Application} documentation. * * @docauthor Ed Spencer - * @constructor */ Ext.define('Ext.app.Controller', { - /** - * @cfg {String} id The id of this controller. You can use this id when dispatching. - */ mixins: { observable: 'Ext.util.Observable' }, + /** + * @cfg {String} id The id of this controller. You can use this id when dispatching. + */ + onClassExtended: function(cls, data) { var className = Ext.getClassName(cls), match = className.match(/^(.*)\.controller\./); @@ -10826,6 +11249,10 @@ Ext.define('Ext.app.Controller', { } }, + /** + * Creates new Controller. + * @param {Object} config (optional) Config object. + */ constructor: function(config) { this.mixins.observable.constructor.call(this, config); @@ -10908,22 +11335,65 @@ Ext.define('Ext.app.Controller', { return cached; }, + /** + * Adds listeners to components selected via {@link Ext.ComponentQuery}. Accepts an + * object containing component paths mapped to a hash of listener functions. + * + * In the following example the `updateUser` function is mapped to to the `click` + * event on a button component, which is a child of the `useredit` component. + * + * Ext.define('AM.controller.Users', { + * init: function() { + * this.control({ + * 'useredit button[action=save]': { + * click: this.updateUser + * } + * }); + * }, + * + * updateUser: function(button) { + * console.log('clicked the Save button'); + * } + * }); + * + * See {@link Ext.ComponentQuery} for more information on component selectors. + * + * @param {String|Object} selectors If a String, the second argument is used as the + * listeners, otherwise an object of selectors -> listeners is assumed + * @param {Object} listeners + */ control: function(selectors, listeners) { this.application.control(selectors, listeners, this); }, + /** + * Returns a reference to a {@link Ext.app.Controller controller} with the given name + * @param name {String} + */ getController: function(name) { return this.application.getController(name); }, + /** + * Returns a reference to a {@link Ext.data.Store store} with the given name + * @param name {String} + */ getStore: function(name) { return this.application.getStore(name); }, + /** + * Returns a reference to a {@link Ext.data.Model Model} with the given name + * @param name {String} + */ getModel: function(model) { return this.application.getModel(model); }, + /** + * Returns a reference to a view with the given name + * @param name {String} + */ getView: function(view) { return this.application.getView(view); } @@ -11119,8 +11589,6 @@ Ext.define('Ext.data.Errors', { * *Several Operations can be batched together in a {@link Ext.data.Batch batch}.
* - * @constructor - * @param {Object} config Optional config object */ Ext.define('Ext.data.Operation', { /** @@ -11214,7 +11682,11 @@ Ext.define('Ext.data.Operation', { * @private */ error: undefined, - + + /** + * Creates new Operation object. + * @param {Object} config (optional) Config object. + */ constructor: function(config) { Ext.apply(this, config || {}); }, @@ -11456,9 +11928,6 @@ Ext.define('Ext.data.validations', { * @extends Object * *Simple wrapper class that represents a set of records returned by a Proxy.
- * - * @constructor - * Creates the new ResultSet */ Ext.define('Ext.data.ResultSet', { /** @@ -11491,6 +11960,10 @@ Ext.define('Ext.data.ResultSet', { * @cfg {Array} records The array of record instances. Required */ + /** + * Creates the resultSet + * @param {Object} config (optional) Config object. + */ constructor: function(config) { Ext.apply(this, config); @@ -11522,9 +11995,6 @@ Ext.define('Ext.data.ResultSet', { * {@link Ext.data.proxy.WebStorage Web Storage proxy} (see {@link Ext.data.proxy.LocalStorage localStorage} * and {@link Ext.data.proxy.SessionStorage sessionStorage}) or just in memory via a * {@link Ext.data.proxy.Memory MemoryProxy}. - * - * @constructor - * @param {Object} config Optional config object */ Ext.define('Ext.data.writer.Writer', { alias: 'writer.base', @@ -11570,6 +12040,10 @@ new Ext.data.writer.Writer({ */ nameProperty: 'name', + /** + * Creates new Writer. + * @param {Object} config (optional) Config object. + */ constructor: function(config) { Ext.apply(this, config); }, @@ -11715,8 +12189,10 @@ Ext.define('Ext.util.Floating', { }, onFloatParentHide: function() { - this.showOnParentShow = this.isVisible(); - this.hide(); + if (this.hideOnParentHide !== false) { + this.showOnParentShow = this.isVisible(); + this.hide(); + } }, onFloatParentShow: function() { @@ -11787,8 +12263,8 @@ Ext.define('Ext.util.Floating', { me.setPosition(xy); } }, - - + + /** * Gets the x/y offsets to constrain this float * @private @@ -11798,7 +12274,7 @@ Ext.define('Ext.util.Floating', { getConstrainVector: function(constrainTo){ var me = this, el; - + if (me.constrain || me.constrainHeader) { el = me.constrainHeader ? me.header.el : me.el; constrainTo = constrainTo || (me.floatParent && me.floatParent.getTargetEl()) || me.container; @@ -11926,13 +12402,6 @@ Ext.define('Ext.layout.container.AbstractContainer', { type: 'container', - fixedLayout: true, - - // @private - managedHeight: true, - // @private - managedWidth: true, - /** * @cfg {Boolean} bindToOwnerCtComponent * Flag to notify the ownerCt Component on afterLayout of a change @@ -11953,37 +12422,6 @@ Ext.define('Ext.layout.container.AbstractContainer', { * */ - isManaged: function(dimension) { - dimension = Ext.String.capitalize(dimension); - var me = this, - child = me, - managed = me['managed' + dimension], - ancestor = me.owner.ownerCt; - - if (ancestor && ancestor.layout) { - while (ancestor && ancestor.layout) { - if (managed === false || ancestor.layout['managed' + dimension] === false) { - managed = false; - break; - } - ancestor = ancestor.ownerCt; - } - } - return managed; - }, - - layout: function() { - var me = this, - owner = me.owner; - if (Ext.isNumber(owner.height) || owner.isViewport) { - me.managedHeight = false; - } - if (Ext.isNumber(owner.width) || owner.isViewport) { - me.managedWidth = false; - } - me.callParent(arguments); - }, - /** * Set the size of an item within the Container. We should always use setCalculatedSize. * @private @@ -12035,7 +12473,6 @@ Ext.define('Ext.layout.container.AbstractContainer', { * (For example a {Ext.view.BoundList BoundList} within an {@link Ext.window.Window Window}, or a {@link Ext.menu.Menu Menu}), * are managed by a ZIndexManager owned by that floating Container. So ComboBox dropdowns within Windows will have managed z-indices * guaranteed to be correct, relative to the Window. - * @constructor */ Ext.define('Ext.ZIndexManager', { @@ -12521,14 +12958,16 @@ var map = new Ext.util.KeyMap("my-element", [ ]); * Note: A KeyMap starts enabled - * @constructor - * @param {Mixed} el The element to bind to - * @param {Object} binding The binding (see {@link #addBinding}) - * @param {String} eventName (optional) The event to bind to (defaults to "keydown") */ Ext.define('Ext.util.KeyMap', { alternateClassName: 'Ext.KeyMap', - + + /** + * Creates new KeyMap. + * @param {Mixed} el The element to bind to + * @param {Object} binding The binding (see {@link #addBinding}) + * @param {String} eventName (optional) The event to bind to (defaults to "keydown") + */ constructor: function(el, binding, eventName){ var me = this; @@ -12799,14 +13238,15 @@ map.addBinding({ * * Optionally, a CSS class may be applied to the element during the time it is pressed. * - * @constructor - * @param {Mixed} el The element to listen on - * @param {Object} config */ - Ext.define('Ext.util.ClickRepeater', { extend: 'Ext.util.Observable', + /** + * Creates new ClickRepeater. + * @param {Mixed} el The element to listen on + * @param {Object} config (optional) Config object. + */ constructor : function(el, config){ this.el = Ext.get(el); this.el.unselectable(); @@ -13057,6 +13497,8 @@ Ext.define('Ext.layout.component.Button', { ownerEl = owner.el, btnEl = owner.btnEl, btnInnerEl = owner.btnInnerEl, + btnIconEl = owner.btnIconEl, + sizeIconEl = (owner.icon || owner.iconCls) && (owner.iconAlign == "top" || owner.iconAlign == "bottom"), minWidth = owner.minWidth, maxWidth = owner.maxWidth, ownerWidth, btnFrameWidth, metrics; @@ -13077,11 +13519,16 @@ Ext.define('Ext.layout.component.Button', { ownerEl.setWidth(metrics.width + btnFrameWidth + me.adjWidth); btnEl.setWidth(metrics.width + btnFrameWidth); btnInnerEl.setWidth(metrics.width + btnFrameWidth); + + if (sizeIconEl) { + btnIconEl.setWidth(metrics.width + btnFrameWidth); + } } else { // Remove any previous fixed widths ownerEl.setWidth(null); btnEl.setWidth(null); btnInnerEl.setWidth(null); + btnIconEl.setWidth(null); } // Handle maxWidth/minWidth config @@ -13157,19 +13604,16 @@ Ext.define('Ext.layout.component.Button', { } }); /** - * @class Ext.util.TextMetrics - ** Provides precise pixel measurements for blocks of text so that you can determine exactly how high and * wide, in pixels, a given block of text will be. Note that when measuring text, it should be plain text and - * should not contain any HTML, otherwise it may not be measured correctly.
- *The measurement works by copying the relevant CSS styles that can affect the font related display, + * should not contain any HTML, otherwise it may not be measured correctly. + * + * The measurement works by copying the relevant CSS styles that can affect the font related display, * then checking the size of an element that is auto-sized. Note that if the text is multi-lined, you must - * provide a fixed width when doing the measurement.
- * - *+ * provide a **fixed width** when doing the measurement. + * * If multiple measurements are being done on the same element, you create a new instance to initialize * to avoid the overhead of copying the styles to the element repeatedly. - *
*/ Ext.define('Ext.util.TextMetrics', { statics: { @@ -13181,7 +13625,7 @@ Ext.define('Ext.util.TextMetrics', { * @param {String} text The text to measure * @param {Number} fixedWidth (optional) If the text will be multiline, you have to set a fixed width * in order to accurately measure the text height - * @return {Object} An object containing the text's size {width: (width), height: (height)} + * @return {Object} An object containing the text's size `{width: (width), height: (height)}` */ measure: function(el, text, fixedWidth){ var me = this, @@ -13206,9 +13650,9 @@ Ext.define('Ext.util.TextMetrics', { }, /** - * @constructor + * Creates new TextMetrics. * @param {Mixed} bindTo The element to bind to. - * @param {Number} fixedWidth A fixed width to apply to the measuring element. + * @param {Number} fixedWidth (optional) A fixed width to apply to the measuring element. */ constructor: function(bindTo, fixedWidth){ var measure = this.measure = Ext.getBody().createChild({ @@ -13226,10 +13670,9 @@ Ext.define('Ext.util.TextMetrics', { }, /** - *Only available on the instance returned from {@link #createInstance}, not on the singleton.
* Returns the size of the specified text based on the internal element's style and width properties * @param {String} text The text to measure - * @return {Object} An object containing the text's size {width: (width), height: (height)} + * @return {Object} An object containing the text's size `{width: (width), height: (height)}` */ getSize: function(text){ var measure = this.measure, @@ -13296,10 +13739,10 @@ Ext.define('Ext.util.TextMetrics', { /** * Returns the width in pixels of the passed text, or the width of the text in this Element. * @param {String} text The text to measure. Defaults to the innerHTML of the element. - * @param {Number} min (Optional) The minumum value to return. - * @param {Number} max (Optional) The maximum value to return. + * @param {Number} min (optional) The minumum value to return. + * @param {Number} max (optional) The maximum value to return. * @return {Number} The text width in pixels. - * @member Ext.core.Element getTextWidth + * @member Ext.core.Element */ getTextWidth : function(text, min, max){ return Ext.Number.constrain(Ext.util.TextMetrics.measure(this.dom, Ext.value(text, this.dom.innerHTML, true)).width, min || 0, max || 1000000); @@ -13803,9 +14246,6 @@ var nav = new Ext.util.KeyNav("my-element", { scope : this }); - * @constructor - * @param {Mixed} el The element to bind to - * @param {Object} config The config */ Ext.define('Ext.util.KeyNav', { @@ -13831,7 +14271,12 @@ Ext.define('Ext.util.KeyNav', { tab: 9 } }, - + + /** + * Creates new KeyNav. + * @param {Mixed} el The element to bind to + * @param {Object} config The config + */ constructor: function(el, config){ this.setConfig(el, config || {}); }, @@ -14083,20 +14528,22 @@ underlying animation will create the appropriate Ext.fx.target.Target object by the instance to be animated. The following types of objects can be animated: -- {@link #Ext.fx.target.Component Components} -- {@link #Ext.fx.target.Element Elements} -- {@link #Ext.fx.target.Sprite Sprites} + +- {@link Ext.fx.target.Component Components} +- {@link Ext.fx.target.Element Elements} +- {@link Ext.fx.target.Sprite Sprites} * @markdown * @abstract - * @constructor - * @param {Mixed} target The object to be animated */ - Ext.define('Ext.fx.target.Target', { isAnimTarget: true, + /** + * Creates new Target. + * @param {Mixed} target The object to be animated + */ constructor: function(target) { this.target = target; this.id = this.getId(); @@ -14447,9 +14894,6 @@ Ext.define('Ext.fx.CubicBezier', { } }); /** - * @class Ext.draw.Color - * @extends Object - * * Represents an RGB color and provides helper functions get * color components in HSL color space. */ @@ -14471,7 +14915,7 @@ Ext.define('Ext.draw.Color', { lightnessFactor: 0.2, /** - * @constructor + * Creates new Color. * @param {Number} red Red component (0..255) * @param {Number} green Green component (0..255) * @param {Number} blue Blue component (0..255) @@ -14510,7 +14954,7 @@ Ext.define('Ext.draw.Color', { /** * Get the RGB values. - * @return {Array} + * @return {[Number]} */ getRGB: function() { var me = this; @@ -14519,7 +14963,7 @@ Ext.define('Ext.draw.Color', { /** * Get the equivalent HSL components of the color. - * @return {Array} + * @return {[Number]} */ getHSL: function() { var me = this, @@ -14594,9 +15038,12 @@ Ext.define('Ext.draw.Color', { /** * Convert a color to hexadecimal format. * - * @param {String|Array} color The color value (i.e 'rgb(255, 255, 255)', 'color: #ffffff'). + * **Note:** This method is both static and instance. + * + * @param {String/[String]} color The color value (i.e 'rgb(255, 255, 255)', 'color: #ffffff'). * Can also be an Array, in this case the function handles the first member. * @returns {String} The color in hexadecimal format. + * @static */ toHex: function(color) { if (Ext.isArray(color)) { @@ -14629,8 +15076,11 @@ Ext.define('Ext.draw.Color', { * * If the string is not recognized, an undefined will be returned instead. * + * **Note:** This method is both static and instance. + * * @param {String} str Color in string. * @returns Ext.draw.Color + * @static */ fromString: function(str) { var values, r, g, b, @@ -14676,10 +15126,13 @@ Ext.define('Ext.draw.Color', { /** * Create a new color based on the specified HSL values. * + * **Note:** This method is both static and instance. + * * @param {Number} h Hue component (0..359) * @param {Number} s Saturation component (0..1) * @param {Number} l Lightness component (0..1) * @returns Ext.draw.Color + * @static */ fromHSL: function(h, s, l) { var C, X, m, i, rgb = [], @@ -14744,12 +15197,14 @@ Ext.define('Ext.draw.Color', { * @class Ext.dd.StatusProxy * A specialized drag proxy that supports a drop status icon, {@link Ext.Layer} styles and auto-repair. This is the * default drag proxy used by all Ext.dd components. - * @constructor - * @param {Object} config */ Ext.define('Ext.dd.StatusProxy', { animRepair: false, + /** + * Creates new StatusProxy. + * @param {Object} config (optional) Config object. + */ constructor: function(config){ Ext.apply(this, config); this.id = this.id || Ext.id(); @@ -14926,14 +15381,16 @@ Ext.define('Ext.dd.StatusProxy', { * A custom drag proxy implementation specific to {@link Ext.panel.Panel}s. This class * is primarily used internally for the Panel's drag drop implementation, and * should never need to be created directly. - * @constructor - * @param panel The {@link Ext.panel.Panel} to proxy for - * @param config Configuration options */ Ext.define('Ext.panel.Proxy', { alternateClassName: 'Ext.dd.PanelProxy', - + + /** + * Creates new panel proxy. + * @param {Ext.panel.Panel} panel The {@link Ext.panel.Panel} to proxy for + * @param {Object} config (optional) Config object + */ constructor: function(panel, config){ /** * @property panel @@ -15187,6 +15644,8 @@ Ext.define('Ext.layout.component.AbstractDock', { }, bodyBox: {} }; + // Clear isAutoDock flag + delete layout.isAutoDock; Ext.applyIf(info, me.getTargetInfo()); @@ -15232,6 +15691,8 @@ Ext.define('Ext.layout.component.AbstractDock', { if (layout && layout.isLayout) { // Auto-Sized so have the container layout notify the component layout. layout.bindToOwnerCtComponent = true; + // Set flag so we don't do a redundant container layout + layout.isAutoDock = layout.autoSize !== true; layout.layout(); // If this is an autosized container layout, then we must compensate for a @@ -15465,6 +15926,7 @@ Ext.define('Ext.layout.component.AbstractDock', { */ adjustAutoBox : function (box, index) { var info = this.info, + owner = this.owner, bodyBox = info.bodyBox, size = info.size, boxes = info.boxes, @@ -15495,33 +15957,43 @@ Ext.define('Ext.layout.component.AbstractDock', { box.y = bodyBox.y; if (!box.overlay) { bodyBox.y += box.height; + if (owner.isFixedHeight()) { + bodyBox.height -= box.height; + } else { + size.height += box.height; + } } - size.height += box.height; break; case 'bottom': + if (!box.overlay) { + if (owner.isFixedHeight()) { + bodyBox.height -= box.height; + } else { + size.height += box.height; + } + } box.y = (bodyBox.y + bodyBox.height); - size.height += box.height; break; case 'left': box.x = bodyBox.x; if (!box.overlay) { bodyBox.x += box.width; - if (autoSizedCtLayout) { - size.width += box.width; - } else { + if (owner.isFixedWidth()) { bodyBox.width -= box.width; + } else { + size.width += box.width; } } break; case 'right': if (!box.overlay) { - if (autoSizedCtLayout) { - size.width += box.width; - } else { + if (owner.isFixedWidth()) { bodyBox.width -= box.width; + } else { + size.width += box.width; } } box.x = (bodyBox.x + bodyBox.width); @@ -15740,6 +16212,13 @@ Ext.define('Ext.layout.component.AbstractDock', { */ configureItem : function(item, pos) { this.callParent(arguments); + if (item.dock == 'top' || item.dock == 'bottom') { + item.layoutManagedWidth = 1; + item.layoutManagedHeight = 2; + } else { + item.layoutManagedWidth = 2; + item.layoutManagedHeight = 1; + } item.addCls(Ext.baseCSSPrefix + 'docked'); item.addClsWithUI('docked-' + item.dock); @@ -15758,6 +16237,130 @@ Ext.define('Ext.layout.component.AbstractDock', { this.childrenChanged = true; } }); +/** + * @class Ext.util.Memento + * This class manages a set of captured properties from an object. These captured properties + * can later be restored to an object. + */ +Ext.define('Ext.util.Memento', function () { + + function captureOne (src, target, prop) { + src[prop] = target[prop]; + } + + function removeOne (src, target, prop) { + delete src[prop]; + } + + function restoreOne (src, target, prop) { + var value = src[prop]; + if (value || src.hasOwnProperty(prop)) { + restoreValue(target, prop, value); + } + } + + function restoreValue (target, prop, value) { + if (Ext.isDefined(value)) { + target[prop] = value; + } else { + delete target[prop]; + } + } + + function doMany (doOne, src, target, props) { + if (src) { + if (Ext.isArray(props)) { + Ext.each(props, function (prop) { + doOne(src, target, prop); + }); + } else { + doOne(src, target, props); + } + } + } + + return { + /** + * @property data + * The collection of captured properties. + * @private + */ + data: null, + + /** + * @property target + * The default target object for capture/restore (passed to the constructor). + */ + target: null, + + /** + * Creates a new memento and optionally captures properties from the target object. + * @param {Object} target The target from which to capture properties. If specified in the + * constructor, this target becomes the default target for all other operations. + * @param {String|Array} props The property or array of properties to capture. + */ + constructor: function (target, props) { + if (target) { + this.target = target; + if (props) { + this.capture(props); + } + } + }, + + /** + * Captures the specified properties from the target object in this memento. + * @param {String|Array} props The property or array of properties to capture. + * @param {Object} target The object from which to capture properties. + */ + capture: function (props, target) { + doMany(captureOne, this.data || (this.data = {}), target || this.target, props); + }, + + /** + * Removes the specified properties from this memento. These properties will not be + * restored later without re-capturing their values. + * @param {String|Array} props The property or array of properties to remove. + */ + remove: function (props) { + doMany(removeOne, this.data, null, props); + }, + + /** + * Restores the specified properties from this memento to the target object. + * @param {String|Array} props The property or array of properties to restore. + * @param {Boolean} clear True to remove the restored properties from this memento or + * false to keep them (default is true). + * @param {Object} target The object to which to restore properties. + */ + restore: function (props, clear, target) { + doMany(restoreOne, this.data, target || this.target, props); + if (clear !== false) { + this.remove(props); + } + }, + + /** + * Restores all captured properties in this memento to the target object. + * @param {Boolean} clear True to remove the restored properties from this memento or + * false to keep them (default is true). + * @param {Object} target The object to which to restore properties. + */ + restoreAll: function (clear, target) { + var me = this, + t = target || this.target; + + Ext.Object.each(me.data, function (prop, value) { + restoreValue(t, prop, value); + }); + + if (clear !== false) { + delete me.data; + } + } + }; +}()); + /** * @class Ext.app.EventBus * @private @@ -15807,7 +16410,9 @@ Ext.define('Ext.app.EventBus', { for (i = 0, ln = events.length; i < ln; i++) { event = events[i]; // Fire the event! - return event.fire.apply(event, Array.prototype.slice.call(args, 1)); + if (event.fire.apply(event, Array.prototype.slice.call(args, 1)) === false) { + return false; + }; } } } @@ -16282,7 +16887,7 @@ var myData = [ *(Optional) Used when converting received data into a Date when the {@link #type} is specified as "date"
.
A format string for the {@link Ext.Date#parse Ext.Date.parse} function, or "timestamp" if the * value provided by the Reader is a UNIX timestamp, or "time" if the value provided by the Reader is a - * javascript millisecond timestamp. See {@link Date}
+ * javascript millisecond timestamp. See {@link Ext.Date} */ dateFormat: null, @@ -16512,8 +17117,6 @@ Order ID: 50, which contains items: 3 orders of iPhone * - * @constructor - * @param {Object} config Optional config object */ Ext.define('Ext.data.reader.Reader', { requires: ['Ext.data.ResultSet'], @@ -16564,6 +17167,10 @@ Ext.define('Ext.data.reader.Reader', { isReader: true, + /** + * Creates new Reader. + * @param {Object} config (optional) Config object. + */ constructor: function(config) { var me = this; @@ -17363,9 +17970,6 @@ Ext.define('Ext.data.writer.Json', { * *Proxies also support batching of Operations via a {@link Ext.data.Batch batch} object, invoked by the {@link #batch} method.
* - * @constructor - * Creates the Proxy - * @param {Object} config Optional config object */ Ext.define('Ext.data.proxy.Proxy', { alias: 'proxy.proxy', @@ -17415,6 +18019,10 @@ Ext.define('Ext.data.proxy.Proxy', { isProxy: true, + /** + * Creates the Proxy + * @param {Object} config (optional) Config object. + */ constructor: function(config) { config = config || {}; @@ -17716,30 +18324,31 @@ Ext.define('Ext.data.proxy.Server', { cacheString: "_dc", /** - * @cfg {Number} timeout (optional) The number of milliseconds to wait for a response. Defaults to 30 seconds. + * @cfg {Number} timeout (optional) The number of milliseconds to wait for a response. + * Defaults to 30000 milliseconds (30 seconds). */ timeout : 30000, /** * @cfg {Object} api - * Specific urls to call on CRUD action methods "read", "create", "update" and "destroy". + * Specific urls to call on CRUD action methods "create", "read", "update" and "destroy". * Defaults to:
api: {
- read : undefined,
create : undefined,
+ read : undefined,
update : undefined,
destroy : undefined
}
*
- * The url is built based upon the action being executed [load|create|save|destroy] + *
The url is built based upon the action being executed [create|read|update|destroy] * using the commensurate {@link #api} property, or if undefined default to the * configured {@link Ext.data.Store}.{@link Ext.data.proxy.Server#url url}.
For example:
*
api: {
- load : '/controller/load',
- create : '/controller/new',
- save : '/controller/update',
+ create : '/controller/new',
+ read : '/controller/load',
+ update : '/controller/update',
destroy : '/controller/destroy_action'
}
*
@@ -18619,7 +19228,7 @@ store.load();
*
* @constructor
* @param {Object} data An object containing keys corresponding to this model's fields, and their associated values
- * @param {Number} id Optional unique ID to assign to this model instance
+ * @param {Number} id (optional) Unique ID to assign to this model instance
*/
Ext.define('Ext.data.Model', {
alternateClassName: 'Ext.data.Record',
@@ -18901,10 +19510,10 @@ Ext.define('Ext.data.Model', {
dirty : false,
/**
- * @cfg {String} persistanceProperty The property on this Persistable object that its data is saved to.
+ * @cfg {String} persistenceProperty The property on this Persistable object that its data is saved to.
* Defaults to 'data' (e.g. all persistable data resides in this.data.)
*/
- persistanceProperty: 'data',
+ persistenceProperty: 'data',
evented: false,
isModel: true,
@@ -18975,7 +19584,16 @@ Ext.define('Ext.data.Model', {
*/
me.modified = {};
- me[me.persistanceProperty] = {};
+ // Deal with spelling error in previous releases
+ if (me.persistanceProperty) {
+ //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 {Ext.view.DataView DataView}, or {Ext.grid.Panel GridPanel},
- * or {@link Ext.tree.Panel TreePanel} be used.
Shows this Component, rendering it first if {@link #autoRender} or {{@link "floating} are true
.
Shows this Component, rendering it first if {@link #autoRender} or {@link #floating} are true
.
After being shown, a {@link #floating} Component (such as a {@link Ext.window.Window}), is activated it and brought to the front of - * its {@link #ZIndexManager z-index stack}.
+ * its {@link #zIndexManager z-index stack}. * @param {String/Element} animateTarget Optional, and only valid for {@link #floating} Components such as * {@link Ext.window.Window Window}s or {@link Ext.tip.ToolTip ToolTip}s, or regular Components which have been configured * withfloating: true
. The target from which the Component should
@@ -20626,7 +21262,6 @@ alert(t.getXType()); // alerts 'textfield'
/**
* @class Ext.layout.container.Container
* @extends Ext.layout.container.AbstractContainer
-* @private
* This class is intended to be extended or created via the {@link Ext.container.Container#layout layout} * configuration property. See {@link Ext.container.Container#layout} for additional details.
*/ @@ -20676,11 +21311,6 @@ Ext.define('Ext.layout.container.Container', { } }, - afterLayout: function() { - this.owner.afterLayout(arguments); - this.callParent(arguments); - }, - /** * @protected * Returns all items that are rendered @@ -20768,8 +21398,6 @@ Ext.define('Ext.layout.container.Auto', { type: 'autocontainer', - fixedLayout: false, - bindToOwnerCtComponent: true, // @private @@ -20796,6 +21424,18 @@ Ext.define('Ext.layout.container.Auto', { me.setItemSize(items[i]); } } + }, + + configureItem: function(item) { + + // Auto layout does not manage any dimensions. + // We have to check our type, because this could be called as a superclass method in a subclass + if (this.type === 'autocontainer') { + item.layoutManagedHeight = 2; + item.layoutManagedWidth = 2; + } + + this.callParent(arguments); } }); /** @@ -21129,7 +21769,7 @@ items: [ if (me.rendered && layout && !me.suspendLayout) { // If either dimension is being auto-set, then it requires a ComponentLayout to be run. - if ((!Ext.isNumber(me.width) || !Ext.isNumber(me.height)) && me.componentLayout.type !== 'autocomponent') { + if (!me.isFixedWidth() || !me.isFixedHeight()) { // Only run the ComponentLayout if it is not already in progress if (me.componentLayout.layoutBusy !== true) { me.doComponentLayout(); @@ -21138,7 +21778,7 @@ items: [ } } } - // Both dimensions defined, run a ContainerLayout + // Both dimensions set, either by configuration, or by an owning layout, run a ContainerLayout else { // Only run the ContainerLayout if it is not already in progress if (layout.layoutBusy !== true) { @@ -21475,9 +22115,11 @@ for more details. } } - // Resume Layouts now that all items have been removed and do a single layout + // Resume Layouts now that all items have been removed and do a single layout (if we removed anything!) me.suspendLayout = false; - me.doLayout(); + if (len) { + me.doLayout(); + } return items; }, @@ -21830,8 +22472,6 @@ Ext.Ajax.request({ *Note: since the code above is generated by a server script, the autoLoad
params for
* the Store, the user's preferred date format, the metadata to allow generation of the Model layout, and the ColumnModel
* can all be generated into the code since these are all known on the server.
This class represents a rectangular region in X,Y space, and performs geometric + * transformations or tests upon the region.
+ *This class may be used to compare the document regions occupied by elements.
*/ Ext.define('Ext.util.Region', { @@ -23836,10 +24469,9 @@ Ext.define('Ext.util.Region', { statics: { /** * @static - * @param {Mixed} el A string, DomElement or Ext.core.Element representing an element - * on the page. - * @returns {Ext.util.Region} region * Retrieves an Ext.util.Region for a particular element. + * @param {Mixed} el An element ID, htmlElement or Ext.core.Element representing an element in the document. + * @returns {Ext.util.Region} region */ getRegion: function(el) { return Ext.fly(el).getPageBox(true); @@ -23847,8 +24479,9 @@ Ext.define('Ext.util.Region', { /** * @static - * @param {Object} o An object with top, right, bottom, left properties - * @return {Ext.util.Region} region The region constructed based on the passed object + * Creates a Region from a "box" Object which contains four numeric propertiestop
, right
, bottom
and left
.
+ * @param {Object} o An object with top
, right
, bottom
and left
properties.
+ * @return {Ext.util.Region} region The Region constructed based on the passed object
*/
from: function(o) {
return new this(o.top, o.right, o.bottom, o.left);
@@ -23858,11 +24491,11 @@ Ext.define('Ext.util.Region', {
/* End Definitions */
/**
- * @constructor
- * @param {Number} top Top
- * @param {Number} right Right
- * @param {Number} bottom Bottom
- * @param {Number} left Left
+ * Creates a region from the bounding sides.
+ * @param {Number} top Top The topmost pixel of the Region.
+ * @param {Number} right Right The rightmost pixel of the Region.
+ * @param {Number} bottom Bottom The bottom pixel of the Region.
+ * @param {Number} left Left The leftmost pixel of the Region.
*/
constructor : function(t, r, b, l) {
var me = this;
@@ -24126,7 +24759,7 @@ Ext.define('Ext.util.Region', {
},
/**
- * Copy a new instance
+ * Create a copy of this Region.
* @return {Ext.util.Region}
*/
copy: function() {
@@ -24136,7 +24769,7 @@ Ext.define('Ext.util.Region', {
/**
* Copy the values of another Region to this Region
* @param {Region} The region to copy from.
- * @return {Ext.util.Point} this This point
+ * @return {Ext.util.Region} This Region
*/
copyFrom: function(p) {
var me = this;
@@ -24148,7 +24781,7 @@ Ext.define('Ext.util.Region', {
return this;
},
- /**
+ /*
* Dump this to an eye-friendly string, great for debugging
* @return {String}
*/
@@ -24156,7 +24789,6 @@ Ext.define('Ext.util.Region', {
return "Region[" + this.top + "," + this.right + "," + this.bottom + "," + this.left + "]";
},
-
/**
* Translate this region by the given offset amount
* @param {Ext.util.Offset/Object} offset Object containing the x
and y
properties.
@@ -25629,8 +26261,6 @@ Ext.define('Ext.layout.container.Box', {
bindToOwnerCtContainer: true,
- fixedLayout: false,
-
// availableSpaceOffset is used to adjust the availableWidth, typically used
// to reserve space for a scrollbar
availableSpaceOffset: 0,
@@ -25679,11 +26309,12 @@ Ext.define('Ext.layout.container.Box', {
*/
getChildBox: function(child) {
child = child.el || this.owner.getComponent(child).el;
+ var size = child.getBox(false, true);
return {
- left: child.getLeft(true),
- top: child.getTop(true),
- width: child.getWidth(),
- height: child.getHeight()
+ left: size.left,
+ top: size.top,
+ width: size.width,
+ height: size.height
};
},
@@ -25740,6 +26371,8 @@ Ext.define('Ext.layout.container.Box', {
paddingPerpendicular = perpendicularOffset + padding[me.perpendicularRightBottom],
availPerpendicularSize = mmax(0, perpendicularSize - paddingPerpendicular),
+ innerCtBorderWidth = me.innerCt.getBorderWidth(me.perpendicularLT + me.perpendicularRB),
+
isStart = me.pack == 'start',
isCenter = me.pack == 'center',
isEnd = me.pack == 'end',
@@ -25965,7 +26598,7 @@ Ext.define('Ext.layout.container.Box', {
// When calculating a centered position within the content box of the innerCt, the width of the borders must be subtracted from
// the size to yield the space available to center within.
// The updateInnerCtSize method explicitly adds the border widths to the set size of the innerCt.
- diff = mmax(availPerpendicularSize, maxSize) - me.innerCt.getBorderWidth(me.perpendicularLT + me.perpendicularRB) - calcs[perpendicularPrefix];
+ diff = mmax(availPerpendicularSize, maxSize) - innerCtBorderWidth - calcs[perpendicularPrefix];
if (diff > 0) {
calcs[me.perpendicularLeftTop] = perpendicularOffset + Math.round(diff / 2);
}
@@ -26058,7 +26691,7 @@ Ext.define('Ext.layout.container.Box', {
}
if (results.recalculate) {
- items = me.getVisibleItems(owner);
+ items = me.getVisibleItems();
calcs = me.calculateChildBoxes(items, targetSize);
boxes = calcs.boxes;
}
@@ -26441,7 +27074,21 @@ Ext.define('Ext.layout.container.HBox', {
perpendicularRB: 'b',
perpendicularLeftTop: 'top',
perpendicularRightBottom: 'bottom',
- perpendicularPosition: 'y'
+ perpendicularPosition: 'y',
+ configureItem: function(item) {
+ if (item.flex) {
+ item.layoutManagedWidth = 1;
+ } else {
+ item.layoutManagedWidth = 2;
+ }
+
+ if (this.align === 'stretch' || this.align === 'stretchmax') {
+ item.layoutManagedHeight = 1;
+ } else {
+ item.layoutManagedHeight = 2;
+ }
+ this.callParent(arguments);
+ }
});
/**
* @class Ext.layout.container.VBox
@@ -26531,7 +27178,21 @@ Ext.define('Ext.layout.container.VBox', {
perpendicularRB: 'r',
perpendicularLeftTop: 'left',
perpendicularRightBottom: 'right',
- perpendicularPosition: 'x'
+ perpendicularPosition: 'x',
+ configureItem: function(item) {
+ if (item.flex) {
+ item.layoutManagedHeight = 1;
+ } else {
+ item.layoutManagedHeight = 2;
+ }
+
+ if (this.align === 'stretch' || this.align === 'stretchmax') {
+ item.layoutManagedWidth = 1;
+ } else {
+ item.layoutManagedWidth = 2;
+ }
+ this.callParent(arguments);
+ }
});
/**
* @class Ext.FocusManager
@@ -26955,10 +27616,14 @@ Ext.define('Ext.FocusManager', {
if (!me.focusedCmp || !(parent = me.focusedCmp.up(':focusable'))) {
me.focusEl.focus();
- return;
+ } else {
+ parent.focus();
}
- parent.focus();
+ // In some browsers (Chrome) FocusManager can handle this before other
+ // handlers. Ext Windows have their own Esc key handling, so we need to
+ // return true here to allow the event to bubble.
+ return true;
},
navigateSiblings: function(e, source, parent) {
@@ -27584,7 +28249,6 @@ Example usage:
* @constructor
* Creates a new Toolbar
* @param {Object/Array} config A config object or an array of buttons to {@link #add}
- * @xtype toolbar
* @docauthor Robert Dougan A base class which provides methods common to Panel classes across the Sencha product range.
*Please refer to sub class's documentation
- * @constructor - * @param {Object} config The config object */ Ext.define('Ext.panel.AbstractPanel', { @@ -27845,7 +28508,7 @@ Ext.define('Ext.panel.AbstractPanel', { * A shortcut to add or remove the border on the body of a panel. This only applies to a panel which has the {@link #frame} configuration set to `true`. * Defaults toundefined
.
*/
-
+
/**
* @cfg {String/Object/Function} bodyStyle
* Custom CSS styles to be applied to the panel's body element, which can be supplied as a valid CSS style string,
@@ -27859,7 +28522,7 @@ bodyStyle: {
}
*
*/
-
+
/**
* @cfg {String/Array} bodyCls
* A CSS class, space-delimited string of classes, or array of classes to be applied to the panel's body element.
@@ -27874,6 +28537,36 @@ bodyCls: ['foo', 'bar']
componentLayout: 'dock',
+ /**
+ * @cfg {Object} defaultDockWeights
+ * This object holds the default weights applied to dockedItems that have no weight. These start with a
+ * weight of 1, to allow negative weights to insert before top items and are odd numbers
+ * so that even weights can be used to get between different dock orders.
+ *
+ * To make default docking order match border layout, do this:
+ *
+Ext.panel.AbstractPanel.prototype.defaultDockWeights = { top: 1, bottom: 3, left: 5, right: 7 };
+ * Changing these defaults as above or individually on this object will effect all Panels.
+ * To change the defaults on a single panel, you should replace the entire object:
+ *
+initComponent: function () {
+ // NOTE: Don't change members of defaultDockWeights since the object is shared.
+ this.defaultDockWeights = { top: 1, bottom: 3, left: 5, right: 7 };
+
+ this.callParent();
+}
+ *
+ * To change only one of the default values, you do this:
+ *
+initComponent: function () {
+ // NOTE: Don't change members of defaultDockWeights since the object is shared.
+ this.defaultDockWeights = Ext.applyIf({ top: 10 }, this.defaultDockWeights);
+
+ this.callParent();
+}
+ */
+ defaultDockWeights: { top: 1, left: 3, right: 5, bottom: 7 },
+
renderTpl: ['- * dd = new Ext.dd.DragDrop("div1", "group1"); - *+ * + * dd = new Ext.dd.DragDrop("div1", "group1"); + * * Since none of the event handlers have been implemented, nothing would * actually happen if you were to run the code above. Normally you would * override this class or one of the default implementations, but you can * also override the methods you want on an instance of the class... - *
- * dd.onDragDrop = function(e, id) { - * alert("dd was dropped on " + id); - * } - *- * @constructor - * @param {String} id of the element that is linked to this instance - * @param {String} sGroup the group of related DragDrop objects - * @param {object} config an object containing configurable attributes - * Valid properties for DragDrop: - * padding, isTarget, maintainOffset, primaryButtonOnly + * + * dd.onDragDrop = function(e, id) { + * alert("dd was dropped on " + id); + * } + * */ - Ext.define('Ext.dd.DragDrop', { requires: ['Ext.dd.DragDropManager'], + + /** + * Creates new DragDrop. + * @param {String} id of the element that is linked to this instance + * @param {String} sGroup the group of related DragDrop objects + * @param {object} config an object containing configurable attributes. + * Valid properties for DragDrop: + * + * - padding + * - isTarget + * - maintainOffset + * - primaryButtonOnly + */ constructor: function(id, sGroup, config) { if(id) { this.init(id, sGroup, config); @@ -31475,8 +32385,7 @@ Ext.define('Ext.dd.DragDrop', { locked: false, /** - * Lock this instance - * @method lock + * Locks this instance */ lock: function() { this.locked = true; @@ -31491,8 +32400,7 @@ Ext.define('Ext.dd.DragDrop', { moveOnly: false, /** - * Unlock this instace - * @method unlock + * Unlocks this instace */ unlock: function() { this.locked = false; @@ -31624,17 +32532,15 @@ Ext.define('Ext.dd.DragDrop', { * region the linked element is. This is done in part to work around a * bug in some browsers that mis-report the mousedown if the previous * mouseup happened outside of the window. This property is set to true - * if outer handles are defined. + * if outer handles are defined. Defaults to false. * * @property hasOuterHandles * @type boolean - * @default false */ hasOuterHandles: false, /** * Code that executes immediately before the startDrag event - * @method b4StartDrag * @private */ b4StartDrag: function(x, y) { }, @@ -31642,7 +32548,6 @@ Ext.define('Ext.dd.DragDrop', { /** * Abstract method called after a drag/drop object is clicked * and the drag or mousedown time thresholds have beeen met. - * @method startDrag * @param {int} X click location * @param {int} Y click location */ @@ -31650,7 +32555,6 @@ Ext.define('Ext.dd.DragDrop', { /** * Code that executes immediately before the onDrag event - * @method b4Drag * @private */ b4Drag: function(e) { }, @@ -31658,7 +32562,6 @@ Ext.define('Ext.dd.DragDrop', { /** * Abstract method called during the onMouseMove event while dragging an * object. - * @method onDrag * @param {Event} e the mousemove event */ onDrag: function(e) { /* override this */ }, @@ -31666,9 +32569,8 @@ Ext.define('Ext.dd.DragDrop', { /** * Abstract method called when this element fist begins hovering over * another DragDrop obj - * @method onDragEnter * @param {Event} e the mousemove event - * @param {String|DragDrop[]} id In POINT mode, the element + * @param {String/[DragDrop]} id In POINT mode, the element * id this is hovering over. In INTERSECT mode, an array of one or more * dragdrop items being hovered over. */ @@ -31676,7 +32578,6 @@ Ext.define('Ext.dd.DragDrop', { /** * Code that executes immediately before the onDragOver event - * @method b4DragOver * @private */ b4DragOver: function(e) { }, @@ -31684,7 +32585,6 @@ Ext.define('Ext.dd.DragDrop', { /** * Abstract method called when this element is hovering over another * DragDrop obj - * @method onDragOver * @param {Event} e the mousemove event * @param {String|DragDrop[]} id In POINT mode, the element * id this is hovering over. In INTERSECT mode, an array of dd items @@ -31694,16 +32594,14 @@ Ext.define('Ext.dd.DragDrop', { /** * Code that executes immediately before the onDragOut event - * @method b4DragOut * @private */ b4DragOut: function(e) { }, /** * Abstract method called when we are no longer hovering over an element - * @method onDragOut * @param {Event} e the mousemove event - * @param {String|DragDrop[]} id In POINT mode, the element + * @param {String/[DragDrop]} id In POINT mode, the element * id this was hovering over. In INTERSECT mode, an array of dd items * that the mouse is no longer over. */ @@ -31711,7 +32609,6 @@ Ext.define('Ext.dd.DragDrop', { /** * Code that executes immediately before the onDragDrop event - * @method b4DragDrop * @private */ b4DragDrop: function(e) { }, @@ -31719,9 +32616,8 @@ Ext.define('Ext.dd.DragDrop', { /** * Abstract method called when this item is dropped on another DragDrop * obj - * @method onDragDrop * @param {Event} e the mouseup event - * @param {String|DragDrop[]} id In POINT mode, the element + * @param {String/[DragDrop]} id In POINT mode, the element * id this was dropped on. In INTERSECT mode, an array of dd items this * was dropped on. */ @@ -31730,43 +32626,37 @@ Ext.define('Ext.dd.DragDrop', { /** * Abstract method called when this item is dropped on an area with no * drop target - * @method onInvalidDrop * @param {Event} e the mouseup event */ onInvalidDrop: function(e) { /* override this */ }, /** * Code that executes immediately before the endDrag event - * @method b4EndDrag * @private */ b4EndDrag: function(e) { }, /** - * Fired when we are done dragging the object - * @method endDrag + * Called when we are done dragging the object * @param {Event} e the mouseup event */ endDrag: function(e) { /* override this */ }, /** * Code executed immediately before the onMouseDown event - * @method b4MouseDown * @param {Event} e the mousedown event * @private */ b4MouseDown: function(e) { }, /** - * Event handler that fires when a drag/drop obj gets a mousedown - * @method onMouseDown + * Called when a drag/drop obj gets a mousedown * @param {Event} e the mousedown event */ onMouseDown: function(e) { /* override this */ }, /** - * Event handler that fires when a drag/drop obj gets a mouseup - * @method onMouseUp + * Called when a drag/drop obj gets a mouseup * @param {Event} e the mouseup event */ onMouseUp: function(e) { /* override this */ }, @@ -31774,13 +32664,12 @@ Ext.define('Ext.dd.DragDrop', { /** * Override the onAvailable method to do what is needed after the initial * position was determined. - * @method onAvailable */ onAvailable: function () { }, /** - * Provides default constraint padding to "constrainTo" elements (defaults to {left: 0, right:0, top:0, bottom:0}). + * Provides default constraint padding to "constrainTo" elements (defaults to `{left:0, right:0, top:0, bottom:0}`). * @type Object */ defaultPadding: { @@ -31792,27 +32681,27 @@ Ext.define('Ext.dd.DragDrop', { /** * Initializes the drag drop object's constraints to restrict movement to a certain element. - * - * Usage: -
- var dd = new Ext.dd.DDProxy("dragDiv1", "proxytest",
- { dragElId: "existingProxyDiv" });
- dd.startDrag = function(){
- this.constrainTo("parent-id");
- };
-
- * Or you can initalize it using the {@link Ext.core.Element} object:
-
- Ext.get("dragDiv1").initDDProxy("proxytest", {dragElId: "existingProxyDiv"}, {
- startDrag : function(){
- this.constrainTo("parent-id");
- }
- });
-
+ *
+ * Usage:
+ *
+ * var dd = new Ext.dd.DDProxy("dragDiv1", "proxytest",
+ * { dragElId: "existingProxyDiv" });
+ * dd.startDrag = function(){
+ * this.constrainTo("parent-id");
+ * };
+ *
+ * Or you can initalize it using the {@link Ext.core.Element} object:
+ *
+ * Ext.get("dragDiv1").initDDProxy("proxytest", {dragElId: "existingProxyDiv"}, {
+ * startDrag : function(){
+ * this.constrainTo("parent-id");
+ * }
+ * });
+ *
* @param {Mixed} constrainTo The element to constrain to.
* @param {Object/Number} pad (optional) Pad provides a way to specify "padding" of the constraints,
- * and can be either a number for symmetrical padding (4 would be equal to {left:4, right:4, top:4, bottom:4}) or
- * an object containing the sides to pad. For example: {right:10, bottom:10}
+ * and can be either a number for symmetrical padding (4 would be equal to `{left:4, right:4, top:4, bottom:4}`) or
+ * an object containing the sides to pad. For example: `{right:10, bottom:10}`
* @param {Boolean} inContent (optional) Constrain the draggable in the content box of the element (inside padding and borders)
*/
constrainTo : function(constrainTo, pad, inContent){
@@ -31849,7 +32738,6 @@ Ext.define('Ext.dd.DragDrop', {
/**
* Returns a reference to the linked element
- * @method getEl
* @return {HTMLElement} the html element
*/
getEl: function() {
@@ -31864,7 +32752,6 @@ Ext.define('Ext.dd.DragDrop', {
* Returns a reference to the actual element to drag. By default this is
* the same as the html element, but it can be assigned to another
* element. An example of this can be found in Ext.dd.DDProxy
- * @method getDragEl
* @return {HTMLElement} the html element
*/
getDragEl: function() {
@@ -31874,10 +32761,9 @@ Ext.define('Ext.dd.DragDrop', {
/**
* Sets up the DragDrop object. Must be called in the constructor of any
* Ext.dd.DragDrop subclass
- * @method init
- * @param id the id of the linked element
+ * @param {String} id the id of the linked element
* @param {String} sGroup the group of related items
- * @param {object} config configuration attributes
+ * @param {Object} config configuration attributes
*/
init: function(id, sGroup, config) {
this.initTarget(id, sGroup, config);
@@ -31888,13 +32774,11 @@ Ext.define('Ext.dd.DragDrop', {
/**
* Initializes Targeting functionality only... the object does not
* get a mousedown handler.
- * @method initTarget
- * @param id the id of the linked element
+ * @param {String} id the id of the linked element
* @param {String} sGroup the group of related items
- * @param {object} config configuration attributes
+ * @param {Object} config configuration attributes
*/
initTarget: function(id, sGroup, config) {
-
// configuration attributes
this.config = config || {};
@@ -31938,7 +32822,6 @@ Ext.define('Ext.dd.DragDrop', {
* a DDProxy implentation will execute apply config on DDProxy, DD, and
* DragDrop in order to get all of the parameters that are available in
* each object.
- * @method applyConfig
*/
applyConfig: function() {
@@ -31953,7 +32836,6 @@ Ext.define('Ext.dd.DragDrop', {
/**
* Executed when the linked element is available
- * @method handleOnAvailable
* @private
*/
handleOnAvailable: function() {
@@ -31962,13 +32844,12 @@ Ext.define('Ext.dd.DragDrop', {
this.onAvailable();
},
- /**
+ /**
* Configures the padding for the target zone in px. Effectively expands
* (or reduces) the virtual object size for targeting calculations.
* Supports css-style shorthand; if only one parameter is passed, all sides
* will have that padding, and if only two are passed, the top and bottom
* will have the first param, the left and right the second.
- * @method setPadding
* @param {int} iTop Top pad
* @param {int} iRight Right pad
* @param {int} iBot Bot pad
@@ -31987,7 +32868,6 @@ Ext.define('Ext.dd.DragDrop', {
/**
* Stores the initial placement of the linked element.
- * @method setInitPosition
* @param {int} diffX the X offset, default 0
* @param {int} diffY the Y offset, default 0
*/
@@ -32015,7 +32895,6 @@ Ext.define('Ext.dd.DragDrop', {
/**
* Sets the start position of the element. This is set when the obj
* is initialized, the reset when a drag is started.
- * @method setStartPosition
* @param pos current position (from previous lookup)
* @private
*/
@@ -32028,11 +32907,10 @@ Ext.define('Ext.dd.DragDrop', {
},
/**
- * Add this instance to a group of related drag/drop objects. All
+ * Adds this instance to a group of related drag/drop objects. All
* instances belong to at least one group, and can belong to as many
* groups as needed.
- * @method addToGroup
- * @param sGroup {string} the name of the group
+ * @param {String} sGroup the name of the group
*/
addToGroup: function(sGroup) {
this.groups[sGroup] = true;
@@ -32040,9 +32918,8 @@ Ext.define('Ext.dd.DragDrop', {
},
/**
- * Remove's this instance from the supplied interaction group
- * @method removeFromGroup
- * @param {string} sGroup The group to drop
+ * Removes this instance from the supplied interaction group
+ * @param {String} sGroup The group to drop
*/
removeFromGroup: function(sGroup) {
if (this.groups[sGroup]) {
@@ -32055,8 +32932,7 @@ Ext.define('Ext.dd.DragDrop', {
/**
* Allows you to specify that an element other than the linked element
* will be moved with the cursor during a drag
- * @method setDragElId
- * @param id {string} the id of the element that will be used to initiate the drag
+ * @param {String} id the id of the element that will be used to initiate the drag
*/
setDragElId: function(id) {
this.dragElId = id;
@@ -32069,8 +32945,7 @@ Ext.define('Ext.dd.DragDrop', {
* content area would normally start the drag operation. Use this method
* to specify that an element inside of the content div is the element
* that starts the drag operation.
- * @method setHandleElId
- * @param id {string} the id of the element that will be used to
+ * @param {String} id the id of the element that will be used to
* initiate the drag.
*/
setHandleElId: function(id) {
@@ -32084,8 +32959,7 @@ Ext.define('Ext.dd.DragDrop', {
/**
* Allows you to set an element outside of the linked element as a drag
* handle
- * @method setOuterHandleElId
- * @param id the id of the element that will be used to initiate the drag
+ * @param {String} id the id of the element that will be used to initiate the drag
*/
setOuterHandleElId: function(id) {
if (typeof id !== "string") {
@@ -32098,8 +32972,7 @@ Ext.define('Ext.dd.DragDrop', {
},
/**
- * Remove all drag and drop hooks for this element
- * @method unreg
+ * Removes all drag and drop hooks for this element
*/
unreg: function() {
Ext.EventManager.un(this.id, "mousedown", this.handleMouseDown, this);
@@ -32114,8 +32987,7 @@ Ext.define('Ext.dd.DragDrop', {
/**
* Returns true if this instance is locked, or the drag drop mgr is locked
* (meaning that all drag/drop is disabled on the page.)
- * @method isLocked
- * @return {boolean} true if this obj or all drag/drop is locked, else
+ * @return {Boolean} true if this obj or all drag/drop is locked, else
* false
*/
isLocked: function() {
@@ -32123,8 +32995,7 @@ Ext.define('Ext.dd.DragDrop', {
},
/**
- * Fired when this object is clicked
- * @method handleMouseDown
+ * Called when this object is clicked
* @param {Event} e
* @param {Ext.dd.DragDrop} oDD the clicked dd object (this dd obj)
* @private
@@ -32171,7 +33042,7 @@ Ext.define('Ext.dd.DragDrop', {
* when clicked. This is designed to facilitate embedding links within a
* drag handle that do something other than start the drag.
* @method addInvalidHandleType
- * @param {string} tagName the type of element to exclude
+ * @param {String} tagName the type of element to exclude
*/
addInvalidHandleType: function(tagName) {
var type = tagName.toUpperCase();
@@ -32182,7 +33053,7 @@ Ext.define('Ext.dd.DragDrop', {
* Lets you to specify an element id for a child of a drag handle
* that should not initiate a drag
* @method addInvalidHandleId
- * @param {string} id the element id of the element you wish to ignore
+ * @param {String} id the element id of the element you wish to ignore
*/
addInvalidHandleId: function(id) {
if (typeof id !== "string") {
@@ -32193,8 +33064,7 @@ Ext.define('Ext.dd.DragDrop', {
/**
* Lets you specify a css class of elements that will not initiate a drag
- * @method addInvalidHandleClass
- * @param {string} cssClass the class of the elements you wish to ignore
+ * @param {String} cssClass the class of the elements you wish to ignore
*/
addInvalidHandleClass: function(cssClass) {
this.invalidHandleClasses.push(cssClass);
@@ -32202,8 +33072,7 @@ Ext.define('Ext.dd.DragDrop', {
/**
* Unsets an excluded tag name set by addInvalidHandleType
- * @method removeInvalidHandleType
- * @param {string} tagName the type of element to unexclude
+ * @param {String} tagName the type of element to unexclude
*/
removeInvalidHandleType: function(tagName) {
var type = tagName.toUpperCase();
@@ -32213,8 +33082,7 @@ Ext.define('Ext.dd.DragDrop', {
/**
* Unsets an invalid handle id
- * @method removeInvalidHandleId
- * @param {string} id the id of the element to re-enable
+ * @param {String} id the id of the element to re-enable
*/
removeInvalidHandleId: function(id) {
if (typeof id !== "string") {
@@ -32225,8 +33093,7 @@ Ext.define('Ext.dd.DragDrop', {
/**
* Unsets an invalid css class
- * @method removeInvalidHandleClass
- * @param {string} cssClass the class of the element(s) you wish to
+ * @param {String} cssClass the class of the element(s) you wish to
* re-enable
*/
removeInvalidHandleClass: function(cssClass) {
@@ -32239,9 +33106,8 @@ Ext.define('Ext.dd.DragDrop', {
/**
* Checks the tag exclusion list to see if this click should be ignored
- * @method isValidHandleChild
* @param {HTMLElement} node the HTMLElement to evaluate
- * @return {boolean} true if this is a valid tag type, false if not
+ * @return {Boolean} true if this is a valid tag type, false if not
*/
isValidHandleChild: function(node) {
@@ -32266,9 +33132,8 @@ Ext.define('Ext.dd.DragDrop', {
},
/**
- * Create the array of horizontal tick marks if an interval was specified
+ * Creates the array of horizontal tick marks if an interval was specified
* in setXConstraint().
- * @method setXTicks
* @private
*/
setXTicks: function(iStartX, iTickSize) {
@@ -32295,9 +33160,8 @@ Ext.define('Ext.dd.DragDrop', {
},
/**
- * Create the array of vertical tick marks if an interval was specified in
+ * Creates the array of vertical tick marks if an interval was specified in
* setYConstraint().
- * @method setYTicks
* @private
*/
setYTicks: function(iStartY, iTickSize) {
@@ -32327,13 +33191,11 @@ Ext.define('Ext.dd.DragDrop', {
* By default, the element can be dragged any place on the screen. Use
* this method to limit the horizontal travel of the element. Pass in
* 0,0 for the parameters if you want to lock the drag to the y axis.
- * @method setXConstraint
* @param {int} iLeft the number of pixels the element can move to the left
* @param {int} iRight the number of pixels the element can move to the
* right
* @param {int} iTickSize optional parameter for specifying that the
- * element
- * should move iTickSize pixels at a time.
+ * element should move iTickSize pixels at a time.
*/
setXConstraint: function(iLeft, iRight, iTickSize) {
this.leftConstraint = iLeft;
@@ -32349,7 +33211,6 @@ Ext.define('Ext.dd.DragDrop', {
/**
* Clears any constraints applied to this instance. Also clears ticks
* since they can't exist independent of a constraint at this time.
- * @method clearConstraints
*/
clearConstraints: function() {
this.constrainX = false;
@@ -32359,7 +33220,6 @@ Ext.define('Ext.dd.DragDrop', {
/**
* Clears any tick interval defined for this instance
- * @method clearTicks
*/
clearTicks: function() {
this.xTicks = null;
@@ -32372,7 +33232,6 @@ Ext.define('Ext.dd.DragDrop', {
* By default, the element can be dragged any place on the screen. Set
* this to limit the vertical travel of the element. Pass in 0,0 for the
* parameters if you want to lock the drag to the x axis.
- * @method setYConstraint
* @param {int} iUp the number of pixels the element can move up
* @param {int} iDown the number of pixels the element can move down
* @param {int} iTickSize optional parameter for specifying that the
@@ -32391,8 +33250,7 @@ Ext.define('Ext.dd.DragDrop', {
},
/**
- * resetConstraints must be called if you manually reposition a dd element.
- * @method resetConstraints
+ * Must be called if you manually reposition a dd element.
* @param {boolean} maintainOffset
*/
resetConstraints: function() {
@@ -32426,7 +33284,6 @@ Ext.define('Ext.dd.DragDrop', {
* Normally the drag element is moved pixel by pixel, but we can specify
* that it move a number of pixels at a time. This method resolves the
* location when we have it set up like this.
- * @method getTick
* @param {int} val where we want to place the object
* @param {int[]} tickArray sorted array of valid points
* @return {int} the closest tick
@@ -32459,7 +33316,6 @@ Ext.define('Ext.dd.DragDrop', {
/**
* toString method
- * @method toString
* @return {string} string representation of the dd obj
*/
toString: function() {
@@ -32467,6 +33323,7 @@ Ext.define('Ext.dd.DragDrop', {
}
});
+
/*
* This is a derivative of the similarly named class in the YUI Library.
* The original license:
@@ -32481,17 +33338,18 @@ Ext.define('Ext.dd.DragDrop', {
* A DragDrop implementation where the linked element follows the
* mouse cursor during a drag.
* @extends Ext.dd.DragDrop
- * @constructor
- * @param {String} id the id of the linked element
- * @param {String} sGroup the group of related DragDrop items
- * @param {object} config an object containing configurable attributes
- * Valid properties for DD:
- * scroll
*/
-
Ext.define('Ext.dd.DD', {
extend: 'Ext.dd.DragDrop',
requires: ['Ext.dd.DragDropManager'],
+
+ /**
+ * Creates new DD instance.
+ * @param {String} id the id of the linked element
+ * @param {String} sGroup the group of related DragDrop items
+ * @param {object} config an object containing configurable attributes.
+ * Valid properties for DD: scroll
+ */
constructor: function(id, sGroup, config) {
if (id) {
this.init(id, sGroup, config);
@@ -32794,6 +33652,7 @@ Ext.define('Ext.dd.DD', {
/**
* @class Ext.dd.DDProxy
+ * @extends Ext.dd.DD
* A DragDrop implementation that inserts an empty, bordered div into
* the document that follows the cursor during drag operations. At the time of
* the click, the frame div is resized to the dimensions of the linked html
@@ -32802,14 +33661,6 @@ Ext.define('Ext.dd.DD', {
* References to the "frame" element refer to the single proxy element that
* was created to be dragged in place of all DDProxy elements on the
* page.
- *
- * @extends Ext.dd.DD
- * @constructor
- * @param {String} id the id of the linked html element
- * @param {String} sGroup the group of related DragDrop objects
- * @param {object} config an object containing configurable attributes
- * Valid properties for DDProxy in addition to those in DragDrop:
- * resizeFrame, centerFrame, dragElId
*/
Ext.define('Ext.dd.DDProxy', {
extend: 'Ext.dd.DD',
@@ -32817,13 +33668,22 @@ Ext.define('Ext.dd.DDProxy', {
statics: {
/**
* The default drag frame div id
- * @property Ext.dd.DDProxy.dragElId
- * @type String
* @static
*/
dragElId: "ygddfdiv"
},
+ /**
+ * Creates new DDProxy.
+ * @param {String} id the id of the linked html element
+ * @param {String} sGroup the group of related DragDrop objects
+ * @param {object} config an object containing configurable attributes.
+ * Valid properties for DDProxy in addition to those in DragDrop:
+ *
+ * - resizeFrame
+ * - centerFrame
+ * - dragElId
+ */
constructor: function(id, sGroup, config) {
if (id) {
this.init(id, sGroup, config);
@@ -32997,9 +33857,6 @@ Ext.define('Ext.dd.DDProxy', {
* @class Ext.dd.DragSource
* @extends Ext.dd.DDProxy
* A simple class that provides the basic implementation needed to make any element draggable.
- * @constructor
- * @param {Mixed} el The container element
- * @param {Object} config
*/
Ext.define('Ext.dd.DragSource', {
extend: 'Ext.dd.DDProxy',
@@ -33039,6 +33896,12 @@ Ext.define('Ext.dd.DragSource', {
*/
repairHighlightColor: 'c3daf9',
+ /**
+ * Creates new drag-source.
+ * @constructor
+ * @param {Mixed} el The container element
+ * @param {Object} config (optional) Config object.
+ */
constructor: function(el, config) {
this.el = Ext.get(el);
if(!this.dragData){
@@ -33540,9 +34403,6 @@ var resultsPanel = Ext.create('Ext.panel.Panel', {
* content area.
* Using these techniques, as long as the layout is chosen and configured correctly, an application may have any level of * nested containment, all dynamically sized according to configuration, the user's preference and available browser size.
- * @constructor - * @param {Object} config The config object - * @xtype panel */ Ext.define('Ext.panel.Panel', { extend: 'Ext.panel.AbstractPanel', @@ -33552,7 +34412,8 @@ Ext.define('Ext.panel.Panel', { 'Ext.util.KeyMap', 'Ext.panel.DD', 'Ext.XTemplate', - 'Ext.layout.component.Dock' + 'Ext.layout.component.Dock', + 'Ext.util.Memento' ], alias: 'widget.panel', alternateClassName: 'Ext.Panel', @@ -33641,13 +34502,13 @@ Ext.define('Ext.panel.Panel', { * clicking the expand button to see it again (defaults to true). */ floatable: true, - + /** * @cfg {Mixed} overlapHeader * True to overlap the header in a panel over the framing of the panel itself. This is needed when frame:true (and is done automatically for you). Otherwise it is undefined. * If you manually add rounded corners to a panel header which does not have frame:true, this will need to be set to true. */ - + /** * @cfg {Boolean} collapsible *True to make the panel collapsible and have an expand/collapse toggle Tool added into @@ -33762,36 +34623,81 @@ tools:[{ */ + /** + * @cfg {String} title + * The title text to be used to display in the {@link Ext.panel.Header panel header} (defaults to ''). + * When a `title` is specified the {@link Ext.panel.Header} will automatically be created and displayed unless + * {@link #preventHeader} is set to `true`. + */ initComponent: function() { var me = this, cls; me.addEvents( - /** - * @event titlechange - * Fires after the Panel title has been set or changed. - * @param {Ext.panel.Panel} p the Panel which has been resized. - * @param {String} newTitle The new title. - * @param {String} oldTitle The previous panel title. - */ + /** + * @event beforeexpand + * Fires before this panel is expanded. Return false to prevent the expand. + * @param {Ext.panel.Panel} p The Panel being expanded. + * @param {Boolean} animate True if the expand is animated, else false. + */ + "beforeexpand", + + /** + * @event beforecollapse + * Fires before this panel is collapsed. Return false to prevent the collapse. + * @param {Ext.panel.Panel} p The Panel being collapsed. + * @param {String} direction. The direction of the collapse. One of
The alignment of any buttons added to this panel. Valid values are 'right', + * 'left' and 'center' (defaults to 'right' for buttons/fbar, 'left' for other toolbar types).
+ *NOTE: The newer way to specify toolbars is to use the dockedItems config, and + * instead of buttonAlign you would add the layout: { pack: 'start' | 'center' | 'end' } + * option to the dockedItem config.
+ */ /** * @cfg {Object/Array} tbar @@ -33965,7 +34888,7 @@ is equivalent to /** * @cfg {Object/Array} buttons -Convenience method used for adding buttons docked to the bottom right of the panel. This is a +Convenience method used for adding buttons docked to the bottom of the panel. This is a synonym for the {@link #fbar} config. buttons: [ @@ -33977,6 +34900,7 @@ is equivalent to dockedItems: [{ xtype: 'toolbar', dock: 'bottom', + ui: 'footer', defaults: {minWidth: {@link #minButtonWidth}}, items: [ { xtype: 'component', flex: 1 }, @@ -33997,7 +34921,7 @@ each of the buttons in the buttons toolbar. /** * @cfg {Object/Array} fbar -Convenience method used for adding items to the bottom right of the panel. Short for Footer Bar. +Convenience method used for adding items to the bottom of the panel. Short for Footer Bar. fbar: [ { type: 'button', text: 'Button 1' } @@ -34008,6 +34932,7 @@ is equivalent to dockedItems: [{ xtype: 'toolbar', dock: 'bottom', + ui: 'footer', defaults: {minWidth: {@link #minButtonWidth}}, items: [ { xtype: 'component', flex: 1 }, @@ -34021,7 +34946,7 @@ each of the buttons in the fbar. * @markdown */ if (me.fbar) { - fbar = initToolbar(me.fbar, 'bottom'); + fbar = initToolbar(me.fbar, 'bottom', true); // only we useButtonAlign fbar.ui = 'footer'; // Apply the minButtonWidth config to buttons in the toolbar @@ -34037,12 +34962,7 @@ each of the buttons in the fbar. }; } - fbar = me.addDocked(fbar)[0]; - fbar.insert(0, { - flex: 1, - xtype: 'component', - focusable: false - }); + me.addDocked(fbar); me.fbar = null; } @@ -34051,19 +34971,19 @@ each of the buttons in the fbar. * * Convenience method. Short for 'Left Bar' (left-docked, vertical toolbar). * - * lbar: [ - * { xtype: 'button', text: 'Button 1' } - * ] + * lbar: [ + * { xtype: 'button', text: 'Button 1' } + * ] * * is equivalent to * - * dockedItems: [{ - * xtype: 'toolbar', - * dock: 'left', - * items: [ - * { xtype: 'button', text: 'Button 1' } - * ] - * }] + * dockedItems: [{ + * xtype: 'toolbar', + * dock: 'left', + * items: [ + * { xtype: 'button', text: 'Button 1' } + * ] + * }] * * @markdown */ @@ -34077,19 +34997,19 @@ each of the buttons in the fbar. * * Convenience method. Short for 'Right Bar' (right-docked, vertical toolbar). * - * rbar: [ - * { xtype: 'button', text: 'Button 1' } - * ] + * rbar: [ + * { xtype: 'button', text: 'Button 1' } + * ] * * is equivalent to * - * dockedItems: [{ - * xtype: 'toolbar', - * dock: 'right', - * items: [ - * { xtype: 'button', text: 'Button 1' } - * ] - * }] + * dockedItems: [{ + * xtype: 'toolbar', + * dock: 'right', + * items: [ + * { xtype: 'button', text: 'Button 1' } + * ] + * }] * * @markdown */ @@ -34182,35 +35102,23 @@ each of the buttons in the fbar. // Dock the header/title me.updateHeader(); - // If initially collapsed, collapsed flag must indicate true current state at this point. - // Do collapse after the first time the Panel's structure has been laid out. + // Call to super after adding the header, to prevent an unnecessary re-layout + me.callParent(arguments); + }, + + afterRender: function() { + var me = this; + me.callParent(arguments); if (me.collapsed) { me.collapsed = false; - topContainer = me.findLayoutController(); - if (!me.hidden && topContainer) { - topContainer.on({ - afterlayout: function() { - me.collapse(null, false, true); - }, - single: true - }); - } else { - me.afterComponentLayout = function() { - delete me.afterComponentLayout; - Ext.getClass(me).prototype.afterComponentLayout.apply(me, arguments); - me.collapse(null, false, true); - }; - } + me.collapse(null, false, true); } - - // Call to super after adding the header, to prevent an unnecessary re-layout - me.callParent(arguments); }, /** * Create, hide, or show the header component as appropriate based on the current config. * @private - * @param {Boolean} force True to force the the header to be created + * @param {Boolean} force True to force the header to be created */ updateHeader: function(force) { var me = this, @@ -34299,7 +35207,7 @@ each of the buttons in the fbar. * Collapses the panel body so that the body becomes hidden. Docked Components parallel to the * border towards which the collapse takes place will remain visible. Fires the {@link #beforecollapse} event which will * cancel the collapse action if it returns false. - * @param {Number} direction. The direction to collapse towards. Must be one ofThe action to take when the close header tool is clicked: + *
'{@link #destroy}'
: '{@link #hide}'
: DefaultNote: This behavior has changed! setting *does* affect the {@link #close} method
+ * which will invoke the approriate closeAction.
+ */
closeAction: 'hide',
ariaRole: 'tooltip',
@@ -35107,9 +36037,6 @@ tip.showBy('my-el', 'tl-tr');
});
/**
- * @class Ext.tip.ToolTip
- * @extends Ext.tip.Tip
- *
* ToolTip is a {@link Ext.tip.Tip} implementation that handles the common case of displaying a
* tooltip when hovering over a certain element or elements on the page. It allows fine-grained
* control over the tooltip's alignment relative to the target element or mouse, and the timing
@@ -35122,7 +36049,7 @@ tip.showBy('my-el', 'tl-tr');
* convenient way of automatically populating and configuring a tooltip based on specific DOM
* attributes of each target element.
*
- * ## Basic Example
+ * # Basic Example
*
* var tip = Ext.create('Ext.tip.ToolTip', {
* target: 'clearButton',
@@ -35131,7 +36058,7 @@ tip.showBy('my-el', 'tl-tr');
*
* {@img Ext.tip.ToolTip/Ext.tip.ToolTip1.png Basic Ext.tip.ToolTip}
*
- * ## Delegation
+ * # Delegation
*
* In addition to attaching a ToolTip to a single element, you can also use delegation to attach
* one ToolTip to many elements under a common parent. This is more efficient than creating many
@@ -35143,15 +36070,43 @@ tip.showBy('my-el', 'tl-tr');
* of the ToolTip based on each delegate element; you can do this by implementing a custom
* listener for the {@link #beforeshow} event. Example:
*
- * var myGrid = Ext.create('Ext.grid.GridPanel', gridConfig);
- * myGrid.on('render', function(grid) {
- * var view = grid.getView(); // Capture the grid's view.
- * grid.tip = Ext.create('Ext.tip.ToolTip', {
- * target: view.el, // The overall target element.
- * delegate: view.itemSelector, // Each grid row causes its own seperate show and hide.
- * trackMouse: true, // Moving within the row should not hide the tip.
- * renderTo: Ext.getBody(), // Render immediately so that tip.body can be referenced prior to the first show.
- * listeners: { // Change content dynamically depending on which element triggered the show.
+ * var store = Ext.create('Ext.data.ArrayStore', {
+ * fields: ['company', 'price', 'change'],
+ * data: [
+ * ['3m Co', 71.72, 0.02],
+ * ['Alcoa Inc', 29.01, 0.42],
+ * ['Altria Group Inc', 83.81, 0.28],
+ * ['American Express Company', 52.55, 0.01],
+ * ['American International Group, Inc.', 64.13, 0.31],
+ * ['AT&T Inc.', 31.61, -0.48]
+ * ]
+ * });
+ *
+ * var grid = Ext.create('Ext.grid.Panel', {
+ * title: 'Array Grid',
+ * store: store,
+ * columns: [
+ * {text: 'Company', flex: 1, dataIndex: 'company'},
+ * {text: 'Price', width: 75, dataIndex: 'price'},
+ * {text: 'Change', width: 75, dataIndex: 'change'}
+ * ],
+ * height: 200,
+ * width: 400,
+ * renderTo: Ext.getBody()
+ * });
+ *
+ * grid.getView().on('render', function(view) {
+ * view.tip = Ext.create('Ext.tip.ToolTip', {
+ * // The overall target element.
+ * target: view.el,
+ * // Each grid row causes its own seperate show and hide.
+ * delegate: view.itemSelector,
+ * // Moving within the row should not hide the tip.
+ * trackMouse: true,
+ * // Render immediately so that tip.body can be referenced prior to the first show.
+ * renderTo: Ext.getBody(),
+ * listeners: {
+ * // Change content dynamically depending on which element triggered the show.
* beforeshow: function updateTipBody(tip) {
* tip.update('Over company "' + view.getRecord(tip.triggerElement).get('company') + '"');
* }
@@ -35161,32 +36116,27 @@ tip.showBy('my-el', 'tl-tr');
*
* {@img Ext.tip.ToolTip/Ext.tip.ToolTip2.png Ext.tip.ToolTip with delegation}
*
- * ## Alignment
+ * # Alignment
*
* The following configuration properties allow control over how the ToolTip is aligned relative to
* the target element and/or mouse pointer:
*
- * - {@link #anchor}
- * - {@link #anchorToTarget}
- * - {@link #anchorOffset}
- * - {@link #trackMouse}
- * - {@link #mouseOffset}
+ * - {@link #anchor}
+ * - {@link #anchorToTarget}
+ * - {@link #anchorOffset}
+ * - {@link #trackMouse}
+ * - {@link #mouseOffset}
*
- * ## Showing/Hiding
+ * # Showing/Hiding
*
* The following configuration properties allow control over how and when the ToolTip is automatically
* shown and hidden:
*
- * - {@link #autoHide}
- * - {@link #showDelay}
- * - {@link #hideDelay}
- * - {@link #dismissDelay}
+ * - {@link #autoHide}
+ * - {@link #showDelay}
+ * - {@link #hideDelay}
+ * - {@link #dismissDelay}
*
- * @constructor
- * Create a new ToolTip instance
- * @param {Object} config The configuration options
- * @xtype tooltip
- * @markdown
* @docauthor Jason Johnston Optional. A {@link Ext.DomQuery DomQuery}
- * selector which allows selection of individual elements within the
- * When specified, the child element of the target which caused a show
- * event is placed into the This may be useful when a Component has regular, repeating elements
- * in it, each of which need a ToolTip which contains information specific
- * to that element. For example:{@link #delegate}
- * option to cause selected child elements of the {@link #target}
+ * When a ToolTip is configured with the `{@link #delegate}`
+ * option to cause selected child elements of the `{@link #target}`
* Element to each trigger a seperate show event, this property is set to
* the DOM element which triggered the show.
* @type DOMElement
@@ -35207,8 +36157,8 @@ Ext.define('Ext.tip.ToolTip', {
*/
/**
* @cfg {Boolean} autoHide True to automatically hide the tooltip after the
- * mouse exits the target element or after the {@link #dismissDelay}
- * has expired if set (defaults to true). If {@link #closable} = true
+ * mouse exits the target element or after the `{@link #dismissDelay}`
+ * has expired if set (defaults to true). If `{@link #closable} = true`
* a close tool button will be rendered into the tooltip header.
*/
/**
@@ -35247,48 +36197,35 @@ Ext.define('Ext.tip.ToolTip', {
/**
* @cfg {Boolean} anchorToTarget True to anchor the tooltip to the target
* element, false to anchor it relative to the mouse coordinates (defaults
- * to true). When anchorToTarget
is true, use
- * {@link #defaultAlign}
to control tooltip alignment to the
- * target element. When anchorToTarget
is false, use
- * {@link #anchorPosition}
instead to control alignment.
+ * to true). When `anchorToTarget` is true, use
+ * `{@link #defaultAlign}` to control tooltip alignment to the
+ * target element. When `anchorToTarget` is false, use
+ * `{@link #anchorPosition}` instead to control alignment.
*/
anchorToTarget: true,
/**
* @cfg {Number} anchorOffset A numeric pixel value used to offset the
* default position of the anchor arrow (defaults to 0). When the anchor
- * position is on the top or bottom of the tooltip, anchorOffset
+ * position is on the top or bottom of the tooltip, `anchorOffset`
* will be used as a horizontal offset. Likewise, when the anchor position
- * is on the left or right side, anchorOffset
will be used as
+ * is on the left or right side, `anchorOffset` will be used as
* a vertical offset.
*/
anchorOffset: 0,
/**
- * @cfg {String} delegate {@link #target}
element to trigger showing and hiding the
- * ToolTip as the mouse moves within the target.{@link #triggerElement}
property
- * before the ToolTip is shown.
+ * @cfg {String} delegate
+ *
+ * A {@link Ext.DomQuery DomQuery} selector which allows selection of individual elements within the
+ * `{@link #target}` element to trigger showing and hiding the ToolTip as the mouse moves within the
+ * target.
+ *
+ * When specified, the child element of the target which caused a show event is placed into the
+ * `{@link #triggerElement}` property before the ToolTip is shown.
+ *
+ * This may be useful when a Component has regular, repeating elements in it, each of which need a
+ * ToolTip which contains information specific to that element.
+ *
+ * See the delegate example in class documentation of {@link Ext.tip.ToolTip}.
*/
// private
@@ -35795,9 +36732,6 @@ myGrid.on('render', function(grid) {
* @extends Ext.tip.ToolTip
* A specialized tooltip class for tooltips that can be specified in markup and automatically managed by the global
* {@link Ext.tip.QuickTipManager} instance. See the QuickTipManager class header for additional usage details and examples.
- * @constructor
- * Create a new Tip
- * @param {Object} config The configuration options
* @xtype quicktip
*/
Ext.define('Ext.tip.QuickTip', {
@@ -36356,11 +37290,10 @@ Ext.define('Ext.tip.QuickTipManager', function() {
* files whenever we add a new class, but more importantly it enables us to create a minimized build of our entire
* application using the Ext JS 4 SDK Tools.
*
- * For more information about writing Ext JS 4 applications, please see the
- * application architecture guide.
+ * For more information about writing Ext JS 4 applications, please see the
+ * [application architecture guide](#/guide/application_architecture).
*
* @docauthor Ed Spencer
- * @constructor
*/
Ext.define('Ext.app.Application', {
extend: 'Ext.app.Controller',
@@ -36407,6 +37340,10 @@ Ext.define('Ext.app.Application', {
*/
autoCreateViewport: false,
+ /**
+ * Creates new Application.
+ * @param {Object} config (optional) Config object.
+ */
constructor: function(config) {
config = config || {};
Ext.apply(this, config);
@@ -36539,7 +37476,7 @@ Ext.define('Ext.app.Application', {
/**
* @class Ext.chart.Callout
- * @ignore
+ * A mixin providing callout functionality for Ext.chart.series.Series.
*/
Ext.define('Ext.chart.Callout', {
@@ -36994,7 +37931,10 @@ Ext.define('Ext.layout.component.Draw', {
});
/**
* @class Ext.chart.theme.Theme
- * @ignore
+ *
+ * Provides chart theming.
+ *
+ * Used as mixins by Ext.chart.Chart.
*/
Ext.define('Ext.chart.theme.Theme', {
@@ -37276,9 +38216,12 @@ function() {
* a handle to a mask instance from the chart object. The `chart.mask` element is a
* `Ext.Panel`.
*
- * @constructor
*/
Ext.define('Ext.chart.Mask', {
+ /**
+ * Creates new Mask.
+ * @param {Object} config (optional) Config object.
+ */
constructor: function(config) {
var me = this;
@@ -37466,7 +38409,7 @@ Ext.define('Ext.chart.Mask', {
*
* Handles panning and zooming capabilities.
*
- * @ignore
+ * Used as mixin by Ext.chart.Chart.
*/
Ext.define('Ext.chart.Navigation', {
@@ -37624,9 +38567,6 @@ Ext.define('Ext.chart.Shape', {
}
});
/**
- * @class Ext.draw.Surface
- * @extends Object
- *
* A Surface is an interface to render methods inside a draw {@link Ext.draw.Component}.
* A Surface contains methods to render sprites, get bounding boxes of sprites, add
* sprites to the canvas, initialize other graphic components, etc. One of the most used
@@ -37648,7 +38588,7 @@ Ext.define('Ext.chart.Shape', {
* The configuration object passed in the `add` method is the same as described in the {@link Ext.draw.Sprite}
* class documentation.
*
- * ### Listeners
+ * # Listeners
*
* You can also add event listeners to the surface using the `Observable` listener syntax. Supported events are:
*
@@ -37669,73 +38609,82 @@ Ext.define('Ext.chart.Shape', {
* }
* });
*
- * ## Example
+ * # Example
*
- * drawComponent.surface.add([
- * {
- * type: 'circle',
- * radius: 10,
- * fill: '#f00',
- * x: 10,
- * y: 10,
- * group: 'circles'
- * },
- * {
- * type: 'circle',
- * radius: 10,
- * fill: '#0f0',
- * x: 50,
- * y: 50,
- * group: 'circles'
- * },
- * {
- * type: 'circle',
- * radius: 10,
- * fill: '#00f',
- * x: 100,
- * y: 100,
- * group: 'circles'
- * },
- * {
- * type: 'rect',
- * radius: 10,
- * x: 10,
- * y: 10,
- * group: 'rectangles'
- * },
- * {
- * type: 'rect',
- * radius: 10,
- * x: 50,
- * y: 50,
- * group: 'rectangles'
- * },
- * {
- * type: 'rect',
- * radius: 10,
- * x: 100,
- * y: 100,
- * group: 'rectangles'
- * }
- * ]);
- *
+ * var drawComponent = Ext.create('Ext.draw.Component', {
+ * width: 800,
+ * height: 600,
+ * renderTo: document.body
+ * }), surface = drawComponent.surface;
+ *
+ * surface.add([{
+ * type: 'circle',
+ * radius: 10,
+ * fill: '#f00',
+ * x: 10,
+ * y: 10,
+ * group: 'circles'
+ * }, {
+ * type: 'circle',
+ * radius: 10,
+ * fill: '#0f0',
+ * x: 50,
+ * y: 50,
+ * group: 'circles'
+ * }, {
+ * type: 'circle',
+ * radius: 10,
+ * fill: '#00f',
+ * x: 100,
+ * y: 100,
+ * group: 'circles'
+ * }, {
+ * type: 'rect',
+ * width: 20,
+ * height: 20,
+ * fill: '#f00',
+ * x: 10,
+ * y: 10,
+ * group: 'rectangles'
+ * }, {
+ * type: 'rect',
+ * width: 20,
+ * height: 20,
+ * fill: '#0f0',
+ * x: 50,
+ * y: 50,
+ * group: 'rectangles'
+ * }, {
+ * type: 'rect',
+ * width: 20,
+ * height: 20,
+ * fill: '#00f',
+ * x: 100,
+ * y: 100,
+ * group: 'rectangles'
+ * }]);
+ *
* // Get references to my groups
- * my circles = surface.getGroup('circles');
- * my rectangles = surface.getGroup('rectangles');
- *
+ * circles = surface.getGroup('circles');
+ * rectangles = surface.getGroup('rectangles');
+ *
* // Animate the circles down
* circles.animate({
* duration: 1000,
- * translate: {
- * y: 200
+ * to: {
+ * translate: {
+ * y: 200
+ * }
* }
* });
- *
+ *
* // Animate the rectangles across
* rectangles.animate({
* duration: 1000,
- * translate: {
- * x: 200
+ * to: {
+ * translate: {
+ * x: 200
+ * }
* }
* });
*/
@@ -37754,11 +38703,12 @@ Ext.define('Ext.draw.Surface', {
statics: {
/**
- * Create and return a new concrete Surface instance appropriate for the current environment.
+ * Creates and returns a new concrete Surface instance appropriate for the current environment.
* @param {Object} config Initial configuration for the Surface instance
- * @param {Array} enginePriority Optional order of implementations to use; the first one that is
- * available in the current environment will be used. Defaults to
- *
-var myGrid = Ext.create('Ext.grid.GridPanel', gridConfig);
-myGrid.on('render', function(grid) {
- var view = grid.getView(); // Capture the grid's view.
- grid.tip = Ext.create('Ext.tip.ToolTip', {
- target: view.el, // The overall target element.
- delegate: view.itemSelector, // Each grid row causes its own seperate show and hide.
- trackMouse: true, // Moving within the row should not hide the tip.
- renderTo: Ext.getBody(), // Render immediately so that tip.body can be referenced prior to the first show.
- listeners: { // Change content dynamically depending on which element triggered the show.
- beforeshow: function(tip) {
- tip.update('Over Record ID ' + view.getRecord(tip.triggerElement).id);
- }
- }
- });
-});
- *
['Svg', 'Vml']
.
+ * @param {[String]} enginePriority Optional order of implementations to use; the first one that is
+ * available in the current environment will be used. Defaults to `['Svg', 'Vml']`.
+ * @return {Object} The created Surface or false.
+ * @static
*/
create: function(config, enginePriority) {
enginePriority = enginePriority || ['Svg', 'Vml'];
@@ -37821,22 +38771,27 @@ Ext.define('Ext.draw.Surface', {
zIndex: 0
},
- /**
- * @cfg {Number} height
- * The height of this component in pixels (defaults to auto).
- * Note to express this dimension as a percentage or offset see {@link Ext.Component#anchor}.
- */
- /**
- * @cfg {Number} width
- * The width of this component in pixels (defaults to auto).
- * Note to express this dimension as a percentage or offset see {@link Ext.Component#anchor}.
- */
+ /**
+ * @cfg {Number} height
+ * The height of this component in pixels (defaults to auto).
+ * **Note** to express this dimension as a percentage or offset see {@link Ext.Component#anchor}.
+ */
+ /**
+ * @cfg {Number} width
+ * The width of this component in pixels (defaults to auto).
+ * **Note** to express this dimension as a percentage or offset see {@link Ext.Component#anchor}.
+ */
+
container: undefined,
height: 352,
width: 512,
x: 0,
y: 0,
+ /**
+ * Creates new Surface.
+ * @param {Object} config (optional) Config object.
+ */
constructor: function(config) {
var me = this;
config = config || {};
@@ -37888,10 +38843,10 @@ Ext.define('Ext.draw.Surface', {
*
* For example:
*
- * drawComponent.surface.addCls(sprite, 'x-visible');
- *
+ * drawComponent.surface.addCls(sprite, 'x-visible');
+ *
* @param {Object} sprite The sprite to add the class to.
- * @param {String/Array} className The CSS class to add, or an array of classes
+ * @param {String/[String]} className The CSS class to add, or an array of classes
* @method
*/
addCls: Ext.emptyFn,
@@ -37901,10 +38856,10 @@ Ext.define('Ext.draw.Surface', {
*
* For example:
*
- * drawComponent.surface.removeCls(sprite, 'x-visible');
- *
+ * drawComponent.surface.removeCls(sprite, 'x-visible');
+ *
* @param {Object} sprite The sprite to remove the class from.
- * @param {String/Array} className The CSS class to remove, or an array of classes
+ * @param {String/[String]} className The CSS class to remove, or an array of classes
* @method
*/
removeCls: Ext.emptyFn,
@@ -37914,10 +38869,10 @@ Ext.define('Ext.draw.Surface', {
*
* For example:
*
- * drawComponent.surface.setStyle(sprite, {
- * 'cursor': 'pointer'
- * });
- *
+ * drawComponent.surface.setStyle(sprite, {
+ * 'cursor': 'pointer'
+ * });
+ *
* @param {Object} sprite The sprite to add, or an array of classes to
* @param {Object} styles An Object with CSS styles.
* @method
@@ -37988,7 +38943,7 @@ Ext.define('Ext.draw.Surface', {
*
* For example:
*
- * drawComponent.surface.setSize(500, 500);
+ * drawComponent.surface.setSize(500, 500);
*
* This method is generally called when also setting the size of the draw Component.
*
@@ -38063,7 +39018,7 @@ Ext.define('Ext.draw.Surface', {
onMouseLeave: Ext.emptyFn,
/**
- * Add a gradient definition to the Surface. Note that in some surface engines, adding
+ * Adds a gradient definition to the Surface. Note that in some surface engines, adding
* a gradient via this method will not take effect if the surface has already been rendered.
* Therefore, it is preferred to pass the gradients as an item to the surface config, rather
* than calling this method, especially if the surface is rendered immediately (e.g. due to
@@ -38072,32 +39027,32 @@ Ext.define('Ext.draw.Surface', {
*
* The gradient object to be passed into this method is composed by:
*
- *
- * - **id** - string - The unique name of the gradient.
- * - **angle** - number, optional - The angle of the gradient in degrees.
- * - **stops** - object - An object with numbers as keys (from 0 to 100) and style objects as values.
- *
+ * - **id** - string - The unique name of the gradient.
+ * - **angle** - number, optional - The angle of the gradient in degrees.
+ * - **stops** - object - An object with numbers as keys (from 0 to 100) and style objects as values.
*
- For example:
- drawComponent.surface.addGradient({
- id: 'gradientId',
- angle: 45,
- stops: {
- 0: {
- color: '#555'
- },
- 100: {
- color: '#ddd'
- }
- }
- });
+ * For example:
+ *
+ * drawComponent.surface.addGradient({
+ * id: 'gradientId',
+ * angle: 45,
+ * stops: {
+ * 0: {
+ * color: '#555'
+ * },
+ * 100: {
+ * color: '#ddd'
+ * }
+ * }
+ * });
*
* @method
*/
addGradient: Ext.emptyFn,
/**
- * Add a Sprite to the surface. See {@link Ext.draw.Sprite} for the configuration object to be passed into this method.
+ * Adds a Sprite to the surface. See {@link Ext.draw.Sprite} for the configuration object to be
+ * passed into this method.
*
* For example:
*
@@ -38109,7 +39064,7 @@ Ext.define('Ext.draw.Surface', {
* y: 100
* });
*
- */
+ */
add: function() {
var args = Array.prototype.slice.call(arguments),
sprite,
@@ -38137,7 +39092,7 @@ Ext.define('Ext.draw.Surface', {
/**
* @private
- * Insert or move a given sprite into the correct position in the items
+ * Inserts or moves a given sprite into the correct position in the items
* MixedCollection, according to its zIndex. Will be inserted at the end of
* an existing series of sprites with the same or lower zIndex. If the sprite
* is already positioned within an appropriate zIndex group, it will not be moved.
@@ -38184,15 +39139,15 @@ Ext.define('Ext.draw.Surface', {
},
/**
- * Remove a given sprite from the surface, optionally destroying the sprite in the process.
+ * Removes a given sprite from the surface, optionally destroying the sprite in the process.
* You can also call the sprite own `remove` method.
*
* For example:
*
- * drawComponent.surface.remove(sprite);
- * //or...
- * sprite.remove();
- *
+ * drawComponent.surface.remove(sprite);
+ * //or...
+ * sprite.remove();
+ *
* @param {Ext.draw.Sprite} sprite
* @param {Boolean} destroySprite
* @return {Number} the sprite's new index in the list
@@ -38211,12 +39166,12 @@ Ext.define('Ext.draw.Surface', {
},
/**
- * Remove all sprites from the surface, optionally destroying the sprites in the process.
+ * Removes all sprites from the surface, optionally destroying the sprites in the process.
*
* For example:
*
- * drawComponent.surface.removeAll();
- *
+ * drawComponent.surface.removeAll();
+ *
* @param {Boolean} destroySprites Whether to destroy all sprites when removing them.
* @return {Number} The sprite's new index in the list.
*/
@@ -38384,8 +39339,8 @@ Ext.define('Ext.draw.Surface', {
*
* For example:
*
- * var spriteGroup = drawComponent.surface.getGroup('someGroupId');
- *
+ * var spriteGroup = drawComponent.surface.getGroup('someGroupId');
+ *
* @param {String} id The unique identifier of the group.
* @return {Object} The {@link Ext.draw.CompositeSprite}.
*/
@@ -38425,8 +39380,8 @@ Ext.define('Ext.draw.Surface', {
*
* For example:
*
- * var spriteGroup = drawComponent.surface.setText(sprite, 'my new text');
- *
+ * var spriteGroup = drawComponent.surface.setText(sprite, 'my new text');
+ *
* @param {Object} sprite The Sprite to change the text.
* @param {String} text The new text to be set.
* @method
@@ -38720,7 +39675,6 @@ Ext.define('Ext.draw.Component', {
* @class Ext.chart.LegendItem
* @extends Ext.draw.CompositeSprite
* A single item of a legend (marker plus label)
- * @constructor
*/
Ext.define('Ext.chart.LegendItem', {
@@ -39009,7 +39963,6 @@ Ext.define('Ext.chart.LegendItem', {
});
*
- * @constructor
*/
Ext.define('Ext.chart.Legend', {
@@ -39094,6 +40047,10 @@ Ext.define('Ext.chart.Legend', {
*/
boxZIndex: 100,
+ /**
+ * Creates new Legend.
+ * @param {Object} config (optional) Config object.
+ */
constructor: function(config) {
var me = this;
if (config) {
@@ -39331,10 +40288,7 @@ Ext.define('Ext.chart.Legend', {
* select a color theme `Category1` for coloring the series, set the legend to the right part of the chart and
* then tell the chart to render itself in the body element of the document. For more information about the axes and
* series configurations please check the documentation of each series (Line, Bar, Pie, etc).
- *
- * @xtype chart
*/
-
Ext.define('Ext.chart.Chart', {
/* Begin Definitions */
@@ -40059,7 +41013,7 @@ Ext.define('Ext.chart.Chart', {
/**
* @class Ext.chart.Highlight
- * @ignore
+ * A mixin providing highlight functionality for Ext.chart.series.Series.
*/
Ext.define('Ext.chart.Highlight', {
@@ -40108,10 +41062,7 @@ Ext.define('Ext.chart.Highlight', {
opts = me.highlightCfg,
surface = me.chart.surface,
animate = me.chart.animate,
- p,
- from,
- to,
- pi;
+ p, from, to, pi;
if (!me.highlight || !sprite || sprite._highlighted) {
return;
@@ -40121,8 +41072,7 @@ Ext.define('Ext.chart.Highlight', {
}
sprite._highlighted = true;
if (!sprite._defaults) {
- sprite._defaults = Ext.apply(sprite._defaults || {},
- sprite.attr);
+ sprite._defaults = Ext.apply({}, sprite.attr);
from = {};
to = {};
for (p in opts) {
@@ -40152,6 +41102,7 @@ Ext.define('Ext.chart.Highlight', {
}
sprite._from = from;
sprite._to = to;
+ sprite._endStyle = to;
}
if (animate) {
sprite._anim = Ext.create('Ext.fx.Anim', {
@@ -40179,9 +41130,7 @@ Ext.define('Ext.chart.Highlight', {
opts = me.highlightCfg,
animate = me.chart.animate,
i = 0,
- obj,
- p,
- sprite;
+ obj, p, sprite;
for (; i < len; i++) {
if (!items[i]) {
@@ -40203,6 +41152,8 @@ Ext.define('Ext.chart.Highlight', {
}
}
if (animate) {
+ //sprite._to = obj;
+ sprite._endStyle = obj;
sprite._anim = Ext.create('Ext.fx.Anim', {
target: sprite,
to: obj,
@@ -40345,7 +41296,6 @@ Ext.define('Ext.chart.Label', {
var me = this,
chart = me.chart,
gradients = chart.gradients,
- gradient,
items = me.items,
animate = chart.animate,
config = me.label,
@@ -40355,14 +41305,12 @@ Ext.define('Ext.chart.Label', {
group = me.labelsGroup,
store = me.chart.store,
len = store.getCount(),
- ratio = items.length / len,
- i, count, index, j,
- k, gradientsCount = (gradients || 0) && gradients.length,
- colorStopTotal, colorStopIndex, colorStop,
- item, label, storeItem,
- sprite, spriteColor, spriteBrightness, labelColor,
+ itemLength = (items || 0) && items.length,
+ ratio = itemLength / len,
+ gradientsCount = (gradients || 0) && gradients.length,
Color = Ext.draw.Color,
- colorString;
+ gradient, i, count, index, j, k, colorStopTotal, colorStopIndex, colorStop, item, label,
+ storeItem, sprite, spriteColor, spriteBrightness, labelColor, colorString;
if (display == 'none') {
return;
@@ -40393,7 +41341,18 @@ Ext.define('Ext.chart.Label', {
//set contrast
if (config.contrast && item.sprite) {
sprite = item.sprite;
- colorString = sprite._to && sprite._to.fill || sprite.attr.fill;
+ //set the color string to the color to be set.
+ if (sprite._endStyle) {
+ colorString = sprite._endStyle.fill;
+ }
+ else if (sprite._to) {
+ colorString = sprite._to.fill;
+ }
+ else {
+ colorString = sprite.attr.fill;
+ }
+ colorString = colorString || sprite.attr.fill;
+
spriteColor = Color.fromString(colorString);
//color wasn't parsed property maybe because it's a gradient id
if (colorString && !spriteColor) {
@@ -40415,9 +41374,11 @@ Ext.define('Ext.chart.Label', {
else {
spriteBrightness = spriteColor.getGrayscale() / 255;
}
+ if (label.isOutside) {
+ spriteBrightness = 1;
+ }
labelColor = Color.fromString(label.attr.color || label.attr.fill).getHSL();
-
- labelColor[2] = spriteBrightness > 0.5? 0.2 : 0.8;
+ labelColor[2] = spriteBrightness > 0.5 ? 0.2 : 0.8;
label.setAttributes({
fill: String(Color.fromHSL.apply({}, labelColor))
}, true);
@@ -40532,7 +41493,7 @@ Ext.define('Ext.chart.TipSurface', {
/**
* @class Ext.chart.Tip
- * @ignore
+ * Provides tips for Ext.chart.series.Series.
*/
Ext.define('Ext.chart.Tip', {
@@ -40617,7 +41578,7 @@ Ext.define('Ext.chart.Tip', {
});
/**
* @class Ext.chart.axis.Abstract
- * @ignore
+ * Base class for all axis classes.
*/
Ext.define('Ext.chart.axis.Abstract', {
@@ -40627,6 +41588,10 @@ Ext.define('Ext.chart.axis.Abstract', {
/* End Definitions */
+ /**
+ * Creates new Axis.
+ * @param {Object} config (optional) Config options.
+ */
constructor: function(config) {
config = config || {};
@@ -40725,6 +41690,47 @@ Ext.define('Ext.chart.axis.Axis', {
/* End Definitions */
+ /**
+ * @cfg {Boolean | Object} grid
+ * The grid configuration enables you to set a background grid for an axis.
+ * If set to *true* on a vertical axis, vertical lines will be drawn.
+ * If set to *true* on a horizontal axis, horizontal lines will be drawn.
+ * If both are set, a proper grid with horizontal and vertical lines will be drawn.
+ *
+ * You can set specific options for the grid configuration for odd and/or even lines/rows.
+ * Since the rows being drawn are rectangle sprites, you can set to an odd or even property
+ * all styles that apply to {@link Ext.draw.Sprite}. For more information on all the style
+ * properties you can set please take a look at {@link Ext.draw.Sprite}. Some useful style properties are `opacity`, `fill`, `stroke`, `stroke-width`, etc.
+ *
+ * The possible values for a grid option are then *true*, *false*, or an object with `{ odd, even }` properties
+ * where each property contains a sprite style descriptor object that is defined in {@link Ext.draw.Sprite}.
+ *
+ * For example:
+ *
+ * axes: [{
+ * type: 'Numeric',
+ * grid: true,
+ * position: 'left',
+ * fields: ['data1', 'data2', 'data3'],
+ * title: 'Number of Hits',
+ * grid: {
+ * odd: {
+ * opacity: 1,
+ * fill: '#ddd',
+ * stroke: '#bbb',
+ * 'stroke-width': 1
+ * }
+ * }
+ * }, {
+ * type: 'Category',
+ * position: 'bottom',
+ * fields: ['name'],
+ * title: 'Month of the Year',
+ * grid: true
+ * }]
+ *
+ */
+
/**
* @cfg {Number} majorTickSteps
* If `minimum` and `maximum` are specified it forces the number of major ticks to the specified value.
@@ -41846,7 +42852,6 @@ Ext.define('Ext.chart.axis.Gauge', {
* We use a grid configuration to set odd background rows to a certain style and even rows
* to be transparent/ignored.
*
- * @constructor
*/
Ext.define('Ext.chart.axis.Numeric', {
@@ -41863,22 +42868,20 @@ Ext.define('Ext.chart.axis.Numeric', {
alias: 'axis.numeric',
constructor: function(config) {
- var me = this, label, f;
+ var me = this,
+ hasLabel = !!(config.label && config.label.renderer),
+ label;
+
me.callParent([config]);
label = me.label;
if (me.roundToDecimal === false) {
return;
}
- if (label.renderer) {
- f = label.renderer;
- label.renderer = function(v) {
- return me.roundToDecimal( f(v), me.decimals );
- };
- } else {
+ if (!hasLabel) {
label.renderer = function(v) {
return me.roundToDecimal(v, me.decimals);
};
- }
+ }
},
roundToDecimal: function(v, dec) {
@@ -42176,11 +43179,9 @@ Ext.define('Ext.chart.axis.Radial', {
* in {@link Ext.data.Store} the data is saved as a flat {@link Ext.util.MixedCollection MixedCollection}, whereas in
* {@link Ext.data.TreeStore TreeStore} we use a {@link Ext.data.Tree} to maintain the data's hierarchy.
Finally, AbstractStore provides an API for sorting and filtering data via its {@link #sorters} and {@link #filters} - * {@link Ext.util.MixedCollection MixedCollections}. Although this functionality is provided by AbstractStore, there's a - * good description of how to use it in the introduction of {@link Ext.data.Store}. - * + * The store provides filtering and sorting support. This sorting/filtering can happen on the client side + * or can be completed on the server. This is controlled by the {@link #remoteSort} and (@link #remoteFilter{ config + * options. For more information see the {@link #sort} and {@link #filter} methods. */ Ext.define('Ext.data.AbstractStore', { requires: ['Ext.util.MixedCollection', 'Ext.data.Operation', 'Ext.util.Filter'], @@ -42883,6 +43884,11 @@ Ext.define('Ext.data.AbstractStore', { /** * @class Ext.util.Grouper * @extends Ext.util.Sorter + +Represents a single grouper that can be applied to a Store. The grouper works +in the same fashion as the {@link Ext.util.Sorter}. + + * @markdown */ Ext.define('Ext.util.Grouper', { @@ -42894,7 +43900,7 @@ Ext.define('Ext.util.Grouper', { /* End Definitions */ /** - * Function description + * Returns the value for grouping to be used. * @param {Ext.data.Model} instance The Model instance * @return {String} The group string for this model */ @@ -43111,8 +44117,6 @@ new Ext.view.View({ *
An object literal of this form could also be used as the {@link #data} config option.
* - * @constructor - * @param {Object} config * @xtype jsonstore */ Ext.define('Ext.data.JsonStore', { @@ -45159,7 +46164,6 @@ Ext.define('Ext.data.JsonStore', { * Since `constrain` is set to true all other values for other dates not between * the fromDate and toDate will not be displayed. * - * @constructor */ Ext.define('Ext.chart.axis.Time', { @@ -45863,7 +46867,6 @@ Ext.define('Ext.chart.series.Series', { * * Common base class for series implementations which plot values using x/y coordinates. * - * @constructor */ Ext.define('Ext.chart.series.Cartesian', { @@ -47271,6 +48274,7 @@ Ext.define('Ext.chart.series.Bar', { text: text }); + label.isOutside = false; if (column) { if (display == outside) { if (height + offsetY + attr.height > (yValue >= 0 ? zero - chartBBox.y : chartBBox.y + chartBBox.height - zero)) { @@ -47279,6 +48283,7 @@ Ext.define('Ext.chart.series.Bar', { } else { if (height + offsetY > attr.height) { display = outside; + label.isOutside = true; } } x = attr.x + groupBarWidth / 2; @@ -47296,6 +48301,7 @@ Ext.define('Ext.chart.series.Bar', { else { if (width + offsetX > attr.width) { display = outside; + label.isOutside = true; } } x = display == insideStart ? @@ -47431,8 +48437,29 @@ Ext.define('Ext.chart.series.Bar', { * @param index */ getLegendColor: function(index) { - var me = this; - return me.colorArrayStyle[index % me.colorArrayStyle.length]; + var me = this, + colorLength = me.colorArrayStyle.length; + + if (me.style && me.style.fill) { + return me.style.fill; + } else { + return me.colorArrayStyle[index % colorLength]; + } + }, + + highlightItem: function(item) { + this.callParent(arguments); + this.renderLabels(); + }, + + unHighlightItem: function() { + this.callParent(arguments); + this.renderLabels(); + }, + + cleanHighlights: function() { + this.callParent(arguments); + this.renderLabels(); } }); /** @@ -48159,12 +49186,22 @@ Ext.define('Ext.chart.series.Line', { style: {}, /** - * @cfg {Boolean} smooth - * If true, the line will be smoothed/rounded around its points, otherwise straight line - * segments will be drawn. Defaults to false. + * @cfg {Boolean/Number} smooth + * If set to `true` or a non-zero number, the line will be smoothed/rounded around its points; otherwise + * straight line segments will be drawn. + * + * A numeric value is interpreted as a divisor of the horizontal distance between consecutive points in + * the line; larger numbers result in sharper curves while smaller numbers result in smoother curves. + * + * If set to `true` then a default numeric value of 3 will be used. Defaults to `false`. */ smooth: false, + /** + * @private Default numeric smoothing value to be used when {@link #smooth} = true. + */ + defaultSmoothness: 3, + /** * @cfg {Boolean} fill * If true, the area below the line will be filled in using the {@link #style.eefill} and @@ -48263,7 +49300,8 @@ Ext.define('Ext.chart.series.Line', { markerGroup = me.markerGroup, enableShadows = chart.shadow, shadowGroups = me.shadowGroups, - shadowAttributes = this.shadowAttributes, + shadowAttributes = me.shadowAttributes, + smooth = me.smooth, lnsh = shadowGroups.length, dummyPath = ["M"], path = ["M"], @@ -48273,6 +49311,7 @@ Ext.define('Ext.chart.series.Line', { shadowBarAttr, xValues = [], yValues = [], + storeIndices = [], numericAxis = true, axisCount = 0, onbreak = false, @@ -48287,10 +49326,11 @@ Ext.define('Ext.chart.series.Line', { 'top': 'bottom', 'bottom': 'top' }, + isNumber = Ext.isNumber, seriesIdx = me.seriesIdx, shadows, shadow, shindex, fromPath, fill, fillPath, rendererAttributes, x, y, prevX, prevY, firstY, markerCount, i, j, ln, axis, ends, marker, markerAux, item, xValue, yValue, coords, xScale, yScale, minX, maxX, minY, maxY, line, animation, endMarkerStyle, - endLineStyle, type, props, firstMarker, count; + endLineStyle, type, props, firstMarker, count, smoothPath, renderPath; //if store is empty then there's nothing to draw. if (!store || !store.getCount()) { @@ -48370,7 +49410,7 @@ Ext.define('Ext.chart.series.Line', { // If a field was specified without a corresponding axis, create one to get bounds //only do this for the axis where real values are bound (that's why we check for //me.axis) - if (me.xField && !Ext.isNumber(minX)) { + if (me.xField && !isNumber(minX)) { if (me.axis == 'bottom' || me.axis == 'top') { axis = Ext.create('Ext.chart.axis.Axis', { chart: chart, @@ -48389,7 +49429,7 @@ Ext.define('Ext.chart.series.Line', { } } - if (me.yField && !Ext.isNumber(minY)) { + if (me.yField && !isNumber(minY)) { if (me.axis == 'right' || me.axis == 'left') { axis = Ext.create('Ext.chart.axis.Axis', { chart: chart, @@ -48413,7 +49453,10 @@ Ext.define('Ext.chart.series.Line', { xScale = bbox.width / (store.getCount() - 1); } else { - xScale = bbox.width / (maxX - minX); + //In case some person decides to set an axis' minimum and maximum + //configuration properties to the same value, then fallback the + //denominator to a > 0 value. + xScale = bbox.width / ((maxX - minX) || (store.getCount() - 1)); } if (isNaN(minY)) { @@ -48421,7 +49464,10 @@ Ext.define('Ext.chart.series.Line', { yScale = bbox.height / (store.getCount() - 1); } else { - yScale = bbox.height / (maxY - minY); + //In case some person decides to set an axis' minimum and maximum + //configuration properties to the same value, then fallback the + //denominator to a > 0 value. + yScale = bbox.height / ((maxY - minY) || (store.getCount() - 1)); } store.each(function(record, i) { @@ -48447,6 +49493,7 @@ Ext.define('Ext.chart.series.Line', { || (me.axis != 'left' && me.axis != 'right' && !numericAxis)) { yValue = i; } + storeIndices.push(i); xValues.push(xValue); yValues.push(yValue); }, me); @@ -48541,12 +49588,13 @@ Ext.define('Ext.chart.series.Line', { }; } } + me.items.push({ series: me, value: [xValue, yValue], point: [x, y], sprite: marker, - storeItem: store.getAt(i) + storeItem: store.getAt(storeIndices[i]) }); prevX = x; prevY = y; @@ -48556,19 +49604,23 @@ Ext.define('Ext.chart.series.Line', { //nothing to be rendered return; } - - if (me.smooth) { - path = Ext.draw.Draw.smooth(path, 6); + + if (smooth) { + smoothPath = Ext.draw.Draw.smooth(path, isNumber(smooth) ? smooth : me.defaultSmoothness); } + renderPath = smooth ? smoothPath : path; + //Correct path if we're animating timeAxis intervals if (chart.markerIndex && me.previousPath) { fromPath = me.previousPath; - fromPath.splice(1, 2); + if (!smooth) { + Ext.Array.erase(fromPath, 1, 2); + } } else { fromPath = path; } - + // Only create a line if one doesn't exist. if (!me.line) { me.line = surface.add(Ext.apply({ @@ -48601,7 +49653,7 @@ Ext.define('Ext.chart.series.Line', { } } if (me.fill) { - fillPath = path.concat([ + fillPath = renderPath.concat([ ["L", x, bbox.y + bbox.height], ["L", bbox.x, bbox.y + bbox.height], ["L", bbox.x, firstY] @@ -48611,7 +49663,7 @@ Ext.define('Ext.chart.series.Line', { group: group, type: 'path', opacity: endLineStyle.opacity || 0.3, - fill: colorArrayStyle[seriesIdx % colorArrayLength] || endLineStyle.fill, + fill: endLineStyle.fill || colorArrayStyle[seriesIdx % colorArrayLength], path: dummyPath }); } @@ -48621,7 +49673,7 @@ Ext.define('Ext.chart.series.Line', { fill = me.fill; line = me.line; //Add renderer to line. There is not unique record associated with this. - rendererAttributes = me.renderer(line, false, { path: path }, i, store); + rendererAttributes = me.renderer(line, false, { path: renderPath }, i, store); Ext.apply(rendererAttributes, endLineStyle || {}, { stroke: endLineStyle.stroke || endLineStyle.fill }); @@ -48645,12 +49697,12 @@ Ext.define('Ext.chart.series.Line', { for(j = 0; j < lnsh; j++) { if (chart.markerIndex && me.previousPath) { me.onAnimate(shadows[j], { - to: { path: path }, + to: { path: renderPath }, from: { path: fromPath } }); } else { me.onAnimate(shadows[j], { - to: { path: path } + to: { path: renderPath } }); } } @@ -48660,7 +49712,7 @@ Ext.define('Ext.chart.series.Line', { me.onAnimate(me.fillPath, { to: Ext.apply({}, { path: fillPath, - fill: colorArrayStyle[seriesIdx % colorArrayLength] || endLineStyle.fill + fill: endLineStyle.fill || colorArrayStyle[seriesIdx % colorArrayLength] }, endLineStyle || {}) }); } @@ -48684,7 +49736,7 @@ Ext.define('Ext.chart.series.Line', { } } } else { - rendererAttributes = me.renderer(me.line, false, { path: path, hidden: false }, i, store); + rendererAttributes = me.renderer(me.line, false, { path: renderPath, hidden: false }, i, store); Ext.apply(rendererAttributes, endLineStyle || {}, { stroke: endLineStyle.stroke || endLineStyle.fill }); @@ -48696,7 +49748,7 @@ Ext.define('Ext.chart.series.Line', { shadows = me.line.shadows; for(j = 0; j < lnsh; j++) { shadows[j].setAttributes({ - path: path + path: renderPath }, true); } } @@ -48724,7 +49776,11 @@ Ext.define('Ext.chart.series.Line', { } if (chart.markerIndex) { - path.splice(1, 0, path[1], path[2]); + if (me.smooth) { + Ext.Array.erase(path, 1, 2); + } else { + Ext.Array.splice(path, 1, 0, path[1], path[2]); + } me.previousPath = path; } me.renderLabels(); @@ -50063,7 +51119,7 @@ Ext.define('Ext.chart.series.Pie', { */ getLegendColor: function(index) { var me = this; - return me.colorArrayStyle[index % me.colorArrayStyle.length]; + return (me.colorSet && me.colorSet[index % me.colorSet.length]) || me.colorArrayStyle[index % me.colorArrayStyle.length]; } }); @@ -51299,58 +52355,47 @@ Ext.define('Ext.chart.theme.Base', { /** * @author Ed Spencer - * @class Ext.data.ArrayStore - * @extends Ext.data.Store - * @ignore * - *Small helper class to make creating {@link Ext.data.Store}s from Array data easier. - * An ArrayStore will be automatically configured with a {@link Ext.data.reader.Array}.
+ * Small helper class to make creating {@link Ext.data.Store}s from Array data easier. An ArrayStore will be + * automatically configured with a {@link Ext.data.reader.Array}. * - *A store configuration would be something like:
-
-var store = new Ext.data.ArrayStore({
- // store configs
- autoDestroy: true,
- storeId: 'myStore',
- // reader configs
- idIndex: 0,
- fields: [
- 'company',
- {name: 'price', type: 'float'},
- {name: 'change', type: 'float'},
- {name: 'pctChange', type: 'float'},
- {name: 'lastChange', type: 'date', dateFormat: 'n/j h:ia'}
- ]
-});
-
- * This store is configured to consume a returned object of the form: -
-var myData = [
- ['3m Co',71.72,0.02,0.03,'9/1 12:00am'],
- ['Alcoa Inc',29.01,0.42,1.47,'9/1 12:00am'],
- ['Boeing Co.',75.43,0.53,0.71,'9/1 12:00am'],
- ['Hewlett-Packard Co.',36.53,-0.03,-0.08,'9/1 12:00am'],
- ['Wal-Mart Stores, Inc.',45.45,0.73,1.63,'9/1 12:00am']
-];
-
-*
- * An object literal of this form could also be used as the {@link #data} config option.
+ * A store configuration would be something like: * - **Note: Although not listed here, this class accepts all of the configuration options of - * {@link Ext.data.reader.Array ArrayReader}.
+ * var store = Ext.create('Ext.data.ArrayStore', { + * // store configs + * autoDestroy: true, + * storeId: 'myStore', + * // reader configs + * idIndex: 0, + * fields: [ + * 'company', + * {name: 'price', type: 'float'}, + * {name: 'change', type: 'float'}, + * {name: 'pctChange', type: 'float'}, + * {name: 'lastChange', type: 'date', dateFormat: 'n/j h:ia'} + * ] + * }); * - * @constructor - * @param {Object} config - * @xtype arraystore + * This store is configured to consume a returned object of the form: + * + * var myData = [ + * ['3m Co',71.72,0.02,0.03,'9/1 12:00am'], + * ['Alcoa Inc',29.01,0.42,1.47,'9/1 12:00am'], + * ['Boeing Co.',75.43,0.53,0.71,'9/1 12:00am'], + * ['Hewlett-Packard Co.',36.53,-0.03,-0.08,'9/1 12:00am'], + * ['Wal-Mart Stores, Inc.',45.45,0.73,1.63,'9/1 12:00am'] + * ]; + * + * An object literal of this form could also be used as the {@link #data} config option. + * + * **Note:** Although not listed here, this class accepts all of the configuration options of + * **{@link Ext.data.reader.Array ArrayReader}**. */ Ext.define('Ext.data.ArrayStore', { extend: 'Ext.data.Store', alias: 'store.array', uses: ['Ext.data.reader.Array'], - /** - * @cfg {Ext.data.DataReader} reader @hide - */ constructor: function(config) { config = config || {}; @@ -51395,8 +52440,6 @@ Ext.define('Ext.data.ArrayStore', { * *Usually these are only used internally by {@link Ext.data.proxy.Proxy} classes
* - * @constructor - * @param {Object} config Optional config object */ Ext.define('Ext.data.Batch', { mixins: { @@ -51452,6 +52495,10 @@ Ext.define('Ext.data.Batch', { */ pauseOnException: true, + /** + * Creates new Batch object. + * @param {Object} config (optional) Config object + */ constructor: function(config) { var me = this; @@ -51807,38 +52854,37 @@ associations: [{ return function(options, scope) { options = options || {}; - var foreignKeyId = this.get(foreignKey), - instance, callbackFn; + var model = this, + foreignKeyId = model.get(foreignKey), + instance, + args; - if (this[instanceName] === undefined) { + if (model[instanceName] === undefined) { instance = Ext.ModelManager.create({}, associatedName); instance.set(primaryKey, foreignKeyId); if (typeof options == 'function') { options = { callback: options, - scope: scope || this + scope: scope || model }; } associatedModel.load(foreignKeyId, options); + model[instanceName] = associatedModel; + return associatedModel; } else { - instance = this[instanceName]; - + instance = model[instanceName]; + args = [instance]; + scope = scope || model; + //TODO: We're duplicating the callback invokation code that the instance.load() call above //makes here - ought to be able to normalize this - perhaps by caching at the Model.load layer //instead of the association layer. - if (typeof options == 'function') { - options.call(scope || this, instance); - } - - if (options.success) { - options.success.call(scope || this, instance); - } - - if (options.callback) { - options.callback.call(scope || this, instance); - } + Ext.callback(options, scope, args); + Ext.callback(options.success, scope, args); + Ext.callback(options.failure, scope, args); + Ext.callback(options.callback, scope, args); return instance; } @@ -51903,7 +52949,7 @@ Ext.define('Ext.data.BufferStore', { *A provider does not need to be invoked directly, providers are added via - * {@link Ext.direct.Manager}.{@link Ext.direct.Manager#add add}.
+ * {@link Ext.direct.Manager}.{@link Ext.direct.Manager#addProvider addProvider}. * *Router
* @@ -52136,7 +53182,7 @@ Ext.direct.Manager.addProvider({ * method for all requests. Alternatively, you can provide an {@link #api} configuration. This * allows you to specify a different remoting method for each CRUD action. * - * ## Paramaters + * ## Parameters * This proxy provides options to help configure which parameters will be sent to the server. * By specifying the {@link #paramsAsHash} option, it will send an object literal containing each * of the passed parameters. The {@link #paramOrder} option can be used to specify the order in which @@ -52330,9 +53376,6 @@ paramOrder: 'param1|param2|param' **Note: Although not listed here, this class accepts all of the configuration options of * {@link Ext.data.reader.Json JsonReader} and {@link Ext.data.proxy.JsonP JsonPProxy}.
- * @constructor - * @param {Object} config * @xtype jsonpstore */ Ext.define('Ext.data.JsonPStore', { @@ -53280,47 +54324,41 @@ Ext.define('Ext.data.NodeInterface', { modelName = record.modelName, modelClass = mgr.getModel(modelName), idName = modelClass.prototype.idProperty, - instances = Ext.Array.filter(mgr.all.getArray(), function(item) { - return item.modelName == modelName; - }), - iln = instances.length, newFields = [], - i, instance, jln, j, newField; + i, newField, len; // Start by adding the NodeInterface methods to the Model's prototype modelClass.override(this.getPrototypeBody()); newFields = this.applyFields(modelClass, [ - {name: idName, type: 'string', defaultValue: null}, - {name: 'parentId', type: 'string', defaultValue: null}, - {name: 'index', type: 'int', defaultValue: null}, - {name: 'depth', type: 'int', defaultValue: 0}, - {name: 'expanded', type: 'bool', defaultValue: false, persist: false}, - {name: 'checked', type: 'auto', defaultValue: null}, - {name: 'leaf', type: 'bool', defaultValue: false, persist: false}, - {name: 'cls', type: 'string', defaultValue: null, persist: false}, - {name: 'iconCls', type: 'string', defaultValue: null, persist: false}, - {name: 'root', type: 'boolean', defaultValue: false, persist: false}, - {name: 'isLast', type: 'boolean', defaultValue: false, persist: false}, - {name: 'isFirst', type: 'boolean', defaultValue: false, persist: false}, - {name: 'allowDrop', type: 'boolean', defaultValue: true, persist: false}, - {name: 'allowDrag', type: 'boolean', defaultValue: true, persist: false}, - {name: 'loaded', type: 'boolean', defaultValue: false, persist: false}, - {name: 'loading', type: 'boolean', defaultValue: false, persist: false}, - {name: 'href', type: 'string', defaultValue: null, persist: false}, - {name: 'hrefTarget',type: 'string', defaultValue: null, persist: false}, - {name: 'qtip', type: 'string', defaultValue: null, persist: false}, - {name: 'qtitle', type: 'string', defaultValue: null, persist: false} + {name: idName, type: 'string', defaultValue: null}, + {name: 'parentId', type: 'string', defaultValue: null}, + {name: 'index', type: 'int', defaultValue: null}, + {name: 'depth', type: 'int', defaultValue: 0}, + {name: 'expanded', type: 'bool', defaultValue: false, persist: false}, + {name: 'expandable', type: 'bool', defaultValue: true, persist: false}, + {name: 'checked', type: 'auto', defaultValue: null}, + {name: 'leaf', type: 'bool', defaultValue: false, persist: false}, + {name: 'cls', type: 'string', defaultValue: null, persist: false}, + {name: 'iconCls', type: 'string', defaultValue: null, persist: false}, + {name: 'root', type: 'boolean', defaultValue: false, persist: false}, + {name: 'isLast', type: 'boolean', defaultValue: false, persist: false}, + {name: 'isFirst', type: 'boolean', defaultValue: false, persist: false}, + {name: 'allowDrop', type: 'boolean', defaultValue: true, persist: false}, + {name: 'allowDrag', type: 'boolean', defaultValue: true, persist: false}, + {name: 'loaded', type: 'boolean', defaultValue: false, persist: false}, + {name: 'loading', type: 'boolean', defaultValue: false, persist: false}, + {name: 'href', type: 'string', defaultValue: null, persist: false}, + {name: 'hrefTarget', type: 'string', defaultValue: null, persist: false}, + {name: 'qtip', type: 'string', defaultValue: null, persist: false}, + {name: 'qtitle', type: 'string', defaultValue: null, persist: false} ]); - jln = newFields.length; - // Set default values to all instances already out there - for (i = 0; i < iln; i++) { - instance = instances[i]; - for (j = 0; j < jln; j++) { - newField = newFields[j]; - if (instance.get(newField.name) === undefined) { - instance.data[newField.name] = newField.defaultValue; - } + len = newFields.length; + // Set default values + for (i = 0; i < len; ++i) { + newField = newFields[i]; + if (record.get(newField.name) === undefined) { + record.data[newField.name] = newField.defaultValue; } } } @@ -53437,9 +54475,10 @@ Ext.define('Ext.data.NodeInterface', { "beforecollapse", /** - * @event beforecollapse - * Fires before this node is collapsed. - * @param {Node} this The collapsing node + * @event sort + * Fires when this node's childNodes are sorted. + * @param {Node} this This node. + * @param {Array} The childNodes of this node. */ "sort" ]); @@ -53582,7 +54621,12 @@ Ext.define('Ext.data.NodeInterface', { * @return {Boolean} */ isExpandable : function() { - return this.get('expandable') || this.hasChildNodes(); + var me = this; + + if (me.get('expandable')) { + return !(me.isLeaf() || (me.isLoaded() && !me.hasChildNodes())); + } + return false; }, /** @@ -53689,7 +54733,7 @@ Ext.define('Ext.data.NodeInterface', { } // remove it from childNodes collection - me.childNodes.splice(index, 1); + Ext.Array.erase(me.childNodes, index, 1); // update child refs if (me.firstChild == node) { @@ -53839,7 +54883,7 @@ Ext.define('Ext.data.NodeInterface', { me.setFirstChild(node); } - me.childNodes.splice(refIndex, 0, node); + Ext.Array.splice(me.childNodes, refIndex, 0, node); node.parentNode = me; node.nextSibling = refNode; @@ -54197,7 +55241,7 @@ Ext.define('Ext.data.NodeInterface', { // whether we have to asynchronously load the children from the server // first. Thats why we pass a callback function to the event that the // store can call once it has loaded and parsed all the children. - me.fireEvent('beforeexpand', me, function(records) { + me.fireEvent('beforeexpand', me, function() { me.set('expanded', true); me.fireEvent('expand', me, me.childNodes, false); @@ -54249,15 +55293,14 @@ Ext.define('Ext.data.NodeInterface', { nodes[i].expand(recursive, function () { expanding--; if (callback && !expanding) { - Ext.callback(callback, scope || me, me.childNodes); + Ext.callback(callback, scope || me, [me.childNodes]); } }); } } if (!expanding && callback) { - Ext.callback(callback, scope || me, me.childNodes); - } + Ext.callback(callback, scope || me, [me.childNodes]); } }, /** @@ -54273,7 +55316,7 @@ Ext.define('Ext.data.NodeInterface', { if (!me.isLeaf()) { // Now we check if this record is already collapsing or collapsed if (!me.collapsing && me.isExpanded()) { - me.fireEvent('beforecollapse', me, function(records) { + me.fireEvent('beforecollapse', me, function() { me.set('expanded', false); me.fireEvent('collapse', me, me.childNodes, false); @@ -54293,7 +55336,7 @@ Ext.define('Ext.data.NodeInterface', { } // If it's not then we fire the callback right away else { - Ext.callback(callback, scope || me, me.childNodes); + Ext.callback(callback, scope || me, [me.childNodes]); } }, @@ -54318,14 +55361,14 @@ Ext.define('Ext.data.NodeInterface', { nodes[i].collapse(recursive, function () { collapsing--; if (callback && !collapsing) { - Ext.callback(callback, scope || me, me.childNodes); + Ext.callback(callback, scope || me, [me.childNodes]); } }); } } if (!collapsing && callback) { - Ext.callback(callback, scope || me, me.childNodes); + Ext.callback(callback, scope || me, [me.childNodes]); } } }; @@ -54588,8 +55631,6 @@ Ext.define('Ext.data.NodeStore', { * All this class does is standardize the representation of a Request as used by any ServerProxy subclass, * it does not contain any actual logic or perform the request itself. * - * @constructor - * @param {Object} config Optional config object */ Ext.define('Ext.data.Request', { /** @@ -54612,6 +55653,10 @@ Ext.define('Ext.data.Request', { */ url: undefined, + /** + * Creates the Request object. + * @param {Object} config (optional) Config object. + */ constructor: function(config) { Ext.apply(this, config); } @@ -54627,8 +55672,6 @@ Ext.define('Ext.data.Request', { * centralized fashion. In general this class is not used directly, rather used internally * by other parts of the framework. * - * @constructor - * @param {Node} root (optional) The root node */ Ext.define('Ext.data.Tree', { alias: 'data.tree', @@ -54642,7 +55685,11 @@ Ext.define('Ext.data.Tree', { * @type Node */ root: null, - + + /** + * Creates new Tree object. + * @param {Node} root (optional) The root node + */ constructor: function(root) { var me = this; @@ -54905,21 +55952,20 @@ Ext.define('Ext.data.Tree', { } }); /** - * @class Ext.data.TreeStore - * @extends Ext.data.AbstractStore - * * The TreeStore is a store implementation that is backed by by an {@link Ext.data.Tree}. * It provides convenience methods for loading nodes, as well as the ability to use * the hierarchical tree structure combined with a store. This class is generally used * in conjunction with {@link Ext.tree.Panel}. This class also relays many events from * the Tree for convenience. * - * ## Using Models + * # Using Models + * * If no Model is specified, an implicit model will be created that implements {@link Ext.data.NodeInterface}. * The standard Tree fields will also be copied onto the Model for maintaining their state. * - * ## Reading Nested Data - * For the tree to read nested data, the {@link Ext.data.Reader} must be configured with a root property, + * # Reading Nested Data + * + * For the tree to read nested data, the {@link Ext.data.reader.Reader} must be configured with a root property, * so the reader can find nested data for each node. If a root is not specified, it will default to * 'children'. */ @@ -54929,14 +55975,33 @@ Ext.define('Ext.data.TreeStore', { requires: ['Ext.data.Tree', 'Ext.data.NodeInterface', 'Ext.data.NodeStore'], /** - * @cfg {Boolean} clearOnLoad (optional) Default to true. Remove previously existing - * child nodes before loading. + * @cfg {Ext.data.Model/Ext.data.NodeInterface/Object} root + * The root node for this store. For example: + * + * root: { + * expanded: true, + * text: "My Root", + * children: [ + * { text: "Child 1", leaf: true }, + * { text: "Child 2", expanded: true, children: [ + * { text: "GrandChild", leaf: true } + * ] } + * ] + * } + * + * Setting the `root` config option is the same as calling {@link #setRootNode}. + */ + + /** + * @cfg {Boolean} clearOnLoad + * Remove previously existing child nodes before loading. Default to true. */ clearOnLoad : true, /** - * @cfg {String} nodeParam The name of the parameter sent to the server which contains - * the identifier of the node. Defaults to 'node'. + * @cfg {String} nodeParam + * The name of the parameter sent to the server which contains the identifier of the node. + * Defaults to 'node'. */ nodeParam: 'node', @@ -54953,7 +56018,8 @@ Ext.define('Ext.data.TreeStore', { defaultRootProperty: 'children', /** - * @cfg {Boolean} folderSort Set to true to automatically prepend a leaf sorter (defaults to undefined) + * @cfg {Boolean} folderSort + * Set to true to automatically prepend a leaf sorter. Defaults to `undefined`. */ folderSort: false, @@ -54961,7 +56027,6 @@ Ext.define('Ext.data.TreeStore', { var me = this, root, fields; - config = Ext.apply({}, config); @@ -54978,23 +56043,6 @@ Ext.define('Ext.data.TreeStore', { // We create our data tree. me.tree = Ext.create('Ext.data.Tree'); - - me.tree.on({ - scope: me, - remove: me.onNodeRemove, - beforeexpand: me.onBeforeNodeExpand, - beforecollapse: me.onBeforeNodeCollapse, - append: me.onNodeAdded, - insert: me.onNodeAdded - }); - - me.onBeforeSort(); - - root = me.root; - if (root) { - delete me.root; - me.setRootNode(root); - } me.relayEvents(me.tree, [ /** @@ -55118,6 +56166,25 @@ Ext.define('Ext.data.TreeStore', { */ "rootchange" ]); + + me.tree.on({ + scope: me, + remove: me.onNodeRemove, + // this event must follow the relay to beforeitemexpand to allow users to + // cancel the expand: + beforeexpand: me.onBeforeNodeExpand, + beforecollapse: me.onBeforeNodeCollapse, + append: me.onNodeAdded, + insert: me.onNodeAdded + }); + + me.onBeforeSort(); + + root = me.root; + if (root) { + delete me.root; + me.setRootNode(root); + } me.addEvents( /** @@ -55248,8 +56315,8 @@ Ext.define('Ext.data.TreeStore', { }, /** - * Sets the root node for this store - * @param {Ext.data.Model/Ext.data.NodeInterface} root + * Sets the root node for this store. See also the {@link #root} config option. + * @param {Ext.data.Model/Ext.data.NodeInterface/Object} root * @return {Ext.data.NodeInterface} The new root */ setRootNode: function(root) { @@ -55385,7 +56452,7 @@ Ext.define('Ext.data.TreeStore', { }, /** - * Create any new records when a write is returned from the server. + * Creates any new records when a write is returned from the server. * @private * @param {Array} records The array of new records * @param {Ext.data.Operation} operation The operation that just completed @@ -55424,7 +56491,7 @@ Ext.define('Ext.data.TreeStore', { }, /** - * Update any records when a write is returned from the server. + * Updates any records when a write is returned from the server. * @private * @param {Array} records The array of updated records * @param {Ext.data.Operation} operation The operation that just completed @@ -55455,7 +56522,7 @@ Ext.define('Ext.data.TreeStore', { }, /** - * Remove any records when a write is returned from the server. + * Removes any records when a write is returned from the server. * @private * @param {Array} records The array of removed records * @param {Ext.data.Operation} operation The operation that just completed @@ -55543,8 +56610,6 @@ var store = new Ext.data.XmlStore({ * An object literal of this form could also be used as the {@link #data} config option. *Note: Although not listed here, this class accepts all of the configuration options of * {@link Ext.data.reader.Xml XmlReader}.
- * @constructor - * @param {Object} config * @xtype xmlstore */ Ext.define('Ext.data.XmlStore', { @@ -55937,10 +57002,6 @@ Ext.define('Ext.data.proxy.JsonP', { *WebStorageProxy is simply a superclass for the {@link Ext.data.proxy.LocalStorage localStorage} and * {@link Ext.data.proxy.SessionStorage sessionStorage} proxies. It uses the new HTML5 key/value client-side storage * objects to save {@link Ext.data.Model model instances} for offline use.
- * - * @constructor - * Creates the proxy, throws an error if local storage is not supported in the current browser - * @param {Object} config Optional config object */ Ext.define('Ext.data.proxy.WebStorage', { extend: 'Ext.data.proxy.Client', @@ -55952,7 +57013,8 @@ Ext.define('Ext.data.proxy.WebStorage', { id: undefined, /** - * @ignore + * Creates the proxy, throws an error if local storage is not supported in the current browser + * @param {Object} config (optional) Config object. */ constructor: function(config) { this.callParent(arguments); @@ -57001,19 +58063,15 @@ Ext.define('Ext.data.reader.Xml', { } return function(root) { - var node = Ext.DomQuery.selectNode(expr, root), - val = me.getNodeValue(node); - - return Ext.isEmpty(val) ? null : val; + return me.getNodeValue(Ext.DomQuery.selectNode(expr, root)); }; }, getNodeValue: function(node) { - var val; if (node && node.firstChild) { - val = node.firstChild.nodeValue; + return node.firstChild.nodeValue; } - return val || null; + return undefined; }, //inherit docs @@ -57115,7 +58173,6 @@ Ext.define('Ext.data.reader.Xml', { return this.callParent([doc]); } }); - /** * @author Ed Spencer * @class Ext.data.writer.Xml @@ -57212,9 +58269,6 @@ Ext.define('Ext.data.writer.Xml', { * created after some kind of interaction with the server. * The event class is essentially just a data structure * to hold a direct response. - * - * @constructor - * @param {Object} config The config object */ Ext.define('Ext.direct.Event', { @@ -57227,7 +58281,11 @@ Ext.define('Ext.direct.Event', { /* End Definitions */ status: true, - + + /** + * Creates new Event. + * @param {Object} config (optional) Config object. + */ constructor: function(config) { Ext.apply(this, config); }, @@ -57705,8 +58763,6 @@ Ext.define('Ext.direct.RemotingMethod', { * @class Ext.direct.Transaction * @extends Object *Supporting Class for Ext.Direct (not intended to be used directly).
- * @constructor - * @param {Object} config */ Ext.define('Ext.direct.Transaction', { @@ -57720,7 +58776,11 @@ Ext.define('Ext.direct.Transaction', { }, /* End Definitions */ - + + /** + * Creates new Transaction. + * @param {Object} config (optional) Config object. + */ constructor: function(config){ var me = this; @@ -58530,6 +59590,7 @@ Ext.define('Ext.draw.SpriteDD', { * The configuration of a Sprite is an object with the following properties: * * - **type** - (String) The type of the sprite. Possible options are 'circle', 'path', 'rect', 'text', 'square', 'image'. + * - **group** - (String/Array) The group that this sprite belongs to, or an array of groups. Only relevant when added to a {@link Ext.draw.Surface}. * - **width** - (Number) Used in rectangle sprites, the width of the rectangle. * - **height** - (Number) Used in rectangle sprites, the height of the rectangle. * - **size** - (Number) Used in square sprites, the dimension of the square. @@ -58543,9 +59604,12 @@ Ext.define('Ext.draw.SpriteDD', { * - **stroke-width** - (Number) The width of the stroke. * - **font** - (String) Used with text type sprites. The full font description. Uses the same syntax as the CSS `font` parameter. * - **text** - (String) Used with text type sprites. The text itself. + * - **translate** - (Object) Defines a translation for the Sprite. There's more information on this property below. + * - **rotate** - (Object) Defines a rotation for the Sprite. There's more information on this property below. + * - **scale** - (Object) Defines a scaling for the Sprite. There's more information on this property below. * - * Additionally there are three transform objects that can be set with `setAttributes` which are `translate`, `rotate` and - * `scale`. + * + * ## Translation * * For translate, the configuration object contains x and y attributes that indicate where to * translate the object. For example: @@ -58556,6 +59620,9 @@ Ext.define('Ext.draw.SpriteDD', { * y: 10 * } * }, true); + * + * + * ## Rotation * * For rotation, the configuration object contains x and y attributes for the center of the rotation (which are optional), * and a `degrees` attribute that specifies the rotation in degrees. For example: @@ -58565,6 +59632,21 @@ Ext.define('Ext.draw.SpriteDD', { * degrees: 90 * } * }, true); + * + * That example will create a 90 degrees rotation using the centroid of the Sprite as center of rotation, whereas: + * + * sprite.setAttributes({ + * rotate: { + * x: 0, + * y: 0, + * degrees: 90 + * } + * }, true); + * + * will create a rotation around the `(0, 0)` axis. + * + * + * ## Scaling * * For scaling, the configuration object contains x and y attributes for the x-axis and y-axis scaling. For example: * @@ -58575,6 +59657,22 @@ Ext.define('Ext.draw.SpriteDD', { * } * }, true); * + * You can also specify the center of scaling by adding `cx` and `cy` as properties: + * + * sprite.setAttributes({ + * scale: { + * cx: 0, + * cy: 0, + * x: 10, + * y: 3 + * } + * }, true); + * + * That last example will scale a sprite taking as centers of scaling the `(0, 0)` coordinate. + * + * + * ## Creating and adding a Sprite to a Surface + * * Sprites can be created with a reference to a {@link Ext.draw.Surface} * * var drawComponent = Ext.create('Ext.draw.Component', options here...); @@ -58611,6 +59709,68 @@ Ext.define('Ext.draw.SpriteDD', { * }); */ Ext.define('Ext.draw.Sprite', { + + /** + * @cfg {String} type The type of the sprite. Possible options are 'circle', 'path', 'rect', 'text', 'square', 'image' + */ + + /** + * @cfg {Number} width Used in rectangle sprites, the width of the rectangle + */ + + /** + * @cfg {Number} height Used in rectangle sprites, the height of the rectangle + */ + + /** + * @cfg {Number} size Used in square sprites, the dimension of the square + */ + + /** + * @cfg {Number} radius Used in circle sprites, the radius of the circle + */ + + /** + * @cfg {Number} x The position along the x-axis + */ + + /** + * @cfg {Number} y The position along the y-axis + */ + + /** + * @cfg {Array} path Used in path sprites, the path of the sprite written in SVG-like path syntax + */ + + /** + * @cfg {Number} opacity The opacity of the sprite + */ + + /** + * @cfg {String} fill The fill color + */ + + /** + * @cfg {String} stroke The stroke color + */ + + /** + * @cfg {Number} stroke-width The width of the stroke + */ + + /** + * @cfg {String} font Used with text type sprites. The full font description. Uses the same syntax as the CSS font parameter + */ + + /** + * @cfg {String} text Used with text type sprites. The text itself + */ + + /** + * @cfg {String/Array} group The group that this sprite belongs to, or an array of groups. Only relevant when added to a + * {@link Ext.draw.Surface} + */ + /* Begin Definitions */ mixins: { @@ -58953,6 +60113,8 @@ Ext.define('Ext.draw.engine.Svg', { strokeOpacity: "stroke-opacity", strokeLinejoin: "stroke-linejoin" }, + + parsers: {}, minDefaults: { circle: { @@ -59361,6 +60523,12 @@ Ext.define('Ext.draw.engine.Svg', { el = sprite.el, group = sprite.group, sattr = sprite.attr, + parsers = me.parsers, + //Safari does not handle linear gradients correctly in quirksmode + //ref: https://bugs.webkit.org/show_bug.cgi?id=41952 + //ref: EXTJSIV-1472 + gradientsMap = me.gradientsMap || {}, + safariFix = Ext.isSafari && !Ext.isStrict, groups, i, ln, attrs, font, key, style, name, rect; if (group) { @@ -59386,7 +60554,6 @@ Ext.define('Ext.draw.engine.Svg', { } else if (sprite.type == "path" && attrs.d) { attrs.d = Ext.draw.Draw.pathToString(Ext.draw.Draw.pathToAbsolute(attrs.d)); - } sprite.dirtyPath = false; // } @@ -59413,9 +60580,22 @@ Ext.define('Ext.draw.engine.Svg', { } for (key in attrs) { if (attrs.hasOwnProperty(key) && attrs[key] != null) { - el.dom.setAttribute(key, attrs[key]); + //Safari does not handle linear gradients correctly in quirksmode + //ref: https://bugs.webkit.org/show_bug.cgi?id=41952 + //ref: EXTJSIV-1472 + //if we're Safari in QuirksMode and we're applying some color attribute and the value of that + //attribute is a reference to a gradient then assign a plain color to that value instead of the gradient. + if (safariFix && ('color|stroke|fill'.indexOf(key) > -1) && (attrs[key] in gradientsMap)) { + attrs[key] = gradientsMap[attrs[key]]; + } + if (key in parsers) { + el.dom.setAttribute(key, parsers[key](attrs[key], sprite, me)); + } else { + el.dom.setAttribute(key, attrs[key]); + } } } + if (sprite.type == 'text') { me.tuneText(sprite, attrs); } @@ -59493,40 +60673,49 @@ Ext.define('Ext.draw.engine.Svg', { addGradient: function(gradient) { gradient = Ext.draw.Draw.parseGradient(gradient); - var ln = gradient.stops.length, + var me = this, + ln = gradient.stops.length, vector = gradient.vector, - gradientEl, - stop, - stopEl, - i; - if (gradient.type == "linear") { - gradientEl = this.createSvgElement("linearGradient"); - gradientEl.setAttribute("x1", vector[0]); - gradientEl.setAttribute("y1", vector[1]); - gradientEl.setAttribute("x2", vector[2]); - gradientEl.setAttribute("y2", vector[3]); - } - else { - gradientEl = this.createSvgElement("radialGradient"); - gradientEl.setAttribute("cx", gradient.centerX); - gradientEl.setAttribute("cy", gradient.centerY); - gradientEl.setAttribute("r", gradient.radius); - if (Ext.isNumber(gradient.focalX) && Ext.isNumber(gradient.focalY)) { - gradientEl.setAttribute("fx", gradient.focalX); - gradientEl.setAttribute("fy", gradient.focalY); + //Safari does not handle linear gradients correctly in quirksmode + //ref: https://bugs.webkit.org/show_bug.cgi?id=41952 + //ref: EXTJSIV-1472 + usePlain = Ext.isSafari && !Ext.isStrict, + gradientEl, stop, stopEl, i, gradientsMap; + + gradientsMap = me.gradientsMap || {}; + + if (!usePlain) { + if (gradient.type == "linear") { + gradientEl = me.createSvgElement("linearGradient"); + gradientEl.setAttribute("x1", vector[0]); + gradientEl.setAttribute("y1", vector[1]); + gradientEl.setAttribute("x2", vector[2]); + gradientEl.setAttribute("y2", vector[3]); } - } - gradientEl.id = gradient.id; - this.getDefs().appendChild(gradientEl); - - for (i = 0; i < ln; i++) { - stop = gradient.stops[i]; - stopEl = this.createSvgElement("stop"); - stopEl.setAttribute("offset", stop.offset + "%"); - stopEl.setAttribute("stop-color", stop.color); - stopEl.setAttribute("stop-opacity",stop.opacity); - gradientEl.appendChild(stopEl); + else { + gradientEl = me.createSvgElement("radialGradient"); + gradientEl.setAttribute("cx", gradient.centerX); + gradientEl.setAttribute("cy", gradient.centerY); + gradientEl.setAttribute("r", gradient.radius); + if (Ext.isNumber(gradient.focalX) && Ext.isNumber(gradient.focalY)) { + gradientEl.setAttribute("fx", gradient.focalX); + gradientEl.setAttribute("fy", gradient.focalY); + } + } + gradientEl.id = gradient.id; + me.getDefs().appendChild(gradientEl); + for (i = 0; i < ln; i++) { + stop = gradient.stops[i]; + stopEl = me.createSvgElement("stop"); + stopEl.setAttribute("offset", stop.offset + "%"); + stopEl.setAttribute("stop-color", stop.color); + stopEl.setAttribute("stop-opacity",stop.opacity); + gradientEl.appendChild(stopEl); + } + } else { + gradientsMap['url(#' + gradient.id + ')'] = gradient.stops[0].color; } + me.gradientsMap = gradientsMap; }, /** @@ -59580,7 +60769,7 @@ Ext.define('Ext.draw.engine.Svg', { cls = cls.replace(me.trimRe, ''); idx = Ext.Array.indexOf(elClasses, cls); if (idx != -1) { - elClasses.splice(idx, 1); + Ext.Array.erase(elClasses, idx, 1); } } } @@ -60193,64 +61382,77 @@ Ext.define('Ext.draw.engine.Vml', { }, setSize: function(width, height) { - var me = this, - viewBox = me.viewBox, - scaleX, scaleY, items, i, len; + var me = this; width = width || me.width; height = height || me.height; me.width = width; me.height = height; - if (!me.el) { - return; - } + if (me.el) { + // Size outer div + if (width != undefined) { + me.el.setWidth(width); + } + if (height != undefined) { + me.el.setHeight(height); + } - // Size outer div - if (width != undefined) { - me.el.setWidth(width); - } - if (height != undefined) { - me.el.setHeight(height); + // Handle viewBox sizing + me.applyViewBox(); + + me.callParent(arguments); } + }, + + setViewBox: function(x, y, width, height) { + this.callParent(arguments); + this.viewBox = { + x: x, + y: y, + width: width, + height: height + }; + this.applyViewBox(); + }, + + /** + * @private Using the current viewBox property and the surface's width and height, calculate the + * appropriate viewBoxShift that will be applied as a persistent transform to all sprites. + */ + applyViewBox: function() { + var me = this, + viewBox = me.viewBox, + width = me.width, + height = me.height, + viewBoxX, viewBoxY, viewBoxWidth, viewBoxHeight, + relativeHeight, relativeWidth, size; - // Handle viewBox sizing if (viewBox && (width || height)) { - var viewBoxX = viewBox.x, - viewBoxY = viewBox.y, - viewBoxWidth = viewBox.width, - viewBoxHeight = viewBox.height, - relativeHeight = height / viewBoxHeight, - relativeWidth = width / viewBoxWidth, - size; + viewBoxX = viewBox.x; + viewBoxY = viewBox.y; + viewBoxWidth = viewBox.width; + viewBoxHeight = viewBox.height; + relativeHeight = height / viewBoxHeight; + relativeWidth = width / viewBoxWidth; + if (viewBoxWidth * relativeHeight < width) { viewBoxX -= (width - viewBoxWidth * relativeHeight) / 2 / relativeHeight; } if (viewBoxHeight * relativeWidth < height) { viewBoxY -= (height - viewBoxHeight * relativeWidth) / 2 / relativeWidth; } + size = 1 / Math.max(viewBoxWidth / width, viewBoxHeight / height); - // Scale and translate group + me.viewBoxShift = { dx: -viewBoxX, dy: -viewBoxY, scale: size }; - items = me.items.items; - for (i = 0, len = items.length; i < len; i++) { - me.transform(items[i]); - } + me.items.each(function(item) { + me.transform(item); + }); } - this.callParent(arguments); - }, - - setViewBox: function(x, y, width, height) { - this.callParent(arguments); - this.viewBox = { - x: x, - y: y, - width: width, - height: height - }; }, onAdd: function(item) { @@ -60686,43 +61888,51 @@ Ext.define('Ext.layout.container.Fit', { setItemBox : function(item, box) { var me = this; if (item && box.height > 0) { - if (me.isManaged('width') === true) { + if (!me.owner.isFixedWidth()) { box.width = undefined; } - if (me.isManaged('height') === true) { + if (!me.owner.isFixedHeight()) { box.height = undefined; } me.setItemSize(item, box.width, box.height); } + }, + + configureItem: function(item) { + + // Card layout only controls dimensions which IT has controlled. + // That calculation has to be determined at run time by examining the ownerCt's isFixedWidth()/isFixedHeight() methods + item.layoutManagedHeight = 0; + item.layoutManagedWidth = 0; + + this.callParent(arguments); } }); /** - * @class Ext.layout.container.AbstractCard - * @extends Ext.layout.container.Fit - *This layout manages multiple child Components, each is fit to the Container, where only a single child Component + * This layout manages multiple child Components, each is fit to the Container, where only a single child Component * can be visible at any given time. This layout style is most commonly used for wizards, tab implementations, etc. * This class is intended to be extended or created via the layout:'card' {@link Ext.container.Container#layout} config, - * and should generally not need to be created directly via the new keyword.
- *The CardLayout's focal method is {@link #setActiveItem}. Since only one panel is displayed at a time, + * and should generally not need to be created directly via the new keyword. + * + * The CardLayout's focal method is {@link #setActiveItem}. Since only one panel is displayed at a time, * the only way to move from one Component to the next is by calling setActiveItem, passing the id or index of * the next panel to display. The layout itself does not provide a user interface for handling this navigation, - * so that functionality must be provided by the developer.
- *Containers that are configured with a card layout will have a method setActiveItem dynamically added to it. - *
- var p = new Ext.panel.Panel({
- fullscreen: true,
- layout: 'card',
- items: [{
- html: 'Card 1'
- },{
- html: 'Card 2'
- }]
- });
- p.setActiveItem(1);
-
- *
+ * so that functionality must be provided by the developer.
+ *
+ * Containers that are configured with a card layout will have a method setActiveItem dynamically added to it.
+ *
+ * var p = new Ext.panel.Panel({
+ * fullscreen: true,
+ * layout: 'card',
+ * items: [{
+ * html: 'Card 1'
+ * },{
+ * html: 'Card 2'
+ * }]
+ * });
+ * p.setActiveItem(1);
+ *
*/
-
Ext.define('Ext.layout.container.AbstractCard', {
/* Begin Definitions */
@@ -60847,12 +62057,12 @@ Ext.define('Ext.layout.container.AbstractCard', {
/**
* Return the active (visible) component in the layout to the next card
- * @returns {Ext.Component}
+ * @returns {Ext.Component} The next component or false.
*/
- getNext: function(wrap) {
+ getNext: function() {
//NOTE: Removed the JSDoc for this function's arguments because it is not actually supported in 4.0. This
//should come back in 4.1
-
+ var wrap = arguments[0];
var items = this.getLayoutItems(),
index = Ext.Array.indexOf(items, this.activeItem);
return items[index + 1] || (wrap ? items[0] : false);
@@ -60860,22 +62070,23 @@ Ext.define('Ext.layout.container.AbstractCard', {
/**
* Sets the active (visible) component in the layout to the next card
+ * @return {Ext.Component} the activated component or false when nothing activated.
*/
- next: function(anim, wrap) {
+ next: function() {
//NOTE: Removed the JSDoc for this function's arguments because it is not actually supported in 4.0. This
//should come back in 4.1
-
+ var anim = arguments[0], wrap = arguments[1];
return this.setActiveItem(this.getNext(wrap), anim);
},
/**
* Return the active (visible) component in the layout to the previous card
- * @returns {Ext.Component}
+ * @returns {Ext.Component} The previous component or false.
*/
- getPrev: function(wrap) {
+ getPrev: function() {
//NOTE: Removed the JSDoc for this function's arguments because it is not actually supported in 4.0. This
//should come back in 4.1
-
+ var wrap = arguments[0];
var items = this.getLayoutItems(),
index = Ext.Array.indexOf(items, this.activeItem);
return items[index - 1] || (wrap ? items[items.length - 1] : false);
@@ -60883,11 +62094,12 @@ Ext.define('Ext.layout.container.AbstractCard', {
/**
* Sets the active (visible) component in the layout to the previous card
+ * @return {Ext.Component} the activated component or false when nothing activated.
*/
- prev: function(anim, wrap) {
+ prev: function() {
//NOTE: Removed the JSDoc for this function's arguments because it is not actually supported in 4.0. This
//should come back in 4.1
-
+ var anim = arguments[0], wrap = arguments[1];
return this.setActiveItem(this.getPrev(wrap), anim);
}
});
@@ -60909,7 +62121,7 @@ Ext.define('Ext.layout.container.AbstractCard', {
*/
Ext.define('Ext.selection.Model', {
extend: 'Ext.util.Observable',
- alternateClassName: 'Ext.AbstractStoreSelectionModel',
+ alternateClassName: 'Ext.AbstractSelectionModel',
requires: ['Ext.data.StoreManager'],
// lastSelected
@@ -60918,7 +62130,7 @@ Ext.define('Ext.selection.Model', {
* Modes of selection.
* Valid values are SINGLE, SIMPLE, and MULTI. Defaults to 'SINGLE'
*/
-
+
/**
* @cfg {Boolean} allowDeselect
* Allow users to deselect a record in a DataView, List or Grid. Only applicable when the SelectionModel's mode is 'SINGLE'. Defaults to false.
@@ -60931,8 +62143,8 @@ Ext.define('Ext.selection.Model', {
* records.
*/
selected: null,
-
-
+
+
/**
* Prune records when they are removed from the store from the selection.
* This is a private flag. For an example of its usage, take a look at
@@ -60943,10 +62155,10 @@ Ext.define('Ext.selection.Model', {
constructor: function(cfg) {
var me = this;
-
+
cfg = cfg || {};
Ext.apply(me, cfg);
-
+
me.addEvents(
/**
* @event selectionchange
@@ -60968,14 +62180,14 @@ Ext.define('Ext.selection.Model', {
// maintains the currently selected records.
me.selected = Ext.create('Ext.util.MixedCollection');
-
+
me.callParent(arguments);
},
// binds the store to the selModel.
bind : function(store, initial){
var me = this;
-
+
if(!initial && me.store){
if(store !== me.store && me.store.autoDestroy){
me.store.destroy();
@@ -61012,7 +62224,7 @@ Ext.define('Ext.selection.Model', {
i = 0,
len = selections.length,
start = me.getSelection().length;
-
+
me.bulkChange = true;
for (; i < len; i++) {
me.doSelect(selections[i], true, suppressEvent);
@@ -61032,7 +62244,7 @@ Ext.define('Ext.selection.Model', {
i = 0,
len = selections.length,
start = me.getSelection().length;
-
+
me.bulkChange = true;
for (; i < len; i++) {
me.doDeselect(selections[i], suppressEvent);
@@ -61045,9 +62257,9 @@ Ext.define('Ext.selection.Model', {
// Provides differentiation of logic between MULTI, SIMPLE and SINGLE
// selection modes. Requires that an event be passed so that we can know
// if user held ctrl or shift.
- selectWithEvent: function(record, e) {
+ selectWithEvent: function(record, e, keepExisting) {
var me = this;
-
+
switch (me.selectionMode) {
case 'MULTI':
if (e.ctrlKey && me.isSelected(record)) {
@@ -61057,7 +62269,7 @@ Ext.define('Ext.selection.Model', {
} else if (e.ctrlKey) {
me.doSelect(record, true, false);
} else if (me.isSelected(record) && !e.shiftKey && !e.ctrlKey && me.selected.getCount() > 1) {
- me.doSelect(record, false, false);
+ me.doSelect(record, keepExisting, false);
} else {
me.doSelect(record, false);
}
@@ -61096,22 +62308,22 @@ Ext.define('Ext.selection.Model', {
tmp,
dontDeselect,
records = [];
-
+
if (me.isLocked()){
return;
}
-
+
if (!keepExisting) {
- me.clearSelections();
+ me.deselectAll(true);
}
-
+
if (!Ext.isNumber(startRow)) {
startRow = store.indexOf(startRow);
- }
+ }
if (!Ext.isNumber(endRow)) {
endRow = store.indexOf(endRow);
}
-
+
// swap values
if (startRow > endRow){
tmp = endRow;
@@ -61130,7 +62342,7 @@ Ext.define('Ext.selection.Model', {
} else {
dontDeselect = (dir == 'up') ? startRow : endRow;
}
-
+
for (i = startRow; i <= endRow; i++){
if (selectedCount == (endRow - startRow + 1)) {
if (i != dontDeselect) {
@@ -61142,7 +62354,7 @@ Ext.define('Ext.selection.Model', {
}
me.doMultiSelect(records, true);
},
-
+
/**
* Selects a record instance by record instance or index.
* @param {Ext.data.Model/Index} records An array of records or an index
@@ -61161,11 +62373,11 @@ Ext.define('Ext.selection.Model', {
deselect: function(records, suppressEvent) {
this.doDeselect(records, suppressEvent);
},
-
+
doSelect: function(records, keepExisting, suppressEvent) {
var me = this,
record;
-
+
if (me.locked) {
return;
}
@@ -61186,17 +62398,24 @@ Ext.define('Ext.selection.Model', {
change = false,
i = 0,
len, record;
-
+
if (me.locked) {
return;
}
-
+
records = !Ext.isArray(records) ? [records] : records;
len = records.length;
if (!keepExisting && selected.getCount() > 0) {
+ if (me.doDeselect(me.getSelection(), suppressEvent) === false) {
+ return;
+ }
+ // TODO - coalesce the selectionchange event in deselect w/the one below...
+ }
+
+ function commit () {
+ selected.add(record);
change = true;
- me.doDeselect(me.getSelection(), suppressEvent);
}
for (; i < len; i++) {
@@ -61204,11 +62423,9 @@ Ext.define('Ext.selection.Model', {
if (keepExisting && me.isSelected(record)) {
continue;
}
- change = true;
me.lastSelected = record;
- selected.add(record);
- me.onSelectChange(record, true, suppressEvent);
+ me.onSelectChange(record, true, suppressEvent, commit);
}
me.setLastFocused(record, suppressEvent);
// fire selchange if there was a change and there is no suppressEvent flag
@@ -61219,38 +62436,49 @@ Ext.define('Ext.selection.Model', {
doDeselect: function(records, suppressEvent) {
var me = this,
selected = me.selected,
- change = false,
i = 0,
- len, record;
-
+ len, record,
+ attempted = 0,
+ accepted = 0;
+
if (me.locked) {
- return;
+ return false;
}
if (typeof records === "number") {
records = [me.store.getAt(records)];
+ } else if (!Ext.isArray(records)) {
+ records = [records];
+ }
+
+ function commit () {
+ ++accepted;
+ selected.remove(record);
}
- records = !Ext.isArray(records) ? [records] : records;
len = records.length;
+
for (; i < len; i++) {
record = records[i];
- if (selected.remove(record)) {
+ if (me.isSelected(record)) {
if (me.lastSelected == record) {
me.lastSelected = selected.last();
}
- me.onSelectChange(record, false, suppressEvent);
- change = true;
+ ++attempted;
+ me.onSelectChange(record, false, suppressEvent, commit);
}
}
+
// fire selchange if there was a change and there is no suppressEvent flag
- me.maybeFireSelectionChange(change && !suppressEvent);
+ me.maybeFireSelectionChange(accepted > 0 && !suppressEvent);
+ return accepted === attempted;
},
doSingleSelect: function(record, suppressEvent) {
var me = this,
+ changed = false,
selected = me.selected;
-
+
if (me.locked) {
return;
}
@@ -61259,16 +62487,28 @@ Ext.define('Ext.selection.Model', {
if (me.isSelected(record)) {
return;
}
- if (selected.getCount() > 0) {
- me.doDeselect(me.lastSelected, suppressEvent);
+
+ function commit () {
+ me.bulkChange = true;
+ if (selected.getCount() > 0 && me.doDeselect(me.lastSelected, suppressEvent) === false) {
+ delete me.bulkChange;
+ return false;
+ }
+ delete me.bulkChange;
+
+ selected.add(record);
+ me.lastSelected = record;
+ changed = true;
}
- selected.add(record);
- me.lastSelected = record;
- me.onSelectChange(record, true, suppressEvent);
- if (!suppressEvent) {
- me.setLastFocused(record);
+
+ me.onSelectChange(record, true, suppressEvent, commit);
+
+ if (changed) {
+ if (!suppressEvent) {
+ me.setLastFocused(record);
+ }
+ me.maybeFireSelectionChange(!suppressEvent);
}
- me.maybeFireSelectionChange(!suppressEvent);
},
/**
@@ -61282,7 +62522,7 @@ Ext.define('Ext.selection.Model', {
me.lastFocused = record;
me.onLastFocusChanged(recordBeforeLast, record, supressFocus);
},
-
+
/**
* Determines if this record is currently focused.
* @param Ext.data.Record record
@@ -61307,13 +62547,14 @@ Ext.define('Ext.selection.Model', {
getLastSelected: function() {
return this.lastSelected;
},
-
+
getLastFocused: function() {
return this.lastFocused;
},
/**
* Returns an array of the currently selected records.
+ * @return {Array} The selected records
*/
getSelection: function() {
return this.selected.getRange();
@@ -61321,6 +62562,7 @@ Ext.define('Ext.selection.Model', {
/**
* Returns the current selectionMode. SINGLE, MULTI or SIMPLE.
+ * @return {String} The selectionMode
*/
getSelectionMode: function() {
return this.selectionMode;
@@ -61362,9 +62604,9 @@ Ext.define('Ext.selection.Model', {
record = Ext.isNumber(record) ? this.store.getAt(record) : record;
return this.selected.indexOf(record) !== -1;
},
-
+
/**
- * Returns true if there is a selected record.
+ * Returns true if there are any a selected records.
* @return {Boolean}
*/
hasSelection: function() {
@@ -61398,7 +62640,7 @@ Ext.define('Ext.selection.Model', {
}
me.clearSelections();
-
+
if (me.store.indexOf(lastFocused) !== -1) {
// restore the last focus but supress restoring focus
this.setLastFocused(lastFocused, true);
@@ -61408,7 +62650,7 @@ Ext.define('Ext.selection.Model', {
// perform the selection again
me.doSelect(toBeSelected, false, true);
}
-
+
me.maybeFireSelectionChange(change);
},
@@ -61419,10 +62661,9 @@ Ext.define('Ext.selection.Model', {
*/
clearSelections: function() {
// reset the entire selection to nothing
- var me = this;
- me.selected.clear();
- me.lastSelected = null;
- me.setLastFocused(null);
+ this.selected.clear();
+ this.lastSelected = null;
+ this.setLastFocused(null);
},
// when a record is added to a store
@@ -61433,14 +62674,9 @@ Ext.define('Ext.selection.Model', {
// when a store is cleared remove all selections
// (if there were any)
onStoreClear: function() {
- var me = this,
- selected = this.selected;
-
- if (selected.getCount > 0) {
- selected.clear();
- me.lastSelected = null;
- me.setLastFocused(null);
- me.maybeFireSelectionChange(true);
+ if (this.selected.getCount > 0) {
+ this.clearSelections();
+ this.maybeFireSelectionChange(true);
}
},
@@ -61450,7 +62686,7 @@ Ext.define('Ext.selection.Model', {
onStoreRemove: function(store, record) {
var me = this,
selected = me.selected;
-
+
if (me.locked || !me.pruneRemoved) {
return;
}
@@ -61466,6 +62702,10 @@ Ext.define('Ext.selection.Model', {
}
},
+ /**
+ * Gets the count of selected records.
+ * @return {Number} The number of selected records
+ */
getCount: function() {
return this.selected.getCount();
},
@@ -61506,20 +62746,38 @@ Ext.define('Ext.selection.Model', {
*/
Ext.define('Ext.selection.DataViewModel', {
extend: 'Ext.selection.Model',
-
+
requires: ['Ext.util.KeyNav'],
deselectOnContainerClick: true,
-
+
/**
* @cfg {Boolean} enableKeyNav
- *
+ *
* Turns on/off keyboard navigation within the DataView. Defaults to true.
*/
enableKeyNav: true,
-
+
constructor: function(cfg){
this.addEvents(
+ /**
+ * @event beforedeselect
+ * Fired before a record is deselected. If any listener returns false, the
+ * deselection is cancelled.
+ * @param {Ext.selection.DataViewModel} this
+ * @param {Ext.data.Model} record The deselected record
+ */
+ 'beforedeselect',
+
+ /**
+ * @event beforeselect
+ * Fired before a record is selected. If any listener returns false, the
+ * selection is cancelled.
+ * @param {Ext.selection.DataViewModel} this
+ * @param {Ext.data.Model} record The selected record
+ */
+ 'beforeselect',
+
/**
* @event deselect
* Fired after a record is deselected
@@ -61527,7 +62785,7 @@ Ext.define('Ext.selection.DataViewModel', {
* @param {Ext.data.Model} record The deselected record
*/
'deselect',
-
+
/**
* @event select
* Fired after a record is selected
@@ -61538,7 +62796,7 @@ Ext.define('Ext.selection.DataViewModel', {
);
this.callParent(arguments);
},
-
+
bindComponent: function(view) {
var me = this,
eventListeners = {
@@ -61568,15 +62826,15 @@ Ext.define('Ext.selection.DataViewModel', {
this.deselectAll();
}
},
-
+
initKeyNav: function(view) {
var me = this;
-
+
if (!view.rendered) {
view.on('render', Ext.Function.bind(me.initKeyNav, me, [view], 0), me, {single: true});
return;
}
-
+
view.el.set({
tabIndex: -1
});
@@ -61588,7 +62846,7 @@ Ext.define('Ext.selection.DataViewModel', {
scope: me
});
},
-
+
onNavKey: function(step) {
step = step || 1;
var me = this,
@@ -61596,42 +62854,39 @@ Ext.define('Ext.selection.DataViewModel', {
selected = me.getSelection()[0],
numRecords = me.view.store.getCount(),
idx;
-
+
if (selected) {
idx = view.indexOf(view.getNode(selected)) + step;
} else {
idx = 0;
}
-
+
if (idx < 0) {
idx = numRecords - 1;
} else if (idx >= numRecords) {
idx = 0;
}
-
+
me.select(idx);
},
// Allow the DataView to update the ui
- onSelectChange: function(record, isSelected, suppressEvent) {
+ onSelectChange: function(record, isSelected, suppressEvent, commitFn) {
var me = this,
view = me.view,
- allowSelect = true;
-
- if (isSelected) {
- if (!suppressEvent) {
- allowSelect = me.fireEvent('beforeselect', me, record) !== false;
- }
- if (allowSelect) {
+ eventName = isSelected ? 'select' : 'deselect';
+
+ if ((suppressEvent || me.fireEvent('before' + eventName, me, record)) !== false &&
+ commitFn() !== false) {
+
+ if (isSelected) {
view.onItemSelect(record);
- if (!suppressEvent) {
- me.fireEvent('select', me, record);
- }
+ } else {
+ view.onItemDeselect(record);
}
- } else {
- view.onItemDeselect(record);
+
if (!suppressEvent) {
- me.fireEvent('deselect', me, record);
+ me.fireEvent(eventName, me, record);
}
}
}
@@ -61665,13 +62920,14 @@ Ext.define('Ext.selection.DataViewModel', {
* all sub-domains if you need to access cookies across different sub-domains (defaults to null which uses the same
* domain the page is running on including the 'www' like 'www.sencha.com')
* @cfg {Boolean} secure True if the site is using SSL (defaults to false)
- * @constructor
- * Create a new CookieProvider
- * @param {Object} config The configuration object
*/
Ext.define('Ext.state.CookieProvider', {
extend: 'Ext.state.Provider',
+ /**
+ * Creates a new CookieProvider.
+ * @param {Object} config (optional) Config object.
+ */
constructor : function(config){
var me = this;
me.path = "/";
@@ -61743,6 +62999,14 @@ Ext.define('Ext.state.CookieProvider', {
}
});
+/**
+ * @class Ext.state.LocalStorageProvider
+ * @extends Ext.state.Provider
+ * A Provider implementation which saves and retrieves state via the HTML5 localStorage object.
+ * If the browser does not support local storage, an exception will be thrown upon instantiating
+ * this class.
+ */
+
Ext.define('Ext.state.LocalStorageProvider', {
/* Begin Definitions */
@@ -61921,17 +63185,17 @@ Ext.define('Ext.view.AbstractView', {
'Ext.DomQuery',
'Ext.selection.DataViewModel'
],
-
+
inheritableStatics: {
getRecord: function(node) {
return this.getBoundView(node).getRecord(node);
},
-
+
getBoundView: function(node) {
return Ext.getCmp(node.boundView);
}
},
-
+
/**
* @cfg {String/Array/Ext.XTemplate} tpl
* @required
@@ -61952,14 +63216,14 @@ Ext.define('Ext.view.AbstractView', {
* working with. The itemSelector is used to map DOM nodes to records. As such, there should
* only be one root level element that matches the selector for each record.
*/
-
+
/**
* @cfg {String} itemCls
* Specifies the class to be assigned to each element in the view when used in conjunction with the
* {@link #itemTpl} configuration.
*/
itemCls: Ext.baseCSSPrefix + 'dataview-item',
-
+
/**
* @cfg {String/Array/Ext.XTemplate} itemTpl
* The inner portion of the item template to be rendered. Follows an XTemplate
@@ -61968,7 +63232,7 @@ Ext.define('Ext.view.AbstractView', {
/**
* @cfg {String} overItemCls
- * A CSS class to apply to each item in the view on mouseover (defaults to undefined).
+ * A CSS class to apply to each item in the view on mouseover (defaults to undefined).
* Ensure {@link #trackOver} is set to `true` to make use of this.
*/
@@ -61980,18 +63244,25 @@ Ext.define('Ext.view.AbstractView', {
*/
loadingText: 'Loading...',
+ /**
+ * @cfg {Boolean/Object} loadMask
+ * False to disable a load mask from displaying will the view is loading. This can also be a
+ * {@link Ext.LoadMask} configuration object. Defaults to true.
+ */
+ loadMask: true,
+
/**
* @cfg {String} loadingCls
* The CSS class to apply to the loading message element (defaults to Ext.LoadMask.prototype.msgCls "x-mask-loading")
*/
-
+
/**
* @cfg {Boolean} loadingUseMsg
* Whether or not to use the loading message.
* @private
*/
loadingUseMsg: true,
-
+
/**
* @cfg {Number} loadingHeight
@@ -62038,12 +63309,12 @@ Ext.define('Ext.view.AbstractView', {
//private
last: false,
-
+
triggerEvent: 'itemclick',
triggerCtEvent: 'containerclick',
-
+
addCmpEvents: function() {
-
+
},
// private
@@ -62052,7 +63323,7 @@ Ext.define('Ext.view.AbstractView', {
isDef = Ext.isDefined,
itemTpl = me.itemTpl,
memberFn = {};
-
+
if (itemTpl) {
if (Ext.isArray(itemTpl)) {
// string array
@@ -62062,11 +63333,11 @@ Ext.define('Ext.view.AbstractView', {
memberFn = Ext.apply(memberFn, itemTpl.initialConfig);
itemTpl = itemTpl.html;
}
-
+
if (!me.itemSelector) {
me.itemSelector = '.' + me.itemCls;
}
-
+
itemTpl = Ext.String.format('Function which can be overridden which returns the data object passed to this * DataView's {@link #tpl template} to render the whole DataView.
@@ -62297,12 +63590,13 @@ Ext.define('Ext.view.AbstractView', { collectData : function(records, startIndex){ var r = [], i = 0, - len = records.length; + len = records.length, + record; for(; i < len; i++){ - r[r.length] = this.prepareData(records[i].data, startIndex + i, records[i]); + record = records[i]; + r[r.length] = this.prepareData(record[record.persistenceProperty], startIndex + i, record); } - return r; }, @@ -62317,11 +63611,9 @@ Ext.define('Ext.view.AbstractView', { onUpdate : function(ds, record){ var me = this, index = me.store.indexOf(record), - original, node; if (index > -1){ - original = me.all.elements[index]; node = me.bufferRender([record], index)[0]; me.all.replaceElement(index, node, true); @@ -62339,12 +63631,12 @@ Ext.define('Ext.view.AbstractView', { onAdd : function(ds, records, index) { var me = this, nodes; - + if (me.all.getCount() === 0) { me.refresh(); return; } - + nodes = me.bufferRender(records, index); me.doAdd(nodes, records, index); @@ -62354,21 +63646,22 @@ Ext.define('Ext.view.AbstractView', { }, doAdd: function(nodes, records, index) { - var n, a = this.all.elements; - if (index < this.all.getCount()) { - n = this.all.item(index).insertSibling(nodes, 'before', true); - a.splice.apply(a, [index, 0].concat(nodes)); - } + var all = this.all; + + if (index < all.getCount()) { + all.item(index).insertSibling(nodes, 'before', true); + } else { - n = this.all.last().insertSibling(nodes, 'after', true); - a.push.apply(a, nodes); - } + all.last().insertSibling(nodes, 'after', true); + } + + Ext.Array.insert(all.elements, index, nodes); }, - + // private onRemove : function(ds, record, index) { var me = this; - + me.doRemove(record, index); me.updateIndexes(index); if (me.store.getCount() === 0){ @@ -62376,7 +63669,7 @@ Ext.define('Ext.view.AbstractView', { } me.fireEvent('itemremove', record, index); }, - + doRemove: function(record, index) { this.all.removeElement(index, true); }, @@ -62418,11 +63711,11 @@ Ext.define('Ext.view.AbstractView', { */ bindStore : function(store, initial) { var me = this; - + if (!initial && me.store) { if (store !== me.store && me.store.autoDestroy) { me.store.destroy(); - } + } else { me.mun(me.store, { scope: me, @@ -62454,12 +63747,12 @@ Ext.define('Ext.view.AbstractView', { me.loadMask.bindStore(store); } } - + me.store = store; // Bind the store to our selection model me.getSelectionModel().bind(store); - - if (store) { + + if (store && (!initial || store.getCount())) { me.refresh(true); } }, @@ -62482,7 +63775,7 @@ Ext.define('Ext.view.AbstractView', { findItemByChild: function(node){ return Ext.fly(node).findParent(this.getItemSelector(), this.getTargetEl()); }, - + /** * Returns the template node by the Ext.EventObject or null if it is not found. * @param {Ext.EventObject} e @@ -62530,13 +63823,13 @@ Ext.define('Ext.view.AbstractView', { /** * Gets a record from a node * @param {Element/HTMLElement} node The node to evaluate - * + * * @return {Record} record The {@link Ext.data.Model} object */ getRecord: function(node){ return this.store.data.getByKey(Ext.getDom(node).viewRecordId); }, - + /** * Returns true if the passed node is selected, else false. @@ -62548,7 +63841,7 @@ Ext.define('Ext.view.AbstractView', { var r = this.getRecord(node); return this.selModel.isSelected(r); }, - + /** * Selects a record instance by record instance or index. * @param {Ext.data.Model/Index} records An array of records or an index @@ -62584,7 +63877,7 @@ Ext.define('Ext.view.AbstractView', { } return nodeInfo; }, - + /** * @private */ @@ -62592,16 +63885,16 @@ Ext.define('Ext.view.AbstractView', { var ns = this.all.elements, ln = ns.length, i = 0; - + for (; i < ln; i++) { if (ns[i].viewRecordId === record.internalId) { return ns[i]; } } - + return null; }, - + /** * Gets a range nodes. * @param {Number} start (optional) The index of the first node in the range @@ -62643,7 +63936,7 @@ Ext.define('Ext.view.AbstractView', { onDestroy : function() { var me = this; - + me.all.clear(); me.callParent(); me.bindStore(null); @@ -62661,7 +63954,7 @@ Ext.define('Ext.view.AbstractView', { var node = this.getNode(record); Ext.fly(node).removeCls(this.selectedItemCls); }, - + getItemSelector: function() { return this.itemSelector; } @@ -62687,7 +63980,7 @@ Ext.define('Ext.view.AbstractView', { * True to enable multiselection by clicking on multiple items without requiring the user to hold Shift or Ctrl, * false to force the user to hold Ctrl or Shift to select more than on item (defaults to false). */ - + /** * Gets the number of selected nodes. * @return {Number} The node count @@ -62698,7 +63991,7 @@ Ext.define('Ext.view.AbstractView', { } return this.selModel.getSelection().length; }, - + /** * Gets an array of the selected records * @return {Array} An array of {@link Ext.data.Model} objects @@ -62709,7 +64002,7 @@ Ext.define('Ext.view.AbstractView', { } return this.selModel.getSelection(); }, - + select: function(records, keepExisting, supressEvents) { if (Ext.global.console) { Ext.global.console.warn("DataView: select will be removed, please access select through a DataView's SelectionModel, ie: view.getSelectionModel().select()"); @@ -62717,7 +64010,7 @@ Ext.define('Ext.view.AbstractView', { var sm = this.getSelectionModel(); return sm.select.apply(sm, arguments); }, - + clearSelections: function() { if (Ext.global.console) { Ext.global.console.warn("DataView: clearSelections will be removed, please access deselectAll through DataView's SelectionModel, ie: view.getSelectionModel().deselectAll()"); @@ -62725,7 +64018,7 @@ Ext.define('Ext.view.AbstractView', { var sm = this.getSelectionModel(); return sm.deselectAll(); } - }); + }); }); }); @@ -62787,8 +64080,6 @@ var btn = panel.getComponent('myAction'); var aRef = btn.baseAction; aRef.setText('New text'); - * @constructor - * @param {Object} config The configuration options */ Ext.define('Ext.Action', { @@ -62832,6 +64123,10 @@ Ext.define('Ext.Action', { *{@link #handler}
is executed. Defaults to the browser window.
*/
+ /**
+ * Creates new Action.
+ * @param {Object} config Config object.
+ */
constructor : function(config){
this.initialConfig = config;
this.itemId = config.itemId = (config.itemId || config.id || Ext.id());
@@ -63076,10 +64371,6 @@ editor.startEdit(el); // The value of the field will be taken as the innerHTML o
*
* {@img Ext.Editor/Ext.Editor.png Ext.Editor component}
*
- * @constructor
- * Create a new Editor
- * @param {Object} config The config object
- * @xtype editor
*/
Ext.define('Ext.Editor', {
@@ -63595,9 +64886,6 @@ Ext.define('Ext.Img', {
* '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.A {@link #} delegate may be provided which may be either the element to use as the mousedown target * or a {@link Ext.DomQuery} selector to activate multiple mousedown targets.
- * @constructor Create a new ComponentTracker - * @param {object} comp The Component to provide dragging for. - * @param {object} config The config object */ Ext.define('Ext.util.ComponentDragger', { @@ -67692,13 +68971,18 @@ Ext.define('Ext.util.ComponentDragger', { /** * @cfg {Boolean} constrainDelegate - * Specify astrue
to constrain the drag handles within the {@link constrainTo} region.
+ * Specify as true
to constrain the drag handles within the {@link #constrainTo} region.
*/
extend: 'Ext.dd.DragTracker',
autoStart: 500,
+ /**
+ * Creates new ComponentDragger.
+ * @param {object} comp The Component to provide dragging for.
+ * @param {object} config (optional) Config object
+ */
constructor: function(comp, config) {
this.comp = comp;
this.initialConstrainTo = config.constrainTo;
@@ -68126,6 +69410,11 @@ Ext.define("Ext.form.Labelable", {
* Sets the active error message to the given string. This replaces the entire error message
* contents with the given string. Also see {@link #setActiveErrors} which accepts an Array of
* messages and formats them according to the {@link #activeErrorsTpl}.
+ *
+ * Note that this only updates the error message element's text and attributes, you'll have
+ * to call doComponentLayout to actually update the field's layout to match. If the field extends
+ * {@link Ext.form.field.Base} you should call {@link Ext.form.field.Base#markInvalid markInvalid} instead.
+ *
* @param {String} msg The error message
*/
setActiveError: function(msg) {
@@ -68147,6 +69436,11 @@ Ext.define("Ext.form.Labelable", {
* Set the active error message to an Array of error messages. The messages are formatted into
* a single message string using the {@link #activeErrorsTpl}. Also see {@link #setActiveError}
* which allows setting the entire error contents with a single string.
+ *
+ * Note that this only updates the error message element's text and attributes, you'll have
+ * to call doComponentLayout to actually update the field's layout to match. If the field extends
+ * {@link Ext.form.field.Base} you should call {@link Ext.form.field.Base#markInvalid markInvalid} instead.
+ *
* @param {Array} errors The error messages
*/
setActiveErrors: function(errors) {
@@ -68156,7 +69450,11 @@ Ext.define("Ext.form.Labelable", {
},
/**
- * Clears the active error.
+ * Clears the active error message(s).
+ *
+ * Note that this only clears the error message element's text and attributes, you'll have
+ * to call doComponentLayout to actually update the field's layout to match. If the field extends
+ * {@link Ext.form.field.Base} you should call {@link Ext.form.field.Base#clearInvalid clearInvalid} instead.
*/
unsetActiveError: function() {
delete this.activeError;
@@ -68758,7 +70056,7 @@ Ext.define('Ext.layout.component.field.Field', {
/**
* Return the set of strategy functions from the {@link #labelStrategies labelStrategies collection}
- * that is appropriate for the field's {@link Ext.form.field.Field#labelAlign labelAlign} config.
+ * that is appropriate for the field's {@link Ext.form.Labelable#labelAlign labelAlign} config.
*/
getLabelStrategy: function() {
var me = this,
@@ -68769,7 +70067,7 @@ Ext.define('Ext.layout.component.field.Field', {
/**
* Return the set of strategy functions from the {@link #errorStrategies errorStrategies collection}
- * that is appropriate for the field's {@link Ext.form.field.Field#msgTarget msgTarget} config.
+ * that is appropriate for the field's {@link Ext.form.Labelable#msgTarget msgTarget} config.
*/
getErrorStrategy: function() {
var me = this,
@@ -68785,7 +70083,7 @@ Ext.define('Ext.layout.component.field.Field', {
/**
* Collection of named strategies for laying out and adjusting labels to accommodate error messages.
- * An appropriate one will be chosen based on the owner field's {@link Ext.form.field.Field#labelAlign} config.
+ * An appropriate one will be chosen based on the owner field's {@link Ext.form.Labelable#labelAlign} config.
*/
labelStrategies: (function() {
var applyIf = Ext.applyIf,
@@ -68865,7 +70163,7 @@ Ext.define('Ext.layout.component.field.Field', {
/**
* Collection of named strategies for laying out and adjusting insets to accommodate error messages.
- * An appropriate one will be chosen based on the owner field's {@link Ext.form.field.Field#msgTarget} config.
+ * An appropriate one will be chosen based on the owner field's {@link Ext.form.Labelable#msgTarget} config.
*/
errorStrategies: (function() {
function setDisplayed(el, displayed) {
@@ -69381,9 +70679,7 @@ anchor: '-50 75%'
/**
* @cfg {String} defaultAnchor
- *
- * default anchor for all child container items applied if no anchor or specific width is set on the child item. Defaults to '100%'.
- *
+ * Default anchor for all child container items applied if no anchor or specific width is set on the child item. Defaults to '100%'.
*/
defaultAnchor: '100%',
@@ -69403,8 +70699,8 @@ anchor: '-50 75%'
components = me.getVisibleItems(owner),
len = components.length,
boxes = [],
- box, newTargetSize, anchorWidth, anchorHeight, component, anchorSpec, calcWidth, calcHeight,
- anchorsArray, anchor, i, el, cleaner;
+ box, newTargetSize, component, anchorSpec, calcWidth, calcHeight,
+ i, el, cleaner;
if (ownerWidth < 20 && ownerHeight < 20) {
return;
@@ -69420,21 +70716,6 @@ anchor: '-50 75%'
});
}
- // find the container anchoring size
- if (owner.anchorSize) {
- if (typeof owner.anchorSize == 'number') {
- anchorWidth = owner.anchorSize;
- }
- else {
- anchorWidth = owner.anchorSize.width;
- anchorHeight = owner.anchorSize.height;
- }
- }
- else {
- anchorWidth = owner.initialConfig.width;
- anchorHeight = owner.initialConfig.height;
- }
-
// Work around WebKit RightMargin bug. We're going to inline-block all the children only ONCE and remove it when we're done
if (!Ext.supports.RightMargin) {
cleaner = Ext.core.Element.getRightMarginFixCleaner(target);
@@ -69444,24 +70725,19 @@ anchor: '-50 75%'
for (i = 0; i < len; i++) {
component = components[i];
el = component.el;
- anchor = component.anchor;
-
- if (!component.anchor && component.items && !Ext.isNumber(component.width) && !(Ext.isIE6 && Ext.isStrict)) {
- component.anchor = anchor = me.defaultAnchor;
- }
- if (anchor) {
- anchorSpec = component.anchorSpec;
- // cache all anchor values
- if (!anchorSpec) {
- anchorsArray = anchor.split(' ');
- component.anchorSpec = anchorSpec = {
- right: me.parseAnchor(anchorsArray[0], component.initialConfig.width, anchorWidth),
- bottom: me.parseAnchor(anchorsArray[1], component.initialConfig.height, anchorHeight)
- };
+ anchorSpec = component.anchorSpec;
+ if (anchorSpec) {
+ if (anchorSpec.right) {
+ calcWidth = me.adjustWidthAnchor(anchorSpec.right(ownerWidth) - el.getMargin('lr'), component);
+ } else {
+ calcWidth = undefined;
+ }
+ if (anchorSpec.bottom) {
+ calcHeight = me.adjustHeightAnchor(anchorSpec.bottom(ownerHeight) - el.getMargin('tb'), component);
+ } else {
+ calcHeight = undefined;
}
- calcWidth = anchorSpec.right ? me.adjustWidthAnchor(anchorSpec.right(ownerWidth) - el.getMargin('lr'), component) : undefined;
- calcHeight = anchorSpec.bottom ? me.adjustHeightAnchor(anchorSpec.bottom(ownerHeight) - el.getMargin('tb'), component) : undefined;
boxes.push({
component: component,
@@ -69538,6 +70814,60 @@ anchor: '-50 75%'
// private
adjustHeightAnchor: function(value, comp) {
return value;
+ },
+
+ configureItem: function(item) {
+ var me = this,
+ owner = me.owner,
+ anchor= item.anchor,
+ anchorsArray,
+ anchorSpec,
+ anchorWidth,
+ anchorHeight;
+
+ if (!item.anchor && item.items && !Ext.isNumber(item.width) && !(Ext.isIE6 && Ext.isStrict)) {
+ item.anchor = anchor = me.defaultAnchor;
+ }
+
+ // find the container anchoring size
+ if (owner.anchorSize) {
+ if (typeof owner.anchorSize == 'number') {
+ anchorWidth = owner.anchorSize;
+ }
+ else {
+ anchorWidth = owner.anchorSize.width;
+ anchorHeight = owner.anchorSize.height;
+ }
+ }
+ else {
+ anchorWidth = owner.initialConfig.width;
+ anchorHeight = owner.initialConfig.height;
+ }
+
+ if (anchor) {
+ // cache all anchor values
+ anchorsArray = anchor.split(' ');
+ item.anchorSpec = anchorSpec = {
+ right: me.parseAnchor(anchorsArray[0], item.initialConfig.width, anchorWidth),
+ bottom: me.parseAnchor(anchorsArray[1], item.initialConfig.height, anchorHeight)
+ };
+
+ if (anchorSpec.right) {
+ item.layoutManagedWidth = 1;
+ } else {
+ item.layoutManagedWidth = 2;
+ }
+
+ if (anchorSpec.bottom) {
+ item.layoutManagedHeight = 1;
+ } else {
+ item.layoutManagedHeight = 2;
+ }
+ } else {
+ item.layoutManagedWidth = 2;
+ item.layoutManagedHeight = 2;
+ }
+ this.callParent(arguments);
}
});
@@ -69685,9 +71015,6 @@ Ext.create('Ext.window.Window', {
}
}).show();
- * @constructor
- * @param {Object} config The config object
- * @xtype window
*/
Ext.define('Ext.window.Window', {
extend: 'Ext.panel.Panel',
@@ -70158,8 +71485,18 @@ Ext.define('Ext.window.Window', {
// private
afterShow: function(animateTarget) {
- var me = this;
+ var me = this,
+ animating = animateTarget || me.animateTarget;
+
+ if (animating) {
+ /*
+ * If we're animating, constrain the positioning before calling the
+ * superclass, otherwise we'll be animating to the unconstrained
+ * window position.
+ */
+ me.doConstrain();
+ }
// Perform superclass's afterShow tasks
// Which might include animating a proxy from an animTarget
me.callParent(arguments);
@@ -70169,7 +71506,9 @@ Ext.define('Ext.window.Window', {
}
me.syncMonitorWindowResize();
- me.doConstrain();
+ if (!animating) {
+ me.doConstrain();
+ }
if (me.keyMap) {
me.keyMap.enable();
@@ -70465,11 +71804,7 @@ __Example usage:__
renderTo: Ext.getBody()
});
- * @constructor
- * Creates a new Field
- * @param {Object} config Configuration options
*
- * @xtype field
* @markdown
* @docauthor Jason Johnston A {@link Ext.form.FieldContainer field container} which has a specialized layout for arranging + * A {@link Ext.form.FieldContainer field container} which has a specialized layout for arranging * {@link Ext.form.field.Checkbox} controls into columns, and provides convenience {@link Ext.form.field.Field} methods * for {@link #getValue getting}, {@link #setValue setting}, and {@link #validate validating} the group - * of checkboxes as a whole.
- *Validation: Individual checkbox fields themselves have no default validation behavior, but + * of checkboxes as a whole. + * + * # Validation + * + * Individual checkbox fields themselves have no default validation behavior, but * sometimes you want to require a user to select at least one of a group of checkboxes. CheckboxGroup - * allows this by setting the config {@link #allowBlank}:false; when the user does not check at + * allows this by setting the config `{@link #allowBlank}:false`; when the user does not check at * least one of the checkboxes, the entire group will be highlighted as invalid and the - * {@link #blankText error message} will be displayed according to the {@link #msgTarget} config.
- *Layout: The default layout for CheckboxGroup makes it easy to arrange the checkboxes into + * {@link #blankText error message} will be displayed according to the {@link #msgTarget} config. + * + * # Layout + * + * The default layout for CheckboxGroup makes it easy to arrange the checkboxes into * columns; see the {@link #columns} and {@link #vertical} config documentation for details. You may also * use a completely different layout by setting the {@link #layout} to one of the other supported layout * types; for instance you may wish to use a custom arrangement of hbox and vbox containers. In that case - * the checkbox components at any depth will still be managed by the CheckboxGroup's validation.
- * {@img Ext.form.RadioGroup/Ext.form.RadioGroup.png Ext.form.RadioGroup component} - *Example usage:
- *
-Ext.create('Ext.form.Panel', {
- title: 'RadioGroup Example',
- width: 300,
- height: 125,
- bodyPadding: 10,
- renderTo: Ext.getBody(),
- items:[{
- xtype: 'radiogroup',
- fieldLabel: 'Two Columns',
- // Arrange radio buttons into two columns, distributed vertically
- columns: 2,
- vertical: true,
- items: [
- {boxLabel: 'Item 1', name: 'rb', inputValue: '1'},
- {boxLabel: 'Item 2', name: 'rb', inputValue: '2', checked: true},
- {boxLabel: 'Item 3', name: 'rb', inputValue: '3'},
- {boxLabel: 'Item 4', name: 'rb', inputValue: '4'},
- {boxLabel: 'Item 5', name: 'rb', inputValue: '5'},
- {boxLabel: 'Item 6', name: 'rb', inputValue: '6'}
- ]
- }]
-});
- *
- * @constructor
- * Creates a new CheckboxGroup
- * @param {Object} config Configuration options
- * @xtype checkboxgroup
+ * the checkbox components at any depth will still be managed by the CheckboxGroup's validation.
+ *
+ * {@img Ext.form.CheckboxGroup/Ext.form.CheckboxGroup.png Ext.form.CheckboxGroup component}
+ *
+ * # Example usage
+ *
+ * Ext.create('Ext.form.Panel', {
+ * title: 'Checkbox Group',
+ * width: 300,
+ * height: 125,
+ * bodyPadding: 10,
+ * renderTo: Ext.getBody(),
+ * items:[{
+ * xtype: 'checkboxgroup',
+ * fieldLabel: 'Two Columns',
+ * // Arrange radio buttons into two columns, distributed vertically
+ * columns: 2,
+ * vertical: true,
+ * items: [
+ * {boxLabel: 'Item 1', name: 'rb', inputValue: '1'},
+ * {boxLabel: 'Item 2', name: 'rb', inputValue: '2', checked: true},
+ * {boxLabel: 'Item 3', name: 'rb', inputValue: '3'},
+ * {boxLabel: 'Item 4', name: 'rb', inputValue: '4'},
+ * {boxLabel: 'Item 5', name: 'rb', inputValue: '5'},
+ * {boxLabel: 'Item 6', name: 'rb', inputValue: '6'}
+ * ]
+ * }]
+ * });
+ *
*/
Ext.define('Ext.form.CheckboxGroup', {
extend:'Ext.form.FieldContainer',
@@ -74803,10 +76124,6 @@ Ext.define('Ext.form.CheckboxManager', {
* }]
* });
*
- * @constructor
- * Create a new FieldSet
- * @param {Object} config Configuration options
- * @xtype fieldset
* @docauthor Jason Johnston A {@link Ext.form.FieldContainer field container} which has a specialized layout for arranging - * {@link Ext.form.field.Radio} controls into columns, and provides convenience {@link Ext.form.field.Field} methods - * for {@link #getValue getting}, {@link #setValue setting}, and {@link #validate validating} the group - * of radio buttons as a whole.
- *Validation: Individual radio buttons themselves have no default validation behavior, but + * A {@link Ext.form.FieldContainer field container} which has a specialized layout for arranging + * {@link Ext.form.field.Radio} controls into columns, and provides convenience {@link Ext.form.field.Field} + * methods for {@link #getValue getting}, {@link #setValue setting}, and {@link #validate validating} the + * group of radio buttons as a whole. + * + * # Validation + * + * Individual radio buttons themselves have no default validation behavior, but * sometimes you want to require a user to select one of a group of radios. RadioGroup - * allows this by setting the config {@link #allowBlank}:false; when the user does not check at + * allows this by setting the config `{@link #allowBlank}:false`; when the user does not check at * one of the radio buttons, the entire group will be highlighted as invalid and the * {@link #blankText error message} will be displayed according to the {@link #msgTarget} config.
- *Layout: The default layout for RadioGroup makes it easy to arrange the radio buttons into + * + * # Layout + * + * The default layout for RadioGroup makes it easy to arrange the radio buttons into * columns; see the {@link #columns} and {@link #vertical} config documentation for details. You may also * use a completely different layout by setting the {@link #layout} to one of the other supported layout * types; for instance you may wish to use a custom arrangement of hbox and vbox containers. In that case - * the Radio components at any depth will still be managed by the RadioGroup's validation.
- *Example usage:
- *
-var myRadioGroup = new Ext.form.RadioGroup({
- id: 'myGroup',
- xtype: 'radiogroup',
- fieldLabel: 'Single Column',
- // Arrange radio buttons into three columns, distributed vertically
- columns: 3,
- vertical: true,
- items: [
- {boxLabel: 'Item 1', name: 'rb', inputValue: '1'},
- {boxLabel: 'Item 2', name: 'rb', inputValue: '2', checked: true},
- {boxLabel: 'Item 3', name: 'rb', inputValue: '3'}
- {boxLabel: 'Item 4', name: 'rb', inputValue: '4'}
- {boxLabel: 'Item 5', name: 'rb', inputValue: '5'}
- {boxLabel: 'Item 6', name: 'rb', inputValue: '6'}
- ]
-});
- *
- * @constructor
- * Creates a new RadioGroup
- * @param {Object} config Configuration options
- * @xtype radiogroup
+ * the Radio components at any depth will still be managed by the RadioGroup's validation.
+ *
+ * {@img Ext.form.RadioGroup/Ext.form.RadioGroup.png Ext.form.RadioGroup component}
+ *
+ * # Example usage
+ *
+ * Ext.create('Ext.form.Panel', {
+ * title: 'RadioGroup Example',
+ * width: 300,
+ * height: 125,
+ * bodyPadding: 10,
+ * renderTo: Ext.getBody(),
+ * items:[{
+ * xtype: 'radiogroup',
+ * fieldLabel: 'Two Columns',
+ * // Arrange radio buttons into two columns, distributed vertically
+ * columns: 2,
+ * vertical: true,
+ * items: [
+ * {boxLabel: 'Item 1', name: 'rb', inputValue: '1'},
+ * {boxLabel: 'Item 2', name: 'rb', inputValue: '2', checked: true},
+ * {boxLabel: 'Item 3', name: 'rb', inputValue: '3'},
+ * {boxLabel: 'Item 4', name: 'rb', inputValue: '4'},
+ * {boxLabel: 'Item 5', name: 'rb', inputValue: '5'},
+ * {boxLabel: 'Item 6', name: 'rb', inputValue: '6'}
+ * ]
+ * }]
+ * });
+ *
*/
Ext.define('Ext.form.RadioGroup', {
extend: 'Ext.form.CheckboxGroup',
@@ -75602,7 +76920,7 @@ Ext.define('Ext.form.RadioGroup', {
*/
/**
* @cfg {Boolean} allowBlank True to allow every item in the group to be blank (defaults to true).
- * If allowBlank = false and no items are selected at validation time, {@link @blankText} will
+ * If allowBlank = false and no items are selected at validation time, {@link #blankText} will
* be used as the error text.
*/
allowBlank : true,
@@ -76035,10 +77353,6 @@ __Example usage:__
renderTo: Ext.getBody()
});
- * @constructor
- * Creates a new Checkbox
- * @param {Object} config Configuration options
- * @xtype checkboxfield
* @docauthor Robert Dougan By default, pressing the up and down arrow keys will also trigger the onSpinUp and onSpinDown methods; * to prevent this, set {@link #keyNavEnabled} = false.
* - * @constructor - * Creates a new Spinner field - * @param {Object} config Configuration options - * @xtype spinnerfield */ Ext.define('Ext.form.field.Spinner', { extend: 'Ext.form.field.Trigger', @@ -78191,11 +79507,7 @@ and mouse wheel handlers set `{@link #keyNavEnabled keyNavEnabled}:false` and }); - * @constructor - * Creates a new Number field - * @param {Object} config Configuration options * - * @xtype numberfield * @markdown * @docauthor Jason JohnstontriggerCls
will be appended if specified.
* Defaults to 'x-form-arrow-trigger' for ComboBox.
*/
triggerCls: Ext.baseCSSPrefix + 'form-arrow-trigger',
/**
- * @cfg {Ext.data.Store/Array} store The data source to which this combo is bound (defaults to undefined).
+ * @cfg {Ext.data.Store/Array} store The data source to which this combo is bound (defaults to undefined
).
* Acceptable values for this property are:
* ['Foo','Bar']
)[['f','Foo'],['b','Bar']]
)See also {@link #queryMode}.
+ *See also {@link #queryMode}
.
true
, allows the combo field to hold more than one value at a time, and allows selecting
* multiple items from the dropdown list. The combo's text field will show all selected values separated by
- * the {@link #delimiter}. (Defaults to false.)
+ * the {@link #delimiter}. (Defaults to false
.)
*/
multiSelect: false,
/**
* @cfg {String} delimiter
* The character(s) used to separate the {@link #displayField display values} of multiple selected items
- * when {@link #multiSelect} = true. Defaults to ', '.
+ * when {@link #multiSelect} = true
. Defaults to ', '
.
*/
delimiter: ', ',
/**
* @cfg {String} displayField The underlying {@link Ext.data.Field#name data field name} to bind to this
* ComboBox (defaults to 'text').
- * See also {@link #valueField}.
+ *See also {@link #valueField}
.
Note: use of a valueField requires the user to make a selection in order for a value to be - * mapped. See also {@link #displayField}.
+ *Note: use of a valueField
requires the user to make a selection in order for a value to be
+ * mapped. See also {@link #displayField}
.
{@link #doQuery run the query} specified by the {@link #allQuery} config option
'all'
: Default
+ * {@link #doQuery run the query} specified by the {@link #allQuery}
config option
'query'
:
* {@link #doQuery run the query} using the {@link Ext.form.field.Base#getRawValue raw value}.
See also {@link #queryParam}
.
{@link #queryMode}: 'remote'
(defaults to 'query'
). If explicitly set to a falsy value it will
+ * not be sent.
*/
queryParam: 'query',
/**
* @cfg {String} queryMode
- * The mode for queries. Acceptable values are:
+ * The mode in which the ComboBox uses the configured Store. Acceptable values are:
* Automatically loads the {@link #store} the first time the trigger - * is clicked. If you do not want the store to be automatically loaded the first time the trigger is - * clicked, set to 'local' and manually load the store. To force a requery of the store - * every time the trigger is clicked see {@link #lastQuery}.
'remote'
: Default
+ * In queryMode: 'remote'
, the ComboBox loads its Store dynamically based upon user interaction.
This is typically used for "autocomplete" type inputs, and after the user finishes typing, the Store is {@link Ext.data.Store#load load}ed.
+ *A parameter containing the typed string is sent in the load request. The default parameter name for the input string is query
, but this
+ * can be configured using the {@link #queryParam} config.
In queryMode: 'remote'
, the Store may be configured with {@link Ext.data.Store#remoteFilter remoteFilter}: true
,
+ * and further filters may be programatically added to the Store which are then passed with every load request which allows the server
+ * to further refine the returned dataset.
Typically, in an autocomplete situation, {@link #hideTrigger} is configured true
because it has no meaning for autocomplete.
'local'
:
* ComboBox loads local data
*
var combo = new Ext.form.field.ComboBox({
@@ -79438,28 +80760,28 @@ var combo = new Ext.form.field.ComboBox({
queryCaching: true,
/**
- * @cfg {Number} pageSize If greater than 0, a {@link Ext.toolbar.Paging} is displayed in the
+ * @cfg {Number} pageSize If greater than 0
, a {@link Ext.toolbar.Paging} is displayed in the
* footer of the dropdown list and the {@link #doQuery filter queries} will execute with page start and
- * {@link Ext.toolbar.Paging#pageSize limit} parameters. Only applies when {@link #queryMode} = 'remote'
- * (defaults to 0).
+ * {@link Ext.toolbar.Paging#pageSize limit} parameters. Only applies when {@link #queryMode} = 'remote'
+ * (defaults to 0
).
*/
pageSize: 0,
/**
* @cfg {Number} queryDelay The length of time in milliseconds to delay between the start of typing and
- * sending the query to filter the dropdown list (defaults to 500 if {@link #queryMode} = 'remote'
- * or 10 if {@link #queryMode} = 'local')
+ * sending the query to filter the dropdown list (defaults to 500
if {@link #queryMode} = 'remote'
+ * or 10
if {@link #queryMode} = 'local'
)
*/
/**
* @cfg {Number} minChars The minimum number of characters the user must type before autocomplete and
- * {@link #typeAhead} activate (defaults to 4 if {@link #queryMode} = 'remote' or 0 if
- * {@link #queryMode} = 'local', does not apply if {@link Ext.form.field.Trigger#editable editable} = false).
+ * {@link #typeAhead} activate (defaults to 4
if {@link #queryMode} = 'remote'
or 0
if
+ * {@link #queryMode} = 'local'
, does not apply if {@link Ext.form.field.Trigger#editable editable} = false
).
*/
/**
- * @cfg {Boolean} autoSelect true to automatically highlight the first result gathered by the data store
- * in the dropdown list when it is opened. (Defaults to true). A false value would cause nothing in the
+ * @cfg {Boolean} autoSelect true
to automatically highlight the first result gathered by the data store
+ * in the dropdown list when it is opened. (Defaults to true
). A false value would cause nothing in the
* list to be highlighted automatically, so the user would have to manually highlight an item before pressing
* the enter or {@link #selectOnTab tab} key to select it (unless the value of ({@link #typeAhead}) were true),
* or use the mouse to select a value.
@@ -79467,27 +80789,27 @@ var combo = new Ext.form.field.ComboBox({
autoSelect: true,
/**
- * @cfg {Boolean} typeAhead true to populate and autoselect the remainder of the text being
+ * @cfg {Boolean} typeAhead true
to populate and autoselect the remainder of the text being
* typed after a configurable delay ({@link #typeAheadDelay}) if it matches a known value (defaults
- * to false)
+ * to false
)
*/
typeAhead: false,
/**
* @cfg {Number} typeAheadDelay The length of time in milliseconds to wait until the typeahead text is displayed
- * if {@link #typeAhead} = true (defaults to 250)
+ * if {@link #typeAhead} = true
(defaults to 250
)
*/
typeAheadDelay: 250,
/**
* @cfg {Boolean} selectOnTab
- * Whether the Tab key should select the currently highlighted item. Defaults to true.
+ * Whether the Tab key should select the currently highlighted item. Defaults to true
.
*/
selectOnTab: true,
/**
- * @cfg {Boolean} forceSelection true to restrict the selected value to one of the values in the list,
- * false to allow the user to set arbitrary text into the field (defaults to false)
+ * @cfg {Boolean} forceSelection true
to restrict the selected value to one of the values in the list,
+ * false
to allow the user to set arbitrary text into the field (defaults to false
)
*/
forceSelection: false,
@@ -79514,7 +80836,7 @@ var combo = new Ext.form.field.ComboBox({
});
*
* To make sure the filter in the store is not cleared the first time the ComboBox trigger is used
- * configure the combo with lastQuery=''. Example use:
+ * configure the combo with lastQuery=''
. Example use:
*
var combo = new Ext.form.field.ComboBox({
...
@@ -79542,7 +80864,7 @@ var combo = new Ext.form.field.ComboBox({
/**
* @cfg {Mixed} transform
- * The id, DOM node or {@link Ext.core.Element} of an existing HTML <select> element to
+ * The id, DOM node or {@link Ext.core.Element} of an existing HTML <select>
element to
* convert into a ComboBox. The target select's options will be used to build the options in the ComboBox
* dropdown; a configured {@link #store} will take precedence over this.
*/
@@ -79557,13 +80879,13 @@ var combo = new Ext.form.field.ComboBox({
* - {@link Ext.view.BoundList#emptyText} - defaults to empty string
* - {@link Ext.view.BoundList#getInnerTpl} - defaults to the template defined in BoundList
* - {@link Ext.view.BoundList#itemSelector} - defaults to the value defined in BoundList
- * - {@link Ext.view.BoundList#loadingText} - defaults to 'Loading...'
- * - {@link Ext.view.BoundList#minWidth} - defaults to 70
- * - {@link Ext.view.BoundList#maxWidth} - defaults to undefined
- * - {@link Ext.view.BoundList#maxHeight} - defaults to 300
- * - {@link Ext.view.BoundList#resizable} - defaults to false
- * - {@link Ext.view.BoundList#shadow} - defaults to 'sides'
- * - {@link Ext.view.BoundList#width} - defaults to undefined (automatically set to the width
+ *
- {@link Ext.view.BoundList#loadingText} - defaults to
'Loading...'
+ * - {@link Ext.view.BoundList#minWidth} - defaults to
70
+ * - {@link Ext.view.BoundList#maxWidth} - defaults to
undefined
+ * - {@link Ext.view.BoundList#maxHeight} - defaults to
300
+ * - {@link Ext.view.BoundList#resizable} - defaults to
false
+ * - {@link Ext.view.BoundList#shadow} - defaults to
'sides'
+ * - {@link Ext.view.BoundList#width} - defaults to
undefined
(automatically set to the width
* of the ComboBox field if {@link #matchFieldWidth} is true)
*
true
to force the query to execute even if there are currently fewer
+ * characters in the field than the minimum specified by the {@link #minChars}
config option. It
+ * also clears any filter previously saved in the current store (defaults to false
)
* @return {Boolean} true if the query was permitted to run, false if it was cancelled by a {@link #beforequery} handler.
*/
doQuery: function(queryString, forceAll) {
@@ -79846,12 +81168,19 @@ var combo = new Ext.form.field.ComboBox({
// make sure they aren't querying the same thing
if (!me.queryCaching || me.lastQuery !== queryString) {
me.lastQuery = queryString;
- store.clearFilter(!forceAll);
+
if (isLocalMode) {
- if (!forceAll) {
+ // forceAll means no filtering - show whole dataset.
+ if (forceAll) {
+ store.clearFilter();
+ } else {
+ // Clear filter, but supress event so that the BoundList is not immediately updated.
+ store.clearFilter(true);
store.filter(me.displayField, queryString);
}
} else {
+ // In queryMode: 'remote', we assume Store filters are added by the developer as remote filters,
+ // and these are automatically passed as params with every load call, so we do *not* call clearFilter.
store.load({
params: me.getParams(queryString)
});
@@ -79880,11 +81209,11 @@ var combo = new Ext.form.field.ComboBox({
var p = {},
pageSize = this.pageSize,
param = this.queryParam;
-
+
if (param) {
p[param] = queryString;
}
-
+
if (pageSize) {
p.start = 0;
p.limit = pageSize;
@@ -79953,7 +81282,7 @@ var combo = new Ext.form.field.ComboBox({
me.doQueryTask.delay(me.queryDelay);
}
}
-
+
if (me.enableKeyEvents) {
me.callParent(arguments);
}
@@ -79964,7 +81293,7 @@ var combo = new Ext.form.field.ComboBox({
me.callParent();
/*
- * Setup keyboard handling. If enableKeyEvents is true, we already have
+ * Setup keyboard handling. If enableKeyEvents is true, we already have
* a listener on the inputEl for keyup, so don't create a second.
*/
if (!me.enableKeyEvents) {
@@ -79987,7 +81316,8 @@ var combo = new Ext.form.field.ComboBox({
store: me.store,
displayField: me.displayField,
focusOnToFront: false,
- pageSize: me.pageSize
+ pageSize: me.pageSize,
+ tpl: me.tpl
}, me.listConfig, me.defaultListConfig);
picker = me.picker = Ext.create('Ext.view.BoundList', opts);
@@ -79998,10 +81328,7 @@ var combo = new Ext.form.field.ComboBox({
scope: me
});
- me.mon(picker.getSelectionModel(), {
- selectionChange: me.onListSelectionChange,
- scope: me
- });
+ me.mon(picker.getSelectionModel(), 'selectionchange', me.onListSelectionChange, me);
return picker;
},
@@ -80010,7 +81337,7 @@ var combo = new Ext.form.field.ComboBox({
this.alignPicker();
this.syncSelection();
},
-
+
onItemClick: function(picker, record){
/*
* If we're doing single selection, the selection change events won't fire when
@@ -80020,25 +81347,34 @@ var combo = new Ext.form.field.ComboBox({
lastSelection = me.lastSelection,
valueField = me.valueField,
selected;
-
+
if (!me.multiSelect && lastSelection) {
selected = lastSelection[0];
- if (record.get(valueField) === selected.get(valueField)) {
+ if (selected && (record.get(valueField) === selected.get(valueField))) {
me.collapse();
}
- }
+ }
},
onListSelectionChange: function(list, selectedRecords) {
- var me = this;
+ var me = this,
+ isMulti = me.multiSelect,
+ hasRecords = selectedRecords.length > 0;
// Only react to selection if it is not called from setValue, and if our list is
// expanded (ignores changes to the selection model triggered elsewhere)
if (!me.ignoreSelection && me.isExpanded) {
- if (!me.multiSelect) {
+ if (!isMulti) {
Ext.defer(me.collapse, 1, me);
}
- me.setValue(selectedRecords, false);
- if (selectedRecords.length > 0) {
+ /*
+ * Only set the value here if we're in multi selection mode or we have
+ * a selection. Otherwise setValue will be called with an empty value
+ * which will cause the change event to fire twice.
+ */
+ if (isMulti || hasRecords) {
+ me.setValue(selectedRecords, false);
+ }
+ if (hasRecords) {
me.fireEvent('select', me, selectedRecords);
}
me.inputEl.focus();
@@ -80290,11 +81626,6 @@ var combo = new Ext.form.field.ComboBox({
* @extends Ext.Component
* A month picker component. This class is used by the {@link Ext.picker.Date DatePicker} class * to allow browsing and selection of year/months combinations.
- * @constructor - * Create a new MonthPicker - * @param {Object} config The config object - * @xtype monthpicker - * @private */ Ext.define('Ext.picker.Month', { extend: 'Ext.Component', @@ -80353,11 +81684,10 @@ Ext.define('Ext.picker.Month', { /** * @cfg {Date/Array} value The default value to set. See {#setValue setValue} */ - - width: 175, - - height: 195, - + width: 178, + + // used when attached to date picker which isnt showing buttons + smallCls: Ext.baseCSSPrefix + 'monthpicker-small', // private totalYears: 10, @@ -80425,7 +81755,9 @@ Ext.define('Ext.picker.Month', { */ 'yeardblclick' ); - + if (me.small) { + me.addCls(me.smallCls); + } me.setValue(me.value); me.activeYear = me.getYear(new Date().getFullYear() - 4, -4); this.callParent(); @@ -80749,11 +82081,6 @@ Ext.define('Ext.picker.Month', { }); * {@img Ext.picker.Date/Ext.picker.Date.png Ext.picker.Date component} * - * @constructor - * Create a new DatePicker - * @param {Object} config The config object - * - * @xtype datepicker */ Ext.define('Ext.picker.Date', { extend: 'Ext.Component', @@ -81365,6 +82692,7 @@ Ext.define('Ext.picker.Date', { renderTo: me.el, floating: true, shadow: false, + small: me.showToday === false, listeners: { scope: me, cancelclick: me.onCancelClick, @@ -81785,11 +83113,7 @@ configurations; the first one matches the configured `format` while the second m }] }); - * @constructor - * Create a new Date field - * @param {Object} config * - * @xtype datefield * @markdown * @docauthor Jason JohnstonSubmitting the above form will result in three values sent to the server:
* text_field=value+from+text+field&hidden_field_1=value+from+hidden+field&
hidden_field_2=value+from+submit+call
true
to hide the headers.
*/
+ /**
+ * @cfg {Boolean} deferRowRender Defaults to true
to enable deferred row rendering.
This allows the GridView to execute a refresh quickly, with the expensive update of the row + * structure deferred so that layouts with GridPanels appear, and lay out more quickly.
+ */ + /** * @cfg {Boolean} sortableColumns - * Defaults to true. Set to false to disable column sorting via clicking the + * Defaults totrue
. Set to false
to disable column sorting via clicking the
* header and via the Sorting menu items.
*/
sortableColumns: true,
@@ -86656,10 +88052,24 @@ Ext.define('Ext.panel.Table', {
scrollerOwner: true,
invalidateScrollerOnRefresh: true,
-
+
+ /**
+ * @cfg {Boolean} enableColumnMove
+ * Defaults to true
. Set to false
to disable column dragging within this grid.
+ */
enableColumnMove: true,
+
+ /**
+ * @cfg {Boolean} enableColumnResize
+ * Defaults to true
. Set to false
to disable column resizing within this grid.
+ */
enableColumnResize: true,
+ /**
+ * @cfg {Boolean} enableColumnHide
+ * Defaults to true
. Set to false
to disable column hiding within this grid.
+ */
+ enableColumnHide: true,
initComponent: function() {
//{@link Ext.data.Store#remoteSort}
.
*/
sortable: true,
-
+
/**
* @cfg {Boolean} groupable Optional. If the grid uses a {@link Ext.grid.feature.Grouping}, this option
* may be used to disable the header menu item to group by the column selected. By default,
* the header menu group option is enabled. Set to false to disable (but still show) the
* group option in the header menu for the column.
*/
+
+ /**
+ * @cfg {Boolean} fixed Prevents the column from being resizable
+ */
+ /**
+ * @cfg {Boolean} resizable This config has no effect on a grid column, please see {@link #fixed} instead.
+ */
+
/**
* @cfg {Boolean} hideable Optional. Specify as false to prevent the user from hiding this column
* (defaults to true).
@@ -90832,7 +92353,7 @@ Ext.define('Ext.grid.column.Column', {
menuDisabled: false,
/**
- * @cfg {Function} renderer
+ * @method
* A renderer is an 'interceptor' method which can be used transform data (value, appearance, etc.) before it * is rendered. Example:
*{
@@ -90895,7 +92416,7 @@ Ext.define('Ext.grid.column.Column', {
var me = this,
i,
len;
-
+
if (Ext.isDefined(me.header)) {
me.text = me.header;
delete me.header;
@@ -90975,7 +92496,7 @@ Ext.define('Ext.grid.column.Column', {
initRenderData: function() {
var me = this;
-
+
Ext.applyIf(me.renderData, {
text: me.text,
menuDisabled: me.menuDisabled
@@ -90983,12 +92504,15 @@ Ext.define('Ext.grid.column.Column', {
return me.callParent(arguments);
},
- // note that this should invalidate the menu cache
+ /**
+ * Sets the header text for this Column.
+ * @param text The header to display on this Column.
+ */
setText: function(text) {
this.text = text;
if (this.rendered) {
this.textEl.update(text);
- }
+ }
},
// Find the topmost HeaderContainer: An ancestor which is NOT a Header.
@@ -91018,7 +92542,7 @@ Ext.define('Ext.grid.column.Column', {
dblclick: me.onElDblClick,
scope: me
});
-
+
// BrowserBug: Ie8 Strict Mode, this will break the focus for this browser,
// must be fixed when focus management will be implemented.
if (!Ext.isIE8 || !Ext.isStrict) {
@@ -91049,22 +92573,38 @@ Ext.define('Ext.grid.column.Column', {
siblings,
len, i,
oldWidth = me.getWidth(),
- newWidth = 0;
+ newWidth = 0,
+ readyForSizing = true,
+ hidden,
+ sibling;
if (width !== oldWidth) {
// Bubble size changes upwards to group headers
if (headerCt.isGroupHeader) {
-
siblings = headerCt.items.items;
len = siblings.length;
- // Size the owning group to the size of its sub headers
- if (siblings[len - 1].rendered) {
-
- for (i = 0; i < len; i++) {
- newWidth += (siblings[i] === me) ? width : siblings[i].getWidth();
+ /*
+ * setSize will be called for each column as it's rendered
+ * so we want to wait until all sub columns have been rendered
+ * before we try and calculate the size of the outer container.
+ * We also take into account hidden columns, because they won't
+ * be rendered, but we'll still need to make the calculation.
+ */
+ for (i = 0; i < len; i++) {
+ sibling = siblings[i];
+ hidden = sibling.hidden;
+ if (!sibling.rendered && !hidden) {
+ readyForSizing = false;
+ break;
}
+ if (!hidden) {
+ newWidth += (sibling === me) ? width : sibling.getWidth();
+ }
+ }
+
+ if (readyForSizing) {
headerCt.minWidth = newWidth;
headerCt.setWidth(newWidth);
}
@@ -91143,7 +92683,7 @@ Ext.define('Ext.grid.column.Column', {
/**
* @private
- * Double click
+ * Double click
* @param e
* @param t
*/
@@ -91192,7 +92732,7 @@ Ext.define('Ext.grid.column.Column', {
var me = this,
idx,
nextIdx;
-
+
if (me.sortable) {
idx = Ext.Array.indexOf(me.possibleSortStates, me.sortState);
@@ -91385,7 +92925,7 @@ Ext.define('Ext.grid.column.Column', {
isOnRightEdge: function(e) {
return (this.el.getRight() - e.getXY()[0] <= this.handleWidth);
}
-
+
/**
* Retrieves the editing field for editing associated with this header. Returns false if there
* is no field associated with the Header the method will return false. If the
@@ -91398,8 +92938,8 @@ Ext.define('Ext.grid.column.Column', {
*/
// intentionally omit getEditor and setEditor definitions bc we applyIf into columns
// when the editing plugin is injected
-
-
+
+
/**
* Sets the form field to be used for editing. Note: This method only has an implementation
* if an Editing plugin has been enabled on the grid.
@@ -91422,8 +92962,6 @@ columns: [
{text: "Last Updated", width: 120, sortable: true, renderer: Ext.util.Format.dateRenderer('m/d/Y'), dataIndex: 'lastChange'}
]
*
- * @constructor
- * @param {Object} config The configuration options
*/
Ext.define('Ext.grid.RowNumberer', {
extend: 'Ext.grid.column.Column',
@@ -91506,9 +93044,12 @@ Ext.define('Ext.view.DropZone', {
// Fire an event through the client DataView. Lock this DropZone during the event processing so that
// its data does not become corrupted by processing mouse events.
fireViewEvent: function() {
- this.lock();
- var result = this.view.fireEvent.apply(this.view, arguments);
- this.unlock();
+ var me = this,
+ result;
+
+ me.lock();
+ result = me.view.fireEvent.apply(me.view, arguments);
+ me.unlock();
return result;
},
@@ -91619,41 +93160,46 @@ Ext.define('Ext.view.DropZone', {
// The mouse is over a View node
onNodeOver: function(node, dragZone, e, data) {
- if (!Ext.Array.contains(data.records, this.view.getRecord(node))) {
- this.positionIndicator(node, data, e);
+ var me = this;
+
+ if (!Ext.Array.contains(data.records, me.view.getRecord(node))) {
+ me.positionIndicator(node, data, e);
}
- return this.valid ? this.dropAllowed : this.dropNotAllowed;
+ return me.valid ? me.dropAllowed : me.dropNotAllowed;
},
// Moved out of the DropZone without dropping.
// Remove drop position indicator
notifyOut: function(node, dragZone, e, data) {
- this.callParent(arguments);
- delete this.overRecord;
- delete this.currentPosition;
- if (this.indicator) {
- this.indicator.hide();
+ var me = this;
+
+ me.callParent(arguments);
+ delete me.overRecord;
+ delete me.currentPosition;
+ if (me.indicator) {
+ me.indicator.hide();
}
},
// The mouse is past the end of all nodes (or there are no nodes)
onContainerOver : function(dd, e, data) {
- var v = this.view,
- c = v.store.getCount();
+ var me = this,
+ view = me.view,
+ count = view.store.getCount();
// There are records, so position after the last one
- if (c) {
- this.positionIndicator(v.getNode(c - 1), data, e);
+ if (count) {
+ me.positionIndicator(view.getNode(count - 1), data, e);
}
// No records, position the indicator at the top
else {
- delete this.overRecord;
- delete this.currentPosition;
- this.getIndicator().setWidth(Ext.fly(v.el).getWidth()).showAt(0, 0);
- this.valid = true;
+ delete me.overRecord;
+ delete me.currentPosition;
+ me.getIndicator().setWidth(Ext.fly(view.el).getWidth()).showAt(0, 0);
+ me.valid = true;
}
- return this.dropAllowed;
+ return me.dropAllowed;
},
onContainerDrop : function(dd, e, data) {
@@ -91665,7 +93211,7 @@ Ext.define('Ext.view.DropZone', {
dropped = false,
// Create a closure to perform the operation which the event handler may use.
- // Users may now return 0
from the beforedrop handler, and perform any kind
+ // Users may now return false
from the beforedrop handler, and perform any kind
// of asynchronous processing such as an Ext.Msg.confirm, or an Ajax request,
// and complete the drop gesture at some point in the future by calling this function.
processDrop = function () {
@@ -91674,23 +93220,18 @@ Ext.define('Ext.view.DropZone', {
dropped = true;
me.fireViewEvent('drop', node, data, me.overRecord, me.currentPosition);
},
- performOperation;
+ performOperation = false;
if (me.valid) {
performOperation = me.fireViewEvent('beforedrop', node, data, me.overRecord, me.currentPosition, processDrop);
- if (performOperation === 0) {
- return;
- } else if (performOperation !== false) {
+ if (performOperation !== false) {
// If the processDrop function was called in the event handler, do not do it again.
if (!dropped) {
processDrop();
}
- } else {
- return false;
}
- } else {
- return false;
}
+ return performOperation;
}
});
@@ -91723,7 +93264,9 @@ Ext.define('Ext.grid.ViewDropZone', {
}
index = store.indexOf(record);
- if (position == 'after') {
+
+ // 'after', or undefined (meaning a drop at index -1 on an empty View)...
+ if (position !== 'before') {
index++;
}
store.insert(index, data.records);
@@ -91782,7 +93325,6 @@ Ext.define('Ext.grid.ViewDropZone', {
* });
* The action column can be at any index in the columns array, and a grid can have any number of * action columns.
- * @xtype actioncolumn */ Ext.define('Ext.grid.column.Action', { extend: 'Ext.grid.column.Column', @@ -91898,7 +93440,7 @@ Ext.define('Ext.grid.column.Action', { meta.tdCls += ' ' + Ext.baseCSSPrefix + 'action-col-cell'; for (i = 0; i < l; i++) { item = items[i]; - v += ''; @@ -91994,8 +93536,6 @@ Ext.define('Ext.grid.column.Action', { * width: 400, * renderTo: Ext.getBody() * }); - * - * @xtype booleancolumn */ Ext.define('Ext.grid.column.Boolean', { extend: 'Ext.grid.column.Column', @@ -92080,8 +93620,6 @@ Ext.define('Ext.grid.column.Boolean', { * width: 450, * renderTo: Ext.getBody() * }); - * - * @xtype datecolumn */ Ext.define('Ext.grid.column.Date', { extend: 'Ext.grid.column.Column', @@ -92091,7 +93629,7 @@ Ext.define('Ext.grid.column.Date', { /** * @cfg {String} format - * A formatting string as used by {@link Date#format Date.format} to format a Date for this Column. + * A formatting string as used by {@link Ext.Date#format} to format a Date for this Column. * This defaults to the default date from {@link Ext.Date#defaultFormat} which itself my be overridden * in a locale file. */ @@ -92140,8 +93678,6 @@ Ext.define('Ext.grid.column.Date', { * width: 400, * renderTo: Ext.getBody() * }); - * - * @xtype numbercolumn */ Ext.define('Ext.grid.column.Number', { extend: 'Ext.grid.column.Column', @@ -92196,7 +93732,6 @@ Ext.define('Ext.grid.column.Number', { * }); * * @markdown - * @xtype templatecolumn */ Ext.define('Ext.grid.column.Template', { extend: 'Ext.grid.column.Column', @@ -92302,7 +93837,7 @@ Ext.define('Ext.grid.feature.Feature', { * Abstract method to be overriden when a feature should add additional * arguments to its event signature. By default the event will fire: * - view - The underlying Ext.view.Table - * - featureTarget - The matched element by the defined {@link eventSelector} + * - featureTarget - The matched element by the defined {@link #eventSelector} * * The method must also return the eventName as the first index of the array * to be passed to fireEvent. @@ -92371,11 +93906,10 @@ Ext.define('Ext.grid.feature.Feature', { }); /** - * A small abstract class that contains the shared behaviour for any summary - * calculations to be used in the grid. * @class Ext.grid.feature.AbstractSummary * @extends Ext.grid.feature.Feature - * @ignore + * A small abstract class that contains the shared behaviour for any summary + * calculations to be used in the grid. */ Ext.define('Ext.grid.feature.AbstractSummary', { @@ -92449,7 +93983,7 @@ Ext.define('Ext.grid.feature.AbstractSummary', { */ getColumnValue: function(column, summaryData){ var comp = Ext.getCmp(column.id), - value = summaryData[column.dataIndex], + value = summaryData[column.id], renderer = comp.summaryRenderer; if (renderer) { @@ -93269,6 +94803,7 @@ Ext.define('Ext.grid.feature.GroupingSummary', { reader = store.proxy.reader, groups = me.summaryGroups, columns = me.view.headerCt.getColumnsForTpl(), + remote, i, length, fieldData, @@ -93291,8 +94826,7 @@ Ext.define('Ext.grid.feature.GroupingSummary', { reader.root = me.remoteRoot; reader.buildExtractors(true); Ext.Array.each(reader.getRoot(reader.rawData), function(value) { - data[value[groupField]] = value; - data[value[groupField]]._remote = true; + remoteData[value[groupField]] = value; }); // restore initial reader configuration reader.root = root; @@ -93305,8 +94839,15 @@ Ext.define('Ext.grid.feature.GroupingSummary', { for (key in fieldData) { if (fieldData.hasOwnProperty(key)) { - if (!data[key]._remote) { - data[key][comp.dataIndex] = fieldData[key]; + data[key][comp.id] = fieldData[key]; + } + } + + for (key in remoteData) { + if (remoteData.hasOwnProperty(key)) { + remote = remoteData[key][comp.dataIndex]; + if (remote !== undefined) { + data[key][comp.id] = remote; } } } @@ -93629,7 +95170,7 @@ Ext.define('Ext.grid.feature.Summary', { for (i = 0, length = columns.length; i < length; ++i) { comp = Ext.getCmp(columns[i].id); - data[comp.dataIndex] = me.getSummary(store, comp.summaryType, comp.dataIndex, false); + data[comp.id] = me.getSummary(store, comp.summaryType, comp.dataIndex, false); } return data; } @@ -94020,7 +95561,8 @@ Ext.define('Ext.grid.plugin.Editing', { me.grid = grid; me.view = grid.view; me.initEvents(); - me.initFieldAccessors(me.view.getGridColumns()); + me.mon(grid, 'reconfigure', me.onReconfigure, me); + me.onReconfigure(); grid.relayEvents(me, ['beforeedit', 'edit', 'validateedit']); // Marks the grid as editable, so that the SelectionModel @@ -94028,6 +95570,14 @@ Ext.define('Ext.grid.plugin.Editing', { grid.isEditable = true; grid.editingPlugin = grid.view.editingPlugin = me; }, + + /** + * Fires after the grid is reconfigured + * @private + */ + onReconfigure: function(){ + this.initFieldAccessors(this.view.getGridColumns()); + }, /** * @private @@ -94352,7 +95902,7 @@ Ext.define('Ext.grid.plugin.Editing', { Ext.define('Ext.grid.plugin.CellEditing', { alias: 'plugin.cellediting', extend: 'Ext.grid.plugin.Editing', - requires: ['Ext.grid.CellEditor'], + requires: ['Ext.grid.CellEditor', 'Ext.util.DelayedTask'], constructor: function() { /** @@ -94435,6 +95985,12 @@ grid.on('validateedit', function(e) { this.editors = Ext.create('Ext.util.MixedCollection', false, function(editor) { return editor.editorId; }); + this.editTask = Ext.create('Ext.util.DelayedTask'); + }, + + onReconfigure: function(){ + this.editors.clear(); + this.callParent(); }, /** @@ -94443,6 +95999,7 @@ grid.on('validateedit', function(e) { */ destroy: function() { var me = this; + me.editTask.cancel(); me.editors.each(Ext.destroy, Ext); me.editors.clear(); me.callParent(arguments); @@ -94511,13 +96068,13 @@ grid.on('validateedit', function(e) { me.setActiveColumn(columnHeader); // Defer, so we have some time between view scroll to sync up the editor - Ext.defer(ed.startEdit, 15, ed, [me.getCell(record, columnHeader), value]); + me.editTask.delay(15, ed.startEdit, ed, [me.getCell(record, columnHeader), value]); } else { // BrowserBug: WebKit & IE refuse to focus the element, rather // it will focus it and then immediately focus the body. This // temporary hack works for Webkit and IE6. IE7 and 8 are still // broken - me.grid.getView().el.focus((Ext.isWebKit || Ext.isIE) ? 10 : false); + me.grid.getView().getEl(columnHeader).focus((Ext.isWebKit || Ext.isIE) ? 10 : false); } }, @@ -94556,7 +96113,7 @@ grid.on('validateedit', function(e) { getEditor: function(record, column) { var me = this, editors = me.editors, - editorId = column.itemId || column.id, + editorId = column.getItemId(), editor = editors.getByKey(editorId); if (editor) { @@ -94633,7 +96190,7 @@ grid.on('validateedit', function(e) { me.context.record.set(dataIndex, value); // Restore focus back to the view's element. } else { - grid.getView().el.focus(); + grid.getView().getEl(activeColumn).focus(); } me.context.value = value; me.fireEvent('edit', me, me.context); @@ -94648,7 +96205,7 @@ grid.on('validateedit', function(e) { cancelEdit: function() { var me = this, activeEd = me.getActiveEditor(), - viewEl = me.grid.getView().el; + viewEl = me.grid.getView().getEl(me.getActiveColumn()); me.setActiveEditor(null); me.setActiveColumn(null); @@ -94984,7 +96541,7 @@ Ext.define('Ext.grid.plugin.HeaderResizer', { resizeHeader = resizeHeader[resizeHeader.length - 1]; } - if (resizeHeader && !resizeHeader.fixed) { + if (resizeHeader && !(resizeHeader.fixed || this.disabled)) { this.activeHd = resizeHeader; overHeader.el.dom.style.cursor = this.eResizeCursor; } @@ -95562,14 +97119,11 @@ var grid = new Ext.grid.property.Grid({ } }); - * @constructor - * @param {Object} config The grid config object - * @xtype propertygrid */ Ext.define('Ext.grid.property.Grid', { extend: 'Ext.grid.Panel', - + alias: 'widget.propertygrid', alternateClassName: 'Ext.grid.PropertyGrid', @@ -95663,6 +97217,11 @@ var grid = Ext.create('Ext.grid.property.Grid', { */ nameField: 'name', + /** + * @cfg {Number} nameColumnWidth + * Optional. Specify the width for the name column. The value column will take any remaining space. Defaults to 115. + */ + // private config overrides enableColumnMove: false, columnLines: true, @@ -95685,7 +97244,7 @@ var grid = Ext.create('Ext.grid.property.Grid', { // Inject a startEdit which always edits the value column startEdit: function(record, column) { // Maintainer: Do not change this 'this' to 'me'! It is the CellEditing object's own scope. - Ext.grid.plugin.CellEditing.prototype.startEdit.call(this, record, me.headerCt.child('#' + me.valueField)); + return this.self.prototype.startEdit.call(this, record, me.headerCt.child('#' + me.valueField)); } })); @@ -95694,8 +97253,8 @@ var grid = Ext.create('Ext.grid.property.Grid', { onCellSelect: function(position) { if (position.column != 1) { position.column = 1; - Ext.selection.CellModel.prototype.onCellSelect.call(this, position); } + return this.self.prototype.onCellSelect.call(this, position); } }; me.customRenderers = me.customRenderers || {}; @@ -95713,7 +97272,7 @@ var grid = Ext.create('Ext.grid.property.Grid', { /** * @event beforepropertychange * Fires before a property value changes. Handlers can return false to cancel the property change - * (this will internally call {@link Ext.data.Record#reject} on the property's record). + * (this will internally call {@link Ext.data.Model#reject} on the property's record). * @param {Object} source The source data object for the grid (corresponds to the same object passed in * as the {@link #source} config property). * @param {String} recordId The record's id in the data store @@ -95749,7 +97308,7 @@ var grid = Ext.create('Ext.grid.property.Grid', { }; // Track changes to the data so we can fire our events. - this.store.on('update', me.onUpdate, me); + me.store.on('update', me.onUpdate, me); }, // private @@ -95790,7 +97349,7 @@ var grid = Ext.create('Ext.grid.property.Grid', { // returns the correct editor type for the property type, or a custom one keyed by the property name getCellEditor : function(record, column) { var me = this, - propName = record.get(me.nameField), + propName = record.get(me.nameField), val = record.get(me.valueField), editor = me.customEditors[propName]; @@ -95904,15 +97463,14 @@ grid.setSource({ * @class Ext.grid.property.HeaderContainer * @extends Ext.grid.header.Container * A custom HeaderContainer for the {@link Ext.grid.property.Grid}. Generally it should not need to be used directly. - * @constructor - * @param {Ext.grid.property.Grid} grid The grid this store will be bound to - * @param {Object} source The source data config object */ Ext.define('Ext.grid.property.HeaderContainer', { extend: 'Ext.grid.header.Container', alternateClassName: 'Ext.grid.PropertyColumnModel', + + nameWidth: 115, // private - strings used for locale support nameText : 'Name', @@ -95923,27 +97481,31 @@ Ext.define('Ext.grid.property.HeaderContainer', { // private nameColumnCls: Ext.baseCSSPrefix + 'grid-property-name', - - constructor : function(grid, store) { - this.grid = grid; - this.store = store; - this.callParent([{ + /** + * Creates new HeaderContainer. + * @param {Ext.grid.property.Grid} grid The grid this store will be bound to + * @param {Object} source The source data config object + */ + constructor : function(grid, store) { + var me = this; + + me.grid = grid; + me.store = store; + me.callParent([{ items: [{ - header: this.nameText, - width: 115, + header: me.nameText, + width: grid.nameColumnWidth || me.nameWidth, sortable: true, dataIndex: grid.nameField, - renderer: Ext.Function.bind(this.renderProp, this), + renderer: Ext.Function.bind(me.renderProp, me), itemId: grid.nameField, menuDisabled :true, - tdCls: this.nameColumnCls + tdCls: me.nameColumnCls }, { - header: this.valueText, - renderer: Ext.Function.bind(this.renderCell, this), - getEditor: function(record) { - return grid.getCellEditor(record, this); - }, + header: me.valueText, + renderer: Ext.Function.bind(me.renderCell, me), + getEditor: Ext.Function.bind(me.getCellEditor, me), flex: 1, fixed: true, dataIndex: grid.valueField, @@ -95952,6 +97514,10 @@ Ext.define('Ext.grid.property.HeaderContainer', { }] }]); }, + + getCellEditor: function(record){ + return this.grid.getCellEditor(record, this); + }, // private // Render a property name cell @@ -95963,16 +97529,16 @@ Ext.define('Ext.grid.property.HeaderContainer', { // Render a property value cell renderCell : function(val, meta, rec) { var me = this, - renderer = this.grid.customRenderers[rec.get(me.grid.nameField)], + renderer = me.grid.customRenderers[rec.get(me.grid.nameField)], result = val; if (renderer) { - return renderer.apply(this, arguments); + return renderer.apply(me, arguments); } if (Ext.isDate(val)) { - result = this.renderDate(val); + result = me.renderDate(val); } else if (Ext.isBoolean(val)) { - result = this.renderBool(val); + result = me.renderBool(val); } return Ext.util.Format.htmlEncode(result); }, @@ -96035,9 +97601,6 @@ Ext.define('Ext.grid.property.Property', { * A custom {@link Ext.data.Store} for the {@link Ext.grid.property.Grid}. This class handles the mapping * between the custom data source objects supported by the grid and the {@link Ext.grid.property.Property} format * used by the {@link Ext.data.Store} base class. - * @constructor - * @param {Ext.grid.Grid} grid The grid this store will be bound to - * @param {Object} source The source data config object */ Ext.define('Ext.grid.property.Store', { @@ -96047,6 +97610,11 @@ Ext.define('Ext.grid.property.Store', { uses: ['Ext.data.reader.Reader', 'Ext.data.proxy.Proxy', 'Ext.data.ResultSet', 'Ext.grid.property.Property'], + /** + * Creates new property store. + * @param {Ext.grid.Grid} grid The grid this store will be bound to + * @param {Object} source The source data config object + */ constructor : function(grid, source){ var me = this; @@ -96144,7 +97712,7 @@ Ext.define('Ext.grid.property.Store', { // only create if specified. me.source[prop] = value; rec = new Ext.grid.property.Property({name: prop, value: value}, prop); - me.store.add(rec); + me.add(rec); } }, @@ -96152,7 +97720,7 @@ Ext.define('Ext.grid.property.Store', { remove : function(prop) { var rec = this.getRec(prop); if (rec) { - store.remove(rec); + this.callParent([rec]); delete this.source[prop]; } }, @@ -96492,7 +98060,7 @@ Ext.define('Ext.layout.container.Accordion', { extend: 'Ext.layout.container.VBox', alias: ['layout.accordion'], alternateClassName: 'Ext.layout.AccordionLayout', - + align: 'stretch', /** @@ -96570,7 +98138,7 @@ Ext.define('Ext.layout.container.Accordion', { me.callParent(arguments); if (me.fill) { - if (!me.owner.el.dom.style.height) { + if (!me.owner.el.dom.style.height || !me.getLayoutTargetSize().height) { return false; } } else { @@ -96609,7 +98177,6 @@ Ext.define('Ext.layout.container.Accordion', { delete comp.hideHeader; comp.collapsible = true; comp.title = comp.title || ' '; - comp.setBorder(false); // Set initial sizes comp.width = targetSize.width; @@ -96622,12 +98189,19 @@ Ext.define('Ext.layout.container.Accordion', { comp.collapsed = true; } // Otherwise expand the first item with collapsed explicitly configured as false - else if (comp.collapsed === false) { + else if (comp.hasOwnProperty('collapsed') && comp.collapsed === false) { comp.flex = 1; me.expandedItem = i; } else { comp.collapsed = true; } + // If we are fitting, then intercept expand/collapse requests. + me.owner.mon(comp, { + show: me.onComponentShow, + beforeexpand: me.onComponentExpand, + beforecollapse: me.onComponentCollapse, + scope: me + }); } else { delete comp.flex; comp.animCollapse = me.initialAnimate; @@ -96646,10 +98220,10 @@ Ext.define('Ext.layout.container.Accordion', { comp.flex = 1; } } - + // Render all Panels. me.callParent(arguments); - + // Postprocess rendered Panels. ln = renderedPanels.length; for (i = 0; i < ln; i++) { @@ -96660,24 +98234,13 @@ Ext.define('Ext.layout.container.Accordion', { comp.header.addCls(Ext.baseCSSPrefix + 'accordion-hd'); comp.body.addCls(Ext.baseCSSPrefix + 'accordion-body'); - - // If we are fitting, then intercept expand/collapse requests. - if (me.fill) { - me.owner.mon(comp, { - show: me.onComponentShow, - beforeexpand: me.onComponentExpand, - beforecollapse: me.onComponentCollapse, - scope: me - }); - } } }, onLayout: function() { var me = this; - - me.updatePanelClasses(); - + + if (me.fill) { me.callParent(arguments); } else { @@ -96695,24 +98258,27 @@ Ext.define('Ext.layout.container.Accordion', { } } } - + me.updatePanelClasses(); + return me; }, - + updatePanelClasses: function() { var children = this.getLayoutItems(), ln = children.length, siblingCollapsed = true, i, child; - + for (i = 0; i < ln; i++) { child = children[i]; - if (!siblingCollapsed) { - child.header.addCls(Ext.baseCSSPrefix + 'accordion-hd-sibling-expanded'); + + if (siblingCollapsed) { + child.header.removeCls(Ext.baseCSSPrefix + 'accordion-hd-sibling-expanded'); } else { - child.header.removeCls(Ext.baseCSSPrefix + 'accordion-hd-sibling-expanded'); + child.header.addCls(Ext.baseCSSPrefix + 'accordion-hd-sibling-expanded'); } + if (i + 1 == ln && child.collapsed) { child.header.addCls(Ext.baseCSSPrefix + 'accordion-hd-last-collapsed'); } @@ -96741,7 +98307,7 @@ Ext.define('Ext.layout.container.Accordion', { me.setCollapsed(comp); } } - + me.animate = me.initialAnimate; me.layout(); me.animate = false; @@ -96763,7 +98329,7 @@ Ext.define('Ext.layout.container.Accordion', { if (expanded.length === 1 && expanded[0] === comp) { me.setExpanded(toExpand); } - + me.animate = me.initialAnimate; me.layout(); me.animate = false; @@ -96847,8 +98413,6 @@ Ext.define('Ext.layout.container.Accordion', { * The Splitter will then call that sibling Panel's {@link Ext.panel.Panel#collapse collapse} or {@link Ext.panel.Panel#expand expand} method * to perform the appropriate operation (depending on the sibling collapse state). To create the mini-collapse tool but take care * of collapsing yourself, configure the splitter with{@link #performCollapse} false
.
- *
- * @xtype splitter
*/
Ext.define('Ext.resizer.Splitter', {
extend: 'Ext.Component',
@@ -96861,7 +98425,7 @@ Ext.define('Ext.resizer.Splitter', {
],
baseCls: Ext.baseCSSPrefix + 'splitter',
- collapsedCls: Ext.baseCSSPrefix + 'splitter-collapsed',
+ collapsedClsInternal: Ext.baseCSSPrefix + 'splitter-collapsed',
/**
* @cfg {Boolean} collapsible
@@ -96895,6 +98459,11 @@ Ext.define('Ext.resizer.Splitter', {
* that the splitter is between.
*/
defaultSplitMax: 1000,
+
+ /**
+ * @cfg {String} collapsedCls
+ * A class to add to the splitter when it is collapsed. See {@link #collapsible}.
+ */
width: 5,
height: 5,
@@ -96979,15 +98548,17 @@ Ext.define('Ext.resizer.Splitter', {
},
getCollapseTarget: function() {
- return this.collapseTarget.isComponent ? this.collapseTarget : this.collapseTarget == 'prev' ? this.previousSibling() : this.nextSibling();
+ var me = this;
+
+ return me.collapseTarget.isComponent ? me.collapseTarget : me.collapseTarget == 'prev' ? me.previousSibling() : me.nextSibling();
},
onTargetCollapse: function(target) {
- this.el.addCls(this.collapsedCls);
+ this.el.addCls([this.collapsedClsInternal, this.collapsedCls]);
},
onTargetExpand: function(target) {
- this.el.removeCls(this.collapsedCls);
+ this.el.removeCls([this.collapsedClsInternal, this.collapsedCls]);
},
toggleTargetCmp: function(e, t) {
@@ -97097,8 +98668,6 @@ Ext.define('Ext.layout.container.Border', {
bindToOwnerCtContainer: true,
- fixedLayout: false,
-
percentageRe: /(\d+)%/,
slideDirection: {
@@ -97168,6 +98737,14 @@ Ext.define('Ext.layout.container.Border', {
//
},
+ /*
+ * Gathers items for a layout operation. Injected into child Box layouts through configuration.
+ * We must not include child items which are floated over the layout (are primed with a slide out animation)
+ */
+ getVisibleItems: function() {
+ return Ext.ComponentQuery.query(':not([slideOutAnim])', this.callParent(arguments));
+ },
+
initializeBorderLayout: function() {
var me = this,
i = 0,
@@ -97258,7 +98835,8 @@ Ext.define('Ext.layout.container.Border', {
maintainFlex: true,
layout: {
type: 'hbox',
- align: 'stretch'
+ align: 'stretch',
+ getVisibleItems: me.getVisibleItems
}
}));
hBoxItems.push(regions.center);
@@ -97312,7 +98890,8 @@ Ext.define('Ext.layout.container.Border', {
el: me.getTarget(),
layout: Ext.applyIf({
type: 'vbox',
- align: 'stretch'
+ align: 'stretch',
+ getVisibleItems: me.getVisibleItems
}, me.initialConfig)
});
me.createItems(me.shadowContainer, vBoxItems);
@@ -97459,6 +99038,7 @@ Ext.define('Ext.layout.container.Border', {
// Mini collapse means that the splitter is the placeholder Component
if (comp.collapseMode == 'mini') {
comp.placeholder = resizer;
+ resizer.collapsedCls = comp.collapsedCls;
}
// Arrange to hide/show a region's associated splitter when the region is hidden/shown
@@ -97471,7 +99051,7 @@ Ext.define('Ext.layout.container.Border', {
},
// Private
- // Propogates the min/maxHeight values from the inner hbox items to its container.
+ // Propagates the min/maxHeight values from the inner hbox items to its container.
fixHeightConstraints: function () {
var me = this,
ct = me.embeddedContainer,
@@ -97560,7 +99140,7 @@ Ext.define('Ext.layout.container.Border', {
baseCls: comp.baseCls + '-header',
ui: comp.ui,
indicateDrag: comp.draggable,
- cls: Ext.baseCSSPrefix + 'region-collapsed-placeholder ' + Ext.baseCSSPrefix + 'region-collapsed-' + comp.collapseDirection + '-placeholder',
+ cls: Ext.baseCSSPrefix + 'region-collapsed-placeholder ' + Ext.baseCSSPrefix + 'region-collapsed-' + comp.collapseDirection + '-placeholder ' + comp.collapsedCls,
listeners: comp.floatable ? {
click: {
fn: function(e) {
@@ -98080,72 +99660,84 @@ Ext.define('Ext.layout.container.Border', {
/**
* @class Ext.layout.container.Card
* @extends Ext.layout.container.AbstractCard
- * This layout manages multiple child Components, each fitted to the Container, where only a single child Component can be - * visible at any given time. This layout style is most commonly used for wizards, tab implementations, etc. - * This class is intended to be extended or created via the layout:'card' {@link Ext.container.Container#layout} config, - * and should generally not need to be created directly via the new keyword.
- *The CardLayout's focal method is {@link #setActiveItem}. Since only one panel is displayed at a time, - * the only way to move from one Component to the next is by calling setActiveItem, passing the id or index of - * the next panel to display. The layout itself does not provide a user interface for handling this navigation, - * so that functionality must be provided by the developer.
- *In the following example, a simplistic wizard setup is demonstrated. A button bar is added - * to the footer of the containing panel to provide navigation buttons. The buttons will be handled by a - * common navigation routine -- for this example, the implementation of that routine has been ommitted since - * it can be any type of custom logic. Note that other uses of a CardLayout (like a tab control) would require a - * completely different implementation. For serious implementations, a better approach would be to extend - * CardLayout to provide the custom functionality needed. - * {@img Ext.layout.container.Card/Ext.layout.container.Card.png Ext.layout.container.Card container layout} - * Example usage:
- *
- var navHandler = function(direction){
- // This routine could contain business logic required to manage the navigation steps.
- // It would call setActiveItem as needed, manage navigation button state, handle any
- // branching logic that might be required, handle alternate actions like cancellation
- // or finalization, etc. A complete wizard implementation could get pretty
- // sophisticated depending on the complexity required, and should probably be
- // done as a subclass of CardLayout in a real-world implementation.
- };
-
- Ext.create('Ext.panel.Panel', {
- title: 'Example Wizard',
- width: 300,
- height: 200,
- layout: 'card',
- activeItem: 0, // make sure the active item is set on the container config!
- bodyStyle: 'padding:15px',
- defaults: {
- // applied to each contained panel
- border:false
- },
- // just an example of one possible navigation scheme, using buttons
- bbar: [
- {
- id: 'move-prev',
- text: 'Back',
- handler: navHandler(this, [-1]),
- disabled: true
- },
- '->', // greedy spacer so that the buttons are aligned to each side
- {
- id: 'move-next',
- text: 'Next',
- handler: navHandler(this, [1])
- }],
- // the panels (or "cards") within the layout
- items: [{
- id: 'card-0',
- html: '<h1>Welcome to the Wizard!</h1><p>Step 1 of 3</p>'
- },{
- id: 'card-1',
- html: '<p>Step 2 of 3</p>'
- },{
- id: 'card-2',
- html: '<h1>Congratulations!</h1><p>Step 3 of 3 - Complete</p>'
- }],
- renderTo: Ext.getBody()
- });
-
- */
+ *
+ * This layout manages multiple child Components, each fitted to the Container, where only a single child Component can be
+ * visible at any given time. This layout style is most commonly used for wizards, tab implementations, etc.
+ * This class is intended to be extended or created via the layout:'card' {@link Ext.container.Container#layout} config,
+ * and should generally not need to be created directly via the new keyword.
+ *
+ * The CardLayout's focal method is {@link #setActiveItem}. Since only one panel is displayed at a time,
+ * the only way to move from one Component to the next is by calling setActiveItem, passing the id or index of
+ * the next panel to display. The layout itself does not provide a user interface for handling this navigation,
+ * so that functionality must be provided by the developer.
+ *
+ * In the following example, a simplistic wizard setup is demonstrated. A button bar is added
+ * to the footer of the containing panel to provide navigation buttons. The buttons will be handled by a
+ * common navigation routine. Note that other uses of a CardLayout (like a tab control) would require a
+ * completely different implementation. For serious implementations, a better approach would be to extend
+ * CardLayout to provide the custom functionality needed.
+ *
+ * {@img Ext.layout.container.Card/Ext.layout.container.Card.png Ext.layout.container.Card container layout}
+ *
+ * Example usage:
+ *
+ * var navigate = function(panel, direction){
+ * // This routine could contain business logic required to manage the navigation steps.
+ * // It would call setActiveItem as needed, manage navigation button state, handle any
+ * // branching logic that might be required, handle alternate actions like cancellation
+ * // or finalization, etc. A complete wizard implementation could get pretty
+ * // sophisticated depending on the complexity required, and should probably be
+ * // done as a subclass of CardLayout in a real-world implementation.
+ * var layout = panel.getLayout();
+ * layout[direction]();
+ * Ext.getCmp('move-prev').setDisabled(!layout.getPrev());
+ * Ext.getCmp('move-next').setDisabled(!layout.getNext());
+ * };
+ *
+ * Ext.create('Ext.panel.Panel', {
+ * title: 'Example Wizard',
+ * width: 300,
+ * height: 200,
+ * layout: 'card',
+ * activeItem: 0, // make sure the active item is set on the container config!
+ * bodyStyle: 'padding:15px',
+ * defaults: {
+ * // applied to each contained panel
+ * border: false
+ * },
+ * // just an example of one possible navigation scheme, using buttons
+ * bbar: [
+ * {
+ * id: 'move-prev',
+ * text: 'Back',
+ * handler: function(btn) {
+ * navigate(btn.up("panel"), "prev");
+ * },
+ * disabled: true
+ * },
+ * '->', // greedy spacer so that the buttons are aligned to each side
+ * {
+ * id: 'move-next',
+ * text: 'Next',
+ * handler: function(btn) {
+ * navigate(btn.up("panel"), "next");
+ * }
+ * }
+ * ],
+ * // the panels (or "cards") within the layout
+ * items: [{
+ * id: 'card-0',
+ * html: 'Step 1 of 3
' + * },{ + * id: 'card-1', + * html: 'Step 2 of 3
' + * },{ + * id: 'card-2', + * html: 'Step 3 of 3 - Complete
' + * }], + * renderTo: Ext.getBody() + * }); + */ Ext.define('Ext.layout.container.Card', { /* Begin Definitions */ @@ -98157,15 +99749,32 @@ Ext.define('Ext.layout.container.Card', { /* End Definitions */ + /** + * Makes the given card active. + * + * var card1 = Ext.create('Ext.panel.Panel', {itemId: 'card-1'}); + * var card2 = Ext.create('Ext.panel.Panel', {itemId: 'card-2'}); + * var panel = Ext.create('Ext.panel.Panel', { + * layout: 'card', + * activeItem: 0, + * items: [card1, card2] + * }); + * // These are all equivalent + * panel.getLayout().setActiveItem(card2); + * panel.getLayout().setActiveItem('card-2'); + * panel.getLayout().setActiveItem(1); + * + * @param {Ext.Component/Number/String} newCard The component, component {@link Ext.Component#id id}, + * {@link Ext.Component#itemId itemId}, or index of component. + * @return {Ext.Component} the activated component or false when nothing activated. + * False is returned also when trying to activate an already active card. + */ setActiveItem: function(newCard) { var me = this, owner = me.owner, oldCard = me.activeItem, newIndex; - // Block upward layouts until we are done. - me.layoutBusy = true; - newCard = me.parseActiveItem(newCard); newIndex = owner.items.indexOf(newCard); @@ -98187,22 +99796,22 @@ Ext.define('Ext.layout.container.Card', { // Fire the beforeactivate and beforedeactivate events on the cards if (newCard.fireEvent('beforeactivate', newCard, oldCard) === false) { - me.layoutBusy = false; return false; } if (oldCard && oldCard.fireEvent('beforedeactivate', oldCard, newCard) === false) { - me.layoutBusy = false; return false; } // If the card hasnt been sized yet, do it now - if (!me.sizeAllCards) { - me.setItemBox(newCard, me.getTargetBox()); - } - else { + if (me.sizeAllCards) { // onLayout calls setItemBox me.onLayout(); } + else { + me.setItemBox(newCard, me.getTargetBox()); + } + + me.owner.suspendLayout = true; if (oldCard) { if (me.hideInactive) { @@ -98212,26 +99821,29 @@ Ext.define('Ext.layout.container.Card', { } // Make sure the new card is shown + me.owner.suspendLayout = false; if (newCard.hidden) { newCard.show(); + } else { + me.onLayout(); } newCard.fireEvent('activate', newCard, oldCard); - me.layoutBusy = false; - - if (!me.sizeAllCards) { - if (!owner.componentLayout.layoutBusy) { - me.onLayout(); - } - } return newCard; } - - me.layoutBusy = false; return false; - } -}); + }, + + configureItem: function(item) { + + // Card layout only controls dimensions which IT has controlled. + // That calculation has to be determined at run time by examining the ownerCt's isFixedWidth()/isFixedHeight() methods + item.layoutManagedHeight = 0; + item.layoutManagedWidth = 0; + + this.callParent(arguments); + }}); /** * @class Ext.layout.container.Column * @extends Ext.layout.container.Auto @@ -98415,6 +100027,16 @@ Ext.define('Ext.layout.container.Column', { } } delete me.adjustmentPass; + }, + + configureItem: function(item) { + if (item.columnWidth) { + item.layoutManagedWidth = 1; + } else { + item.layoutManagedWidth = 2; + } + item.layoutManagedHeight = 2; + this.callParent(arguments); } }); /** @@ -98531,6 +100153,18 @@ Ext.define('Ext.layout.container.Table', { */ tableAttrs:null, + /** + * @cfg {Object} trAttrs + *An object containing properties which are added to the {@link Ext.core.DomHelper DomHelper} specification + * used to create the layout's <tr> elements. + */ + + /** + * @cfg {Object} tdAttrs + *
An object containing properties which are added to the {@link Ext.core.DomHelper DomHelper} specification
+ * used to create the layout's <td> elements.
+ */
+
/**
* @private
* Iterates over all passed items, ensuring they are rendered in a cell in the proper
@@ -98559,6 +100193,9 @@ Ext.define('Ext.layout.container.Table', {
trEl = rows[rowIdx];
if (!trEl) {
trEl = tbody.insertRow(rowIdx);
+ if (this.trAttrs) {
+ trEl.set(this.trAttrs);
+ }
}
// If no cell present, create and insert one
@@ -98577,6 +100214,9 @@ Ext.define('Ext.layout.container.Table', {
}
// Set the cell properties
+ if (this.tdAttrs) {
+ tdEl.set(this.tdAttrs);
+ }
tdEl.set({
colSpan: item.colspan || 1,
rowSpan: item.rowspan || 1,
@@ -98658,9 +100298,11 @@ Ext.define('Ext.layout.container.Table', {
});
// Increment
- rowspans[colIdx] = item.rowspan || 1;
- colIdx += item.colspan || 1;
- cellIdx++;
+ for (j = item.colspan || 1; j; --j) {
+ rowspans[colIdx] = item.rowspan || 1;
+ ++colIdx;
+ }
+ ++cellIdx;
}
return cells;
@@ -98703,37 +100345,36 @@ Ext.define('Ext.layout.container.Table', {
/**
* @class Ext.menu.Item
* @extends Ext.Component
-
+ *
* A base class for all menu items that require menu-related functionality such as click handling,
* sub-menus, icons, etc.
+ *
* {@img Ext.menu.Menu/Ext.menu.Menu.png Ext.menu.Menu component}
-__Example Usage:__
- Ext.create('Ext.menu.Menu', {
- width: 100,
- height: 100,
- floating: false, // usually you want this set to True (default)
- renderTo: Ext.getBody(), // usually rendered by it's containing component
- items: [{
- text: 'icon item',
- iconCls: 'add16'
- },{
- text: 'text item',
- },{
- text: 'plain item',
- plain: true
- }]
- });
-
- * @xtype menuitem
- * @markdown
- * @constructor
- * @param {Object} config The config object
+ *
+ * __Example Usage:__
+ *
+ * Ext.create('Ext.menu.Menu', {
+ * width: 100,
+ * height: 100,
+ * floating: false, // usually you want this set to True (default)
+ * renderTo: Ext.getBody(), // usually rendered by it's containing component
+ * items: [{
+ * text: 'icon item',
+ * iconCls: 'add16'
+ * },{
+ * text: 'text item',
+ * },{
+ * text: 'plain item',
+ * plain: true
+ * }]
+ * });
+ *
*/
Ext.define('Ext.menu.Item', {
extend: 'Ext.Component',
alias: 'widget.menuitem',
alternateClassName: 'Ext.menu.TextItem',
-
+
/**
* @property {Boolean} activated
* Whether or not this item is currently activated
@@ -98746,19 +100387,19 @@ Ext.define('Ext.menu.Item', {
* @markdown
*/
activeCls: Ext.baseCSSPrefix + 'menu-item-active',
-
+
/**
* @cfg {String} ariaRole @hide
*/
ariaRole: 'menuitem',
-
+
/**
* @cfg {Boolean} canActivate
* Whether or not this menu item can be activated when focused/mouseovered. Defaults to `true`.
* @markdown
*/
canActivate: true,
-
+
/**
* @cfg {Number} clickHideDelay
* The delay in milliseconds to wait before hiding the menu after clicking the menu item.
@@ -98766,13 +100407,13 @@ Ext.define('Ext.menu.Item', {
* @markdown
*/
clickHideDelay: 1,
-
+
/**
* @cfg {Boolean} destroyMenu
* Whether or not to destroy any associated sub-menu when this item is destroyed. Defaults to `true`.
*/
destroyMenu: true,
-
+
/**
* @cfg {String} disabledCls
* The CSS class added to the menu item when the item is disabled.
@@ -98780,40 +100421,40 @@ Ext.define('Ext.menu.Item', {
* @markdown
*/
disabledCls: Ext.baseCSSPrefix + 'menu-item-disabled',
-
+
/**
* @cfg {String} href
* The href attribute to use for the underlying anchor link. Defaults to `#`.
* @markdown
*/
-
+
/**
* @cfg {String} hrefTarget
* The target attribute to use for the underlying anchor link. Defaults to `undefined`.
* @markdown
*/
-
+
/**
* @cfg {Boolean} hideOnClick
* Whether to not to hide the owning menu when this item is clicked. Defaults to `true`.
* @markdown
*/
hideOnClick: true,
-
+
/**
* @cfg {String} icon
* The path to an icon to display in this item. Defaults to `Ext.BLANK_IMAGE_URL`.
* @markdown
*/
-
+
/**
* @cfg {String} iconCls
* A CSS class that specifies a `background-image` to use as the icon for this item. Defaults to `undefined`.
* @markdown
*/
-
+
isMenuItem: true,
-
+
/**
* @cfg {Mixed} menu
* Either an instance of {@link Ext.menu.Menu} or a config object for an {@link Ext.menu.Menu}
@@ -98821,7 +100462,7 @@ Ext.define('Ext.menu.Item', {
* @markdown
* @property {Ext.menu.Menu} menu The sub-menu associated with this item, if one was configured.
*/
-
+
/**
* @cfg {String} menuAlign
* The default {@link Ext.core.Element#getAlignToXY Ext.Element.getAlignToXY} anchor position value for this
@@ -98829,27 +100470,27 @@ Ext.define('Ext.menu.Item', {
* @markdown
*/
menuAlign: 'tl-tr?',
-
+
/**
* @cfg {Number} menuExpandDelay
* The delay in milliseconds before this item's sub-menu expands after this item is moused over. Defaults to `200`.
* @markdown
*/
menuExpandDelay: 200,
-
+
/**
* @cfg {Number} menuHideDelay
* The delay in milliseconds before this item's sub-menu hides after this item is moused out. Defaults to `200`.
* @markdown
*/
menuHideDelay: 200,
-
+
/**
* @cfg {Boolean} plain
* Whether or not this item is plain text/html with no icon or visual activation. Defaults to `false`.
* @markdown
*/
-
+
renderTpl: [
'
0
.
+ */
+ heightIncrement : 0,
+
+ /**
+ * @cfg {Number} widthIncrement The increment to snap the width resize in pixels
+ * Defaults to 0
.
+ */
+ widthIncrement : 0,
+
/**
* @cfg {Number} minHeight The minimum height for the element (defaults to 20)
*/
@@ -100969,6 +102659,8 @@ Ext.define('Ext.resizer.Resizer', {
delegate: '.' + me.handleCls,
dynamic: me.dynamic,
preserveRatio: me.preserveRatio,
+ heightIncrement: me.heightIncrement,
+ widthIncrement: me.widthIncrement,
minHeight: me.minHeight,
maxHeight: me.maxHeight,
minWidth: me.minWidth,
@@ -101121,11 +102813,11 @@ Ext.define('Ext.resizer.Resizer', {
var me = this,
handle;
if (Ext.isIE6) {
- handle = me.east;
+ handle = me.east;
if (handle) {
handle.setHeight(me.el.getHeight());
}
- handle = me.west;
+ handle = me.west;
if (handle) {
handle.setHeight(me.el.getHeight());
}
@@ -101137,6 +102829,8 @@ Ext.define('Ext.resizer.Resizer', {
/**
* @class Ext.resizer.ResizeTracker
* @extends Ext.dd.DragTracker
+ * Private utility class for Ext.resizer.Resizer.
+ * @private
*/
Ext.define('Ext.resizer.ResizeTracker', {
extend: 'Ext.dd.DragTracker',
@@ -101240,6 +102934,8 @@ Ext.define('Ext.resizer.ResizeTracker', {
ratio,
widthAdjust = 0,
heightAdjust = 0,
+ snappedWidth,
+ snappedHeight,
adjustX = 0,
adjustY = 0,
dragRatio,
@@ -101304,16 +103000,49 @@ Ext.define('Ext.resizer.ResizeTracker', {
y: box.y + adjustY
};
+ // Snap value between stops according to configured increments
+ snappedWidth = Ext.Number.snap(newBox.width, me.widthIncrement);
+ snappedHeight = Ext.Number.snap(newBox.height, me.heightIncrement);
+ if (snappedWidth != newBox.width || snappedHeight != newBox.height){
+ switch (region) {
+ case 'northeast':
+ newBox.y -= snappedHeight - newBox.height;
+ break;
+ case 'north':
+ newBox.y -= snappedHeight - newBox.height;
+ break;
+ case 'southwest':
+ newBox.x -= snappedWidth - newBox.width;
+ break;
+ case 'west':
+ newBox.x -= snappedWidth - newBox.width;
+ break;
+ case 'northwest':
+ newBox.x -= snappedWidth - newBox.width;
+ newBox.y -= snappedHeight - newBox.height;
+ }
+ newBox.width = snappedWidth;
+ newBox.height = snappedHeight;
+ }
+
// out of bounds
if (newBox.width < me.minWidth || newBox.width > me.maxWidth) {
newBox.width = Ext.Number.constrain(newBox.width, me.minWidth, me.maxWidth);
- newBox.x = me.lastX || newBox.x;
+
+ // Re-adjust the X position if we were dragging the west side
+ if (adjustX) {
+ newBox.x = box.x + (box.width - newBox.width);
+ }
} else {
me.lastX = newBox.x;
}
if (newBox.height < me.minHeight || newBox.height > me.maxHeight) {
newBox.height = Ext.Number.constrain(newBox.height, me.minHeight, me.maxHeight);
- newBox.y = me.lastY || newBox.y;
+
+ // Re-adjust the Y position if we were dragging the north side
+ if (adjustY) {
+ newBox.y = box.y + (box.height - newBox.height);
+ }
} else {
me.lastY = newBox.y;
}
@@ -101432,12 +103161,27 @@ Ext.define('Ext.resizer.SplitterTracker', {
onBeforeStart: function(e) {
var me = this,
prevCmp = me.getPrevCmp(),
- nextCmp = me.getNextCmp();
+ nextCmp = me.getNextCmp(),
+ collapseEl = me.getSplitter().collapseEl,
+ overlay;
+
+ if (collapseEl && (e.getTarget() === me.getSplitter().collapseEl.dom)) {
+ return false;
+ }
// SplitterTracker is disabled if any of its adjacents are collapsed.
if (nextCmp.collapsed || prevCmp.collapsed) {
return false;
}
+
+ overlay = me.overlay = Ext.getBody().createChild({
+ cls: me.overlayCls,
+ html: ' '
+ });
+ overlay.unselectable();
+ overlay.setSize(Ext.core.Element.getViewWidth(true), Ext.core.Element.getViewHeight(true));
+ overlay.show();
+
// store boxes of previous and next
me.prevBox = prevCmp.getEl().getBox();
me.nextBox = nextCmp.getEl().getBox();
@@ -101446,17 +103190,8 @@ Ext.define('Ext.resizer.SplitterTracker', {
// We move the splitter el. Add the proxy class.
onStart: function(e) {
- var splitter = this.getSplitter(),
- overlay;
-
+ var splitter = this.getSplitter();
splitter.addCls(splitter.baseCls + '-active');
- overlay = this.overlay = Ext.getBody().createChild({
- cls: this.overlayCls,
- html: ' '
- });
- overlay.unselectable();
- overlay.setSize(Ext.core.Element.getViewWidth(true), Ext.core.Element.getViewHeight(true));
- overlay.show();
},
// calculate the constrain Region in which the splitter el may be moved.
@@ -101568,16 +103303,26 @@ Ext.define('Ext.resizer.SplitterTracker', {
layout.onLayout();
},
+ // Cleans up the overlay (if we have one) and calls the base. This cannot be done in
+ // onEnd, because onEnd is only called if a drag is detected but the overlay is created
+ // regardless (by onBeforeStart).
+ endDrag: function () {
+ var me = this;
+
+ if (me.overlay) {
+ me.overlay.remove();
+ delete me.overlay;
+ }
+
+ me.callParent(arguments); // this calls onEnd
+ },
+
// perform the resize and remove the proxy class from the splitter el
onEnd: function(e) {
var me = this,
splitter = me.getSplitter();
splitter.removeCls(splitter.baseCls + '-active');
- if (me.overlay) {
- me.overlay.remove();
- delete me.overlay;
- }
me.performResize();
},
@@ -101825,7 +103570,7 @@ Ext.define('Ext.selection.CellModel', {
/**
* @class Ext.selection.RowModel
* @extends Ext.selection.Model
- *
+ *
* Implement row based navigation via keyboard.
*
* Must synchronize across grid sections
@@ -101834,23 +103579,43 @@ Ext.define('Ext.selection.RowModel', {
extend: 'Ext.selection.Model',
alias: 'selection.rowmodel',
requires: ['Ext.util.KeyNav'],
-
+
/**
* @private
* Number of pixels to scroll to the left/right when pressing
* left/right keys.
*/
deltaScroll: 5,
-
+
/**
* @cfg {Boolean} enableKeyNav
- *
+ *
* Turns on/off keyboard navigation within the grid. Defaults to true.
*/
enableKeyNav: true,
-
+
constructor: function(){
this.addEvents(
+ /**
+ * @event beforedeselect
+ * Fired before a record is deselected. If any listener returns false, the
+ * deselection is cancelled.
+ * @param {Ext.selection.RowSelectionModel} this
+ * @param {Ext.data.Model} record The deselected record
+ * @param {Number} index The row index deselected
+ */
+ 'beforedeselect',
+
+ /**
+ * @event beforeselect
+ * Fired before a record is selected. If any listener returns false, the
+ * selection is cancelled.
+ * @param {Ext.selection.RowSelectionModel} this
+ * @param {Ext.data.Model} record The selected record
+ * @param {Number} index The row index selected
+ */
+ 'beforeselect',
+
/**
* @event deselect
* Fired after a record is deselected
@@ -101859,7 +103624,7 @@ Ext.define('Ext.selection.RowModel', {
* @param {Number} index The row index deselected
*/
'deselect',
-
+
/**
* @event select
* Fired after a record is selected
@@ -101869,12 +103634,12 @@ Ext.define('Ext.selection.RowModel', {
*/
'select'
);
- this.callParent(arguments);
+ this.callParent(arguments);
},
bindComponent: function(view) {
var me = this;
-
+
me.views = me.views || [];
me.views.push(view);
me.bind(view.getStore(), true);
@@ -101891,7 +103656,7 @@ Ext.define('Ext.selection.RowModel', {
initKeyNav: function(view) {
var me = this;
-
+
if (!view.rendered) {
view.on('render', Ext.Function.bind(me.initKeyNav, me, [view], 0), me, {single: true});
return;
@@ -101939,7 +103704,7 @@ Ext.define('Ext.selection.RowModel', {
onKeyEnd: function(e, t) {
var me = this,
last = me.store.getAt(me.store.getCount() - 1);
-
+
if (last) {
if (e.shiftKey) {
me.selectRange(last, me.lastFocused || 0);
@@ -101956,7 +103721,7 @@ Ext.define('Ext.selection.RowModel', {
onKeyHome: function(e, t) {
var me = this,
first = me.store.getAt(0);
-
+
if (first) {
if (e.shiftKey) {
me.selectRange(first, me.lastFocused || 0);
@@ -101977,7 +103742,7 @@ Ext.define('Ext.selection.RowModel', {
prevIdx,
prevRecord,
currRec;
-
+
if (rowsVisible) {
selIdx = me.lastFocused ? me.store.indexOf(me.lastFocused) : 0;
prevIdx = selIdx - rowsVisible;
@@ -102007,7 +103772,7 @@ Ext.define('Ext.selection.RowModel', {
nextIdx,
nextRecord,
currRec;
-
+
if (rowsVisible) {
selIdx = me.lastFocused ? me.store.indexOf(me.lastFocused) : 0;
nextIdx = selIdx + rowsVisible;
@@ -102037,7 +103802,7 @@ Ext.define('Ext.selection.RowModel', {
e.stopEvent();
var me = this,
record = me.lastFocused;
-
+
if (record) {
if (me.isSelected(record)) {
me.doDeselect(record, false);
@@ -102056,7 +103821,7 @@ Ext.define('Ext.selection.RowModel', {
view = me.views[0],
idx = me.store.indexOf(me.lastFocused),
record;
-
+
if (idx > 0) {
// needs to be the filtered count as thats what
// will be visible.
@@ -102081,7 +103846,7 @@ Ext.define('Ext.selection.RowModel', {
// There was no lastFocused record, and the user has pressed up
// Ignore??
//else if (this.selected.getCount() == 0) {
- //
+ //
// this.doSelect(record);
// //view.focusRow(idx - 1);
//}
@@ -102095,7 +103860,7 @@ Ext.define('Ext.selection.RowModel', {
view = me.views[0],
idx = me.store.indexOf(me.lastFocused),
record;
-
+
// needs to be the filtered count as thats what
// will be visible.
if (idx + 1 < me.store.getCount()) {
@@ -102121,21 +103886,21 @@ Ext.define('Ext.selection.RowModel', {
}
}
},
-
+
scrollByDeltaX: function(delta) {
var view = this.views[0],
section = view.up(),
hScroll = section.horizontalScroller;
-
+
if (hScroll) {
hScroll.scrollByDeltaX(delta);
}
},
-
+
onKeyLeft: function(e, t) {
this.scrollByDeltaX(-this.deltaScroll);
},
-
+
onKeyRight: function(e, t) {
this.scrollByDeltaX(this.deltaScroll);
},
@@ -102149,26 +103914,29 @@ Ext.define('Ext.selection.RowModel', {
// Allow the GridView to update the UI by
// adding/removing a CSS class from the row.
- onSelectChange: function(record, isSelected, suppressEvent) {
+ onSelectChange: function(record, isSelected, suppressEvent, commitFn) {
var me = this,
views = me.views,
viewsLn = views.length,
store = me.store,
rowIdx = store.indexOf(record),
+ eventName = isSelected ? 'select' : 'deselect',
i = 0;
-
- for (; i < viewsLn; i++) {
- if (isSelected) {
- views[i].onRowSelect(rowIdx, suppressEvent);
- if (!suppressEvent) {
- me.fireEvent('select', me, record, rowIdx);
- }
- } else {
- views[i].onRowDeselect(rowIdx, suppressEvent);
- if (!suppressEvent) {
- me.fireEvent('deselect', me, record, rowIdx);
+
+ if ((suppressEvent || me.fireEvent('before' + eventName, me, record, rowIdx)) !== false &&
+ commitFn() !== false) {
+
+ for (; i < viewsLn; i++) {
+ if (isSelected) {
+ views[i].onRowSelect(rowIdx, suppressEvent);
+ } else {
+ views[i].onRowDeselect(rowIdx, suppressEvent);
}
}
+
+ if (!suppressEvent) {
+ me.fireEvent(eventName, me, record, rowIdx);
+ }
}
},
@@ -102180,7 +103948,7 @@ Ext.define('Ext.selection.RowModel', {
store = this.store,
rowIdx,
i = 0;
-
+
if (oldFocused) {
rowIdx = store.indexOf(oldFocused);
if (rowIdx != -1) {
@@ -102199,7 +103967,7 @@ Ext.define('Ext.selection.RowModel', {
}
}
},
-
+
onEditorTab: function(editingPlugin, e) {
var me = this,
view = me.views[0],
@@ -102208,12 +103976,12 @@ Ext.define('Ext.selection.RowModel', {
position = view.getPosition(record, header),
direction = e.shiftKey ? 'left' : 'right',
newPosition = view.walkCells(position, direction, e, this.preventWrap);
-
+
if (newPosition) {
editingPlugin.startEditByPosition(newPosition);
}
},
-
+
selectByPosition: function(position) {
var record = this.store.getAt(position.row);
this.select(record);
@@ -102372,8 +104140,9 @@ Ext.define('Ext.selection.CheckboxModel', {
* Synchronize header checker value as selection changes.
* @private
*/
- onSelectChange: function(record, isSelected) {
- this.callParent([record, isSelected]);
+ onSelectChange: function() {
+ this.callParent(arguments);
+
// check to see if all records are selected
var hdSelectStatus = this.selected.getCount() === this.store.getCount();
this.toggleUiHeader(hdSelectStatus);
@@ -102464,7 +104233,6 @@ Ext.define('Ext.selection.TreeModel', {
});
/**
- * @private
* @class Ext.slider.Thumb
* @extends Ext.Base
* @private
@@ -102481,9 +104249,12 @@ Ext.define('Ext.slider.Thumb', {
*/
topZIndex: 10000,
/**
- * @constructor
* @cfg {Ext.slider.MultiSlider} slider The Slider to render to (required)
*/
+ /**
+ * Creates new slider thumb.
+ * @param {Object} config (optional) Config object.
+ */
constructor: function(config) {
var me = this;
@@ -102745,7 +104516,6 @@ Ext.define('Ext.slider.Thumb', {
}
});
- * @xtype slidertip
*/
Ext.define('Ext.slider.Tip', {
extend: 'Ext.tip.Tip',
@@ -102796,7 +104566,7 @@ Ext.define('Ext.slider.Tip', {
* @class Ext.slider.Multi
* @extends Ext.form.field.Base
* Slider which supports vertical or horizontal orientation, keyboard adjustments, configurable snapping, axis - * clicking and animation. Can be added as an item to any container. In addition, + * clicking and animation. Can be added as an item to any container. In addition, * {@img Ext.slider.Multi/Ext.slider.Multi.png Ext.slider.Multi component} *
Example usage:
* Sliders can be created with more than one thumb handle by passing an array of values instead of a single one: @@ -102811,9 +104581,8 @@ Ext.define('Ext.slider.Tip', { //this defaults to true, setting to false allows the thumbs to pass each other {@link #constrainThumbs}: false, renderTo: Ext.getBody() - }); + }); - * @xtype multislider */ Ext.define('Ext.slider.Multi', { extend: 'Ext.form.field.Base', @@ -102953,7 +104722,7 @@ Ext.define('Ext.slider.Multi', { var me = this, tipPlug, hasTip; - + /** * @property thumbs * @type Array @@ -103074,7 +104843,7 @@ Ext.define('Ext.slider.Multi', { var thumbs = this.thumbs, ln = thumbs.length, zIndex, thumb, i; - + for (i = 0; i < ln; i++) { thumb = thumbs[i]; @@ -103136,7 +104905,7 @@ Ext.define('Ext.slider.Multi', { */ initEvents : function() { var me = this; - + me.mon(me.el, { scope : me, mousedown: me.onMouseDown, @@ -103160,7 +104929,7 @@ Ext.define('Ext.slider.Multi', { thumbs = me.thumbs, len = thumbs.length, local; - + if (me.disabled) { return; } @@ -103186,7 +104955,7 @@ Ext.define('Ext.slider.Multi', { onClickChange : function(local) { var me = this, thumb, index; - + if (local.top > me.clickRange[0] && local.top < me.clickRange[1]) { //find the nearest thumb to the click event thumb = me.getNearest(local, 'left'); @@ -103247,13 +105016,13 @@ Ext.define('Ext.slider.Multi', { var me = this, k, val; - + if(me.disabled || me.thumbs.length !== 1) { e.preventDefault(); return; } k = e.getKey(); - + switch(k) { case e.UP: case e.RIGHT: @@ -103272,33 +105041,6 @@ Ext.define('Ext.slider.Multi', { } }, - /** - * @private - * If using snapping, this takes a desired new value and returns the closest snapped - * value to it - * @param {Number} value The unsnapped value - * @return {Number} The value of the nearest snap target - */ - doSnap : function(value) { - var newValue = value, - inc = this.increment, - m; - - if (!(inc && value)) { - return value; - } - m = value % inc; - if (m !== 0) { - newValue -= m; - if (m * 2 >= inc) { - newValue += inc; - } else if (m * 2 < -inc) { - newValue -= inc; - } - } - return Ext.Number.constrain(newValue, this.minValue, this.maxValue); - }, - // private afterRender : function() { var me = this, @@ -103307,7 +105049,7 @@ Ext.define('Ext.slider.Multi', { len = thumbs.length, thumb, v; - + me.callParent(arguments); for (; i < len; i++) { @@ -103345,8 +105087,8 @@ Ext.define('Ext.slider.Multi', { */ normalizeValue : function(v) { var me = this; - - v = me.doSnap(v); + + v = Ext.Number.snap(v, this.increment, this.minValue, this.maxValue); v = Ext.util.Format.round(v, me.decimalPrecision); v = Ext.Number.constrain(v, me.minValue, me.maxValue); return v; @@ -103363,7 +105105,7 @@ Ext.define('Ext.slider.Multi', { thumbs = me.thumbs, len = thumbs.length, t; - + me.minValue = val; me.inputEl.dom.setAttribute('aria-valuemin', val); @@ -103385,7 +105127,7 @@ Ext.define('Ext.slider.Multi', { thumbs = me.thumbs, len = thumbs.length, t; - + me.maxValue = val; me.inputEl.dom.setAttribute('aria-valuemax', val); @@ -103465,7 +105207,7 @@ Ext.define('Ext.slider.Multi', { thumb, el, xy; - + me.callParent(); for (; i < len; i++) { @@ -103499,7 +105241,7 @@ Ext.define('Ext.slider.Multi', { len = thumbs.length, thumb, el; - + this.callParent(); for (; i < len; i++) { @@ -103585,7 +105327,7 @@ Ext.define('Ext.slider.Multi', { // private beforeDestroy : function() { var me = this; - + Ext.destroyMembers(me.innerEl, me.endEl, me.focusEl); Ext.each(me.thumbs, function(thumb) { Ext.destroy(thumb); @@ -103640,7 +105382,6 @@ Ext.define('Ext.slider.Multi', { }); * The class Ext.slider.Single is aliased to Ext.Slider for backwards compatibility. - * @xtype slider */ Ext.define('Ext.slider.Single', { extend: 'Ext.slider.Multi', @@ -103691,8 +105432,6 @@ Ext.define('Ext.slider.Single', { *Represents a single Tab in a {@link Ext.tab.Panel TabPanel}. A Tab is simply a slightly customized {@link Ext.button.Button Button}, * styled to look like a tab. Tabs are optionally closable, and can also be disabled. 99% of the time you will not * need to create Tabs manually as the framework does so automatically when you use a {@link Ext.tab.Panel TabPanel}
- * - * @xtype tab */ Ext.define('Ext.tab.Tab', { extend: 'Ext.button.Button', @@ -103907,7 +105646,7 @@ Ext.define('Ext.tab.Tab', { tag: 'a', cls: me.baseCls + '-close-btn', href: '#', - html: me.closeText, + // html: me.closeText, // removed for EXTJSIV-1719, by rob@sencha.com title: me.closeText }).on('click', Ext.EventManager.preventDefault); // mon ??? } @@ -104028,8 +105767,6 @@ Ext.define('Ext.tab.Tab', { * @class Ext.tab.Bar * @extends Ext.panel.Header *TabBar is used internally by a {@link Ext.tab.Panel TabPanel} and wouldn't usually need to be created manually.
- * - * @xtype tabbar */ Ext.define('Ext.tab.Bar', { extend: 'Ext.panel.Header', @@ -104256,6 +105993,24 @@ configured header {@link Ext.panel.Panel#tools tools}. To display a header, embed the TabPanel in a {@link Ext.panel.Panel Panel} which uses `{@link Ext.container.Container#layout layout:'fit'}`. +__Controlling tabs:__ +Configuration options for the {@link Ext.tab.Tab} that represents the component can be passed in by specifying the tabConfig option: + + Ext.create('Ext.tab.Panel', { + width: 400, + height: 400, + renderTo: document.body, + items: [{ + title: 'Foo' + }, { + title: 'Bar', + tabConfig: { + title: 'Custom Title', + tooltip: 'A button tooltip' + } + }] + }); + __Examples:__ Here is a basic TabPanel rendered to the body. This also shows the useful configuration {@link #activeTab}, which allows you to set the active tab on render. @@ -104314,7 +106069,7 @@ Example usage: tabs.setActiveTab(users); }, 1000); -You can remove the background of the TabBar by setting the {@link #plain} property to `false`. +You can remove the background of the TabBar by setting the {@link #plain} property to `true`. Example usage: @@ -104491,9 +106246,6 @@ Example usage: }); * @extends Ext.Panel - * @constructor - * @param {Object} config The configuration options - * @xtype tabpanel * @markdown */ Ext.define('Ext.tab.Panel', { @@ -104682,16 +106434,22 @@ Ext.define('Ext.tab.Panel', { * Makes sure we have a Tab for each item added to the TabPanel */ onAdd: function(item, index) { - var me = this; - - item.tab = me.tabBar.insert(index, { - xtype: 'tab', - card: item, - disabled: item.disabled, - closable: item.closable, - hidden: item.hidden, - tabBar: me.tabBar - }); + var me = this, + cfg = item.tabConfig || {}, + defaultConfig = { + xtype: 'tab', + card: item, + disabled: item.disabled, + closable: item.closable, + hidden: item.hidden, + tabBar: me.tabBar + }; + + if (item.closeText) { + defaultConfig.closeText = item.closeText; + } + cfg = Ext.applyIf(cfg, defaultConfig); + item.tab = me.tabBar.insert(index, cfg); item.on({ scope : me, @@ -104841,9 +106599,6 @@ Ext.define('Ext.tab.Panel', { * renderTo: Ext.getBody() * }); * - * @constructor - * Creates a new Spacer - * @xtype tbspacer */ Ext.define('Ext.toolbar.Spacer', { extend: 'Ext.Component', @@ -104903,17 +106658,17 @@ Ext.define('Ext.tree.Column', { } } if (record.isLast()) { - if (record.isLeaf() || (record.isLoaded() && !record.hasChildNodes())) { - buf.unshift(format(imgText, (elbowPrefix + 'end'), Ext.BLANK_IMAGE_URL)); - } else { + if (record.isExpandable()) { buf.unshift(format(imgText, (elbowPrefix + 'end-plus ' + expanderCls), Ext.BLANK_IMAGE_URL)); + } else { + buf.unshift(format(imgText, (elbowPrefix + 'end'), Ext.BLANK_IMAGE_URL)); } } else { - if (record.isLeaf() || (record.isLoaded() && !record.hasChildNodes())) { - buf.unshift(format(imgText, (treePrefix + 'elbow'), Ext.BLANK_IMAGE_URL)); - } else { + if (record.isExpandable()) { buf.unshift(format(imgText, (elbowPrefix + 'plus ' + expanderCls), Ext.BLANK_IMAGE_URL)); + } else { + buf.unshift(format(imgText, (treePrefix + 'elbow'), Ext.BLANK_IMAGE_URL)); } } } else { @@ -105152,14 +106907,9 @@ Ext.define('Ext.tree.View', { // +1 because of the tr with th'es that is already there Ext.fly(children[relativeIndex + 1]).insertSibling(nodes, 'before', true); } - + // We also have to update the CompositeElementLite collection of the DataView - if (index < a.length) { - a.splice.apply(a, [index, 0].concat(nodes)); - } - else { - a.push.apply(a, nodes); - } + Ext.Array.insert(a, index, nodes); // If we were in an animation we need to now change the animation // because the targetEl just got higher. @@ -105434,38 +107184,30 @@ Ext.define('Ext.tree.View', { } }); /** - * @class Ext.tree.Panel - * @extends Ext.panel.Table - * * The TreePanel provides tree-structured UI representation of tree-structured data. * A TreePanel must be bound to a {@link Ext.data.TreeStore}. TreePanel's support - * multiple columns through the {@link columns} configuration. + * multiple columns through the {@link #columns} configuration. * * Simple TreePanel using inline data. * * {@img Ext.tree.Panel/Ext.tree.Panel1.png Ext.tree.Panel component} * - * ## Simple Tree Panel (no columns) + * Code: * * var store = Ext.create('Ext.data.TreeStore', { * root: { * expanded: true, - * text:"", - * user:"", - * status:"", * children: [ - * { text:"detention", leaf: true }, - * { text:"homework", expanded: true, - * children: [ - * { text:"book report", leaf: true }, - * { text:"alegrbra", leaf: true} - * ] - * }, - * { text: "buy lottery tickets", leaf:true } + * { text: "detention", leaf: true }, + * { text: "homework", expanded: true, children: [ + * { text: "book report", leaf: true }, + * { text: "alegrbra", leaf: true} + * ] }, + * { text: "buy lottery tickets", leaf: true } * ] * } * }); - * + * * Ext.create('Ext.tree.Panel', { * title: 'Simple Tree', * width: 200, @@ -105474,8 +107216,6 @@ Ext.define('Ext.tree.View', { * rootVisible: false, * renderTo: Ext.getBody() * }); - * - * @xtype treepanel */ Ext.define('Ext.tree.Panel', { extend: 'Ext.panel.Table', @@ -105486,19 +107226,21 @@ Ext.define('Ext.tree.Panel', { selType: 'treemodel', treeCls: Ext.baseCSSPrefix + 'tree-panel', - + + deferRowRender: false, + /** - * @cfg {Boolean} lines false to disable tree lines (defaults to true) + * @cfg {Boolean} lines False to disable tree lines. Defaults to true. */ lines: true, /** - * @cfg {Boolean} useArrows true to use Vista-style arrows in the tree (defaults to false) + * @cfg {Boolean} useArrows True to use Vista-style arrows in the tree. Defaults to false. */ useArrows: false, /** - * @cfg {Boolean} singleExpand true if only 1 node per branch may be expanded + * @cfg {Boolean} singleExpand True if only 1 node per branch may be expanded. Defaults to false. */ singleExpand: false, @@ -105508,23 +107250,37 @@ Ext.define('Ext.tree.Panel', { }, /** - * @cfg {Boolean} animate true to enable animated expand/collapse (defaults to the value of {@link Ext#enableFx Ext.enableFx}) + * @cfg {Boolean} animate True to enable animated expand/collapse. Defaults to the value of {@link Ext#enableFx}. */ /** - * @cfg {Boolean} rootVisible false to hide the root node (defaults to true) + * @cfg {Boolean} rootVisible False to hide the root node. Defaults to true. */ rootVisible: true, /** - * @cfg {Boolean} displayField The field inside the model that will be used as the node's text. (defaults to text) + * @cfg {Boolean} displayField The field inside the model that will be used as the node's text. Defaults to 'text'. */ displayField: 'text', /** - * @cfg {Boolean} root Allows you to not specify a store on this TreePanel. This is useful for creating a simple - * tree with preloaded data without having to specify a TreeStore and Model. A store and model will be created and - * root will be passed to that store. + * @cfg {Ext.data.Model/Ext.data.NodeInterface/Object} root + * Allows you to not specify a store on this TreePanel. This is useful for creating a simple tree with preloaded + * data without having to specify a TreeStore and Model. A store and model will be created and root will be passed + * to that store. For example: + * + * Ext.create('Ext.tree.Panel', { + * title: 'Simple Tree', + * root: { + * text: "Root node", + * expanded: true, + * children: [ + * { text: "Child 1", leaf: true }, + * { text: "Child 2", leaf: true } + * ] + * }, + * renderTo: Ext.getBody() + * }); */ root: null, @@ -105534,12 +107290,11 @@ Ext.define('Ext.tree.Panel', { lockedCfgCopy: ['displayField', 'root', 'singleExpand', 'useArrows', 'lines', 'rootVisible'], /** - * @cfg {Boolean} hideHeaders - * Specify astrue
to hide the headers.
+ * @cfg {Boolean} hideHeaders True to hide the headers. Defaults to `undefined`.
*/
/**
- * @cfg {Boolean} folderSort Set to true to automatically prepend a leaf sorter to the store (defaults to undefined)
+ * @cfg {Boolean} folderSort True to automatically prepend a leaf sorter to the store. Defaults to `undefined`.
*/
constructor: function(config) {
@@ -105831,7 +107586,7 @@ Ext.define('Ext.tree.Panel', {
* Expand the tree to the path of a particular node.
* @param {String} path The path to expand. The path should include a leading separator.
* @param {String} field (optional) The field to get the data from. Defaults to the model idProperty.
- * @param {String} separator (optional) A separator to use. Defaults to '/'.
+ * @param {String} separator (optional) A separator to use. Defaults to `'/'`.
* @param {Function} callback (optional) A function to execute when the expand finishes. The callback will be called with
* (success, lastNode) where success is if the expand was successful and lastNode is the last node that was expanded.
* @param {Object} scope (optional) The scope of the callback function
@@ -105879,7 +107634,7 @@ Ext.define('Ext.tree.Panel', {
* Expand the tree to the path of a particular node, then selecti t.
* @param {String} path The path to select. The path should include a leading separator.
* @param {String} field (optional) The field to get the data from. Defaults to the model idProperty.
- * @param {String} separator (optional) A separator to use. Defaults to '/'.
+ * @param {String} separator (optional) A separator to use. Defaults to `'/'`.
* @param {Function} callback (optional) A function to execute when the select finishes. The callback will be called with
* (bSuccess, oLastNode) where bSuccess is if the select was successful and oLastNode is the last node that was expanded.
* @param {Object} scope (optional) The scope of the callback function
@@ -105895,7 +107650,7 @@ Ext.define('Ext.tree.Panel', {
keys = path.split(separator);
last = keys.pop();
- me.expandPath(keys.join('/'), field, separator, function(success, node){
+ me.expandPath(keys.join(separator), field, separator, function(success, node){
var doSuccess = false;
if (success && node) {
node = node.findChild(field, last);
@@ -105911,6 +107666,7 @@ Ext.define('Ext.tree.Panel', {
}, me);
}
});
+
/**
* @class Ext.view.DragZone
* @extends Ext.dd.DragZone
@@ -105938,7 +107694,7 @@ Ext.define('Ext.view.DragZone', {
// So a View's DragZone cannot use the View's main element because the DropZone must use that
// because the DropZone may need to scroll on hover at a scrolling boundary, and it is the View's
// main element which handles scrolling.
- // We use the View's parent element to drag from. Ideally, we would use the internal structure, but that
+ // We use the View's parent element to drag from. Ideally, we would use the internal structure, but that
// is transient; DataView's recreate the internal structure dynamically as data changes.
// TODO: Ext 5.0 DragDrop must allow multiple DD objects to share the same element.
me.callParent([me.view.el.dom.parentNode]);
@@ -105958,6 +107714,12 @@ Ext.define('Ext.view.DragZone', {
onItemMouseDown: function(view, record, item, index, e) {
if (!this.isPreventDrag(e, record, item, index)) {
this.handleMouseDown(e);
+
+ // If we want to allow dragging of multi-selections, then veto the following handlers (which, in the absence of ctrlKey, would deselect)
+ // if the mousedowned record is selected
+ if (view.getSelectionModel().selectionMode == 'MULTI' && !e.ctrlKey && view.getSelectionModel().isSelected(record)) {
+ return false;
+ }
}
},
@@ -105998,7 +107760,7 @@ Ext.define('Ext.view.DragZone', {
// Update the selection to match what would have been selected if the user had
// done a full click on the target node rather than starting a drag from it
if (!selectionModel.isSelected(record) || e.hasModifier()) {
- selectionModel.selectWithEvent(record, e);
+ selectionModel.selectWithEvent(record, e, true);
}
data.records = selectionModel.getSelection();
@@ -106178,10 +107940,10 @@ Ext.define('Ext.tree.ViewDropZone', {
}
// Respect the allowDrop field on Tree nodes
- if (position === 'append' && targetNode.get('allowDrop') == false) {
+ if (position === 'append' && targetNode.get('allowDrop') === false) {
return false;
}
- else if (position != 'append' && targetNode.parentNode.get('allowDrop') == false) {
+ else if (position != 'append' && targetNode.parentNode.get('allowDrop') === false) {
return false;
}
@@ -106210,6 +107972,7 @@ Ext.define('Ext.tree.ViewDropZone', {
this.queueExpand(targetNode);
}
+
if (this.isValidDropPoint(node, position, dragZone, e, data)) {
this.valid = true;
this.currentPosition = position;
@@ -106218,24 +107981,26 @@ Ext.define('Ext.tree.ViewDropZone', {
indicator.setWidth(Ext.fly(node).getWidth());
indicatorY = Ext.fly(node).getY() - Ext.fly(view.el).getY() - 1;
+ /*
+ * In the code below we show the proxy again. The reason for doing this is showing the indicator will
+ * call toFront, causing it to get a new z-index which can sometimes push the proxy behind it. We always
+ * want the proxy to be above, so calling show on the proxy will call toFront and bring it forward.
+ */
if (position == 'before') {
returnCls = targetNode.isFirst() ? Ext.baseCSSPrefix + 'tree-drop-ok-above' : Ext.baseCSSPrefix + 'tree-drop-ok-between';
indicator.showAt(0, indicatorY);
- indicator.toFront();
- }
- else if (position == 'after') {
+ dragZone.proxy.show();
+ } else if (position == 'after') {
returnCls = targetNode.isLast() ? Ext.baseCSSPrefix + 'tree-drop-ok-below' : Ext.baseCSSPrefix + 'tree-drop-ok-between';
indicatorY += Ext.fly(node).getHeight();
indicator.showAt(0, indicatorY);
- indicator.toFront();
- }
- else {
+ dragZone.proxy.show();
+ } else {
returnCls = Ext.baseCSSPrefix + 'tree-drop-ok-append';
// @TODO: set a class on the parent folder node to be able to style it
indicator.hide();
}
- }
- else {
+ } else {
this.valid = false;
}
@@ -106322,7 +108087,9 @@ Ext.define('Ext.tree.ViewDropZone', {
//FIXME: the check for n.firstChild is not a great solution here. Ideally the line should simply read
//Ext.fly(n.firstChild) but this yields errors in IE6 and 7. See ticket EXTJSIV-1705 for more details
Ext.Array.forEach(recordDomNodes, function(n) {
- Ext.fly(n.firstChild ? n.firstChild : n).highlight(me.dropHighlightColor);
+ if (n) {
+ Ext.fly(n.firstChild ? n.firstChild : n).highlight(me.dropHighlightColor);
+ }
});
}
};
@@ -107111,7 +108878,7 @@ Ext.define('Ext.view.TableChunker', {
'{[this.openTableWrap()]}',
'', ' |
---|