X-Git-Url: http://git.ithinksw.org/extjs.git/blobdiff_plain/3789b528d8dd8aad4558e38e22d775bcab1cbd36..f562e4c6e5fac7bcb445985b99acbea4d706e6f0:/ext-all-debug.js diff --git a/ext-all-debug.js b/ext-all-debug.js index e5db5769..8fc6dc00 100644 --- a/ext-all-debug.js +++ b/ext-all-debug.js @@ -1,15 +1,23 @@ /* -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. + */ (function() { var global = this, objectPrototype = Object.prototype, - toString = Object.prototype.toString, + toString = objectPrototype.toString, enumerables = true, enumerablesTest = { toString: 1 }, i; @@ -128,13 +136,6 @@ licensing@sencha.com }; } - if (!superclass) { - Ext.Error.raise({ - sourceClass: 'Ext', - sourceMethod: 'extend', - msg: 'Attempting to extend from a class which has not been loaded on the page.' - }); - } var F = function() {}, @@ -228,11 +229,6 @@ licensing@sencha.com return 'object'; } - Ext.Error.raise({ - sourceClass: 'Ext', - sourceMethod: 'typeOf', - msg: 'Failed to determine the type of the specified value "' + value + '". This is most likely a bug.' - }); }, @@ -253,7 +249,8 @@ licensing@sencha.com isObject: (toString.call(null) === '[object Object]') ? function(value) { - return value !== null && value !== undefined && toString.call(value) === '[object Object]' && value.nodeType === undefined; + + return value !== null && value !== undefined && toString.call(value) === '[object Object]' && value.ownerDocument === undefined; } : function(value) { return toString.call(value) === '[object Object]'; @@ -378,7 +375,7 @@ licensing@sencha.com var i = 0; do { - uniqueGlobalNamespace = 'ExtSandbox' + (++i); + uniqueGlobalNamespace = 'ExtBox' + (++i); } while (Ext.global[uniqueGlobalNamespace] !== undefined); Ext.global[uniqueGlobalNamespace] = Ext; @@ -410,7 +407,7 @@ licensing@sencha.com (function() { -var version = '4.0.1', Version; +var version = '4.0.7', Version; Ext.Version = Version = Ext.extend(Object, { @@ -595,7 +592,7 @@ Ext.String = { escapeRegexRe: /([-.*+?^${}()|[\]\/\\])/g, /** - * Convert certain characters (&, <, >, and ') to their HTML character equivalents for literal display in web pages. + * Convert certain characters (&, <, >, and ") to their HTML character equivalents for literal display in web pages. * @param {String} value The string to encode * @return {String} The encoded text * @method @@ -621,7 +618,12 @@ Ext.String = { }; })(), - + /** + * Convert certain characters (&, <, >, and ") from their HTML character equivalents. + * @param {String} value The string to decode + * @return {String} The decoded text + * @method + */ htmlDecode: (function() { var entities = { '&': '&', @@ -712,6 +714,14 @@ Ext.String = { return format.replace(Ext.String.formatRe, function(m, i) { return args[i]; }); + }, + + + repeat: function(pattern, count, sep) { + for (var buf = [], i = count; i--; ) { + buf.push(pattern); + } + return buf.join(sep || ''); } }; @@ -736,6 +746,26 @@ Ext.Number = { }, + snap : function(value, increment, minValue, maxValue) { + var newValue = value, + m; + + if (!(increment && value)) { + return value; + } + m = value % increment; + if (m !== 0) { + newValue -= m; + if (m * 2 >= increment) { + newValue += increment; + } else if (m * 2 < -increment) { + newValue -= increment; + } + } + return Ext.Number.constrain(newValue, minValue, maxValue); + }, + + toFixed: function(value, precision) { if (isToFixedBroken) { precision = precision || 0; @@ -767,6 +797,34 @@ Ext.num = function() { var arrayPrototype = Array.prototype, slice = arrayPrototype.slice, + supportsSplice = function () { + var array = [], + lengthBefore, + j = 20; + + if (!array.splice) { + return false; + } + + + + + while (j--) { + array.push("A"); + } + + array.splice(15, 0, "F", "F", "F", "F", "F","F","F","F","F","F","F","F","F","F","F","F","F","F","F","F","F"); + + lengthBefore = array.length; + array.splice(13, 0, "XXX"); + + if (lengthBefore+1 != array.length) { + return false; + } + + + return true; + }(), supportsForEach = 'forEach' in arrayPrototype, supportsMap = 'map' in arrayPrototype, supportsIndexOf = 'indexOf' in arrayPrototype, @@ -779,6 +837,7 @@ Ext.num = function() { }(), supportsSliceOnNodeList = true, ExtArray; + try { if (typeof document !== 'undefined') { @@ -788,6 +847,99 @@ Ext.num = function() { supportsSliceOnNodeList = false; } + function fixArrayIndex (array, index) { + return (index < 0) ? Math.max(0, array.length + index) + : Math.min(array.length, index); + } + + + function replaceSim (array, index, removeCount, insert) { + var add = insert ? insert.length : 0, + length = array.length, + pos = fixArrayIndex(array, index); + + + if (pos === length) { + if (add) { + array.push.apply(array, insert); + } + } else { + var remove = Math.min(removeCount, length - pos), + tailOldPos = pos + remove, + tailNewPos = tailOldPos + add - remove, + tailCount = length - tailOldPos, + lengthAfterRemove = length - remove, + i; + + if (tailNewPos < tailOldPos) { + for (i = 0; i < tailCount; ++i) { + array[tailNewPos+i] = array[tailOldPos+i]; + } + } else if (tailNewPos > tailOldPos) { + for (i = tailCount; i--; ) { + array[tailNewPos+i] = array[tailOldPos+i]; + } + } + + if (add && pos === lengthAfterRemove) { + array.length = lengthAfterRemove; + array.push.apply(array, insert); + } else { + array.length = lengthAfterRemove + add; + for (i = 0; i < add; ++i) { + array[pos+i] = insert[i]; + } + } + } + + return array; + } + + function replaceNative (array, index, removeCount, insert) { + if (insert && insert.length) { + if (index < array.length) { + array.splice.apply(array, [index, removeCount].concat(insert)); + } else { + array.push.apply(array, insert); + } + } else { + array.splice(index, removeCount); + } + return array; + } + + function eraseSim (array, index, removeCount) { + return replaceSim(array, index, removeCount); + } + + function eraseNative (array, index, removeCount) { + array.splice(index, removeCount); + return array; + } + + function spliceSim (array, index, removeCount) { + var pos = fixArrayIndex(array, index), + removed = array.slice(index, fixArrayIndex(array, pos+removeCount)); + + if (arguments.length < 4) { + replaceSim(array, pos, removeCount); + } else { + replaceSim(array, pos, removeCount, slice.call(arguments, 3)); + } + + return removed; + } + + function spliceNative (array) { + return array.splice.apply(array, slice.call(arguments, 1)); + } + + var erase = supportsSplice ? eraseNative : eraseSim, + replace = supportsSplice ? replaceNative : replaceSim, + splice = supportsSplice ? spliceNative : spliceSim; + + + ExtArray = Ext.Array = { each: function(array, fn, scope, reverse) { @@ -922,9 +1074,6 @@ Ext.num = function() { every: function(array, fn, scope) { - if (!fn) { - Ext.Error.raise('Ext.Array.every must have a callback function passed as second argument.'); - } if (supportsEvery) { return array.every(fn, scope); } @@ -943,9 +1092,6 @@ Ext.num = function() { some: function(array, fn, scope) { - if (!fn) { - Ext.Error.raise('Ext.Array.some must have a callback function passed as second argument.'); - } if (supportsSome) { return array.some(fn, scope); } @@ -1039,7 +1185,7 @@ Ext.num = function() { var index = ExtArray.indexOf(array, item); if (index !== -1) { - array.splice(index, 1); + erase(array, index, 1); } return array; @@ -1088,8 +1234,8 @@ Ext.num = function() { } } - minArray = Ext.Array.unique(minArray); - arrays.splice(x, 1); + minArray = ExtArray.unique(minArray); + erase(arrays, x, 1); @@ -1123,7 +1269,7 @@ Ext.num = function() { for (i = 0,lnB = arrayB.length; i < lnB; i++) { for (j = 0; j < ln; j++) { if (clone[j] === arrayB[i]) { - clone.splice(j, 1); + erase(clone, j, 1); j--; ln--; } @@ -1134,6 +1280,26 @@ Ext.num = function() { }, + + slice: ([1,2].slice(1, undefined).length ? + function (array, begin, end) { + return slice.call(array, begin, end); + } : + + function (array, begin, end) { + + + if (typeof begin === 'undefined') { + return slice.call(array); + } + if (typeof end === 'undefined') { + return slice.call(array, begin); + } + return slice.call(array, begin, end); + } + ), + + sort: function(array, sortFn) { if (supportsSort) { if (sortFn) { @@ -1256,48 +1422,61 @@ Ext.num = function() { } return sum; - } + }, + + + erase: erase, + + + insert: function (array, index, items) { + return replace(array, index, 0, items); + }, + + + replace: replace, + + + splice: splice }; - Ext.each = Ext.Array.each; + Ext.each = ExtArray.each; - Ext.Array.union = Ext.Array.merge; + ExtArray.union = ExtArray.merge; - Ext.min = Ext.Array.min; + Ext.min = ExtArray.min; - Ext.max = Ext.Array.max; + Ext.max = ExtArray.max; - Ext.sum = Ext.Array.sum; + Ext.sum = ExtArray.sum; - Ext.mean = Ext.Array.mean; + Ext.mean = ExtArray.mean; - Ext.flatten = Ext.Array.flatten; + Ext.flatten = ExtArray.flatten; - Ext.clean = Ext.Array.clean; + Ext.clean = ExtArray.clean; - Ext.unique = Ext.Array.unique; + Ext.unique = ExtArray.unique; - Ext.pluck = Ext.Array.pluck; + Ext.pluck = ExtArray.pluck; Ext.toArray = function() { return ExtArray.toArray.apply(ExtArray, arguments); - } + }; })(); - Ext.Function = { @@ -1332,22 +1511,27 @@ Ext.Function = { }; }, - + bind: function(fn, scope, args, appendArgs) { + if (arguments.length === 2) { + return function() { + return fn.apply(scope, arguments); + } + } + var method = fn, - applyArgs; + slice = Array.prototype.slice; return function() { var callArgs = args || arguments; if (appendArgs === true) { - callArgs = Array.prototype.slice.call(arguments, 0); + callArgs = slice.call(arguments, 0); callArgs = callArgs.concat(args); } - else if (Ext.isNumber(appendArgs)) { - callArgs = Array.prototype.slice.call(arguments, 0); - applyArgs = [appendArgs, 0].concat(args); - Array.prototype.splice.apply(callArgs, applyArgs); + else if (typeof appendArgs == 'number') { + callArgs = slice.call(arguments, 0); + Ext.Array.insert(callArgs, appendArgs, args); } return method.apply(scope || window, callArgs); @@ -1433,7 +1617,7 @@ Ext.Function = { return function() { var me = this; if (timerId) { - clearInterval(timerId); + clearTimeout(timerId); timerId = null; } timerId = setTimeout(function(){ @@ -1461,6 +1645,28 @@ Ext.Function = { timer = setTimeout(execute, interval - elapsed); } }; + }, + + + interceptBefore: function(object, methodName, fn) { + var method = object[methodName] || Ext.emptyFn; + + return object[methodName] = function() { + var ret = fn.apply(this, arguments); + method.apply(this, arguments); + + return ret; + }; + }, + + + interceptAfter: function(object, methodName, fn) { + var method = object[methodName] || Ext.emptyFn; + + return object[methodName] = function() { + method.apply(this, arguments); + return fn.apply(this, arguments); + }; } }; @@ -1584,15 +1790,6 @@ var ExtObject = Ext.Object = { matchedKeys = name.match(/(\[):?([^\]]*)\]/g); matchedName = name.match(/^([^\[]+)/); - if (!matchedName) { - Ext.Error.raise({ - sourceClass: "Ext.Object", - sourceMethod: "fromQueryString", - queryString: queryString, - recursive: recursive, - msg: 'Malformed query string given, failed parsing name from "' + part + '"' - }); - } name = matchedName[0]; keys = []; @@ -2645,6 +2842,7 @@ var Base = Ext.Base = function() {}; }, + initConfig: function(config) { if (!this.$configInited) { this.config = Ext.Object.merge({}, this.config || {}, config || {}); @@ -2674,6 +2872,7 @@ var Base = Ext.Base = function() {}; return this; }), + callParent: function(args) { @@ -2681,13 +2880,6 @@ var Base = Ext.Base = function() {}; parentClass, methodName; if (!method.$owner) { - if (!method.caller) { - Ext.Error.raise({ - sourceClass: Ext.getClassName(this), - sourceMethod: "callParent", - msg: "Attempting to call a protected method from the public scope, which is not allowed" - }); - } method = method.caller; } @@ -2695,14 +2887,6 @@ var Base = Ext.Base = function() {}; parentClass = method.$owner.superclass; methodName = method.$name; - if (!(methodName in parentClass)) { - Ext.Error.raise({ - sourceClass: Ext.getClassName(this), - sourceMethod: methodName, - msg: "this.callParent() was called but there's no such method (" + methodName + - ") found in the parent class (" + (Ext.getClassName(parentClass) || 'Object') + ")" - }); - } return parentClass[methodName].apply(this, args || []); }, @@ -2724,22 +2908,6 @@ var Base = Ext.Base = function() {}; callOverridden: function(args) { var method = this.callOverridden.caller; - if (!method.$owner) { - Ext.Error.raise({ - sourceClass: Ext.getClassName(this), - sourceMethod: "callOverridden", - msg: "Attempting to call a protected method from the public scope, which is not allowed" - }); - } - - if (!method.$previous) { - Ext.Error.raise({ - sourceClass: Ext.getClassName(this), - sourceMethod: "callOverridden", - msg: "this.callOverridden was called in '" + method.$name + - "' but this method has never been overridden" - }); - } return method.$previous.apply(this, args || []); }, @@ -2755,20 +2923,20 @@ var Base = Ext.Base = function() {}; }, - own: flexSetter(function(name, value) { - if (typeof value === 'function') { + own: function(name, value) { + if (typeof value == 'function') { this.ownMethod(name, value); } else { this.prototype[name] = value; } - }), + }, ownMethod: function(name, fn) { var originalFn; - if (fn.$owner !== undefined && fn !== Ext.emptyFn) { + if (typeof fn.$owner !== 'undefined' && fn !== Ext.emptyFn) { originalFn = fn; fn = function() { @@ -2776,11 +2944,6 @@ var Base = Ext.Base = function() {}; }; } - var className; - className = Ext.getClassName(this); - if (className) { - fn.displayName = className + '#' + name; - } fn.$owner = this; fn.$name = name; @@ -2799,10 +2962,41 @@ var Base = Ext.Base = function() {}; }, + addInheritableStatics: function(members) { + var inheritableStatics, + hasInheritableStatics, + prototype = this.prototype, + name, member; + + inheritableStatics = prototype.$inheritableStatics; + hasInheritableStatics = prototype.$hasInheritableStatics; + + if (!inheritableStatics) { + inheritableStatics = prototype.$inheritableStatics = []; + hasInheritableStatics = prototype.$hasInheritableStatics = {}; + } + + + for (name in members) { + if (members.hasOwnProperty(name)) { + member = members[name]; + this[name] = member; + + if (!hasInheritableStatics[name]) { + hasInheritableStatics[name] = true; + inheritableStatics.push(name); + } + } + } + + return this; + }, + + implement: function(members) { var prototype = this.prototype, - name, i, member, previous; - var className = Ext.getClassName(this); + enumerables = Ext.enumerables, + name, i, member; for (name in members) { if (members.hasOwnProperty(name)) { member = members[name]; @@ -2810,18 +3004,13 @@ var Base = Ext.Base = function() {}; if (typeof member === 'function') { member.$owner = this; member.$name = name; - if (className) { - member.displayName = className + '#' + name; - } } prototype[name] = member; } } - if (Ext.enumerables) { - var enumerables = Ext.enumerables; - + if (enumerables) { for (i = enumerables.length; i--;) { name = enumerables[i]; @@ -2854,8 +3043,28 @@ var Base = Ext.Base = function() {}; override: function(members) { var prototype = this.prototype, + enumerables = Ext.enumerables, name, i, member, previous; + if (arguments.length === 2) { + name = members; + member = arguments[1]; + + if (typeof member == 'function') { + if (typeof prototype[name] == 'function') { + previous = prototype[name]; + member.$previous = previous; + } + + this.ownMethod(name, member); + } + else { + prototype[name] = member; + } + + return this; + } + for (name in members) { if (members.hasOwnProperty(name)) { member = members[name]; @@ -2874,14 +3083,12 @@ var Base = Ext.Base = function() {}; } } - if (Ext.enumerables) { - var enumerables = Ext.enumerables; - + if (enumerables) { for (i = enumerables.length; i--;) { name = enumerables[i]; if (members.hasOwnProperty(name)) { - if (prototype[name] !== undefined) { + if (typeof prototype[name] !== 'undefined') { previous = prototype[name]; members[name].$previous = previous; } @@ -2895,40 +3102,53 @@ var Base = Ext.Base = function() {}; }, - mixin: flexSetter(function(name, cls) { + + mixin: function(name, cls) { var mixin = cls.prototype, my = this.prototype, - i, fn; + key, fn; - for (i in mixin) { - if (mixin.hasOwnProperty(i)) { - if (my[i] === undefined) { - if (typeof mixin[i] === 'function') { - fn = mixin[i]; + for (key in mixin) { + if (mixin.hasOwnProperty(key)) { + if (typeof my[key] === 'undefined' && key !== 'mixins' && key !== 'mixinId') { + if (typeof mixin[key] === 'function') { + fn = mixin[key]; - if (fn.$owner === undefined) { - this.ownMethod(i, fn); + if (typeof fn.$owner === 'undefined') { + this.ownMethod(key, fn); } else { - my[i] = fn; + my[key] = fn; } } else { - my[i] = mixin[i]; + my[key] = mixin[key]; } } - else if (i === 'config' && my.config && mixin.config) { + + else if (key === 'config' && my.config && mixin.config) { Ext.Object.merge(my.config, mixin.config); } + } } - if (my.mixins === undefined) { - my.mixins = {}; + if (typeof mixin.onClassMixedIn !== 'undefined') { + mixin.onClassMixedIn.call(cls, this); + } + + if (!my.hasOwnProperty('mixins')) { + if ('mixins' in my) { + my.mixins = Ext.Object.merge({}, my.mixins); + } + else { + my.mixins = {}; + } } my.mixins[name] = mixin; - }), + }, + getName: function() { @@ -2937,7 +3157,9 @@ var Base = Ext.Base = function() {}; createAlias: flexSetter(function(alias, origin) { - this.prototype[alias] = this.prototype[origin]; + this.prototype[alias] = function() { + return this[origin].apply(this, arguments); + } }) }); @@ -2959,7 +3181,7 @@ var Base = Ext.Base = function() {}; Ext.Class = Class = function(newClass, classData, onClassCreated) { - if (typeof newClass !== 'function') { + if (typeof newClass != 'function') { onClassCreated = classData; classData = newClass; newClass = function() { @@ -2975,7 +3197,7 @@ var Base = Ext.Base = function() {}; registeredPreprocessors = Class.getPreprocessors(), index = 0, preprocessors = [], - preprocessor, preprocessors, staticPropertyName, process, i, j, ln; + preprocessor, staticPropertyName, process, i, j, ln; for (i = 0, ln = baseStaticProperties.length; i < ln; i++) { staticPropertyName = baseStaticProperties[i]; @@ -2987,7 +3209,7 @@ var Base = Ext.Base = function() {}; for (j = 0, ln = preprocessorStack.length; j < ln; j++) { preprocessor = preprocessorStack[j]; - if (typeof preprocessor === 'string') { + if (typeof preprocessor == 'string') { preprocessor = registeredPreprocessors[preprocessor]; if (!preprocessor.always) { @@ -3004,7 +3226,7 @@ var Base = Ext.Base = function() {}; } } - classData.onClassCreated = onClassCreated; + classData.onClassCreated = onClassCreated || Ext.emptyFn; classData.onBeforeClassCreated = function(cls, data) { onClassCreated = data.onClassCreated; @@ -3014,9 +3236,7 @@ var Base = Ext.Base = function() {}; cls.implement(data); - if (onClassCreated) { - onClassCreated.call(cls, cls); - } + onClassCreated.call(cls, cls); }; process = function(cls, data) { @@ -3079,7 +3299,7 @@ var Base = Ext.Base = function() {}; var defaultPreprocessors = this.defaultPreprocessors, index; - if (typeof offset === 'string') { + if (typeof offset == 'string') { if (offset === 'first') { defaultPreprocessors.unshift(name); @@ -3097,13 +3317,14 @@ var Base = Ext.Base = function() {}; index = Ext.Array.indexOf(defaultPreprocessors, relativeName); if (index !== -1) { - defaultPreprocessors.splice(Math.max(0, index + offset), 0, name); + Ext.Array.splice(defaultPreprocessors, Math.max(0, index + offset), 0, name); } return this; } }); + Class.registerPreprocessor('extend', function(cls, data) { var extend = data.extend, base = Ext.Base, @@ -3139,6 +3360,7 @@ var Base = Ext.Base = function() {}; delete data.extend; + parentStatics = parentPrototype.$inheritableStatics; if (parentStatics) { @@ -3150,15 +3372,19 @@ var Base = Ext.Base = function() {}; } } } + + if (parentPrototype.config) { clsPrototype.config = Ext.Object.merge({}, parentPrototype.config); } else { clsPrototype.config = {}; } + + if (clsPrototype.$onExtended) { clsPrototype.$onExtended.call(cls, cls, data); } @@ -3167,50 +3393,30 @@ var Base = Ext.Base = function() {}; clsPrototype.$onExtended = data.onClassExtended; delete data.onClassExtended; } + }, true); + + Class.registerPreprocessor('statics', function(cls, data) { - var statics = data.statics, - name; - - for (name in statics) { - if (statics.hasOwnProperty(name)) { - cls[name] = statics[name]; - } - } + cls.addStatics(data.statics); delete data.statics; }); + + + Class.registerPreprocessor('inheritableStatics', function(cls, data) { - var statics = data.inheritableStatics, - inheritableStatics, - prototype = cls.prototype, - name; - - inheritableStatics = prototype.$inheritableStatics; - - if (!inheritableStatics) { - inheritableStatics = prototype.$inheritableStatics = []; - } - - for (name in statics) { - if (statics.hasOwnProperty(name)) { - cls[name] = statics[name]; - inheritableStatics.push(name); - } - } + cls.addInheritableStatics(data.inheritableStatics); delete data.inheritableStatics; }); + - Class.registerPreprocessor('mixins', function(cls, data) { - cls.mixin(data.mixins); - - delete data.mixins; - }); - + + Class.registerPreprocessor('config', function(cls, data) { var prototype = cls.prototype; @@ -3231,7 +3437,7 @@ var Base = Ext.Base = function() {}; data[setter] = function(val) { var ret = this[apply].call(this, val, this[pName]); - if (ret !== undefined) { + if (typeof ret != 'undefined') { this[pName] = ret; } @@ -3249,10 +3455,55 @@ var Base = Ext.Base = function() {}; Ext.Object.merge(prototype.config, data.config); delete data.config; }); + + + + + Class.registerPreprocessor('mixins', function(cls, data) { + var mixins = data.mixins, + name, mixin, i, ln; + + delete data.mixins; + + Ext.Function.interceptBefore(data, 'onClassCreated', function(cls) { + if (mixins instanceof Array) { + for (i = 0,ln = mixins.length; i < ln; i++) { + mixin = mixins[i]; + name = mixin.prototype.mixinId || mixin.$className; + + cls.mixin(name, mixin); + } + } + else { + for (name in mixins) { + if (mixins.hasOwnProperty(name)) { + cls.mixin(name, mixins[name]); + } + } + } + }); + }); - Class.setDefaultPreprocessors(['extend', 'statics', 'inheritableStatics', 'mixins', 'config']); + + + Class.setDefaultPreprocessors([ + 'extend' + + ,'statics' + + + ,'inheritableStatics' + + + ,'config' + + + ,'mixins' + + ]); + Ext.extend = function(subclass, superclass, members) { if (arguments.length === 2 && Ext.isObject(superclass)) { members = superclass; @@ -3267,7 +3518,21 @@ var Base = Ext.Base = function() {}; } members.extend = superclass; - members.preprocessors = ['extend', 'mixins', 'config', 'statics']; + members.preprocessors = [ + 'extend' + + ,'statics' + + + ,'inheritableStatics' + + + ,'mixins' + + + ,'config' + + ]; if (subclass) { cls = new Class(subclass, members); @@ -3286,6 +3551,7 @@ var Base = Ext.Base = function() {}; return cls; }; + })(); @@ -3324,20 +3590,11 @@ var Base = Ext.Base = function() {}; instantiators: [], - - instantiationCounts: {}, isCreated: function(className) { var i, ln, part, root, parts; - if (typeof className !== 'string' || className.length < 1) { - Ext.Error.raise({ - sourceClass: "Ext.ClassManager", - sourceMethod: "exist", - msg: "Invalid classname, must be a string and must not be empty" - }); - } if (this.classes.hasOwnProperty(className) || this.existCache.hasOwnProperty(className)) { return true; @@ -3369,13 +3626,6 @@ var Base = Ext.Base = function() {}; parseNamespace: function(namespace) { - if (typeof namespace !== 'string') { - Ext.Error.raise({ - sourceClass: "Ext.ClassManager", - sourceMethod: "parseNamespace", - msg: "Invalid namespace, must be a string" - }); - } var cache = this.namespaceParseCache; @@ -3422,10 +3672,11 @@ var Base = Ext.Base = function() {}; setNamespace: function(name, value) { var root = Ext.global, parts = this.parseNamespace(name), - leaf = parts.pop(), - i, ln, part; + ln = parts.length - 1, + leaf = parts[ln], + i, part; - for (i = 0, ln = parts.length; i < ln; i++) { + for (i = 0; i < ln; i++) { part = parts[i]; if (typeof part !== 'string') { @@ -3523,10 +3774,6 @@ var Base = Ext.Base = function() {}; } if (alias && aliasToNameMap[alias] !== className) { - if (aliasToNameMap.hasOwnProperty(alias) && Ext.isDefined(Ext.global.console)) { - Ext.global.console.log("[Ext.ClassManager] Overriding existing alias: '" + alias + "' " + - "of: '" + aliasToNameMap[alias] + "' with: '" + className + "'. Be sure it's intentional."); - } aliasToNameMap[alias] = className; } @@ -3576,13 +3823,6 @@ var Base = Ext.Base = function() {}; create: function(className, data, createdFn) { var manager = this; - if (typeof className !== 'string') { - Ext.Error.raise({ - sourceClass: "Ext", - sourceMethod: "define", - msg: "Invalid class name '" + className + "' specified, must be a non-empty string" - }); - } data.$className = className; @@ -3591,7 +3831,7 @@ var Base = Ext.Base = function() {}; registeredPostprocessors = manager.postprocessors, index = 0, postprocessors = [], - postprocessor, postprocessors, process, i, ln; + postprocessor, process, i, ln; delete data.postprocessors; @@ -3648,18 +3888,7 @@ var Base = Ext.Base = function() {}; if (!className) { className = this.maps.aliasToName[alias]; - if (!className) { - Ext.Error.raise({ - sourceClass: "Ext", - sourceMethod: "createByAlias", - msg: "Cannot create an instance of unrecognized alias: " + alias - }); - } - if (Ext.global.console) { - Ext.global.console.warn("[Ext.Loader] Synchronously loading '" + className + "'; consider adding " + - "Ext.require('" + alias + "') above Ext.onReady"); - } Ext.syncRequire(className); } @@ -3677,13 +3906,6 @@ var Base = Ext.Base = function() {}; possibleName, cls; if (typeof name !== 'function') { - if ((typeof name !== 'string' || name.length < 1)) { - Ext.Error.raise({ - sourceClass: "Ext", - sourceMethod: "create", - msg: "Invalid class name or alias '" + name + "' specified, must be a non-empty string" - }); - } cls = this.get(name); } @@ -3715,37 +3937,13 @@ var Base = Ext.Base = function() {}; if (!cls) { - if (Ext.global.console) { - Ext.global.console.warn("[Ext.Loader] Synchronously loading '" + name + "'; consider adding " + - "Ext.require('" + ((possibleName) ? alias : name) + "') above Ext.onReady"); - } Ext.syncRequire(name); cls = this.get(name); } - if (!cls) { - Ext.Error.raise({ - sourceClass: "Ext", - sourceMethod: "create", - msg: "Cannot create an instance of unrecognized class name / alias: " + alias - }); - } - - if (typeof cls !== 'function') { - Ext.Error.raise({ - sourceClass: "Ext", - sourceMethod: "create", - msg: "'" + name + "' is a singleton and cannot be instantiated" - }); - } - - if (!this.instantiationCounts[name]) { - this.instantiationCounts[name] = 0; - } - this.instantiationCounts[name]++; return this.getInstantiator(args.length)(cls, args); }, @@ -3821,7 +4019,7 @@ var Base = Ext.Base = function() {}; index = Ext.Array.indexOf(defaultPostprocessors, relativeName); if (index !== -1) { - defaultPostprocessors.splice(Math.max(0, index + offset), 0, name); + Ext.Array.splice(defaultPostprocessors, Math.max(0, index + offset), 0, name); } return this; @@ -3833,13 +4031,6 @@ var Base = Ext.Base = function() {}; names = [], name, alias, aliases, possibleName, regex, i, ln; - if (typeof expression !== 'string' || expression.length < 1) { - Ext.Error.raise({ - sourceClass: "Ext.ClassManager", - sourceMethod: "getNamesByExpression", - msg: "Expression " + expression + " is invalid, must be a non-empty string" - }); - } if (expression.indexOf('*') !== -1) { expression = expression.replace(/\*/g, '(.*?)'); @@ -3885,46 +4076,30 @@ var Base = Ext.Base = function() {}; } }; + var defaultPostprocessors = Manager.defaultPostprocessors; + + + Manager.registerPostprocessor('alias', function(name, cls, data) { var aliases = data.alias, - widgetPrefix = 'widget.', - i, ln, alias; + i, ln; - if (!(aliases instanceof Array)) { - aliases = [aliases]; - } + delete data.alias; for (i = 0, ln = aliases.length; i < ln; i++) { alias = aliases[i]; - if (typeof alias !== 'string') { - Ext.Error.raise({ - sourceClass: "Ext", - sourceMethod: "define", - msg: "Invalid alias of: '" + alias + "' for class: '" + name + "'; must be a valid string" - }); - } - this.setAlias(cls, alias); } - - - for (i = 0, ln = aliases.length; i < ln; i++) { - alias = aliases[i]; - - if (alias.substring(0, widgetPrefix.length) === widgetPrefix) { - - cls.xtype = cls.$xtype = alias.substring(widgetPrefix.length); - break; - } - } }); + Manager.registerPostprocessor('singleton', function(name, cls, data, fn) { fn.call(this, name, new cls(), data); return false; }); + Manager.registerPostprocessor('alternateClassName', function(name, cls, data) { var alternates = data.alternateClassName, i, ln, alternate; @@ -3936,13 +4111,6 @@ var Base = Ext.Base = function() {}; for (i = 0, ln = alternates.length; i < ln; i++) { alternate = alternates[i]; - if (typeof alternate !== 'string') { - Ext.Error.raise({ - sourceClass: "Ext", - sourceMethod: "define", - msg: "Invalid alternate of: '" + alternate + "' for class: '" + name + "'; must be a valid string" - }); - } this.set(alternate, cls); } @@ -4006,7 +4174,71 @@ var Base = Ext.Base = function() {}; createByAlias: alias(Manager, 'instantiateByAlias'), - define: alias(Manager, 'create'), + + + define: function (className, data, createdFn) { + if (!data.override) { + return Manager.create.apply(Manager, arguments); + } + + var requires = data.requires, + uses = data.uses, + overrideName = className; + + className = data.override; + + + data = Ext.apply({}, data); + delete data.requires; + delete data.uses; + delete data.override; + + + if (typeof requires == 'string') { + requires = [ className, requires ]; + } else if (requires) { + requires = requires.slice(0); + requires.unshift(className); + } else { + requires = [ className ]; + } + + + + + + + + + + + + + + + + return Manager.create(overrideName, { + requires: requires, + uses: uses, + isPartial: true, + constructor: function () { + } + }, function () { + var cls = Manager.get(className); + if (cls.override) { + cls.override(data); + } else { + cls.self.override(data); + } + + if (createdFn) { + + + + createdFn.call(cls); + } + }); + }, getClassName: alias(Manager, 'getName'), @@ -4035,6 +4267,7 @@ var Base = Ext.Base = function() {}; namespace: alias(Manager, 'createNamespaces') }); + Ext.createWidget = Ext.widget; @@ -4043,14 +4276,62 @@ var Base = Ext.Base = function() {}; Class.registerPreprocessor('className', function(cls, data) { if (data.$className) { cls.$className = data.$className; - cls.displayName = cls.$className; } }, true); Class.setDefaultPreprocessorPosition('className', 'first'); -})(Ext.Class, Ext.Function.alias); + Class.registerPreprocessor('xtype', function(cls, data) { + var xtypes = Ext.Array.from(data.xtype), + widgetPrefix = 'widget.', + aliases = Ext.Array.from(data.alias), + i, ln, xtype; + + data.xtype = xtypes[0]; + data.xtypes = xtypes; + aliases = data.alias = Ext.Array.from(data.alias); + + for (i = 0,ln = xtypes.length; i < ln; i++) { + xtype = xtypes[i]; + + + aliases.push(widgetPrefix + xtype); + } + + data.alias = aliases; + }); + + Class.setDefaultPreprocessorPosition('xtype', 'last'); + + Class.registerPreprocessor('alias', function(cls, data) { + var aliases = Ext.Array.from(data.alias), + xtypes = Ext.Array.from(data.xtypes), + widgetPrefix = 'widget.', + widgetPrefixLength = widgetPrefix.length, + i, ln, alias, xtype; + + for (i = 0, ln = aliases.length; i < ln; i++) { + alias = aliases[i]; + + + if (alias.substring(0, widgetPrefixLength) === widgetPrefix) { + xtype = alias.substring(widgetPrefixLength); + Ext.Array.include(xtypes, xtype); + + if (!cls.xtype) { + cls.xtype = data.xtype = xtype; + } + } + } + + data.alias = aliases; + data.xtypes = xtypes; + }); + + Class.setDefaultPreprocessorPosition('alias', 'last'); + +})(Ext.Class, Ext.Function.alias); (function(Manager, Class, flexSetter, alias) { @@ -4210,7 +4491,7 @@ var Base = Ext.Base = function() {}; do { if (Manager.isCreated(requires[j])) { - requires.splice(j, 1); + Ext.Array.erase(requires, j, 1); } else { j++; @@ -4218,7 +4499,7 @@ var Base = Ext.Base = function() {}; } while (j < requires.length); if (item.requires.length === 0) { - this.queue.splice(i, 1); + Ext.Array.erase(this.queue, i, 1); item.callback.call(item.scope); this.refreshQueue(); break; @@ -4466,48 +4747,7 @@ var Base = Ext.Base = function() {}; this.refreshQueue(); } - if (this.numPendingFiles <= 1) { - window.status = "Finished loading all dependencies, onReady fired!"; - } - else { - window.status = "Loading dependencies, " + this.numPendingFiles + " files left..."; - } - if (!this.syncModeEnabled && this.numPendingFiles === 0 && this.isLoading && !this.hasFileLoadError) { - var queue = this.queue, - requires, - i, ln, j, subLn, missingClasses = [], missingPaths = []; - - for (i = 0, ln = queue.length; i < ln; i++) { - requires = queue[i].requires; - - for (j = 0, subLn = requires.length; j < ln; j++) { - if (this.isFileLoaded[requires[j]]) { - missingClasses.push(requires[j]); - } - } - } - - if (missingClasses.length < 1) { - return; - } - - missingClasses = Ext.Array.filter(missingClasses, function(item) { - return !this.requiresMap.hasOwnProperty(item); - }, this); - - for (i = 0,ln = missingClasses.length; i < ln; i++) { - missingPaths.push(this.classNameToFilePathMap[missingClasses[i]]); - } - - Ext.Error.raise({ - sourceClass: "Ext.Loader", - sourceMethod: "onFileLoaded", - msg: "The following classes are not declared even if their files have been " + - "loaded: '" + missingClasses.join("', '") + "'. Please check the source code of their " + - "corresponding files for possible typos: '" + missingPaths.join("', '") + "'" - }); - } }, @@ -4515,13 +4755,6 @@ var Base = Ext.Base = function() {}; this.numPendingFiles--; this.hasFileLoadError = true; - Ext.Error.raise({ - sourceClass: "Ext.Loader", - classToLoad: className, - loadPath: filePath, - loadingType: isSynchronous ? 'synchronous' : 'async', - msg: errorMessage - }); }, @@ -4619,6 +4852,7 @@ var Base = Ext.Base = function() {}; Loader.onReady(fn, scope, true, options); }; + Class.registerPreprocessor('loader', function(cls, data, continueFn) { var me = this, dependencies = [], @@ -4645,7 +4879,7 @@ var Base = Ext.Base = function() {}; } } } - else { + else if (typeof propertyValue != 'function') { for (j in propertyValue) { if (propertyValue.hasOwnProperty(j)) { value = propertyValue[j]; @@ -4664,37 +4898,6 @@ var Base = Ext.Base = function() {}; return; } - var deadlockPath = [], - requiresMap = Loader.requiresMap, - detectDeadlock; - - - - if (className) { - requiresMap[className] = dependencies; - - detectDeadlock = function(cls) { - deadlockPath.push(cls); - - if (requiresMap[cls]) { - if (Ext.Array.contains(requiresMap[cls], className)) { - Ext.Error.raise({ - sourceClass: "Ext.Loader", - msg: "Deadlock detected while loading dependencies! '" + className + "' and '" + - deadlockPath[1] + "' " + "mutually require each other. Path: " + - deadlockPath.join(' -> ') + " -> " + deadlockPath[0] - }); - } - - for (i = 0, ln = requiresMap[cls].length; i < ln; i++) { - detectDeadlock(requiresMap[cls][i]); - } - } - }; - - detectDeadlock(className); - } - Loader.require(dependencies, function() { for (i = 0, ln = dependencyProperties.length; i < ln; i++) { @@ -4715,7 +4918,7 @@ var Base = Ext.Base = function() {}; } } } - else { + else if (typeof propertyValue != 'function') { for (var k in propertyValue) { if (propertyValue.hasOwnProperty(k)) { value = propertyValue[k]; @@ -4737,6 +4940,7 @@ var Base = Ext.Base = function() {}; Class.setDefaultPreprocessorPosition('loader', 'after', 'className'); + Manager.registerPostprocessor('uses', function(name, cls, data) { var uses = Ext.Array.from(data.uses), items = [], @@ -4833,73 +5037,6 @@ Ext.Error = Ext.extend(Error, { }); -(function () { - var prevOnError, timer, errors = 0, - extraordinarilyBad = /(out of stack)|(too much recursion)|(stack overflow)|(out of memory)/i, - win = Ext.global; - - if (typeof window === 'undefined') { - return; - } - - - function notify () { - var counters = Ext.log.counters, - supports = Ext.supports, - hasOnError = supports && supports.WindowOnError; - - - if (counters && (counters.error + counters.warn + counters.info + counters.log)) { - var msg = [ 'Logged Errors:',counters.error, 'Warnings:',counters.warn, - 'Info:',counters.info, 'Log:',counters.log].join(' '); - if (errors) { - msg = '*** Errors: ' + errors + ' - ' + msg; - } else if (counters.error) { - msg = '*** ' + msg; - } - win.status = msg; - } - - - if (!Ext.isDefined(Ext.Error.notify)) { - Ext.Error.notify = Ext.isIE6 || Ext.isIE7; - } - if (Ext.Error.notify && (hasOnError ? errors : (counters && counters.error))) { - Ext.Error.notify = false; - - if (timer) { - win.clearInterval(timer); - timer = null; - } - - alert('Unhandled error on page: See console or log'); - poll(); - } - } - - - - - function poll () { - timer = win.setInterval(notify, 1000); - } - - - - prevOnError = win.onerror || Ext.emptyFn; - win.onerror = function (message) { - ++errors; - - if (!extraordinarilyBad.test(message)) { - - - notify(); - } - - return prevOnError.apply(this, arguments); - }; - poll(); -})(); @@ -4990,7 +5127,7 @@ Ext.JSON = new(function() { this.encodeDate = function(o) { - return '"' + o.getFullYear() + "-" + return '"' + o.getFullYear() + "-" + pad(o.getMonth() + 1) + "-" + pad(o.getDate()) + "T" + pad(o.getHours()) + ":" @@ -5028,7 +5165,7 @@ Ext.JSON = new(function() { Ext.Error.raise({ sourceClass: "Ext.JSON", sourceMethod: "decode", - msg: "You're trying to decode and invalid JSON String: " + json + msg: "You're trying to decode an invalid JSON String: " + json }); } }; @@ -5046,8 +5183,6 @@ Ext.apply(Ext, { userAgent: navigator.userAgent.toLowerCase(), cache: {}, idSeed: 1000, - BLANK_IMAGE_URL : 'data:image/gif;base64,R0lGODlhAQABAID/AMDAwAAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==', - isStrict: document.compatMode == "CSS1Compat", windowId: 'ext-window', documentId: 'ext-document', @@ -5062,15 +5197,23 @@ Ext.apply(Ext, { id: function(el, prefix) { + var me = this, + sandboxPrefix = ''; el = Ext.getDom(el, true) || {}; if (el === document) { - el.id = this.documentId; + el.id = me.documentId; } else if (el === window) { - el.id = this.windowId; + el.id = me.windowId; } if (!el.id) { - el.id = (prefix || "ext-gen") + (++Ext.idSeed); + if (me.isSandboxed) { + if (!me.uniqueGlobalNamespace) { + me.getUniqueGlobalNamespace(); + } + sandboxPrefix = me.uniqueGlobalNamespace + '-'; + } + el.id = sandboxPrefix + (prefix || "ext-gen") + (++Ext.idSeed); } return el.id; }, @@ -5169,9 +5312,15 @@ window.undefined = window.undefined; (function(){ + var check = function(regex){ return regex.test(Ext.userAgent); }, + isStrict = document.compatMode == "CSS1Compat", + version = function (is, regex) { + var m; + return (is && (m = regex.exec(Ext.userAgent))) ? parseFloat(m[1]) : 0; + }, docMode = document.documentMode, isOpera = check(/opera/), isOpera10_5 = isOpera && check(/version\/10\.5/), @@ -5181,6 +5330,7 @@ window.undefined = window.undefined; isSafari2 = isSafari && check(/applewebkit\/4/), isSafari3 = isSafari && check(/version\/3/), isSafari4 = isSafari && check(/version\/4/), + isSafari5 = isSafari && check(/version\/5/), isIE = !isOpera && check(/msie/), isIE7 = isIE && (check(/msie 7/) || docMode == 7), isIE8 = isIE && (check(/msie 8/) && docMode != 7 && docMode != 9 || docMode == 8), @@ -5189,24 +5339,32 @@ window.undefined = window.undefined; isGecko = !isWebKit && check(/gecko/), isGecko3 = isGecko && check(/rv:1\.9/), isGecko4 = isGecko && check(/rv:2\.0/), + isGecko5 = isGecko && check(/rv:5\./), isFF3_0 = isGecko3 && check(/rv:1\.9\.0/), isFF3_5 = isGecko3 && check(/rv:1\.9\.1/), isFF3_6 = isGecko3 && check(/rv:1\.9\.2/), isWindows = check(/windows|win32/), isMac = check(/macintosh|mac os x/), isLinux = check(/linux/), - scrollWidth = null, - webKitVersion = isWebKit && (/webkit\/(\d+\.\d+)/.exec(Ext.userAgent)); + scrollbarSize = null, + chromeVersion = version(true, /\bchrome\/(\d+\.\d+)/), + firefoxVersion = version(true, /\bfirefox\/(\d+\.\d+)/), + ieVersion = version(isIE, /msie (\d+\.\d+)/), + operaVersion = version(isOpera, /version\/(\d+\.\d+)/), + safariVersion = version(isSafari, /version\/(\d+\.\d+)/), + webKitVersion = version(isWebKit, /webkit\/(\d+\.\d+)/), + isSecure = /^https/i.test(window.location.protocol); try { document.execCommand("BackgroundImageCache", false, true); } catch(e) {} - Ext.setVersion('extjs', '4.0.1'); + + Ext.setVersion('extjs', '4.0.7'); Ext.apply(Ext, { - SSL_SECURE_URL : Ext.isSecure && isIE ? 'javascript:""' : 'about:blank', + SSL_SECURE_URL : isSecure && isIE ? 'javascript:""' : 'about:blank', @@ -5265,6 +5423,10 @@ window.undefined = window.undefined; } }, + isStrict: isStrict, + + isIEQuirks: isIE && !isStrict, + isOpera : isOpera, @@ -5287,6 +5449,9 @@ window.undefined = window.undefined; isSafari4 : isSafari4, + isSafari5 : isSafari5, + + isSafari2 : isSafari2, @@ -5314,15 +5479,24 @@ window.undefined = window.undefined; isGecko4 : isGecko4, + isGecko5 : isGecko5, - isFF3_0 : isFF3_0, + isFF3_0 : isFF3_0, + isFF3_5 : isFF3_5, + isFF3_6 : isFF3_6, + isFF4 : 4 <= firefoxVersion && firefoxVersion < 5, + + + isFF5 : 5 <= firefoxVersion && firefoxVersion < 6, + + isLinux : isLinux, @@ -5332,10 +5506,28 @@ window.undefined = window.undefined; isMac : isMac, - webKitVersion: webKitVersion ? parseFloat(webKitVersion[1]) : -1, + chromeVersion: chromeVersion, + + + firefoxVersion: firefoxVersion, + + + ieVersion: ieVersion, + + + operaVersion: operaVersion, + + + safariVersion: safariVersion, + + + webKitVersion: webKitVersion, - BLANK_IMAGE_URL : (isIE6 || isIE7) ? 'http:/' + '/www.sencha.com/s.gif' : 'data:image/gif;base64,R0lGODlhAQABAID/AMDAwAAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==', + isSecure: isSecure, + + + BLANK_IMAGE_URL : (isIE6 || isIE7) ? '/' + '/www.sencha.com/s.gif' : 'data:image/gif;base64,R0lGODlhAQABAID/AMDAwAAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==', value : function(v, defaultValue, allowBlank){ @@ -5372,27 +5564,37 @@ window.undefined = window.undefined; }, - getScrollBarWidth: function(force){ + getScrollbarSize: function (force) { if(!Ext.isReady){ return 0; } - if(force === true || scrollWidth === null){ + if(force === true || scrollbarSize === null){ - var cssClass = Ext.isIE9 ? '' : Ext.baseCSSPrefix + 'hide-offsets'; + var cssClass = Ext.isIE9 ? '' : Ext.baseCSSPrefix + 'hide-offsets', - var div = Ext.getBody().createChild('
'), - child = div.child('div', true); - var w1 = child.offsetWidth; + div = Ext.getBody().createChild('
'), + child = div.child('div', true), + w1 = child.offsetWidth; + div.setStyle('overflow', (Ext.isWebKit || Ext.isGecko) ? 'auto' : 'scroll'); - var w2 = child.offsetWidth; + + var w2 = child.offsetWidth, width = w1 - w2; div.remove(); + - scrollWidth = w1 - w2 + 2; + scrollbarSize = { width: width, height: width }; } - return scrollWidth; + + return scrollbarSize; + }, + + + getScrollBarWidth: function(force){ + var size = Ext.getScrollbarSize(force); + return size.width + 2; }, @@ -5409,7 +5611,7 @@ window.undefined = window.undefined; }, - destroyMembers : function(o, arg1, arg2, etc){ + destroyMembers : function(o){ for (var i = 1, a = arguments, len = a.length; i < len; i++) { Ext.destroy(o[a[i]]); delete o[a[i]]; @@ -5417,106 +5619,8 @@ window.undefined = window.undefined; }, - log : function (message) { - var options, dump, - con = Ext.global.console, - log = Ext.log, - level = 'log', - stack, - members, - member; - - if (!Ext.isString(message)) { - options = message; - message = options.msg || ''; - level = options.level || level; - dump = options.dump; - stack = options.stack; - - if (dump && !(con && con.dir)) { - members = []; - - - - Ext.Object.each(dump, function (name, value) { - if (typeof(value) === "function") { - return; - } - - if (!Ext.isDefined(value) || value === null || - Ext.isDate(value) || - Ext.isString(value) || (typeof(value) == "number") || - Ext.isBoolean(value)) { - member = Ext.encode(value); - } else if (Ext.isArray(value)) { - member = '[ ]'; - } else if (Ext.isObject(value)) { - member = '{ }'; - } else { - member = 'undefined'; - } - members.push(Ext.encode(name) + ': ' + member); - }); - - if (members.length) { - message += ' \nData: {\n ' + members.join(',\n ') + '\n}'; - } - dump = null; - } - } - - if (arguments.length > 1) { - message += Array.prototype.slice.call(arguments, 1).join(''); - } - - - - - if (con) { - if (con[level]) { - con[level](message); - } else { - con.log(message); - } - - if (dump) { - con.dir(dump); - } - - if (stack && con.trace) { - - if (!con.firebug || level != 'error') { - con.trace(); - } - } - } else { - - if (level != 'log') { - message = level.toUpperCase() + ': ' + message; - } - - if (Ext.isOpera) { - opera.postError(message); - } else { - var out = log.out || (log.out = []), - max = log.max || (log.max = 100); - - if (out.length >= max) { - - - out.splice(0, out.length - 3 * Math.floor(max / 4)); - } - - out.push(message); - } - } - - - var counters = log.counters || - (log.counters = { error: 0, warn: 0, info: 0, log: 0 }); - - ++counters[level]; - }, + log : + Ext.emptyFn, partition : function(arr, truth){ @@ -5668,7 +5772,7 @@ Ext.application = function(config) { for (; i < decimals; i++) { format += '0'; } - v = UtilFormat.number(v, format); + v = UtilFormat.number(v, format); if ((end || UtilFormat.currencyAtEnd) === true) { return Ext.String.format("{0}{1}{2}", negativeSign, v, currencySign || UtilFormat.currencySign); } else { @@ -5738,8 +5842,7 @@ Ext.application = function(config) { }, - number: - function(v, formatString) { + number: function(v, formatString) { if (!formatString) { return v; } @@ -5776,13 +5879,6 @@ Ext.application = function(config) { if (1 < psplit.length) { v = v.toFixed(psplit[1].length); } else if(2 < psplit.length) { - Ext.Error.raise({ - sourceClass: "Ext.util.Format", - sourceMethod: "number", - value: v, - formatString: formatString, - msg: "Invalid number format, should have no more than 1 decimal" - }); } else { v = v.toFixed(0); } @@ -5817,6 +5913,11 @@ Ext.application = function(config) { } } + if (neg) { + + neg = fnum.replace(/[^1-9]/g, '') !== ''; + } + return (neg ? '-' : '') + formatString.replace(/[\d,?\.?]+/, fnum); }, @@ -6411,7 +6512,7 @@ Ext.supports = { Ext.ns('Ext.core'); -Ext.core.DomHelper = function(){ +Ext.core.DomHelper = Ext.DomHelper = function(){ var tempTableEl = null, emptyTags = /^(?:br|frame|hr|img|input|link|meta|range|spacer|wbr|area|param|col)$/i, tableRe = /^table|tbody|tr|td$/i, @@ -6443,11 +6544,11 @@ Ext.core.DomHelper = function(){ (sibling == 'firstChild' ? el : el.parentNode).insertBefore(newNode, el[sibling] || el); } } else { - newNode = Ext.core.DomHelper.insertHtml(pos, el, Ext.core.DomHelper.createHtml(o)); + newNode = Ext.DomHelper.insertHtml(pos, el, Ext.DomHelper.createHtml(o)); } return returnElement ? Ext.get(newNode, true) : newNode; } - + function createDom(o, parentNode){ var el, doc = document, @@ -6480,7 +6581,7 @@ Ext.core.DomHelper = function(){ } } } - Ext.core.DomHelper.applyStyles(el, o.style); + Ext.DomHelper.applyStyles(el, o.style); if ((cn = o.children || o.cn)) { createDom(cn, el); @@ -6595,14 +6696,14 @@ Ext.core.DomHelper = function(){ el.insertBefore(node, before); return node; } + - function createContextualFragment(html){ var div = document.createElement("div"), fragment = document.createDocumentFragment(), i = 0, length, childNodes; - + div.innerHTML = html; childNodes = div.childNodes; length = childNodes.length; @@ -6613,7 +6714,7 @@ Ext.core.DomHelper = function(){ return fragment; } - + pub = { markup : function(o){ @@ -6628,7 +6729,7 @@ Ext.core.DomHelper = function(){ styles = styles.call(); } if (typeof styles == "string") { - styles = Ext.core.Element.parseStyles(styles); + styles = Ext.Element.parseStyles(styles); } if (typeof styles == "object") { el.setStyle(styles); @@ -6650,13 +6751,13 @@ Ext.core.DomHelper = function(){ hash[beforebegin] = ['BeforeBegin', 'previousSibling']; hash[afterend] = ['AfterEnd', 'nextSibling']; - + if (el.insertAdjacentHTML) { if(tableRe.test(el.tagName) && (rs = insertIntoTable(el.tagName.toLowerCase(), where, el, html))){ return rs; } - + hash[afterbegin] = ['AfterBegin', 'firstChild']; hash[beforeend] = ['BeforeEnd', 'lastChild']; @@ -6668,7 +6769,7 @@ Ext.core.DomHelper = function(){ } else { if (Ext.isTextNode(el)) { - where = where === 'afterbegin' ? 'beforebegin' : where; + where = where === 'afterbegin' ? 'beforebegin' : where; where = where === 'beforeend' ? 'afterend' : where; } range = Ext.supports.CreateContextualFragment ? el.ownerDocument.createRange() : undefined; @@ -6691,7 +6792,7 @@ Ext.core.DomHelper = function(){ } else { frag = createContextualFragment(html); } - + if(where == afterbegin){ el.insertBefore(frag, el.firstChild); }else{ @@ -6703,13 +6804,6 @@ Ext.core.DomHelper = function(){ return el[rangeEl]; } } - Ext.Error.raise({ - sourceClass: 'Ext.core.DomHelper', - sourceMethod: 'insertHtml', - htmlToInsert: html, - targetElement: el, - msg: 'Illegal insertion point reached: "' + where + '"' - }); }, @@ -6740,16 +6834,16 @@ Ext.core.DomHelper = function(){ }, createHtml : createHtml, - + createDom: createDom, - + useDom : false, - + createTemplate : function(o){ - var html = Ext.core.DomHelper.createHtml(o); + var html = Ext.DomHelper.createHtml(o); return Ext.create('Ext.Template', html); } }; @@ -6771,6 +6865,7 @@ Ext.core.DomQuery = Ext.DomQuery = function(){ tagTokenRe = /^(#)?([\w-\*]+)/, nthRe = /(\d*)n\+?(\d*)/, nthRe2 = /\D/, + startIdRe = /^\s*\#/, @@ -7188,11 +7283,6 @@ Ext.core.DomQuery = Ext.DomQuery = function(){ } if(!matched){ - Ext.Error.raise({ - sourceClass: 'Ext.DomQuery', - sourceMethod: 'compile', - msg: 'Error parsing selector. Parsing failed at "' + path + '"' - }); } } if(modeMatch[1]){ @@ -7226,11 +7316,6 @@ Ext.core.DomQuery = Ext.DomQuery = function(){ if(!cache[subPath]){ cache[subPath] = Ext.DomQuery.compile(subPath); if(!cache[subPath]){ - Ext.Error.raise({ - sourceClass: 'Ext.DomQuery', - sourceMethod: 'jsSelect', - msg: subPath + ' is not a valid selector' - }); } } var result = cache[subPath](root); @@ -7255,12 +7340,22 @@ Ext.core.DomQuery = Ext.DomQuery = function(){ select : document.querySelectorAll ? function(path, root, type) { root = root || document; - if (!Ext.DomQuery.isXml(root)) { - try { - var cs = root.querySelectorAll(path); - return Ext.Array.toArray(cs); - } - catch (ex) {} + + if (!Ext.DomQuery.isXml(root) && !(Ext.isSafari3 && !Ext.isStrict)) { + try { + + var isDocumentRoot = root.nodeType === 9, + _path = path, + _root = root; + + if (!isDocumentRoot && path.indexOf(',') === -1 && !startIdRe.test(path)) { + _path = '#' + Ext.id(root) + ' ' + path; + _root = root.parentNode; + } + return Ext.Array.toArray(_root.querySelectorAll(_path)); + } + catch (e) { + } } return Ext.DomQuery.jsSelect.call(this, path, root, type); } : function(path, root, type) { @@ -7579,8 +7674,8 @@ Ext.query = Ext.DomQuery.select; this.id = id || Ext.id(dom); }; - var DH = Ext.core.DomHelper, - El = Ext.core.Element; + var DH = Ext.DomHelper, + El = Ext.Element; El.prototype = { @@ -7727,15 +7822,12 @@ Ext.query = Ext.DomQuery.select; } - if (size === "" || size == "auto" || size === undefined || size === null) { + if (size === "" || size == "auto" || size == null) { return size || ''; } if (!unitPattern.test(size)) { - if (Ext.isDefined(Ext.global.console)) { - Ext.global.console.warn("Warning, size detected as NaN on Element.addUnits."); - } return size || ''; } return size; @@ -7767,7 +7859,7 @@ Ext.query = Ext.DomQuery.select; contains: function(el) { - return ! el ? false: Ext.core.Element.isAncestor(this.dom, el.dom ? el.dom: el); + return ! el ? false: Ext.Element.isAncestor(this.dom, el.dom ? el.dom: el); }, @@ -7894,6 +7986,31 @@ Ext.query = Ext.DomQuery.select; return null; }; + + ep.getById = (!Ext.isIE6 && !Ext.isIE7 && !Ext.isIE8) ? El.get : + function (id) { + var dom = this.dom, + cached, el, ret; + + if (dom) { + el = dom.all[id]; + if (el) { + + + cached = EC[id]; + if (cached && cached.el) { + ret = cached.el; + ret.dom = el; + } else { + ret = El.addToCache(new El(el)); + } + return ret; + } + } + + return El.get(id); + }; + El.addToCache = function(el, id) { if (el) { id = id || el.id; @@ -8025,7 +8142,7 @@ Ext.query = Ext.DomQuery.select; })(); -Ext.core.Element.addMethods({ +Ext.Element.addMethods({ findParent : function(simpleSelector, maxDepth, returnEl) { var p = this.dom, @@ -8047,7 +8164,7 @@ Ext.core.Element.addMethods({ } return null; }, - + findParentNode : function(simpleSelector, maxDepth, returnEl) { var p = Ext.fly(this.dom.parentNode, '_internal'); @@ -8061,7 +8178,7 @@ Ext.core.Element.addMethods({ select : function(selector) { - return Ext.core.Element.select(selector, false, this.dom); + return Ext.Element.select(selector, false, this.dom); }, @@ -8117,7 +8234,7 @@ Ext.core.Element.addMethods({ if (!this.dom) { return null; } - + var n = this.dom[start]; while (n) { if (n.nodeType == 1 && (!selector || Ext.DomQuery.is(n, selector))) { @@ -8130,7 +8247,7 @@ Ext.core.Element.addMethods({ }); -Ext.core.Element.addMethods({ +Ext.Element.addMethods({ appendChild : function(el) { return Ext.get(el).appendTo(this); @@ -8195,9 +8312,9 @@ Ext.core.Element.addMethods({ } }else{ if (isAfter && !me.dom.nextSibling) { - rt = Ext.core.DomHelper.append(me.dom.parentNode, el, !returnDom); + rt = Ext.DomHelper.append(me.dom.parentNode, el, !returnDom); } else { - rt = Ext.core.DomHelper[isAfter ? 'insertAfter' : 'insertBefore'](me.dom, el, !returnDom); + rt = Ext.DomHelper[isAfter ? 'insertAfter' : 'insertBefore'](me.dom, el, !returnDom); } } return rt; @@ -8219,13 +8336,13 @@ Ext.core.Element.addMethods({ el = Ext.get(el); me.dom.parentNode.insertBefore(el, me.dom); }else{ - el = Ext.core.DomHelper.insertBefore(me.dom, el); + el = Ext.DomHelper.insertBefore(me.dom, el); } delete Ext.cache[me.id]; Ext.removeNode(me.dom); me.id = Ext.id(me.dom = el); - Ext.core.Element.addToCache(me.isFlyweight ? new Ext.core.Element(me.dom) : me); + Ext.Element.addToCache(me.isFlyweight ? new Ext.Element(me.dom) : me); return me; }, @@ -8233,16 +8350,16 @@ Ext.core.Element.addMethods({ createChild : function(config, insertBefore, returnDom) { config = config || {tag:'div'}; if (insertBefore) { - return Ext.core.DomHelper.insertBefore(insertBefore, config, returnDom !== true); + return Ext.DomHelper.insertBefore(insertBefore, config, returnDom !== true); } else { - return Ext.core.DomHelper[!this.dom.firstChild ? 'insertFirst' : 'append'](this.dom, config, returnDom !== true); + return Ext.DomHelper[!this.dom.firstChild ? 'insertFirst' : 'append'](this.dom, config, returnDom !== true); } }, wrap : function(config, returnDom) { - var newEl = Ext.core.DomHelper.insertBefore(this.dom, config || {tag: "div"}, !returnDom), + var newEl = Ext.DomHelper.insertBefore(this.dom, config || {tag: "div"}, !returnDom), d = newEl.dom || newEl; d.appendChild(this.dom); @@ -8251,16 +8368,16 @@ Ext.core.Element.addMethods({ insertHtml : function(where, html, returnEl) { - var el = Ext.core.DomHelper.insertHtml(where, this.dom, html); + var el = Ext.DomHelper.insertHtml(where, this.dom, html); return returnEl ? Ext.get(el) : el; } }); (function(){ - Ext.core.Element.boxMarkup = '
'; - var supports = Ext.supports, + var ELEMENT = Ext.Element, + supports = Ext.supports, view = document.defaultView, opacityRe = /alpha\(opacity=(.*)\)/i, trimRe = /^\s+|\s+$/g, @@ -8287,16 +8404,26 @@ Ext.core.Element.addMethods({ borders = {l: BORDER + LEFT + WIDTH, r: BORDER + RIGHT + WIDTH, t: BORDER + TOP + WIDTH, b: BORDER + BOTTOM + WIDTH}, paddings = {l: PADDING + LEFT, r: PADDING + RIGHT, t: PADDING + TOP, b: PADDING + BOTTOM}, margins = {l: MARGIN + LEFT, r: MARGIN + RIGHT, t: MARGIN + TOP, b: MARGIN + BOTTOM}, - data = Ext.core.Element.data; + data = ELEMENT.data; + + ELEMENT.boxMarkup = '
'; + + + + ELEMENT.inheritedProps = { + fontSize: 1, + fontStyle: 1, + opacity: 1 + }; + + Ext.override(ELEMENT, { - Ext.override(Ext.core.Element, { - adjustWidth : function(width) { var me = this, isNum = (typeof width == 'number'); - + if(isNum && me.autoBoxAdjust && !me.isBorderBox()){ width -= (me.getBorderWidth("lr") + me.getPadding("lr")); } @@ -8307,7 +8434,7 @@ Ext.core.Element.addMethods({ adjustHeight : function(height) { var me = this, isNum = (typeof height == "number"); - + if(isNum && me.autoBoxAdjust && !me.isBorderBox()){ height -= (me.getBorderWidth("tb") + me.getPadding("tb")); } @@ -8321,11 +8448,11 @@ Ext.core.Element.addMethods({ cls = [], space = ((me.dom.className.replace(trimRe, '') == '') ? "" : " "), i, len, v; - if (!Ext.isDefined(className)) { + if (className === undefined) { return me; } - if (!Ext.isArray(className)) { + if (Object.prototype.toString.call(className) !== '[object Array]') { if (typeof className === 'string') { className = className.replace(trimRe, '').split(spacesRe); if (className.length === 1) { @@ -8355,10 +8482,10 @@ Ext.core.Element.addMethods({ removeCls : function(className){ var me = this, i, idx, len, cls, elClasses; - if (!Ext.isDefined(className)) { + if (className === undefined) { return me; } - if (!Ext.isArray(className)){ + if (Object.prototype.toString.call(className) !== '[object Array]') { className = className.replace(trimRe, '').split(spacesRe); } if (me.dom && me.dom.className) { @@ -8369,7 +8496,7 @@ Ext.core.Element.addMethods({ cls = cls.replace(trimRe, ''); idx = Ext.Array.indexOf(elClasses, cls); if (idx != -1) { - elClasses.splice(idx, 1); + Ext.Array.erase(elClasses, idx, 1); } } } @@ -8432,7 +8559,7 @@ Ext.core.Element.addMethods({ }, - getStyle : function(){ + getStyle : function() { return view && view.getComputedStyle ? function(prop){ var el = this.dom, @@ -8441,49 +8568,74 @@ Ext.core.Element.addMethods({ if(el == document){ return null; } - prop = Ext.core.Element.normalize(prop); + prop = ELEMENT.normalize(prop); out = (v = el.style[prop]) ? v : (cs = view.getComputedStyle(el, "")) ? cs[prop] : null; - + if(prop == 'marginRight' && out != '0px' && !supports.RightMargin){ - cleaner = Ext.core.Element.getRightMarginFixCleaner(el); + cleaner = ELEMENT.getRightMarginFixCleaner(el); display = this.getStyle('display'); el.style.display = 'inline-block'; out = view.getComputedStyle(el, '').marginRight; el.style.display = display; cleaner(); } - + if(prop == 'backgroundColor' && out == 'rgba(0, 0, 0, 0)' && !supports.TransparentColor){ out = 'transparent'; } return out; } : - function(prop){ + function (prop) { var el = this.dom, m, cs; if (el == document) { return null; } - - if (prop == 'opacity') { - if (el.style.filter.match) { - m = el.style.filter.match(opacityRe); - if(m){ - var fv = parseFloat(m[1]); - if(!isNaN(fv)){ - return fv ? fv / 100 : 0; + prop = ELEMENT.normalize(prop); + + do { + if (prop == 'opacity') { + if (el.style.filter.match) { + m = el.style.filter.match(opacityRe); + if(m){ + var fv = parseFloat(m[1]); + if(!isNaN(fv)){ + return fv ? fv / 100 : 0; + } } } + return 1; } - return 1; - } - prop = Ext.core.Element.normalize(prop); - return el.style[prop] || ((cs = el.currentStyle) ? cs[prop] : null); - }; + + + + if (!Ext.isIE6) { + return el.style[prop] || ((cs = el.currentStyle) ? cs[prop] : null); + } + + try { + return el.style[prop] || ((cs = el.currentStyle) ? cs[prop] : null); + } catch (e) { + + + } + + if (!ELEMENT.inheritedProps[prop]) { + break; + } + + el = el.parentNode; + + + + } while (el); + + return null; + } }(), @@ -8515,8 +8667,7 @@ Ext.core.Element.addMethods({ if (!me.dom) { return me; } - - if (!Ext.isObject(prop)) { + if (typeof prop === 'string') { tmp = {}; tmp[prop] = value; prop = tmp; @@ -8528,7 +8679,7 @@ Ext.core.Element.addMethods({ me.setOpacity(value); } else { - me.dom.style[Ext.core.Element.normalize(style)] = value; + me.dom.style[ELEMENT.normalize(style)] = value; } } } @@ -8590,7 +8741,7 @@ Ext.core.Element.addMethods({ } return this; }, - + adjustDirect2DDimension: function(dimension) { var me = this, @@ -8600,7 +8751,7 @@ Ext.core.Element.addMethods({ inlinePosition = dom.style['position'], originIndex = dimension === 'width' ? 0 : 1, floating; - + if (display === 'inline') { dom.style['display'] = 'inline-block'; } @@ -8610,16 +8761,16 @@ Ext.core.Element.addMethods({ floating = (parseFloat(me.getStyle(dimension)) || parseFloat(dom.currentStyle.msTransformOrigin.split(' ')[originIndex]) * 2) % 1; - + dom.style['position'] = inlinePosition; - + if (display === 'inline') { dom.style['display'] = inlineDisplay; } return floating; }, - + getHeight: function(contentHeight, preciseHeight) { var me = this, @@ -8663,7 +8814,7 @@ Ext.core.Element.addMethods({ } return height; }, - + getWidth: function(contentWidth, preciseWidth) { var me = this, @@ -8678,7 +8829,7 @@ Ext.core.Element.addMethods({ overflow = style.overflow; me.setStyle({overflow: 'hidden'}); } - + if (Ext.isOpera10_5) { if (dom.parentNode.currentStyle.position === 'relative') { @@ -8688,7 +8839,7 @@ Ext.core.Element.addMethods({ dom.parentNode.style.position = parentPosition; } width = Math.max(width || 0, dom.offsetWidth); - + @@ -8714,11 +8865,11 @@ Ext.core.Element.addMethods({ width++; } } - + if (contentWidth) { width -= (me.getBorderWidth("lr") + me.getPadding("lr")); } - + if (Ext.isIEQuirks) { me.setStyle({ overflow: overflow}); } @@ -8807,14 +8958,14 @@ Ext.core.Element.addMethods({ if(data(dom, ISCLIPPED)){ data(dom, ISCLIPPED, false); clip = data(dom, ORIGINALCLIP); - if(o.o){ - me.setStyle(OVERFLOW, o.o); + if(clip.o){ + me.setStyle(OVERFLOW, clip.o); } - if(o.x){ - me.setStyle(OVERFLOWX, o.x); + if(clip.x){ + me.setStyle(OVERFLOWX, clip.x); } - if(o.y){ - me.setStyle(OVERFLOWY, o.y); + if(clip.y){ + me.setStyle(OVERFLOWY, clip.y); } } return me; @@ -8838,10 +8989,10 @@ Ext.core.Element.addMethods({ }, margins : margins, - + applyStyles : function(style){ - Ext.core.DomHelper.applyStyles(this.dom, style); + Ext.DomHelper.applyStyles(this.dom, style); return this; }, @@ -8850,7 +9001,7 @@ Ext.core.Element.addMethods({ var styles = {}, len = arguments.length, i = 0, style; - + for(; i < len; ++i) { style = arguments[i]; styles[style] = this.getStyle(style); @@ -8861,7 +9012,7 @@ Ext.core.Element.addMethods({ boxWrap : function(cls){ cls = cls || Ext.baseCSSPrefix + 'box'; - var el = Ext.get(this.insertHtml("beforeBegin", "
" + Ext.String.format(Ext.core.Element.boxMarkup, cls) + "
")); + var el = Ext.get(this.insertHtml("beforeBegin", "
" + Ext.String.format(ELEMENT.boxMarkup, cls) + "
")); Ext.DomQuery.selectNode('.' + cls + '-mc', el.dom).appendChild(this.dom); return el; }, @@ -8869,18 +9020,24 @@ Ext.core.Element.addMethods({ setSize : function(width, height, animate){ var me = this; - if (Ext.isObject(width)){ + if (Ext.isObject(width)) { + animate = height; height = width.height; width = width.width; } width = me.adjustWidth(width); height = me.adjustHeight(height); if(!animate || !me.anim){ + + + if (!Ext.isIEQuirks && (Ext.isIE6 || Ext.isIE7)) { + me.dom.offsetTop; + } me.dom.style.width = me.addUnits(width); me.dom.style.height = me.addUnits(height); } else { - if (!Ext.isObject(animate)) { + if (animate === true) { animate = {}; } me.animate(Ext.applyIf({ @@ -8910,7 +9067,7 @@ Ext.core.Element.addMethods({ getComputedWidth : function(){ var me = this, w = Math.max(me.dom.offsetWidth, me.dom.clientWidth); - + if(!w){ w = parseFloat(me.getStyle('width')) || 0; if(!me.isBorderBox()){ @@ -8978,8 +9135,8 @@ Ext.core.Element.addMethods({ if (isDoc) { ret = { - width : Ext.core.Element.getViewWidth(), - height : Ext.core.Element.getViewHeight() + width : ELEMENT.getViewWidth(), + height : ELEMENT.getViewHeight() }; @@ -9016,8 +9173,8 @@ Ext.core.Element.addMethods({ if (isDoc) { return { - width : Ext.core.Element.getViewWidth(), - height : Ext.core.Element.getViewHeight() + width : ELEMENT.getViewWidth(), + height : ELEMENT.getViewHeight() }; } @@ -9054,14 +9211,28 @@ Ext.core.Element.addMethods({ }, + selectable : function() { + var me = this; + me.dom.unselectable = "off"; + + me.on('selectstart', function (e) { + e.stopPropagation(); + return true; + }); + me.applyStyles("-moz-user-select: text; -khtml-user-select: text;"); + me.removeCls(Ext.baseCSSPrefix + 'unselectable'); + return me; + }, + + unselectable : function(){ var me = this; me.dom.unselectable = "on"; me.swallowEvent("selectstart", true); - me.applyStyles("-moz-user-select:none;-khtml-user-select:none;"); + me.applyStyles("-moz-user-select:-moz-none;-khtml-user-select:none;"); me.addCls(Ext.baseCSSPrefix + 'unselectable'); - + return me; }, @@ -9085,21 +9256,21 @@ Ext.core.Element.addMethods({ })(); -Ext.core.Element.VISIBILITY = 1; +Ext.Element.VISIBILITY = 1; -Ext.core.Element.DISPLAY = 2; +Ext.Element.DISPLAY = 2; -Ext.core.Element.OFFSETS = 3; +Ext.Element.OFFSETS = 3; -Ext.core.Element.ASCLASS = 4; +Ext.Element.ASCLASS = 4; -Ext.core.Element.visibilityCls = Ext.baseCSSPrefix + 'hide-nosize'; +Ext.Element.visibilityCls = Ext.baseCSSPrefix + 'hide-nosize'; -Ext.core.Element.addMethods(function(){ - var El = Ext.core.Element, +Ext.Element.addMethods(function(){ + var El = Ext.Element, OPACITY = "opacity", VISIBILITY = "visibility", DISPLAY = "display", @@ -9303,7 +9474,7 @@ Ext.core.Element.addMethods(function(){ }; }()); -Ext.applyIf(Ext.core.Element.prototype, { +Ext.applyIf(Ext.Element.prototype, { animate: function(config) { var me = this; @@ -9381,7 +9552,7 @@ Ext.applyIf(Ext.core.Element.prototype, { }, - slideIn: function(anchor, obj, slideOut) { + slideIn: function(anchor, obj, slideOut) { var me = this, elStyle = me.dom.style, beforeAnim, wrapAnim; @@ -9399,13 +9570,13 @@ Ext.applyIf(Ext.core.Element.prototype, { } box = me.getBox(); - if ((anchor == 't' || anchor == 'b') && box.height == 0) { + if ((anchor == 't' || anchor == 'b') && box.height === 0) { box.height = me.dom.scrollHeight; } - else if ((anchor == 'l' || anchor == 'r') && box.width == 0) { + else if ((anchor == 'l' || anchor == 'r') && box.width === 0) { box.width = me.dom.scrollWidth; } - + position = me.getPositioning(); me.setSize(box.width, box.height); @@ -9569,7 +9740,7 @@ Ext.applyIf(Ext.core.Element.prototype, { if (obj.useDisplay) { me.setDisplayed(false); } else { - me.hide(); + me.hide(); } } else { @@ -9577,7 +9748,7 @@ Ext.applyIf(Ext.core.Element.prototype, { me.setPositioning(position); } if (wrap.dom) { - wrap.dom.parentNode.insertBefore(me.dom, wrap.dom); + wrap.dom.parentNode.insertBefore(me.dom, wrap.dom); wrap.remove(); } me.setSize(box.width, box.height); @@ -9607,14 +9778,13 @@ Ext.applyIf(Ext.core.Element.prototype, { return me; }, - + slideOut: function(anchor, o) { return this.slideIn(anchor, o, true); }, - puff: function(obj) { var me = this, beforeAnim; @@ -9646,7 +9816,7 @@ Ext.applyIf(Ext.core.Element.prototype, { } else { me.hide(); } - me.clearOpacity(); + me.clearOpacity(); me.setPositioning(position); me.setStyle({fontSize: fontSize}); } @@ -9669,7 +9839,7 @@ Ext.applyIf(Ext.core.Element.prototype, { switchOff: function(obj) { var me = this, beforeAnim; - + obj = Ext.applyIf(obj || {}, { easing: 'ease-in', duration: 500, @@ -9709,7 +9879,7 @@ Ext.applyIf(Ext.core.Element.prototype, { me.setDisplayed(false); } else { me.hide(); - } + } me.clearOpacity(); me.setPositioning(position); me.setSize(size); @@ -9727,7 +9897,7 @@ Ext.applyIf(Ext.core.Element.prototype, { return me; }, - + frame : function(color, count, obj){ var me = this, beforeAnim; @@ -9853,7 +10023,7 @@ Ext.applyIf(Ext.core.Element.prototype, { return me; }, - + highlight: function(color, o) { var me = this, dom = me.dom, @@ -9864,7 +10034,7 @@ Ext.applyIf(Ext.core.Element.prototype, { lns = o.listeners || {}; attr = o.attr || 'backgroundColor'; from[attr] = color || 'ffff9c'; - + if (!o.to) { to = {}; to[attr] = o.endColor || me.getColor(attr, 'ffffff', ''); @@ -9872,14 +10042,14 @@ Ext.applyIf(Ext.core.Element.prototype, { else { to = o.to; } - + o.listeners = Ext.apply(Ext.apply({}, lns), { beforeanimate: function() { restore = dom.style[attr]; me.clearOpacity(); me.show(); - + event = lns.beforeanimate; if (event) { fn = event.fn || event; @@ -9890,7 +10060,7 @@ Ext.applyIf(Ext.core.Element.prototype, { if (dom) { dom.style[attr] = restore; } - + event = lns.afteranimate; if (event) { fn = event.fn || event; @@ -9917,7 +10087,7 @@ Ext.applyIf(Ext.core.Element.prototype, { return me; }, - + fadeIn: function(o) { this.animate(Ext.apply({}, o, { opacity: 1 @@ -9925,7 +10095,7 @@ Ext.applyIf(Ext.core.Element.prototype, { return this; }, - + fadeOut: function(o) { this.animate(Ext.apply({}, o, { opacity: 0 @@ -9933,7 +10103,7 @@ Ext.applyIf(Ext.core.Element.prototype, { return this; }, - + scale: function(w, h, o) { this.animate(Ext.apply({}, o, { width: w, @@ -9942,7 +10112,7 @@ Ext.applyIf(Ext.core.Element.prototype, { return this; }, - + shift: function(config) { this.animate(config); return this; @@ -9950,7 +10120,7 @@ Ext.applyIf(Ext.core.Element.prototype, { }); -Ext.applyIf(Ext.core.Element, { +Ext.applyIf(Ext.Element, { unitRe: /\d+(px|em|%|en|ex|pt|in|cm|mm|pc)$/i, camelRe: /(-[a-z])/gi, opacityRe: /alpha\(opacity=(.*)\)/i, @@ -9962,7 +10132,7 @@ Ext.applyIf(Ext.core.Element, { margins: {l: 'margin-left', r: 'margin-right', t: 'margin-top', b: 'margin-bottom'}, - addUnits : Ext.core.Element.prototype.addUnits, + addUnits : Ext.Element.prototype.addUnits, parseBox : function(box) { @@ -10093,7 +10263,7 @@ Ext.CompositeElementLite = function(els, root){ this.elements = []; this.add(els, root); - this.el = new Ext.core.Element.Flyweight(); + this.el = new Ext.Element.Flyweight(); }; Ext.CompositeElementLite.prototype = { @@ -10125,7 +10295,7 @@ Ext.CompositeElementLite.prototype = { return this; } if(typeof els == "string"){ - els = Ext.core.Element.selectorFunction(els, root); + els = Ext.Element.selectorFunction(els, root); }else if(els.isComposite){ els = els.elements; }else if(!Ext.isIterable(els)){ @@ -10148,7 +10318,7 @@ Ext.CompositeElementLite.prototype = { for(i = 0; i < len; i++) { e = els[i]; if(e){ - Ext.core.Element.prototype[fn].apply(me.getElement(e), args); + Ext.Element.prototype[fn].apply(me.getElement(e), args); } } return me; @@ -10220,7 +10390,7 @@ Ext.CompositeElementLite.prototype = { els[els.length] = me.transformElement(el); } }); - + me.elements = els; return me; }, @@ -10241,7 +10411,7 @@ Ext.CompositeElementLite.prototype = { d.parentNode.insertBefore(replacement, d); Ext.removeNode(d); } - this.elements.splice(index, 1, replacement); + Ext.Array.splice(this.elements, index, 1, replacement); } return this; }, @@ -10257,7 +10427,7 @@ Ext.CompositeElementLite.prototype.on = Ext.CompositeElementLite.prototype.addLi Ext.CompositeElementLite.importElementMethods = function() { var fnName, - ElProto = Ext.core.Element.prototype, + ElProto = Ext.Element.prototype, CelProto = Ext.CompositeElementLite.prototype; for (fnName in ElProto) { @@ -10275,29 +10445,22 @@ Ext.CompositeElementLite.importElementMethods = function() { Ext.CompositeElementLite.importElementMethods(); if(Ext.DomQuery){ - Ext.core.Element.selectorFunction = Ext.DomQuery.select; + Ext.Element.selectorFunction = Ext.DomQuery.select; } -Ext.core.Element.select = function(selector, root){ +Ext.Element.select = function(selector, root){ var els; if(typeof selector == "string"){ - els = Ext.core.Element.selectorFunction(selector, root); + els = Ext.Element.selectorFunction(selector, root); }else if(selector.length !== undefined){ els = selector; }else{ - Ext.Error.raise({ - sourceClass: "Ext.core.Element", - sourceMethod: "select", - selector: selector, - root: root, - msg: "Invalid selector specified: " + selector - }); } return new Ext.CompositeElementLite(els); }; -Ext.select = Ext.core.Element.select; +Ext.select = Ext.Element.select; Ext.util.DelayedTask = function(fn, scope, args) { @@ -10368,13 +10531,6 @@ Ext.require('Ext.util.DelayedTask', function() { listener; scope = scope || me.observable; - if (!fn) { - Ext.Error.raise({ - sourceClass: Ext.getClassName(this.observable), - sourceMethod: "addListener", - msg: "The specified callback function is undefined" - }); - } if (!me.isListening(fn, scope)) { listener = me.createListener(fn, scope, options); @@ -10466,7 +10622,7 @@ Ext.require('Ext.util.DelayedTask', function() { } - me.listeners.splice(index, 1); + Ext.Array.erase(me.listeners, index, 1); return true; } @@ -10537,6 +10693,7 @@ Ext.EventManager = { if(window.attachEvent){ + if (window != top) { return false; } @@ -10641,9 +10798,9 @@ Ext.EventManager = { getId : function(element) { var skipGarbageCollection = false, id; - + element = Ext.getDom(element); - + if (element === document || element === window) { id = element === document ? Ext.documentId : Ext.windowId; } @@ -10654,9 +10811,9 @@ Ext.EventManager = { if (element && (element.getElementById || element.navigator)) { skipGarbageCollection = true; } - + if (!Ext.cache[id]){ - Ext.core.Element.addToCache(new Ext.core.Element(element), id); + Ext.Element.addToCache(new Ext.Element(element), id); if (skipGarbageCollection) { Ext.cache[id].skipGarbageCollection = true; } @@ -10734,7 +10891,7 @@ Ext.EventManager = { addListener: function(element, eventName, fn, scope, options){ - if (Ext.isObject(eventName)) { + if (typeof eventName !== 'string') { this.prepareListenerConfig(element, eventName); return; } @@ -10743,24 +10900,6 @@ Ext.EventManager = { bind, wrap; - if (!dom){ - Ext.Error.raise({ - sourceClass: 'Ext.EventManager', - sourceMethod: 'addListener', - targetElement: element, - eventName: eventName, - msg: 'Error adding "' + eventName + '\" listener for nonexistent element "' + element + '"' - }); - } - if (!fn) { - Ext.Error.raise({ - sourceClass: 'Ext.EventManager', - sourceMethod: 'addListener', - targetElement: element, - eventName: eventName, - msg: 'Error adding "' + eventName + '\" listener. The handler function is undefined.' - }); - } options = options || {}; @@ -10790,7 +10929,7 @@ Ext.EventManager = { removeListener : function(element, eventName, fn, scope) { - if (Ext.isObject(eventName)) { + if (typeof eventName !== 'string') { this.prepareListenerConfig(element, eventName, true); return; } @@ -10834,7 +10973,7 @@ Ext.EventManager = { } - cache.splice(i, 1); + Ext.Array.erase(cache, i, 1); } } }, @@ -10877,7 +11016,7 @@ Ext.EventManager = { createListenerWrap : function(dom, ename, fn, scope, options) { - options = !Ext.isObject(options) ? {} : options; + options = options || {}; var f, gen; @@ -10952,12 +11091,19 @@ Ext.EventManager = { getEventListenerCache : function(element, eventName) { + if (!element) { + return []; + } + var eventCache = this.getElementEventCache(element); return eventCache[eventName] || (eventCache[eventName] = []); }, getElementEventCache : function(element) { + if (!element) { + return {}; + } var elementCache = Ext.cache[this.getId(element)]; return elementCache.events || (elementCache.events = {}); }, @@ -11083,8 +11229,8 @@ Ext.EventManager = { fireResize: function(){ var me = this, - w = Ext.core.Element.getViewWidth(), - h = Ext.core.Element.getViewHeight(); + w = Ext.Element.getViewWidth(), + h = Ext.Element.getViewHeight(); if(me.curHeight != h || me.curWidth != w){ @@ -11172,7 +11318,7 @@ Ext.EventManager.un = Ext.EventManager.removeListener; var bd = document.body || document.getElementsByTagName('body')[0], baseCSSPrefix = Ext.baseCSSPrefix, - cls = [], + cls = [baseCSSPrefix + 'body'], htmlCls = [], html; @@ -11182,66 +11328,107 @@ Ext.EventManager.un = Ext.EventManager.removeListener; html = bd.parentNode; + function add (c) { + cls.push(baseCSSPrefix + c); + } + if (Ext.isIE) { - cls.push(baseCSSPrefix + 'ie'); - } - if (Ext.isIE6) { - cls.push(baseCSSPrefix + 'ie6'); - } - if (Ext.isIE7) { - cls.push(baseCSSPrefix + 'ie7'); - } - if (Ext.isIE8) { - cls.push(baseCSSPrefix + 'ie8'); - } - if (Ext.isIE9) { - cls.push(baseCSSPrefix + 'ie9'); + add('ie'); + + + + + + + + + + + + + if (Ext.isIE6) { + add('ie6'); + } else { + add('ie7p'); + + if (Ext.isIE7) { + add('ie7'); + } else { + add('ie8p'); + + if (Ext.isIE8) { + add('ie8'); + } else { + add('ie9p'); + + if (Ext.isIE9) { + add('ie9'); + } + } + } + } + + if (Ext.isIE6 || Ext.isIE7) { + add('ie7m'); + } + if (Ext.isIE6 || Ext.isIE7 || Ext.isIE8) { + add('ie8m'); + } + if (Ext.isIE7 || Ext.isIE8) { + add('ie78'); + } } if (Ext.isGecko) { - cls.push(baseCSSPrefix + 'gecko'); - } - if (Ext.isGecko3) { - cls.push(baseCSSPrefix + 'gecko3'); - } - if (Ext.isGecko4) { - cls.push(baseCSSPrefix + 'gecko4'); + add('gecko'); + if (Ext.isGecko3) { + add('gecko3'); + } + if (Ext.isGecko4) { + add('gecko4'); + } + if (Ext.isGecko5) { + add('gecko5'); + } } if (Ext.isOpera) { - cls.push(baseCSSPrefix + 'opera'); + add('opera'); } if (Ext.isWebKit) { - cls.push(baseCSSPrefix + 'webkit'); + add('webkit'); } if (Ext.isSafari) { - cls.push(baseCSSPrefix + 'safari'); - } - if (Ext.isSafari2) { - cls.push(baseCSSPrefix + 'safari2'); - } - if (Ext.isSafari3) { - cls.push(baseCSSPrefix + 'safari3'); - } - if (Ext.isSafari4) { - cls.push(baseCSSPrefix + 'safari4'); + add('safari'); + if (Ext.isSafari2) { + add('safari2'); + } + if (Ext.isSafari3) { + add('safari3'); + } + if (Ext.isSafari4) { + add('safari4'); + } + if (Ext.isSafari5) { + add('safari5'); + } } if (Ext.isChrome) { - cls.push(baseCSSPrefix + 'chrome'); + add('chrome'); } if (Ext.isMac) { - cls.push(baseCSSPrefix + 'mac'); + add('mac'); } if (Ext.isLinux) { - cls.push(baseCSSPrefix + 'linux'); + add('linux'); } if (!Ext.supports.CSS3BorderRadius) { - cls.push(baseCSSPrefix + 'nbr'); + add('nbr'); } if (!Ext.supports.CSS3LinearGradient) { - cls.push(baseCSSPrefix + 'nlg'); + add('nlg'); } if (!Ext.scopeResetCSS) { - cls.push(baseCSSPrefix + 'reset'); + add('reset'); } @@ -11256,9 +11443,6 @@ Ext.EventManager.un = Ext.EventManager.removeListener; htmlCls.push(baseCSSPrefix + (Ext.isBorderBox ? 'border-box' : 'strict')); if (!Ext.isStrict) { htmlCls.push(baseCSSPrefix + 'quirks'); - if (Ext.isIE && !Ext.isStrict) { - Ext.isIEQuirks = true; - } } Ext.fly(html, '_internal').addCls(htmlCls); } @@ -11448,6 +11632,44 @@ Ext.define('Ext.EventObjectImpl', { F11: 122, F12: 123, + + WHEEL_SCALE: (function () { + var scale; + + if (Ext.isGecko) { + + scale = 3; + } else if (Ext.isMac) { + + + + + if (Ext.isSafari && Ext.webKitVersion >= 532.0) { + + + + + + + scale = 120; + } else { + + + scale = 12; + } + + + + + + scale *= 3; + } else { + + scale = 120; + } + + return scale; + })(), clickRe: /(dbl)?click/, @@ -11576,17 +11798,17 @@ Ext.define('Ext.EventObjectImpl', { getPageY: function(){ return this.getY(); }, - + getX: function() { return this.getXY()[0]; - }, - + }, + getY: function() { return this.getXY()[1]; }, - + getXY: function() { if (!this.xy) { @@ -11613,16 +11835,58 @@ Ext.define('Ext.EventObjectImpl', { }, - getWheelDelta : function(){ - var event = this.browserEvent, - delta = 0; + correctWheelDelta : function (delta) { + var scale = this.WHEEL_SCALE, + ret = Math.round(delta / scale); - if (event.wheelDelta) { - delta = event.wheelDelta / 120; - } else if (event.detail){ - delta = -event.detail / 3; + if (!ret && delta) { + ret = (delta < 0) ? -1 : 1; } - return delta; + + return ret; + }, + + + getWheelDeltas : function () { + var me = this, + event = me.browserEvent, + dx = 0, dy = 0; + + if (Ext.isDefined(event.wheelDeltaX)) { + dx = event.wheelDeltaX; + dy = event.wheelDeltaY; + } else if (event.wheelDelta) { + dy = event.wheelDelta; + } else if (event.detail) { + dy = -event.detail; + + + + if (dy > 100) { + dy = 3; + } else if (dy < -100) { + dy = -3; + } + + + + if (Ext.isDefined(event.axis) && event.axis === event.HORIZONTAL_AXIS) { + dx = dy; + dy = 0; + } + } + + return { + x: me.correctWheelDelta(dx), + y: me.correctWheelDelta(dy) + }; + }, + + + getWheelDelta : function(){ + var deltas = this.getWheelDeltas(); + + return deltas.y; }, @@ -11743,7 +12007,7 @@ Ext.define('Ext.EventObjectImpl', { return target; } - } + }; } else if (document.createEventObject) { var crazyIEButtons = { 0: 1, 1: 4, 2: 2 }; @@ -11871,7 +12135,6 @@ Ext.define('Ext.EventObjectImpl', { } function cannotInject (target, srcEvent) { - } return function (target) { @@ -11896,10 +12159,10 @@ Ext.EventObject = new Ext.EventObjectImpl(); var doc = document, activeElement = null, isCSS1 = doc.compatMode == "CSS1Compat", - ELEMENT = Ext.core.Element, + ELEMENT = Ext.Element, fly = function(el){ if (!_fly) { - _fly = new Ext.core.Element.Flyweight(); + _fly = new Ext.Element.Flyweight(); } _fly.dom = el; return _fly; @@ -12017,6 +12280,17 @@ Ext.EventObject = new Ext.EventObjectImpl(); return ELEMENT.getXY(el)[0]; }, + getOffsetParent: function (el) { + el = Ext.getDom(el); + try { + + return el.offsetParent; + } catch (e) { + var body = document.body; + return (el == body) ? null : body; + } + }, + getXY : function(el) { var p, pe, @@ -12029,7 +12303,7 @@ Ext.EventObject = new Ext.EventObjectImpl(); scroll, hasAbsolute, bd = (doc.body || doc.documentElement), - ret = [0,0]; + ret; el = Ext.getDom(el); @@ -12037,13 +12311,17 @@ Ext.EventObject = new Ext.EventObjectImpl(); hasAbsolute = fly(el).isStyle("position", "absolute"); if (el.getBoundingClientRect) { - b = el.getBoundingClientRect(); - scroll = fly(document).getScroll(); - ret = [Math.round(b.left + scroll.left), Math.round(b.top + scroll.top)]; - } else { - p = el; + try { + b = el.getBoundingClientRect(); + scroll = fly(document).getScroll(); + ret = [ Math.round(b.left + scroll.left), Math.round(b.top + scroll.top) ]; + } catch (e) { + + } + } - while (p) { + if (!ret) { + for (p = el; p; p = ELEMENT.getOffsetParent(p)) { pe = fly(p); x += p.offsetLeft; y += p.offsetTop; @@ -12059,7 +12337,6 @@ Ext.EventObject = new Ext.EventObjectImpl(); y += bt; } } - p = p.offsetParent; } if (Ext.isSafari && hasAbsolute) { @@ -12084,7 +12361,7 @@ Ext.EventObject = new Ext.EventObjectImpl(); ret = [x,y]; } } - return ret; + return ret || [0,0]; }, setXY : function(el, xy) { @@ -12146,207 +12423,232 @@ Ext.EventObject = new Ext.EventObjectImpl(); -Ext.core.Element.addMethods({ +Ext.Element.addMethods((function(){ + var focusRe = /button|input|textarea|select|object/; + return { + + monitorMouseLeave: function(delay, handler, scope) { + var me = this, + timer, + listeners = { + mouseleave: function(e) { + timer = setTimeout(Ext.Function.bind(handler, scope||me, [e]), delay); + }, + mouseenter: function() { + clearTimeout(timer); + }, + freezeEvent: true + }; - - monitorMouseLeave: function(delay, handler, scope) { - var me = this, - timer, - listeners = { - mouseleave: function(e) { - timer = setTimeout(Ext.Function.bind(handler, scope||me, [e]), delay); - }, - mouseenter: function() { - clearTimeout(timer); - }, - freezeEvent: true - }; + me.on(listeners); + return listeners; + }, - me.on(listeners); - return listeners; - }, + + swallowEvent : function(eventName, preventDefault) { + var me = this; + function fn(e) { + e.stopPropagation(); + if (preventDefault) { + e.preventDefault(); + } + } - - swallowEvent : function(eventName, preventDefault) { - var me = this; - function fn(e) { - e.stopPropagation(); - if (preventDefault) { - e.preventDefault(); + if (Ext.isArray(eventName)) { + Ext.each(eventName, function(e) { + me.on(e, fn); + }); + return me; } - } - - if (Ext.isArray(eventName)) { - Ext.each(eventName, function(e) { - me.on(e, fn); - }); + me.on(eventName, fn); return me; - } - me.on(eventName, fn); - return me; - }, + }, - - relayEvent : function(eventName, observable) { - this.on(eventName, function(e) { - observable.fireEvent(eventName, e); - }); - }, + + relayEvent : function(eventName, observable) { + this.on(eventName, function(e) { + observable.fireEvent(eventName, e); + }); + }, + + clean : function(forceReclean) { + var me = this, + dom = me.dom, + n = dom.firstChild, + nx, + ni = -1; - clean : function(forceReclean) { - var me = this, - dom = me.dom, - n = dom.firstChild, - nx, - ni = -1; - - if (Ext.core.Element.data(dom, 'isCleaned') && forceReclean !== true) { - return me; - } + if (Ext.Element.data(dom, 'isCleaned') && forceReclean !== true) { + return me; + } - while (n) { - nx = n.nextSibling; - if (n.nodeType == 3) { - - if (!(/\S/.test(n.nodeValue))) { - dom.removeChild(n); - - } else if (nx && nx.nodeType == 3) { - n.appendData(Ext.String.trim(nx.data)); - dom.removeChild(nx); - nx = n.nextSibling; + while (n) { + nx = n.nextSibling; + if (n.nodeType == 3) { + + if (!(/\S/.test(n.nodeValue))) { + dom.removeChild(n); + + } else if (nx && nx.nodeType == 3) { + n.appendData(Ext.String.trim(nx.data)); + dom.removeChild(nx); + nx = n.nextSibling; + n.nodeIndex = ++ni; + } + } else { + + Ext.fly(n).clean(); n.nodeIndex = ++ni; } - } else { - - Ext.fly(n).clean(); - n.nodeIndex = ++ni; + n = nx; } - n = nx; - } - Ext.core.Element.data(dom, 'isCleaned', true); - return me; - }, + Ext.Element.data(dom, 'isCleaned', true); + return me; + }, - - load : function(options) { - this.getLoader().load(options); - return this; - }, + + load : function(options) { + this.getLoader().load(options); + return this; + }, + + getLoader : function() { + var dom = this.dom, + data = Ext.Element.data, + loader = data(dom, 'loader'); - getLoader : function() { - var dom = this.dom, - data = Ext.core.Element.data, - loader = data(dom, 'loader'); - - if (!loader) { - loader = Ext.create('Ext.ElementLoader', { - target: this - }); - data(dom, 'loader', loader); - } - return loader; - }, + if (!loader) { + loader = Ext.create('Ext.ElementLoader', { + target: this + }); + data(dom, 'loader', loader); + } + return loader; + }, - - update : function(html, loadScripts, callback) { - var me = this, - id, - dom, - interval; - - if (!me.dom) { - return me; - } - html = html || ''; - dom = me.dom; + + update : function(html, loadScripts, callback) { + var me = this, + id, + dom, + interval; - if (loadScripts !== true) { - dom.innerHTML = html; - Ext.callback(callback, me); - return me; - } + if (!me.dom) { + return me; + } + html = html || ''; + dom = me.dom; - id = Ext.id(); - html += ''; - - interval = setInterval(function(){ - if (!document.getElementById(id)) { - return false; - } - clearInterval(interval); - var DOC = document, - hd = DOC.getElementsByTagName("head")[0], - re = /(?:]*)?>)((\n|\r|.)*?)(?:<\/script>)/ig, - srcRe = /\ssrc=([\'\"])(.*?)\1/i, - typeRe = /\stype=([\'\"])(.*?)\1/i, - match, - attrs, - srcMatch, - typeMatch, - el, - s; + if (loadScripts !== true) { + dom.innerHTML = html; + Ext.callback(callback, me); + return me; + } - while ((match = re.exec(html))) { - attrs = match[1]; - srcMatch = attrs ? attrs.match(srcRe) : false; - if (srcMatch && srcMatch[2]) { - s = DOC.createElement("script"); - s.src = srcMatch[2]; - typeMatch = attrs.match(typeRe); - if (typeMatch && typeMatch[2]) { - s.type = typeMatch[2]; - } - hd.appendChild(s); - } else if (match[2] && match[2].length > 0) { - if (window.execScript) { - window.execScript(match[2]); - } else { - window.eval(match[2]); + id = Ext.id(); + html += ''; + + interval = setInterval(function(){ + if (!document.getElementById(id)) { + return false; + } + clearInterval(interval); + var DOC = document, + hd = DOC.getElementsByTagName("head")[0], + re = /(?:]*)?>)((\n|\r|.)*?)(?:<\/script>)/ig, + srcRe = /\ssrc=([\'\"])(.*?)\1/i, + typeRe = /\stype=([\'\"])(.*?)\1/i, + match, + attrs, + srcMatch, + typeMatch, + el, + s; + + while ((match = re.exec(html))) { + attrs = match[1]; + srcMatch = attrs ? attrs.match(srcRe) : false; + if (srcMatch && srcMatch[2]) { + s = DOC.createElement("script"); + s.src = srcMatch[2]; + typeMatch = attrs.match(typeRe); + if (typeMatch && typeMatch[2]) { + s.type = typeMatch[2]; + } + hd.appendChild(s); + } else if (match[2] && match[2].length > 0) { + if (window.execScript) { + window.execScript(match[2]); + } else { + window.eval(match[2]); + } } } - } - - el = DOC.getElementById(id); - if (el) { - Ext.removeNode(el); - } - Ext.callback(callback, me); - }, 20); - dom.innerHTML = html.replace(/(?:)((\n|\r|.)*?)(?:<\/script>)/ig, ''); - return me; - }, - - removeAllListeners : function() { - this.removeAnchor(); - Ext.EventManager.removeAll(this.dom); - return this; - }, + el = DOC.getElementById(id); + if (el) { + Ext.removeNode(el); + } + Ext.callback(callback, me); + }, 20); + dom.innerHTML = html.replace(/(?:)((\n|\r|.)*?)(?:<\/script>)/ig, ''); + return me; + }, + + removeAllListeners : function() { + this.removeAnchor(); + Ext.EventManager.removeAll(this.dom); + return this; + }, - createProxy : function(config, renderTo, matchBox) { - config = (typeof config == 'object') ? config : {tag : "div", cls: config}; + + getScopeParent: function(){ + var parent = this.dom.parentNode; + return Ext.scopeResetCSS ? parent.parentNode : parent; + }, - var me = this, - proxy = renderTo ? Ext.core.DomHelper.append(renderTo, config, true) : - Ext.core.DomHelper.insertBefore(me.dom, config, true); + + createProxy : function(config, renderTo, matchBox) { + config = (typeof config == 'object') ? config : {tag : "div", cls: config}; - proxy.setVisibilityMode(Ext.core.Element.DISPLAY); - proxy.hide(); - if (matchBox && me.setBox && me.getBox) { - proxy.setBox(me.getBox()); - } - return proxy; - } -}); -Ext.core.Element.prototype.clearListeners = Ext.core.Element.prototype.removeAllListeners; + var me = this, + proxy = renderTo ? Ext.DomHelper.append(renderTo, config, true) : + Ext.DomHelper.insertBefore(me.dom, config, true); + + proxy.setVisibilityMode(Ext.Element.DISPLAY); + proxy.hide(); + if (matchBox && me.setBox && me.getBox) { + proxy.setBox(me.getBox()); + } + return proxy; + }, + + + focusable: function(){ + var dom = this.dom, + nodeName = dom.nodeName.toLowerCase(), + canFocus = false, + hasTabIndex = !isNaN(dom.tabIndex); + + if (!dom.disabled) { + if (focusRe.test(nodeName)) { + canFocus = true; + } else { + canFocus = nodeName == 'a' ? dom.href || hasTabIndex : hasTabIndex; + } + } + return canFocus && this.isVisible(true); + } + }; +})()); +Ext.Element.prototype.clearListeners = Ext.Element.prototype.removeAllListeners; -Ext.core.Element.addMethods({ +Ext.Element.addMethods({ getAnchorXY : function(anchor, local, s){ @@ -12356,8 +12658,8 @@ Ext.core.Element.addMethods({ var me = this, vp = me.dom == document.body || me.dom == document, - w = s.width || vp ? Ext.core.Element.getViewWidth() : me.getWidth(), - h = s.height || vp ? Ext.core.Element.getViewHeight() : me.getHeight(), + w = s.width || vp ? Ext.Element.getViewWidth() : me.getWidth(), + h = s.height || vp ? Ext.Element.getViewHeight() : me.getHeight(), xy, r = Math.round, o = me.getXY(), @@ -12425,7 +12727,7 @@ Ext.core.Element.addMethods({ getAnchor : function(){ - var data = Ext.core.Element.data, + var data = Ext.Element.data, dom = this.dom; if (!dom) { return; @@ -12446,11 +12748,6 @@ Ext.core.Element.addMethods({ el = Ext.get(el); if(!el || !el.dom){ - Ext.Error.raise({ - sourceClass: 'Ext.core.Element', - sourceMethod: 'getAlignVector', - msg: 'Attempted to align an element that doesn\'t exist' - }); } elRegion = el.getRegion(); @@ -12461,11 +12758,6 @@ Ext.core.Element.addMethods({ el = Ext.get(el); if(!el || !el.dom){ - Ext.Error.raise({ - sourceClass: 'Ext.core.Element', - sourceMethod: 'getAlignToXY', - msg: 'Attempted to align an element that doesn\'t exist' - }); } o = o || [0,0]; @@ -12481,8 +12773,8 @@ Ext.core.Element.addMethods({ w, h, r, - dw = Ext.core.Element.getViewWidth() -10, - dh = Ext.core.Element.getViewHeight()-10, + dw = Ext.Element.getViewWidth() -10, + dh = Ext.Element.getViewHeight()-10, p1y, p1x, p2y, @@ -12500,14 +12792,6 @@ Ext.core.Element.addMethods({ m = p.match(/^([a-z]+)-([a-z]+)(\?)?$/); if(!m){ - Ext.Error.raise({ - sourceClass: 'Ext.core.Element', - sourceMethod: 'getAlignToXY', - el: el, - position: p, - offset: o, - msg: 'Attemmpted to align an element with an invalid position: "' + p + '"' - }); } p1 = m[1]; @@ -12627,7 +12911,7 @@ Ext.core.Element.addMethods({ (function(){ -var ELEMENT = Ext.core.Element, +var ELEMENT = Ext.Element, LEFT = "left", RIGHT = "right", TOP = "top", @@ -12638,7 +12922,7 @@ var ELEMENT = Ext.core.Element, AUTO = "auto", ZINDEX = "z-index"; -Ext.override(Ext.core.Element, { +Ext.override(Ext.Element, { getX : function(){ return ELEMENT.getX(this.dom); @@ -12935,14 +13219,14 @@ Ext.override(Ext.core.Element, { var me = this, isBody = me.dom === document.body, scroll, pos, top, left, width, height; - + if (isBody) { scroll = me.getScroll(); left = scroll.left; top = scroll.top; - width = Ext.core.Element.getViewportWidth(); - height = Ext.core.Element.getViewportHeight(); + width = Ext.Element.getViewportWidth(); + height = Ext.Element.getViewportHeight(); } else { pos = me.getXY(); @@ -12960,8 +13244,8 @@ Ext.override(Ext.core.Element, { var me = this, el = me.dom, isDoc = el === document.body, - w = isDoc ? Ext.core.Element.getViewWidth() : el.offsetWidth, - h = isDoc ? Ext.core.Element.getViewHeight() : el.offsetHeight, + w = isDoc ? Ext.Element.getViewWidth() : el.offsetWidth, + h = isDoc ? Ext.Element.getViewHeight() : el.offsetHeight, xy = me.getXY(), t = xy[1], r = xy[0] + w, @@ -13013,7 +13297,7 @@ Ext.override(Ext.core.Element, { })(); -Ext.override(Ext.core.Element, { +Ext.override(Ext.Element, { isScrollable : function(){ var dom = this.dom; @@ -13147,7 +13431,7 @@ Ext.override(Ext.core.Element, { } }); -Ext.core.Element.addMethods( +Ext.Element.addMethods( function() { var VISIBILITY = "visibility", DISPLAY = "display", @@ -13155,7 +13439,7 @@ Ext.core.Element.addMethods( NONE = "none", XMASKED = Ext.baseCSSPrefix + "masked", XMASKEDRELATIVE = Ext.baseCSSPrefix + "masked-relative", - data = Ext.core.Element.data; + data = Ext.Element.data; return { @@ -13183,7 +13467,7 @@ Ext.core.Element.addMethods( enableDisplayMode : function(display) { - this.setVisibilityMode(Ext.core.Element.DISPLAY); + this.setVisibilityMode(Ext.Element.DISPLAY); if (!Ext.isEmpty(display)) { data(this.dom, 'originalDisplay', display); @@ -13197,7 +13481,7 @@ Ext.core.Element.addMethods( var me = this, dom = me.dom, setExpression = dom.style.setExpression, - dh = Ext.core.DomHelper, + dh = Ext.DomHelper, EXTELMASKMSG = Ext.baseCSSPrefix + "mask-msg", el, mask; @@ -13303,7 +13587,7 @@ Ext.core.Element.addMethods( }() ); -Ext.core.Element.addMethods({ +Ext.Element.addMethods({ addKeyListener : function(key, fn, scope){ var config; @@ -13343,7 +13627,7 @@ Ext.apply(Ext.CompositeElementLite.prototype, { return this; } if(typeof els == "string"){ - els = Ext.core.Element.selectorFunction(els, root); + els = Ext.Element.selectorFunction(els, root); } var yels = this.elements; Ext.each(els, function(e) { @@ -13381,7 +13665,7 @@ Ext.apply(Ext.CompositeElementLite.prototype, { Ext.removeNode(el); } } - els.splice(val, 1); + Ext.Array.erase(els, val, 1); } }); return this; @@ -13390,53 +13674,38 @@ Ext.apply(Ext.CompositeElementLite.prototype, { Ext.CompositeElement = Ext.extend(Ext.CompositeElementLite, { - + constructor : function(els, root){ this.elements = []; this.add(els, root); }, - + getElement : function(el){ return el; }, - + transformElement : function(el){ return Ext.get(el); } - - - - - - }); -Ext.core.Element.select = function(selector, unique, root){ +Ext.Element.select = function(selector, unique, root){ var els; if(typeof selector == "string"){ - els = Ext.core.Element.selectorFunction(selector, root); + els = Ext.Element.selectorFunction(selector, root); }else if(selector.length !== undefined){ els = selector; }else{ - Ext.Error.raise({ - sourceClass: "Ext.core.Element", - sourceMethod: "select", - selector: selector, - unique: unique, - root: root, - msg: "Invalid selector specified: " + selector - }); } return (unique === true) ? new Ext.CompositeElement(els) : new Ext.CompositeElementLite(els); }; -Ext.select = Ext.core.Element.select; - +Ext.select = Ext.Element.select; @@ -13495,7 +13764,7 @@ Ext.define('Ext.util.Observable', { }, - eventOptionsRe : /^(?:scope|delay|buffer|single|stopEvent|preventDefault|stopPropagation|normalized|args|delegate|element|vertical|horizontal)$/, + eventOptionsRe : /^(?:scope|delay|buffer|single|stopEvent|preventDefault|stopPropagation|normalized|args|delegate|element|vertical|horizontal|freezeEvent)$/, addManagedListener : function(item, ename, fn, scope, options) { @@ -13503,7 +13772,7 @@ Ext.define('Ext.util.Observable', { managedListeners = me.managedListeners = me.managedListeners || [], config; - if (Ext.isObject(ename)) { + if (typeof ename !== 'string') { options = ename; for (ename in options) { if (options.hasOwnProperty(ename)) { @@ -13528,7 +13797,7 @@ Ext.define('Ext.util.Observable', { }, - removeManagedListener : function(item, ename, fn, scope) { + removeManagedListener : function(item, ename, fn, scope) { var me = this, options, config, @@ -13536,7 +13805,7 @@ Ext.define('Ext.util.Observable', { length, i; - if (Ext.isObject(ename)) { + if (typeof ename !== 'string') { options = ename; for (ename in options) { if (options.hasOwnProperty(ename)) { @@ -13556,44 +13825,57 @@ Ext.define('Ext.util.Observable', { }, - fireEvent: function() { - var me = this, - args = Ext.Array.toArray(arguments), - ename = args[0].toLowerCase(), - ret = true, - event = me.events[ename], - queue = me.eventQueue, - parent; + fireEvent: function(eventName) { + var name = eventName.toLowerCase(), + events = this.events, + event = events && events[name], + bubbles = event && event.bubble; - if (me.eventsSuspended === true) { - 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); + return this.continueFireEvent(name, Ext.Array.slice(arguments, 1), bubbles); + }, + + + continueFireEvent: function(eventName, args, bubbles) { + var target = this, + queue, event, + ret = true; + + do { + if (target.eventsSuspended === true) { + if ((queue = target.eventQueue)) { + queue.push([eventName, args, bubbles]); + } + return ret; + } else { + event = target.events[eventName]; + + + if (event && event != true) { + if ((ret = event.fire.apply(event, args)) === false) { + break; + } } - return parent.fireEvent.apply(parent, args); } - } else if (event && Ext.isObject(event)) { - args.shift(); - ret = event.fire.apply(event, args); - } + } while (bubbles && (target = target.getBubbleParent())); return ret; }, + getBubbleParent: function(){ + var me = this, parent = me.getBubbleTarget && me.getBubbleTarget(); + if (parent && parent.isObservable) { + return parent; + } + return null; + }, + + 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)) { @@ -13622,7 +13904,7 @@ Ext.define('Ext.util.Observable', { event, options; - if (Ext.isObject(ename)) { + if (typeof ename !== 'string') { options = ename; for (ename in options) { if (options.hasOwnProperty(ename)) { @@ -13659,12 +13941,6 @@ Ext.define('Ext.util.Observable', { this.clearManagedListeners(); }, - purgeListeners : function() { - if (Ext.global.console) { - Ext.global.console.warn('Observable: purgeListeners has been deprecated. Please use clearListeners.'); - } - return this.clearListeners.apply(this, arguments); - }, clearManagedListeners : function() { @@ -13678,23 +13954,17 @@ Ext.define('Ext.util.Observable', { this.managedListeners = []; }, - + removeManagedListenerItem: function(isClear, managedListener, item, ename, fn, scope){ if (isClear || (managedListener.item === item && managedListener.ename === ename && (!fn || managedListener.fn === fn) && (!scope || managedListener.scope === scope))) { managedListener.item.un(managedListener.ename, managedListener.fn, managedListener.scope); if (!isClear) { Ext.Array.remove(this.managedListeners, managedListener); - } + } } }, - purgeManagedListeners : function() { - if (Ext.global.console) { - Ext.global.console.warn('Observable: purgeManagedListeners has been deprecated. Please use clearManagedListeners.'); - } - return this.clearManagedListeners.apply(this, arguments); - }, addEvents: function(o) { @@ -13702,12 +13972,12 @@ Ext.define('Ext.util.Observable', { args, len, i; - + me.events = me.events || {}; if (Ext.isString(o)) { args = arguments; i = args.length; - + while (i--) { me.events[args[i]] = me.events[args[i]] || true; } @@ -13733,15 +14003,16 @@ Ext.define('Ext.util.Observable', { resumeEvents: function() { var me = this, - queued = me.eventQueue || []; + queued = me.eventQueue; me.eventsSuspended = false; delete me.eventQueue; - Ext.each(queued, - function(e) { - me.fireEvent.apply(me, e); - }); + if (queued) { + Ext.each(queued, function(e) { + me.continueFireEvent.apply(me, e); + }); + } }, @@ -13787,14 +14058,15 @@ Ext.define('Ext.util.Observable', { } } }, function() { - - - this.createAlias({ + on: 'addListener', + un: 'removeListener', + mon: 'addManagedListener', + mun: 'removeManagedListener' }); @@ -13894,13 +14166,13 @@ Ext.define('Ext.util.Observable', { 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; } } @@ -13984,11 +14256,13 @@ Ext.define('Ext.util.Animate', { getActiveAnimation: function() { return Ext.fx.Manager.getActiveAnimation(this.id); } +}, function(){ + + Ext.applyIf(Ext.Element.prototype, this.prototype); + + Ext.CompositeElementLite.importElementMethods(); }); - -Ext.applyIf(Ext.core.Element.prototype, Ext.util.Animate.prototype); - Ext.define('Ext.state.Provider', { mixins: { observable: 'Ext.util.Observable' @@ -14121,504 +14395,6 @@ Ext.define('Ext.state.Provider', { } }); -Ext.define('Ext.util.HashMap', { - - - - mixins: { - observable: 'Ext.util.Observable' - }, - - constructor: function(config) { - var me = this; - - me.addEvents( - - 'add', - - 'clear', - - 'remove', - - 'replace' - ); - - me.mixins.observable.constructor.call(me, config); - me.clear(true); - }, - - - getCount: function() { - return this.length; - }, - - - getData: function(key, value) { - - if (value === undefined) { - value = key; - key = this.getKey(value); - } - - return [key, value]; - }, - - - getKey: function(o) { - return o.id; - }, - - - add: function(key, value) { - var me = this, - data; - - if (arguments.length === 1) { - value = key; - key = me.getKey(value); - } - - if (me.containsKey(key)) { - me.replace(key, value); - } - - data = me.getData(key, value); - key = data[0]; - value = data[1]; - me.map[key] = value; - ++me.length; - me.fireEvent('add', me, key, value); - return value; - }, - - - replace: function(key, value) { - var me = this, - map = me.map, - old; - - if (!me.containsKey(key)) { - me.add(key, value); - } - old = map[key]; - map[key] = value; - me.fireEvent('replace', me, key, value, old); - return value; - }, - - - remove: function(o) { - var key = this.findKey(o); - if (key !== undefined) { - return this.removeAtKey(key); - } - return false; - }, - - - removeAtKey: function(key) { - var me = this, - value; - - if (me.containsKey(key)) { - value = me.map[key]; - delete me.map[key]; - --me.length; - me.fireEvent('remove', me, key, value); - return true; - } - return false; - }, - - - get: function(key) { - return this.map[key]; - }, - - - clear: function( initial) { - var me = this; - me.map = {}; - me.length = 0; - if (initial !== true) { - me.fireEvent('clear', me); - } - return me; - }, - - - containsKey: function(key) { - return this.map[key] !== undefined; - }, - - - contains: function(value) { - return this.containsKey(this.findKey(value)); - }, - - - getKeys: function() { - return this.getArray(true); - }, - - - getValues: function() { - return this.getArray(false); - }, - - - getArray: function(isKey) { - var arr = [], - key, - map = this.map; - for (key in map) { - if (map.hasOwnProperty(key)) { - arr.push(isKey ? key: map[key]); - } - } - return arr; - }, - - - each: function(fn, scope) { - - var items = Ext.apply({}, this.map), - key, - length = this.length; - - scope = scope || this; - for (key in items) { - if (items.hasOwnProperty(key)) { - if (fn.call(scope, key, items[key], length) === false) { - break; - } - } - } - return this; - }, - - - clone: function() { - var hash = new this.self(), - map = this.map, - key; - - hash.suspendEvents(); - for (key in map) { - if (map.hasOwnProperty(key)) { - hash.add(key, map[key]); - } - } - hash.resumeEvents(); - return hash; - }, - - - findKey: function(value) { - var key, - map = this.map; - - for (key in map) { - if (map.hasOwnProperty(key) && map[key] === value) { - return key; - } - } - return undefined; - } -}); - - - -Ext.define('Ext.Template', { - - - - requires: ['Ext.core.DomHelper', 'Ext.util.Format'], - - statics: { - - from: function(el, config) { - el = Ext.getDom(el); - return new this(el.value || el.innerHTML, config || ''); - } - }, - - - - constructor: function(html) { - var me = this, - args = arguments, - buffer = [], - i = 0, - length = args.length, - value; - - me.initialConfig = {}; - - if (length > 1) { - for (; i < length; i++) { - value = args[i]; - if (typeof value == 'object') { - Ext.apply(me.initialConfig, value); - Ext.apply(me, value); - } else { - buffer.push(value); - } - } - html = buffer.join(''); - } else { - if (Ext.isArray(html)) { - buffer.push(html.join('')); - } else { - buffer.push(html); - } - } - - - me.html = buffer.join(''); - - if (me.compiled) { - me.compile(); - } - }, - isTemplate: true, - - disableFormats: false, - - re: /\{([\w\-]+)(?:\:([\w\.]*)(?:\((.*?)?\))?)?\}/g, - - applyTemplate: function(values) { - var me = this, - useFormat = me.disableFormats !== true, - fm = Ext.util.Format, - tpl = me; - - if (me.compiled) { - return me.compiled(values); - } - function fn(m, name, format, args) { - if (format && useFormat) { - if (args) { - args = [values[name]].concat(Ext.functionFactory('return ['+ args +'];')()); - } else { - args = [values[name]]; - } - if (format.substr(0, 5) == "this.") { - return tpl[format.substr(5)].apply(tpl, args); - } - else { - return fm[format].apply(fm, args); - } - } - else { - return values[name] !== undefined ? values[name] : ""; - } - } - return me.html.replace(me.re, fn); - }, - - - set: function(html, compile) { - var me = this; - me.html = html; - me.compiled = null; - return compile ? me.compile() : me; - }, - - compileARe: /\\/g, - compileBRe: /(\r\n|\n)/g, - compileCRe: /'/g, - /** - * Compiles the template into an internal function, eliminating the RegEx overhead. - * @return {Ext.Template} this - * @hide repeat doc - */ - compile: function() { - var me = this, - fm = Ext.util.Format, - useFormat = me.disableFormats !== true, - body, bodyReturn; - - function fn(m, name, format, args) { - if (format && useFormat) { - args = args ? ',' + args: ""; - if (format.substr(0, 5) != "this.") { - format = "fm." + format + '('; - } - else { - format = 'this.' + format.substr(5) + '('; - } - } - else { - args = ''; - format = "(values['" + name + "'] == undefined ? '' : "; - } - return "'," + format + "values['" + name + "']" + args + ") ,'"; - } - - bodyReturn = me.html.replace(me.compileARe, '\\\\').replace(me.compileBRe, '\\n').replace(me.compileCRe, "\\'").replace(me.re, fn); - body = "this.compiled = function(values){ return ['" + bodyReturn + "'].join('');};"; - eval(body); - return me; - }, - - /** - * Applies the supplied values to the template and inserts the new node(s) as the first child of el. - * @param {Mixed} el The context element - * @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'}) - * @param {Boolean} returnElement (optional) true to return a Ext.core.Element (defaults to undefined) - * @return {HTMLElement/Ext.core.Element} The new node or Element - */ - insertFirst: function(el, values, returnElement) { - return this.doInsert('afterBegin', el, values, returnElement); - }, - - /** - * Applies the supplied values to the template and inserts the new node(s) before el. - * @param {Mixed} el The context element - * @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'}) - * @param {Boolean} returnElement (optional) true to return a Ext.core.Element (defaults to undefined) - * @return {HTMLElement/Ext.core.Element} The new node or Element - */ - insertBefore: function(el, values, returnElement) { - return this.doInsert('beforeBegin', el, values, returnElement); - }, - - /** - * Applies the supplied values to the template and inserts the new node(s) after el. - * @param {Mixed} el The context element - * @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'}) - * @param {Boolean} returnElement (optional) true to return a Ext.core.Element (defaults to undefined) - * @return {HTMLElement/Ext.core.Element} The new node or Element - */ - insertAfter: function(el, values, returnElement) { - return this.doInsert('afterEnd', el, values, returnElement); - }, - - /** - * Applies the supplied values to the template and appends - * the new node(s) to the specified el. - *

For example usage {@link #Template see the constructor}.

- * @param {Mixed} el The context element - * @param {Object/Array} values - * The template values. Can be an array if the params are numeric (i.e. {0}) - * or an object (i.e. {foo: 'bar'}). - * @param {Boolean} returnElement (optional) true to return an Ext.core.Element (defaults to undefined) - * @return {HTMLElement/Ext.core.Element} The new node or Element - */ - append: function(el, values, returnElement) { - return this.doInsert('beforeEnd', el, values, returnElement); - }, - - doInsert: function(where, el, values, returnEl) { - el = Ext.getDom(el); - var newNode = Ext.core.DomHelper.insertHtml(where, el, this.applyTemplate(values)); - return returnEl ? Ext.get(newNode, true) : newNode; - }, - - /** - * Applies the supplied values to the template and overwrites the content of el with the new node(s). - * @param {Mixed} el The context element - * @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'}) - * @param {Boolean} returnElement (optional) true to return a Ext.core.Element (defaults to undefined) - * @return {HTMLElement/Ext.core.Element} The new node or Element - */ - overwrite: function(el, values, returnElement) { - el = Ext.getDom(el); - el.innerHTML = this.applyTemplate(values); - return returnElement ? Ext.get(el.firstChild, true) : el.firstChild; - } -}, function() { - - /** - * Alias for {@link #applyTemplate} - * Returns an HTML fragment of this template with the specified values applied. - * @param {Object/Array} values - * The template values. Can be an array if the params are numeric (i.e. {0}) - * or an object (i.e. {foo: 'bar'}). - * @return {String} The HTML fragment - * @member Ext.Template - * @method apply - */ - this.createAlias('apply', 'applyTemplate'); -}); - -/** - * @class Ext.ComponentQuery - * @extends Object - * - * 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 -
    -
  • component or .component
  • -
  • gridpanel or .gridpanel
  • -
- * - * An itemId or id must be prefixed with a # -
    -
  • #myContainer
  • -
- * - * - * Attributes must be wrapped in brackets -
    -
  • 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 - *

- * - * Queries return an array of components. - * Here are some example queries. -

-    // 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 - */ Ext.define('Ext.ComponentQuery', { singleton: true, uses: ['Ext.ComponentManager'] @@ -14626,8 +14402,8 @@ Ext.define('Ext.ComponentQuery', { var cq = this, - // A function source code pattern with a placeholder which accepts an expression which yields a truth value when applied - // as a member on each item in the passed array. + + filterFnPattern = [ 'var r = [],', 'i = 0,', @@ -14644,9 +14420,9 @@ Ext.define('Ext.ComponentQuery', { ].join(''), filterItems = function(items, operation) { - // Argument list for the operation is [ itemsArray, operationArg1, operationArg2...] - // The operation's method loops over each item in the candidate array and - // returns an array of items which match its criteria + + + return operation.method.apply(this, [ items ].concat(operation.args)); }, @@ -14680,7 +14456,7 @@ Ext.define('Ext.ComponentQuery', { return result; }, - // Filters the passed candidate array and returns only items which match the passed xtype + filterByXType = function(items, xtype, shallow) { if (xtype === '*') { return items.slice(); @@ -14700,7 +14476,7 @@ Ext.define('Ext.ComponentQuery', { } }, - // Filters the passed candidate array and returns only items which have the passed className + filterByClassName = function(items, className) { var EA = Ext.Array, result = [], @@ -14716,7 +14492,7 @@ Ext.define('Ext.ComponentQuery', { return result; }, - // Filters the passed candidate array and returns only items which have the specified property match + filterByAttribute = function(items, property, operator, value) { var result = [], i = 0, @@ -14731,7 +14507,7 @@ Ext.define('Ext.ComponentQuery', { return result; }, - // Filters the passed candidate array and returns only items which have the specified itemId or id + filterById = function(items, id) { var result = [], i = 0, @@ -14746,62 +14522,56 @@ Ext.define('Ext.ComponentQuery', { return result; }, - // Filters the passed candidate array and returns only items which the named pseudo class matcher filters in + filterByPseudo = function(items, name, value) { return cq.pseudos[name](items, value); }, - // Determines leading mode - // > for direct child, and ^ to switch to ownerCt axis + + modeRe = /^(\s?([>\^])\s?|\s|$)/, - // Matches a token with possibly (true|false) appended for the "shallow" parameter + tokenRe = /^(#)?([\w\-]+|\*)(?:\((true|false)\))?/, matchers = [{ - // Checks for .xtype with possibly (true|false) appended for the "shallow" parameter + re: /^\.([\w\-]+)(?:\((true|false)\))?/, method: filterByXType },{ - // checks for [attribute=value] + re: /^(?:[\[](?:@)?([\w\-]+)\s?(?:(=|.=)\s?['"]?(.*?)["']?)?[\]])/, method: filterByAttribute }, { - // checks for #cmpItemId + re: /^#([\w\-]+)/, method: filterById }, { - // checks for :() + re: /^\:([\w\-]+)(?:\(((?:\{[^\}]+\})|(?:(?!\{)[^\s>\/]*?(?!\})))\))?/, method: filterByPseudo }, { - // checks for {} + re: /^(?:\{([^\}]+)\})/, method: filterFnPattern }]; - /** - * @class Ext.ComponentQuery.Query - * @extends Object - * @private - */ + + cq.Query = Ext.extend(Object, { constructor: function(cfg) { cfg = cfg || {}; Ext.apply(this, cfg); }, - /** - * @private - * Executes this Query upon the selected root. - * The root provides the initial source of candidate Component matches which are progressively - * filtered by iterating through this Query's operations cache. - * If no root is provided, all registered Components are searched via the ComponentManager. - * root may be a Container who's descendant Components are filtered - * root may be a Component with an implementation of getRefItems which provides some nested Components such as the - * docked items within a Panel. - * root may be an array of candidate Components to filter using this Query. - */ + + + + + + + + execute : function(root) { var operations = this.operations, i = 0, @@ -14809,26 +14579,26 @@ Ext.define('Ext.ComponentQuery', { operation, workingItems; - // no root, use all Components in the document + if (!root) { workingItems = Ext.ComponentManager.all.getArray(); } - // Root is a candidate Array + else if (Ext.isArray(root)) { workingItems = root; } - // We are going to loop over our operations and take care of them - // one by one. + + for (; i < length; i++) { operation = operations[i]; - // The mode operation requires some custom handling. - // All other operations essentially filter down our current - // working items, while mode replaces our current working - // items by getting children from each one of our current - // working items. The type of mode determines the type of - // children we get. (e.g. > only gets direct children) + + + + + + if (operation.mode === '^') { workingItems = getAncestors(workingItems || [root]); } @@ -14839,8 +14609,8 @@ Ext.define('Ext.ComponentQuery', { workingItems = filterItems(workingItems || getItems([root]), operation); } - // If this is the last operation, it means our current working - // items are the final matched items. Thus return them! + + if (i === length -1) { return workingItems; } @@ -14872,10 +14642,10 @@ Ext.define('Ext.ComponentQuery', { Ext.apply(this, { - // private cache of selectors and matching ComponentQuery.Query objects + cache: {}, - // private cache of pseudo class filter functions + pseudos: { not: function(components, selector){ var CQ = Ext.ComponentQuery, @@ -14892,21 +14662,13 @@ Ext.define('Ext.ComponentQuery', { } } return results; + }, + last: function(components) { + return components[components.length - 1]; } }, - /** - *

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 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 {Array} The matched Components. - * @member Ext.ComponentQuery - */ + query: function(selector, root) { var selectors = selector.split(','), length = selectors.length, @@ -14925,8 +14687,8 @@ Ext.define('Ext.ComponentQuery', { results = results.concat(query.execute(root)); } - // multiple selectors, potential to find duplicates - // lets filter them out. + + if (length > 1) { resultsLn = results.length; for (i = 0; i < resultsLn; i++) { @@ -14941,13 +14703,7 @@ Ext.define('Ext.ComponentQuery', { return results; }, - /** - * Tests whether the passed Component matches the selector string. - * @param component The Component to test - * @param selector The selector string to test against. - * @return {Boolean} True if the Component matches the selector. - * @member Ext.ComponentQuery - */ + is: function(component, selector) { if (!selector) { return true; @@ -14969,35 +14725,35 @@ Ext.define('Ext.ComponentQuery', { selectorMatch, i, matcher, method; - // We are going to parse the beginning of the selector over and - // over again, slicing off the selector any portions we converted into an - // operation, until it is an empty string. + + + while (selector && lastSelector !== selector) { lastSelector = selector; - // First we check if we are dealing with a token like #, * or an xtype + tokenMatch = selector.match(tokenRe); if (tokenMatch) { matchedChar = tokenMatch[1]; - // If the token is prefixed with a # we push a filterById operation to our stack + if (matchedChar === '#') { operations.push({ method: filterById, args: [Ext.String.trim(tokenMatch[2])] }); } - // If the token is prefixed with a . we push a filterByClassName operation to our stack - // FIXME: Not enabled yet. just needs \. adding to the tokenRe prefix + + else if (matchedChar === '.') { operations.push({ method: filterByClassName, args: [Ext.String.trim(tokenMatch[2])] }); } - // If the token is a * or an xtype string, we push a filterByXType - // operation to the stack. + + else { operations.push({ method: filterByXType, @@ -15005,49 +14761,45 @@ Ext.define('Ext.ComponentQuery', { }); } - // Now we slice of the part we just converted into an operation + selector = selector.replace(tokenMatch[0], ''); } - // If the next part of the query is not a space or > or ^, it means we - // are going to check for more things that our current selection - // has to comply to. + + + while (!(modeMatch = selector.match(modeRe))) { - // Lets loop over each type of matcher and execute it - // on our current selector. + + for (i = 0; selector && i < length; i++) { matcher = matchers[i]; selectorMatch = selector.match(matcher.re); method = matcher.method; - // If we have a match, add an operation with the method - // associated with this matcher, and pass the regular - // expression matches are arguments to the operation. + + + if (selectorMatch) { operations.push({ method: Ext.isString(matcher.method) - // Turn a string method into a function by formatting the string with our selector matche expression - // A new method is created for different match expressions, eg {id=='textfield-1024'} - // Every expression may be different in different selectors. + + + ? Ext.functionFactory('items', Ext.String.format.apply(Ext.String, [method].concat(selectorMatch.slice(1)))) : matcher.method, args: selectorMatch.slice(1) }); selector = selector.replace(selectorMatch[0], ''); - break; // Break on match - } - // Exhausted all matches: It's an error - if (i === (length - 1)) { - Ext.Error.raise('Invalid ComponentQuery selector: "' + arguments[0] + '"'); + break; } } } - // Now we are going to check for a mode change. This means a space - // or a > to determine if we are going to select all the children - // of the currently matched items, or a ^ if we are going to use the - // ownerCt axis as the candidate source. - if (modeMatch[1]) { // Assignment, and test for truthiness! + + + + + if (modeMatch[1]) { operations.push({ mode: modeMatch[2]||modeMatch[1] }); @@ -15055,6478 +14807,5352 @@ Ext.define('Ext.ComponentQuery', { } } - // Now that we have all our operations in an array, we are going - // to create a new Query using these operations. + + return new cq.Query({ operations: operations }); } }); }); -/** - * @class Ext.util.Filter - * @extends Object - *

Represents a filter that can be applied to a {@link Ext.util.MixedCollection MixedCollection}. Can either simply - * filter on a property/value pair or pass in a filter function with custom logic. Filters are always used in the context - * of MixedCollections, though {@link Ext.data.Store Store}s frequently create them when filtering and searching on their - * records. Example usage:

-

-//set up a fictional MixedCollection containing a few people to filter on
-var allNames = new Ext.util.MixedCollection();
-allNames.addAll([
-    {id: 1, name: 'Ed',    age: 25},
-    {id: 2, name: 'Jamie', age: 37},
-    {id: 3, name: 'Abe',   age: 32},
-    {id: 4, name: 'Aaron', age: 26},
-    {id: 5, name: 'David', age: 32}
-]);
-
-var ageFilter = new Ext.util.Filter({
-    property: 'age',
-    value   : 32
-});
 
-var longNameFilter = new Ext.util.Filter({
-    filterFn: function(item) {
-        return item.name.length > 4;
-    }
-});
-
-//a new MixedCollection with the 3 names longer than 4 characters
-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', { - - /* Begin Definitions */ +Ext.define('Ext.util.HashMap', { + mixins: { + observable: 'Ext.util.Observable' + }, - /* End Definitions */ - /** - * @cfg {String} property The property to filter on. Required unless a {@link #filter} is passed - */ - - /** - * @cfg {Function} filterFn A custom filter function which is passed each item in the {@link Ext.util.MixedCollection} - * in turn. Should return true to accept each item or false to reject it - */ - /** - * @cfg {Boolean} anyMatch True to allow any match - no regex start/end line anchors will be added. Defaults to false - */ - anyMatch: false, - - /** - * @cfg {Boolean} exactMatch True to force exact match (^ and $ characters added to the regex). Defaults to false. - * Ignored if anyMatch is true. - */ - exactMatch: false, - - /** - * @cfg {Boolean} caseSensitive True to make the regex case sensitive (adds 'i' switch to regex). Defaults to false. - */ - caseSensitive: false, - - /** - * @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 - */ + constructor: function(config) { - Ext.apply(this, config); - - //we're aliasing filter to filterFn mostly for API cleanliness reasons, despite the fact it dirties the code here. - //Ext.util.Sorter takes a sorterFn property but allows .sort to be called - we do the same here - this.filter = this.filter || this.filterFn; + config = config || {}; - if (this.filter == undefined) { - if (this.property == undefined || this.value == undefined) { - // Commented this out temporarily because it stops us using string ids in models. TODO: Remove this once - // Model has been updated to allow string ids - - // Ext.Error.raise("A Filter requires either a property or a filterFn to be set"); - } else { - this.filter = this.createFilterFn(); - } + var me = this, + keyFn = config.keyFn; + + me.addEvents( + + 'add', + + 'clear', + + 'remove', - this.filterFn = this.filter; + 'replace' + ); + + me.mixins.observable.constructor.call(me, config); + me.clear(true); + + if (keyFn) { + me.getKey = keyFn; } }, + - /** - * @private - * Creates a filter function for the configured property/value/anyMatch/caseSensitive options for this Filter - */ - createFilterFn: function() { - var me = this, - matcher = me.createValueMatcher(), - property = me.property; + getCount: function() { + return this.length; + }, + + + getData: function(key, value) { - return function(item) { - return matcher.test(me.getRoot.call(me, item)[property]); - }; + if (value === undefined) { + value = key; + key = this.getKey(value); + } + + return [key, value]; }, + - /** - * @private - * Returns the root property of the given item, based on the configured {@link #root} property - * @param {Object} item The item - * @return {Object} The root property of the object - */ - getRoot: function(item) { - return this.root == undefined ? item : item[this.root]; + getKey: function(o) { + return o.id; }, + - /** - * @private - * Returns a regular expression based on the given value and matching options - */ - createValueMatcher : function() { - var me = this, - value = me.value, - anyMatch = me.anyMatch, - exactMatch = me.exactMatch, - caseSensitive = me.caseSensitive, - escapeRe = Ext.String.escapeRegex; - - if (!value.exec) { // not a regex - value = String(value); + add: function(key, value) { + var me = this, + data; - if (anyMatch === true) { - value = escapeRe(value); - } else { - value = '^' + escapeRe(value); - if (exactMatch === true) { - value += '$'; - } - } - value = new RegExp(value, caseSensitive ? '' : 'i'); - } - - return value; - } -}); -/** - * @class Ext.util.Sorter - * @extends Object - * Represents a single sorter that can be applied to a Store - */ -Ext.define('Ext.util.Sorter', { + if (arguments.length === 1) { + value = key; + key = me.getKey(value); + } + + if (me.containsKey(key)) { + return me.replace(key, value); + } + + data = me.getData(key, value); + key = data[0]; + value = data[1]; + me.map[key] = value; + ++me.length; + me.fireEvent('add', me, key, value); + return value; + }, - /** - * @cfg {String} property The property to sort by. Required unless {@link #sorter} is provided - */ - /** - * @cfg {Function} sorterFn A specific sorter function to execute. Can be passed instead of {@link #property} - */ + replace: function(key, value) { + var me = this, + map = me.map, + old; + + if (!me.containsKey(key)) { + me.add(key, value); + } + old = map[key]; + map[key] = value; + me.fireEvent('replace', me, key, value, old); + return value; + }, + - /** - * @cfg {String} root Optional root property. This is mostly useful when sorting 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 - */ + remove: function(o) { + var key = this.findKey(o); + if (key !== undefined) { + return this.removeAtKey(key); + } + return false; + }, + - /** - * @cfg {Function} transform A function that will be run on each value before - * it is compared in the sorter. The function will receive a single argument, - * the value. - */ + removeAtKey: function(key) { + var me = this, + value; + + if (me.containsKey(key)) { + value = me.map[key]; + delete me.map[key]; + --me.length; + me.fireEvent('remove', me, key, value); + return true; + } + return false; + }, + - /** - * @cfg {String} direction The direction to sort by. Defaults to ASC - */ - direction: "ASC", + get: function(key) { + return this.map[key]; + }, + - constructor: function(config) { + clear: function( initial) { var me = this; - - Ext.apply(me, config); - - if (me.property == undefined && me.sorterFn == undefined) { - Ext.Error.raise("A Sorter requires either a property or a sorter function"); + me.map = {}; + me.length = 0; + if (initial !== true) { + me.fireEvent('clear', me); } - - me.updateSortFunction(); + return me; }, + - /** - * @private - * Creates and returns a function which sorts an array by the given property and direction - * @return {Function} A function which sorts by the property/direction combination provided - */ - createSortFunction: function(sorterFn) { - var me = this, - property = me.property, - direction = me.direction || "ASC", - modifier = direction.toUpperCase() == "DESC" ? -1 : 1; - - //create a comparison function. Takes 2 objects, returns 1 if object 1 is greater, - //-1 if object 2 is greater or 0 if they are equal - return function(o1, o2) { - return modifier * sorterFn.call(me, o1, o2); - }; + containsKey: function(key) { + return this.map[key] !== undefined; }, + - /** - * @private - * Basic default sorter function that just compares the defined property of each object - */ - defaultSorterFn: function(o1, o2) { - var me = this, - transform = me.transform, - v1 = me.getRoot(o1)[me.property], - v2 = me.getRoot(o2)[me.property]; - - if (transform) { - v1 = transform(v1); - v2 = transform(v2); - } + contains: function(value) { + return this.containsKey(this.findKey(value)); + }, - return v1 > v2 ? 1 : (v1 < v2 ? -1 : 0); + + getKeys: function() { + return this.getArray(true); }, + - /** - * @private - * Returns the root property of the given item, based on the configured {@link #root} property - * @param {Object} item The item - * @return {Object} The root property of the object - */ - getRoot: function(item) { - return this.root == undefined ? item : item[this.root]; + getValues: function() { + return this.getArray(false); }, + - // @TODO: Add docs for these three methods - setDirection: function(direction) { - var me = this; - me.direction = direction; - me.updateSortFunction(); + getArray: function(isKey) { + var arr = [], + key, + map = this.map; + for (key in map) { + if (map.hasOwnProperty(key)) { + arr.push(isKey ? key: map[key]); + } + } + return arr; }, + - toggle: function() { - var me = this; - me.direction = Ext.String.toggle(me.direction, "ASC", "DESC"); - me.updateSortFunction(); + each: function(fn, scope) { + + var items = Ext.apply({}, this.map), + key, + length = this.length; + + scope = scope || this; + for (key in items) { + if (items.hasOwnProperty(key)) { + if (fn.call(scope, key, items[key], length) === false) { + break; + } + } + } + return this; }, + - updateSortFunction: function() { - var me = this; - me.sort = me.createSortFunction(me.sorterFn || me.defaultSorterFn); - } -}); -/** - * @class Ext.ElementLoader - * A class used to load remote content to an Element. Sample usage: - *

-Ext.get('el').load({
-    url: 'myPage.php',
-    scripts: true,
-    params: {
-        id: 1
+    clone: function() {
+        var hash = new this.self(),
+            map = this.map,
+            key;
+
+        hash.suspendEvents();
+        for (key in map) {
+            if (map.hasOwnProperty(key)) {
+                hash.add(key, map[key]);
+            }
+        }
+        hash.resumeEvents();
+        return hash;
+    },
+
+    
+    findKey: function(value) {
+        var key,
+            map = this.map;
+
+        for (key in map) {
+            if (map.hasOwnProperty(key) && map[key] === value) {
+                return key;
+            }
+        }
+        return undefined;
     }
 });
- * 
- *

- * In general this class will not be instanced directly, rather the {@link Ext.core.Element#load} method - * will be used. - *

- */ -Ext.define('Ext.ElementLoader', { - /* Begin Definitions */ - mixins: { - observable: 'Ext.util.Observable' +Ext.define('Ext.state.Manager', { + singleton: true, + requires: ['Ext.state.Provider'], + constructor: function() { + this.provider = Ext.create('Ext.state.Provider'); + }, + + + + setProvider : function(stateProvider){ + this.provider = stateProvider; }, - uses: [ - 'Ext.data.Connection', - 'Ext.Ajax' - ], - statics: { - Renderer: { - Html: function(loader, response, active){ - loader.getTarget().update(response.responseText, active.scripts === true); - return true; - } - } + get : function(key, defaultValue){ + return this.provider.get(key, defaultValue); }, - /* End Definitions */ + + set : function(key, value){ + this.provider.set(key, value); + }, - /** - * @cfg {String} url The url to retrieve the content from. Defaults to null. - */ - url: null, + + clear : function(key){ + this.provider.clear(key); + }, - /** - * @cfg {Object} params Any params to be attached to the Ajax request. These parameters will - * be overridden by any params in the load options. Defaults to null. - */ - params: null, + + getProvider : function(){ + return this.provider; + } +}); - /** - * @cfg {Object} baseParams Params that will be attached to every request. These parameters - * will not be overridden by any params in the load options. Defaults to null. - */ - baseParams: null, +Ext.define('Ext.state.Stateful', { - /** - * @cfg {Boolean/Object} autoLoad True to have the loader make a request as soon as it is created. Defaults to false. - * This argument can also be a set of options that will be passed to {@link #load} is called. - */ - autoLoad: false, + - /** - * @cfg {Mixed} target The target element for the loader. It can be the DOM element, the id or an Ext.Element. - */ - target: null, + mixins: { + observable: 'Ext.util.Observable' + }, - /** - * @cfg {Mixed} loadMask True or a string to show when the element is loading. - */ - loadMask: false, + requires: ['Ext.state.Manager'], - /** - * @cfg {Object} ajaxOptions Any additional options to be passed to the request, for example timeout or headers. Defaults to null. - */ - ajaxOptions: null, - /** - * @cfg {Boolean} scripts True to parse any inline script tags in the response. - */ - scripts: false, - /** - * @cfg {Function} success A function to be called when a load request is successful. - */ + + stateful: true, - /** - * @cfg {Function} failure A function to be called when a load request fails. - */ + - /** - * @cfg {Object} scope The scope to execute the {@link #success} and {@link #failure} functions in. - */ - /** - * @cfg {Function} renderer A custom function to render the content to the element. The passed parameters - * are - *
    - *
  • The loader
  • - *
  • The response
  • - *
  • The active request
  • - *
- */ - isLoader: true, + + saveDelay: 100, + + autoGenIdRe: /^((\w+-)|(ext-comp-))\d{4,}$/i, constructor: function(config) { - var me = this, - autoLoad; - + var me = this; + config = config || {}; - Ext.apply(me, config); - me.setTarget(me.target); - me.addEvents( - /** - * @event beforeload - * Fires before a load request is made to the server. - * Returning false from an event listener can prevent the load - * from occurring. - * @param {Ext.ElementLoader} this - * @param {Object} options The options passed to the request - */ - 'beforeload', + if (Ext.isDefined(config.stateful)) { + me.stateful = config.stateful; + } + if (Ext.isDefined(config.saveDelay)) { + me.saveDelay = config.saveDelay; + } + me.stateId = me.stateId || config.stateId; - /** - * @event exception - * Fires after an unsuccessful load. - * @param {Ext.ElementLoader} this - * @param {Object} response The response from the server - * @param {Object} options The options passed to the request - */ - 'exception', + if (!me.stateEvents) { + me.stateEvents = []; + } + if (config.stateEvents) { + me.stateEvents.concat(config.stateEvents); + } + this.addEvents( + + 'beforestaterestore', - /** - * @event exception - * Fires after a successful load. - * @param {Ext.ElementLoader} this - * @param {Object} response The response from the server - * @param {Object} options The options passed to the request - */ - 'load' - ); + + 'staterestore', - // don't pass config because we have already applied it. - me.mixins.observable.constructor.call(me); + + 'beforestatesave', - if (me.autoLoad) { - autoLoad = me.autoLoad; - if (autoLoad === true) { - autoLoad = {}; - } - me.load(autoLoad); + + 'statesave' + ); + me.mixins.observable.constructor.call(me); + if (me.stateful !== false) { + me.initStateEvents(); + me.initState(); } }, - /** - * Set an {Ext.Element} as the target of this loader. Note that if the target is changed, - * any active requests will be aborted. - * @param {Mixed} target The element - */ - setTarget: function(target){ - var me = this; - target = Ext.get(target); - if (me.target && me.target != target) { - me.abort(); - } - me.target = target; + + initStateEvents: function() { + this.addStateEvents(this.stateEvents); }, - /** - * Get the target of this loader. - * @return {Ext.Component} target The target, null if none exists. - */ - getTarget: function(){ - return this.target || null; + + addStateEvents: function(events){ + if (!Ext.isArray(events)) { + events = [events]; + } + + var me = this, + i = 0, + len = events.length; + + for (; i < len; ++i) { + me.on(events[i], me.onStateChange, me); + } }, - /** - * Aborts the active load request - */ - abort: function(){ - var active = this.active; - if (active !== undefined) { - Ext.Ajax.abort(active.request); - if (active.mask) { - this.removeMask(); + + onStateChange: function(){ + var me = this, + delay = me.saveDelay; + + if (delay > 0) { + if (!me.stateTask) { + me.stateTask = Ext.create('Ext.util.DelayedTask', me.saveState, me); } - delete this.active; + me.stateTask.delay(me.saveDelay); + } else { + me.saveState(); } }, + - /** - * Remove the mask on the target - * @private - */ - removeMask: function(){ - this.target.unmask(); + saveState: function() { + var me = this, + id, + state; + + if (me.stateful !== false) { + id = me.getStateId(); + if (id) { + state = me.getState(); + if (me.fireEvent('beforestatesave', me, state) !== false) { + Ext.state.Manager.set(id, state); + me.fireEvent('statesave', me, state); + } + } + } }, + - /** - * Add the mask on the target - * @private - * @param {Mixed} mask The mask configuration - */ - addMask: function(mask){ - this.target.mask(mask === true ? null : mask); + getState: function(){ + return null; }, - /** - * Load new data from the server. - * @param {Object} options The options for the request. They can be any configuration option that can be specified for - * the class, with the exception of the target option. Note that any options passed to the method will override any - * class defaults. - */ - load: function(options) { - if (!this.target) { - Ext.Error.raise('A valid target is required when loading content'); + + applyState: function(state) { + if (state) { + Ext.apply(this, state); } + }, - options = Ext.apply({}, options); - + + getStateId: function() { var me = this, - target = me.target, - mask = Ext.isDefined(options.loadMask) ? options.loadMask : me.loadMask, - params = Ext.apply({}, options.params), - ajaxOptions = Ext.apply({}, options.ajaxOptions), - callback = options.callback || me.callback, - scope = options.scope || me.scope || me, - request; + id = me.stateId; - Ext.applyIf(ajaxOptions, me.ajaxOptions); - Ext.applyIf(options, ajaxOptions); + if (!id) { + id = me.autoGenIdRe.test(String(me.id)) ? null : me.id; + } + return id; + }, - Ext.applyIf(params, me.params); - Ext.apply(params, me.baseParams); + + initState: function(){ + var me = this, + id = me.getStateId(), + state; - Ext.applyIf(options, { - url: me.url - }); + if (me.stateful !== false) { + if (id) { + state = Ext.state.Manager.get(id); + if (state) { + state = Ext.apply({}, state); + if (me.fireEvent('beforestaterestore', me, state) !== false) { + me.applyState(state); + me.fireEvent('staterestore', me, state); + } + } + } + } + }, + + + savePropToState: function (propName, state, stateName) { + var me = this, + value = me[propName], + config = me.initialConfig; - if (!options.url) { - Ext.Error.raise('You must specify the URL from which content should be loaded'); + if (me.hasOwnProperty(propName)) { + if (!config || config[propName] !== value) { + if (state) { + state[stateName || propName] = value; + } + return true; + } } + return false; + }, - Ext.apply(options, { - scope: me, - params: params, - callback: me.onComplete + savePropsToState: function (propNames, state) { + var me = this; + Ext.each(propNames, function (propName) { + me.savePropToState(propName, state); }); + return state; + }, - if (me.fireEvent('beforeload', me, options) === false) { - return; + + destroy: function(){ + var task = this.stateTask; + if (task) { + task.cancel(); } + this.clearListeners(); - if (mask) { - me.addMask(mask); - } + } + +}); + + +Ext.define('Ext.AbstractManager', { - request = Ext.Ajax.request(options); - me.active = { - request: request, - options: options, - mask: mask, - scope: scope, - callback: callback, - success: options.success || me.success, - failure: options.failure || me.failure, - renderer: options.renderer || me.renderer, - scripts: Ext.isDefined(options.scripts) ? options.scripts : me.scripts - }; - me.setOptions(me.active, options); - }, - /** - * Set any additional options on the active request - * @private - * @param {Object} active The active request - * @param {Object} options The initial options - */ - setOptions: Ext.emptyFn, - /** - * Parse the response after the request completes - * @private - * @param {Object} options Ajax options - * @param {Boolean} success Success status of the request - * @param {Object} response The response object - */ - onComplete: function(options, success, response) { - var me = this, - active = me.active, - scope = active.scope, - renderer = me.getRenderer(active.renderer); + requires: ['Ext.util.HashMap'], + - if (success) { - success = renderer.call(me, me, response, active); - } + typeName: 'type', - if (success) { - Ext.callback(active.success, scope, [me, response, options]); - me.fireEvent('load', me, response, options); - } else { - Ext.callback(active.failure, scope, [me, response, options]); - me.fireEvent('exception', me, response, options); - } - Ext.callback(active.callback, scope, [me, success, response, options]); + constructor: function(config) { + Ext.apply(this, config || {}); - if (active.mask) { - me.removeMask(); - } + + this.all = Ext.create('Ext.util.HashMap'); - delete me.active; + this.types = {}; }, - /** - * Gets the renderer to use - * @private - * @param {String/Function} renderer The renderer to use - * @return {Function} A rendering function to use. - */ - getRenderer: function(renderer){ - if (Ext.isFunction(renderer)) { - return renderer; - } - return this.statics().Renderer.Html; - }, - /** - * Automatically refreshes the content over a specified period. - * @param {Number} interval The interval to refresh in ms. - * @param {Object} options (optional) The options to pass to the load method. See {@link #load} - */ - startAutoRefresh: function(interval, options){ - var me = this; - me.stopAutoRefresh(); - me.autoRefresh = setInterval(function(){ - me.load(options); - }, interval); + get : function(id) { + return this.all.get(id); }, + - /** - * Clears any auto refresh. See {@link #startAutoRefresh}. - */ - stopAutoRefresh: function(){ - clearInterval(this.autoRefresh); - delete this.autoRefresh; + register: function(item) { + this.all.add(item); }, + - /** - * Checks whether the loader is automatically refreshing. See {@link #startAutoRefresh}. - * @return {Boolean} True if the loader is automatically refreshing - */ - isAutoRefreshing: function(){ - return Ext.isDefined(this.autoRefresh); + unregister: function(item) { + this.all.remove(item); }, - /** - * Destroys the loader. Any active requests will be aborted. - */ - destroy: function(){ - var me = this; - me.stopAutoRefresh(); - delete me.target; - me.abort(); - me.clearListeners(); - } -}); - -/** - * @class Ext.layout.Layout - * @extends Object - * @private - * Base Layout class - extended by ComponentLayout and ContainerLayout - */ + + registerType : function(type, cls) { + this.types[type] = cls; + cls[this.typeName] = type; + }, -Ext.define('Ext.layout.Layout', { + + isRegistered : function(type){ + return this.types[type] !== undefined; + }, - /* Begin Definitions */ + + create: function(config, defaultType) { + var type = config[this.typeName] || config.type || defaultType, + Constructor = this.types[type]; - /* End Definitions */ - isLayout: true, - initialized: false, + return new Constructor(config); + }, - statics: { - create: function(layout, defaultType) { - var type; - if (layout instanceof Ext.layout.Layout) { - return Ext.createByAlias('layout.' + layout); - } else { - if (Ext.isObject(layout)) { - type = layout.type; - } - else { - type = layout || defaultType; - layout = {}; + + onAvailable : function(id, fn, scope){ + var all = this.all, + item; + + if (all.containsKey(id)) { + item = all.get(id); + fn.call(scope || item, item); + } else { + all.on('add', function(map, key, item){ + if (key == id) { + fn.call(scope || item, item); + all.un('add', fn, scope); } - return Ext.createByAlias('layout.' + type, layout || {}); - } + }); } }, - - constructor : function(config) { - this.id = Ext.id(null, this.type + '-'); - Ext.apply(this, config); + + + each: function(fn, scope){ + this.all.each(fn, scope || this); }, + + + getCount: function(){ + return this.all.getCount(); + } +}); - /** - * @private - */ - layout : function() { - var me = this; - me.layoutBusy = true; - me.initLayout(); - if (me.beforeLayout.apply(me, arguments) !== false) { - me.layoutCancelled = false; - me.onLayout.apply(me, arguments); - me.childrenChanged = false; - me.owner.needsLayout = false; - me.layoutBusy = false; - me.afterLayout.apply(me, arguments); +Ext.define('Ext.ComponentManager', { + extend: 'Ext.AbstractManager', + alternateClassName: 'Ext.ComponentMgr', + + singleton: true, + + typeName: 'xtype', + + + create: function(component, defaultType){ + if (component instanceof Ext.AbstractComponent) { + return component; + } + else if (Ext.isString(component)) { + return Ext.createByAlias('widget.' + component); } else { - me.layoutCancelled = true; + var type = component.xtype || defaultType, + config = component; + + return Ext.createByAlias('widget.' + type, config); } - me.layoutBusy = false; - me.doOwnerCtLayouts(); }, - beforeLayout : function() { - this.renderItems(this.getLayoutItems(), this.getRenderTarget()); - return true; - }, + registerType: function(type, cls) { + this.types[type] = cls; + cls[this.typeName] = type; + cls.prototype[this.typeName] = type; + } +}); - /** - * @private - * Iterates over all passed items, ensuring they are rendered. If the items are already rendered, - * also determines if the items are in the proper place dom. - */ - renderItems : function(items, target) { - var ln = items.length, - i = 0, - item; +Ext.define('Ext.AbstractComponent', { - for (; i < ln; i++) { - item = items[i]; - if (item && !item.rendered) { - this.renderItem(item, target, i); - } - else if (!this.isValidParent(item, target, i)) { - this.moveItem(item, target, i); - } - } - }, + + requires: [ + 'Ext.ComponentQuery', + 'Ext.ComponentManager' + ], - // @private - Validates item is in the proper place in the dom. - isValidParent : function(item, target, position) { - var dom = item.el ? item.el.dom : Ext.getDom(item); - if (dom && target && target.dom) { - if (Ext.isNumber(position) && dom !== target.dom.childNodes[position]) { - return false; - } - return (dom.parentNode == (target.dom || target)); - } - return false; + mixins: { + observable: 'Ext.util.Observable', + animate: 'Ext.util.Animate', + state: 'Ext.state.Stateful' }, - /** - * @private - * Renders the given Component into the target Element. - * @param {Ext.Component} item The Component to render - * @param {Ext.core.Element} target The target Element - * @param {Number} position The position within the target to render the item to - */ - renderItem : function(item, target, position) { - if (!item.rendered) { - item.render(target, position); - this.configureItem(item); - this.childrenChanged = true; - } - }, + + + uses: [ + 'Ext.PluginManager', + 'Ext.ComponentManager', + 'Ext.Element', + 'Ext.DomHelper', + 'Ext.XTemplate', + 'Ext.ComponentQuery', + 'Ext.ComponentLoader', + 'Ext.EventManager', + 'Ext.layout.Layout', + 'Ext.layout.component.Auto', + 'Ext.LoadMask', + 'Ext.ZIndexManager' + ], - /** - * @private - * Moved Component to the provided target instead. - */ - moveItem : function(item, target, position) { - // Make sure target is a dom element - target = target.dom || target; - if (typeof position == 'number') { - position = target.childNodes[position]; - } - target.insertBefore(item.el.dom, position || null); - item.container = Ext.get(target); - this.configureItem(item); - this.childrenChanged = true; + statics: { + AUTO_ID: 1000 }, - /** - * @private - * Adds the layout's targetCls if necessary and sets - * initialized flag when complete. - */ - initLayout : function() { - if (!this.initialized && !Ext.isEmpty(this.targetCls)) { - this.getTarget().addCls(this.targetCls); - } - this.initialized = true; - }, + - // @private Sets the layout owner - setOwner : function(owner) { - this.owner = owner; - }, + isComponent: true, - // @private - Returns empty array - getLayoutItems : function() { - return []; + getAutoId: function() { + return ++Ext.AbstractComponent.AUTO_ID; }, - /** - * @private - * Applies itemCls - */ - configureItem: function(item) { - var me = this, - el = item.el, - owner = me.owner; - - if (me.itemCls) { - el.addCls(me.itemCls); - } - if (owner.itemCls) { - el.addCls(owner.itemCls); - } - }, + - // Placeholder empty functions for subclasses to extend - onLayout : Ext.emptyFn, - afterLayout : Ext.emptyFn, - onRemove : Ext.emptyFn, - onDestroy : Ext.emptyFn, - doOwnerCtLayouts : Ext.emptyFn, - /** - * @private - * Removes itemCls - */ - afterRemove : function(item) { - var me = this, - el = item.el, - owner = me.owner; - - if (item.rendered) { - if (me.itemCls) { - el.removeCls(me.itemCls); - } - if (owner.itemCls) { - el.removeCls(owner.itemCls); - } - } - }, + - /* - * Destroys this layout. This is a template method that is empty by default, but should be implemented - * by subclasses that require explicit destruction to purge event handlers or remove DOM nodes. - * @protected - */ - destroy : function() { - if (!Ext.isEmpty(this.targetCls)) { - var target = this.getTarget(); - if (target) { - target.removeCls(this.targetCls); - } - } - this.onDestroy(); - } -}); -/** - * @class Ext.layout.component.Component - * @extends Ext.layout.Layout - * @private - *

This class is intended to be extended or created via the {@link Ext.Component#componentLayout layout} - * configuration property. See {@link Ext.Component#componentLayout} for additional details.

- */ + -Ext.define('Ext.layout.component.Component', { + - /* Begin Definitions */ + - extend: 'Ext.layout.Layout', + - /* End Definitions */ + + renderTpl: null, - type: 'component', + - monitorChildren: true, + - initLayout : function() { - var me = this, - owner = me.owner, - ownerEl = owner.el; + - if (!me.initialized) { - if (owner.frameSize) { - me.frameSize = owner.frameSize; - } - else { - owner.frameSize = me.frameSize = { - top: 0, - left: 0, - bottom: 0, - right: 0 - }; - } - } - me.callParent(arguments); - }, + - beforeLayout : function(width, height, isSetSize, layoutOwner) { - this.callParent(arguments); + - var me = this, - owner = me.owner, - ownerCt = owner.ownerCt, - layout = owner.layout, - isVisible = owner.isVisible(true), - ownerElChild = owner.el.child, - layoutCollection; + - /* - * Do not layout calculatedSized components for fixedLayouts unless the ownerCt == layoutOwner - * fixedLayouts means layouts which are never auto/auto in the sizing that comes from their ownerCt. - * Currently 3 layouts MAY be auto/auto (Auto, Border, and Box) - * The reason for not allowing component layouts is to stop component layouts from things such as Updater and - * form Validation. - */ - if (!isSetSize && !(Ext.isNumber(width) && Ext.isNumber(height)) && ownerCt && ownerCt.layout && ownerCt.layout.fixedLayout && ownerCt != layoutOwner) { - me.doContainerLayout(); - return false; - } + - // If an ownerCt is hidden, add my reference onto the layoutOnShow stack. Set the needsLayout flag. - // If the owner itself is a directly hidden floater, set the needsLayout object on that for when it is shown. - if (!isVisible && (owner.hiddenAncestor || owner.floating)) { - if (owner.hiddenAncestor) { - layoutCollection = owner.hiddenAncestor.layoutOnShow; - layoutCollection.remove(owner); - layoutCollection.add(owner); - } - owner.needsLayout = { - width: width, - height: height, - isSetSize: false - }; - } + - if (isVisible && this.needsLayout(width, height)) { - me.rawWidth = width; - me.rawHeight = height; - return owner.beforeComponentLayout(width, height, isSetSize, layoutOwner); - } - else { - return false; - } - }, + - /** - * Check if the new size is different from the current size and only - * trigger a layout if it is necessary. - * @param {Mixed} width The new width to set. - * @param {Mixed} height The new height to set. - */ - needsLayout : function(width, height) { - this.lastComponentSize = this.lastComponentSize || { - width: -Infinity, - height: -Infinity - }; - return (this.childrenChanged || this.lastComponentSize.width !== width || this.lastComponentSize.height !== height); - }, + - /** - * Set the size of any element supporting undefined, null, and values. - * @param {Mixed} width The new width to set. - * @param {Mixed} height The new height to set. - */ - setElementSize: function(el, width, height) { - if (width !== undefined && height !== undefined) { - el.setSize(width, height); - } - else if (height !== undefined) { - el.setHeight(height); - } - else if (width !== undefined) { - el.setWidth(width); - } - }, + + tplWriteMode: 'overwrite', - /** - * Returns the owner component's resize element. - * @return {Ext.core.Element} - */ - getTarget : function() { - return this.owner.el; - }, + + baseCls: Ext.baseCSSPrefix + 'component', - /** - *

Returns the element into which rendering must take place. Defaults to the owner Component's encapsulating element.

- * May be overridden in Component layout managers which implement an inner element. - * @return {Ext.core.Element} - */ - getRenderTarget : function() { - return this.owner.el; - }, + - /** - * Set the size of the target element. - * @param {Mixed} width The new width to set. - * @param {Mixed} height The new height to set. - */ - setTargetSize : function(width, height) { - var me = this; - me.setElementSize(me.owner.el, width, height); + - if (me.owner.frameBody) { - var targetInfo = me.getTargetInfo(), - padding = targetInfo.padding, - border = targetInfo.border, - frameSize = me.frameSize; + - me.setElementSize(me.owner.frameBody, - Ext.isNumber(width) ? (width - frameSize.left - frameSize.right - padding.left - padding.right - border.left - border.right) : width, - Ext.isNumber(height) ? (height - frameSize.top - frameSize.bottom - padding.top - padding.bottom - border.top - border.bottom) : height - ); - } + + disabledCls: Ext.baseCSSPrefix + 'item-disabled', - me.autoSized = { - width: !Ext.isNumber(width), - height: !Ext.isNumber(height) - }; + + ui: 'default', - me.lastComponentSize = { - width: width, - height: height - }; - }, + + uiCls: [], - getTargetInfo : function() { - if (!this.targetInfo) { - var target = this.getTarget(), - body = this.owner.getTargetEl(); + - this.targetInfo = { - padding: { - top: target.getPadding('t'), - right: target.getPadding('r'), - bottom: target.getPadding('b'), - left: target.getPadding('l') - }, - border: { - top: target.getBorderWidth('t'), - right: target.getBorderWidth('r'), - bottom: target.getBorderWidth('b'), - left: target.getBorderWidth('l') - }, - bodyMargin: { - top: body.getMargin('t'), - right: body.getMargin('r'), - bottom: body.getMargin('b'), - left: body.getMargin('l') - } - }; - } - return this.targetInfo; - }, + - // Start laying out UP the ownerCt's layout when flagged to do so. - doOwnerCtLayouts: function() { - var owner = this.owner, - ownerCt = owner.ownerCt, - ownerCtComponentLayout, ownerCtContainerLayout; + - if (!ownerCt) { - return; - } + - ownerCtComponentLayout = ownerCt.componentLayout; - ownerCtContainerLayout = ownerCt.layout; + - if (!owner.floating && ownerCtComponentLayout && ownerCtComponentLayout.monitorChildren && !ownerCtComponentLayout.layoutBusy) { - if (!ownerCt.suspendLayout && ownerCtContainerLayout && !ownerCtContainerLayout.layoutBusy) { - // AutoContainer Layout and Dock with auto in some dimension - if (ownerCtContainerLayout.bindToOwnerCtComponent === true) { - ownerCt.doComponentLayout(); - } - // Box Layouts - else if (ownerCtContainerLayout.bindToOwnerCtContainer === true) { - ownerCtContainerLayout.layout(); - } - } - } - }, + - doContainerLayout: function() { - var me = this, - owner = me.owner, - ownerCt = owner.ownerCt, - layout = owner.layout, - ownerCtComponentLayout; + + hidden: false, - // Run the container layout if it exists (layout for child items) - // **Unless automatic laying out is suspended, or the layout is currently running** - if (!owner.suspendLayout && layout && layout.isLayout && !layout.layoutBusy) { - layout.layout(); - } + + disabled: false, - // Tell the ownerCt that it's child has changed and can be re-layed by ignoring the lastComponentSize cache. - if (ownerCt && ownerCt.componentLayout) { - ownerCtComponentLayout = ownerCt.componentLayout; - if (!owner.floating && ownerCtComponentLayout.monitorChildren && !ownerCtComponentLayout.layoutBusy) { - ownerCtComponentLayout.childrenChanged = true; - } - } - }, + - afterLayout : function(width, height, isSetSize, layoutOwner) { - this.doContainerLayout(); - this.owner.afterComponentLayout(width, height, isSetSize, layoutOwner); - } -}); + + draggable: false, -/** - * @class Ext.state.Manager - * This is the global state manager. By default all components that are "state aware" check this class - * for state information if you don't pass them a custom state provider. In order for this class - * to be useful, it must be initialized with a provider when your application initializes. Example usage: -

-// in your initialization function
-init : function(){
-   Ext.state.Manager.setProvider(new Ext.state.CookieProvider());
-   var win = new Window(...);
-   win.restoreState();
-}
- 
- * This class passes on calls from components to the underlying {@link Ext.state.Provider} so that - * there is a common interface that can be used without needing to refer to a specific provider instance - * in every component. - * @singleton - * @docauthor Evan Trimboli - */ -Ext.define('Ext.state.Manager', { - singleton: true, - requires: ['Ext.state.Provider'], - constructor: function() { - this.provider = Ext.create('Ext.state.Provider'); - }, + floating: false, + - /** - * Configures the default state provider for your application - * @param {Provider} stateProvider The state provider to set - */ - setProvider : function(stateProvider){ - this.provider = stateProvider; - }, + hideMode: 'display', - /** - * Returns the current value for a key - * @param {String} name The key name - * @param {Mixed} defaultValue The default value to return if the key lookup does not match - * @return {Mixed} The state data - */ - get : function(key, defaultValue){ - return this.provider.get(key, defaultValue); - }, + - /** - * Sets the value for a key - * @param {String} name The key name - * @param {Mixed} value The state data - */ - set : function(key, value){ - this.provider.set(key, value); - }, + - /** - * Clears a value from the state - * @param {String} name The key name - */ - clear : function(key){ - this.provider.clear(key); - }, + + styleHtmlContent: false, - /** - * Gets the currently configured state provider - * @return {Provider} The state provider - */ - getProvider : function(){ - return this.provider; - } -}); -/** - * @class Ext.state.Stateful - * A mixin for being able to save the state of an object to an underlying - * {@link Ext.state.Provider}. - */ -Ext.define('Ext.state.Stateful', { - /* Begin Definitions */ - - mixins: { - observable: 'Ext.util.Observable' - }, + styleHtmlCls: Ext.baseCSSPrefix + 'html', + - requires: ['Ext.state.Manager'], - /* End Definitions */ - /** - * @cfg {Boolean} stateful - *

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 - * 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 - * {@link Ext.state.Provider#set set} and {@link Ext.state.Provider#get get} - * methods to save and recall name/value pairs. A built-in implementation, - * {@link Ext.state.CookieProvider} is available.

- *

To set the state provider for the current page:

- *

-Ext.state.Manager.setProvider(new Ext.state.CookieProvider({
-    expires: new Date(new Date().getTime()+(1000*60*60*24*7)), //7 days from now
-}));
-     * 
- *

A stateful object attempts to save state when one of the events - * listed in the {@link #stateEvents} configuration fires.

- *

To save state, a stateful object first serializes its state by - * calling {@link #getState}. By default, this function does - * nothing. The developer must provide an implementation which returns an - * 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}

. - *

During construction, a stateful object attempts to restore - * its state by calling {@link Ext.state.Manager#get} passing the - * {@link #stateId}

- *

The resulting object is passed to {@link #applyState}. - * The default implementation of {@link #applyState} simply copies - * properties into the object, but a developer may override this to support - * more behaviour.

- *

You can perform extra processing on state save and restore by attaching - * handlers to the {@link #beforestaterestore}, {@link #staterestore}, - * {@link #beforestatesave} and {@link #statesave} events.

- */ - stateful: true, - /** - * @cfg {String} stateId - * The unique id for this object to use for state management purposes. - *

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 - * save its state (defaults to none). stateEvents may be any type - * of event supported by this object, including browser or custom events - * (e.g., ['click', 'customerchange']).

- *

See {@link #stateful} for an explanation of saving and - * restoring object state.

- */ + - /** - * @cfg {Number} saveBuffer A buffer to be applied if many state events are fired within - * a short period. Defaults to 100. - */ - saveDelay: 100, + autoShow: false, + - autoGenIdRe: /^((\w+-)|(ext-comp-))\d{4,}$/i, + autoRender: false, + + needsLayout: false, + - constructor: function(config) { - var me = this; - + allowDomMove: true, + + + + + rendered: false, + + + componentLayoutCounter: 0, + + weight: 0, + + trimRe: /^\s+|\s+$/g, + spacesRe: /\s+/, + + + + maskOnDisable: true, + + + constructor : function(config) { + var me = this, + i, len; + config = config || {}; - if (Ext.isDefined(config.stateful)) { - me.stateful = config.stateful; - } - if (Ext.isDefined(config.saveDelay)) { - me.saveDelay = config.saveDelay; + me.initialConfig = config; + Ext.apply(me, config); + + me.addEvents( + + 'beforeactivate', + + 'activate', + + 'beforedeactivate', + + 'deactivate', + + 'added', + + 'disable', + + 'enable', + + 'beforeshow', + + 'show', + + 'beforehide', + + 'hide', + + 'removed', + + 'beforerender', + + 'render', + + 'afterrender', + + 'beforedestroy', + + 'destroy', + + 'resize', + + 'move' + ); + + me.getId(); + + me.mons = []; + me.additionalCls = []; + me.renderData = me.renderData || {}; + me.renderSelectors = me.renderSelectors || {}; + + if (me.plugins) { + me.plugins = [].concat(me.plugins); + me.constructPlugins(); } - me.stateId = config.stateId; + + me.initComponent(); + - if (!me.stateEvents) { - me.stateEvents = []; - } - if (config.stateEvents) { - me.stateEvents.concat(config.stateEvents); + Ext.ComponentManager.register(me); + + + me.mixins.observable.constructor.call(me); + me.mixins.state.constructor.call(me, config); + + + this.addStateEvents('resize'); + + + if (me.plugins) { + me.plugins = [].concat(me.plugins); + for (i = 0, len = me.plugins.length; i < len; i++) { + me.plugins[i] = me.initPlugin(me.plugins[i]); + } } - this.addEvents( - /** - * @event beforestaterestore - * Fires before the state of the object is restored. Return false from an event handler to stop the restore. - * @param {Ext.state.Stateful} this - * @param {Object} state The hash of state values returned from the StateProvider. If this - * event is not vetoed, then the state object is passed to applyState. By default, - * that simply copies property values into this object. The method maybe overriden to - * provide custom state restoration. - */ - 'beforestaterestore', + + me.loader = me.getLoader(); + + if (me.renderTo) { + me.render(me.renderTo); - /** - * @event staterestore - * Fires after the state of the object is restored. - * @param {Ext.state.Stateful} this - * @param {Object} state The hash of state values returned from the StateProvider. This is passed - * to applyState. By default, that simply copies property values into this - * object. The method maybe overriden to provide custom state restoration. - */ - 'staterestore', - /** - * @event beforestatesave - * Fires before the state of the object is saved to the configured state provider. Return false to stop the save. - * @param {Ext.state.Stateful} this - * @param {Object} state The hash of state values. This is determined by calling - * getState() on the object. This method must be provided by the - * developer to return whetever representation of state is required, by default, Ext.state.Stateful - * has a null implementation. - */ - 'beforestatesave', - /** - * @event statesave - * Fires after the state of the object is saved to the configured state provider. - * @param {Ext.state.Stateful} this - * @param {Object} state The hash of state values. This is determined by calling - * getState() on the object. This method must be provided by the - * developer to return whetever representation of state is required, by default, Ext.state.Stateful - * has a null implementation. - */ - 'statesave' - ); - me.mixins.observable.constructor.call(me); - if (me.stateful !== false) { - me.initStateEvents(); - me.initState(); } + + if (me.autoShow) { + me.show(); + } + }, - - /** - * Initializes any state events for this object. - * @private - */ - initStateEvents: function() { - this.addStateEvents(this.stateEvents); + + initComponent: function () { + + + this.constructPlugins(); }, + - /** - * Add events that will trigger the state to be saved. - * @param {String/Array} events The event name or an array of event names. - */ - addStateEvents: function(events){ - if (!Ext.isArray(events)) { - events = [events]; + 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 (me.collapsed && cm) { + if (Ext.isDefined(cm.data.width)) { + width = cm.width; + } + if (Ext.isDefined(cm.data.height)) { + height = cm.height; + } } + - var me = this, - i = 0, - len = events.length; - - for (; i < len; ++i) { - me.on(events[i], me.onStateChange, me); + if (layout && me.flex) { + state.flex = me.flex; + if (layout.perpendicularPrefix) { + state[layout.perpendicularPrefix] = me['get' + layout.perpendicularPrefixCap](); + } else { + } } - }, - - /** - * This method is called when any of the {@link #stateEvents} are fired. - * @private - */ - onStateChange: function(){ - var me = this, - delay = me.saveDelay; - if (delay > 0) { - if (!me.stateTask) { - me.stateTask = Ext.create('Ext.util.DelayedTask', me.saveState, me); + else if (layout && me.anchor) { + state.anchor = me.anchor; + anchors = me.anchor.split(' ').concat(null); + if (!anchors[0]) { + if (me.width) { + state.width = width; + } } - me.stateTask.delay(me.saveDelay); - } else { - me.saveState(); + if (!anchors[1]) { + if (me.height) { + state.height = height; + } + } + } + + else { + if (me.width) { + state.width = width; + } + if (me.height) { + state.height = height; + } + } + + + if (state.width == me.initialConfig.width) { + delete state.width; } + if (state.height == me.initialConfig.height) { + delete state.height; + } + + + if (layout && layout.align && (layout.align.indexOf('stretch') !== -1)) { + delete state[layout.perpendicularPrefix]; + } + return state; }, - - /** - * Saves the state of the object to the persistence store. - * @private - */ - saveState: function() { + + show: Ext.emptyFn, + + animate: function(animObj) { var me = this, - id, - state; + to; + + animObj = animObj || {}; + to = animObj.to || {}; + + if (Ext.fx.Manager.hasFxBlock(me.id)) { + return me; + } - if (me.stateful !== false) { - id = me.getStateId(); - if (id) { - state = me.getState(); - if (me.fireEvent('beforestatesave', me, state) !== false) { - Ext.state.Manager.set(id, state); - me.fireEvent('statesave', me, state); + if (!animObj.dynamic && (to.height || to.width)) { + var curWidth = me.getWidth(), + w = curWidth, + curHeight = me.getHeight(), + h = curHeight, + needsResize = false; + + if (to.height && to.height > curHeight) { + h = to.height; + needsResize = true; + } + if (to.width && to.width > curWidth) { + w = to.width; + needsResize = true; + } + + + + + if (needsResize) { + var clearWidth = !Ext.isNumber(me.width), + clearHeight = !Ext.isNumber(me.height); + + me.componentLayout.childrenChanged = true; + me.setSize(w, h, me.ownerCt); + me.el.setSize(curWidth, curHeight); + if (clearWidth) { + delete me.width; + } + if (clearHeight) { + delete me.height; } } } + return me.mixins.animate.animate.apply(me, arguments); }, + - /** - * Gets the current state of the object. By default this function returns null, - * it should be overridden in subclasses to implement methods for getting the state. - * @return {Object} The current state - */ - getState: function(){ - return null; + findLayoutController: function() { + return this.findParentBy(function(c) { + + + return !c.ownerCt || (c.layout.layoutBusy && !c.ownerCt.layout.layoutBusy); + }); }, - - /** - * Applies the state to the object. This should be overridden in subclasses to do - * more complex state operations. By default it applies the state properties onto - * the current object. - * @param {Object} state The state - */ - applyState: function(state) { - if (state) { - Ext.apply(this, state); + + onShow : function() { + + var needsLayout = this.needsLayout; + if (Ext.isObject(needsLayout)) { + this.doComponentLayout(needsLayout.width, needsLayout.height, needsLayout.isSetSize, needsLayout.ownerCt); } }, - - /** - * Gets the state id for this object. - * @return {String} The state id, null if not found. - */ - getStateId: function() { - var me = this, - id = me.stateId; - - if (!id) { - id = me.autoGenIdRe.test(String(me.id)) ? null : me.id; + + constructPlugin: function(plugin) { + if (plugin.ptype && typeof plugin.init != 'function') { + plugin.cmp = this; + plugin = Ext.PluginManager.create(plugin); } - return id; + else if (typeof plugin == 'string') { + plugin = Ext.PluginManager.create({ + ptype: plugin, + cmp: this + }); + } + return plugin; }, + - /** - * Initializes the state of the object upon construction. - * @private - */ - initState: function(){ + constructPlugins: function() { var me = this, - id = me.getStateId(), - state; - - if (me.stateful !== false) { - if (id) { - state = Ext.state.Manager.get(id); - if (state) { - state = Ext.apply({}, state); - if (me.fireEvent('beforestaterestore', me, state) !== false) { - me.applyState(state); - me.fireEvent('staterestore', me, state); - } - } + plugins = me.plugins, + i, len; + + if (plugins) { + for (i = 0, len = plugins.length; i < len; i++) { + + plugins[i] = me.constructPlugin(plugins[i]); } } }, + - /** - * Destroys this stateful object. - */ - destroy: function(){ - var task = this.stateTask; - if (task) { - task.cancel(); + initPlugin : function(plugin) { + plugin.init(this); + + return plugin; + }, + + + doAutoRender: function() { + var me = this; + if (me.floating) { + me.render(document.body); + } else { + me.render(Ext.isBoolean(me.autoRender) ? Ext.getBody() : me.autoRender); } - this.clearListeners(); - - } + }, + -}); + render : function(container, position) { + var me = this; -/** - * @class Ext.AbstractManager - * @extends Object - * @ignore - * Base Manager class - */ + if (!me.rendered && me.fireEvent('beforerender', me) !== false) { -Ext.define('Ext.AbstractManager', { + + + me.rendering = true; - /* Begin Definitions */ + + + if (me.el) { + me.el = Ext.get(me.el); + } - requires: ['Ext.util.HashMap'], + + if (me.floating) { + me.onFloatRender(); + } - /* End Definitions */ + container = me.initContainer(container); - typeName: 'type', + me.onRender(container, position); - constructor: function(config) { - Ext.apply(this, config || {}); + + + me.el.setVisibilityMode(Ext.Element[me.hideMode.toUpperCase()]); - /** - * Contains all of the items currently managed - * @property all - * @type Ext.util.MixedCollection - */ - this.all = Ext.create('Ext.util.HashMap'); + if (me.overCls) { + me.el.hover(me.addOverCls, me.removeOverCls, me); + } - this.types = {}; - }, + me.fireEvent('render', me); - /** - * Returns an item by id. - * For additional details see {@link Ext.util.HashMap#get}. - * @param {String} id The id of the item - * @return {Mixed} The item, undefined if not found. - */ - get : function(id) { - return this.all.get(id); - }, + me.initContent(); - /** - * Registers an item to be managed - * @param {Mixed} item The item to register - */ - register: function(item) { - this.all.add(item); - }, + me.afterRender(container); + me.fireEvent('afterrender', me); - /** - * Unregisters an item by removing it from this manager - * @param {Mixed} item The item to unregister - */ - unregister: function(item) { - this.all.remove(item); - }, + me.initEvents(); - /** - *

Registers a new item constructor, keyed by a type key. - * @param {String} type The mnemonic string by which the class may be looked up. - * @param {Constructor} cls The new instance class. - */ - registerType : function(type, cls) { - this.types[type] = cls; - cls[this.typeName] = type; - }, - - /** - * Checks if an item type is registered. - * @param {String} type The mnemonic string by which the class may be looked up - * @return {Boolean} Whether the type is registered. - */ - isRegistered : function(type){ - return this.types[type] !== undefined; - }, + if (me.hidden) { + + + + me.el.hide(); + } - /** - * Creates and returns an instance of whatever this manager manages, based on the supplied type and config object - * @param {Object} config The config object - * @param {String} defaultType If no type is discovered in the config object, we fall back to this type - * @return {Mixed} The instance of whatever this manager is managing - */ - create: function(config, defaultType) { - var type = config[this.typeName] || config.type || defaultType, - Constructor = this.types[type]; + if (me.disabled) { + + me.disable(true); + } - if (Constructor == undefined) { - Ext.Error.raise("The '" + type + "' type has not been registered with this manager"); + + delete me.rendering; } - - return new Constructor(config); + return me; }, - /** - * Registers a function that will be called when an item with the specified id is added to the manager. This will happen on instantiation. - * @param {String} id The item id - * @param {Function} fn The callback function. Called with a single parameter, the item. - * @param {Object} scope The scope (this reference) in which the callback is executed. Defaults to the item. - */ - onAvailable : function(id, fn, scope){ - var all = this.all, - item; - - if (all.containsKey(id)) { - item = all.get(id); - fn.call(scope || item, item); - } else { - all.on('add', function(map, key, item){ - if (key == id) { - fn.call(scope || item, item); - all.un('add', fn, scope); - } - }); - } - }, - - /** - * Executes the specified function once for each item in the collection. - * Returning false from the function will cease iteration. - * - * The paramaters passed to the function are: - *

    - *
  • key : String

    The key of the item

  • - *
  • value : Number

    The value of the item

  • - *
  • length : Number

    The total number of items in the collection

  • - *
- * @param {Object} fn The function to execute. - * @param {Object} scope The scope to execute in. Defaults to this. - */ - each: function(fn, scope){ - this.all.each(fn, scope || this); - }, - /** - * Gets the number of items in the collection. - * @return {Number} The number of items in the collection. - */ - getCount: function(){ - return this.all.getCount(); - } -}); - -/** - * @class Ext.PluginManager - * @extends Ext.AbstractManager - *

Provides a registry of available Plugin classes indexed by a mnemonic code known as the Plugin's ptype. - * The {@link Ext.Component#xtype xtype} provides a way to avoid instantiating child Components - * when creating a full, nested config object for a complete Ext page.

- *

A child Component may be specified simply as a config object - * as long as the correct {@link Ext.Component#xtype xtype} is specified so that if and when the Component - * needs rendering, the correct type can be looked up for lazy instantiation.

- *

For a list of all available {@link Ext.Component#xtype xtypes}, see {@link Ext.Component}.

- * @singleton - */ -Ext.define('Ext.PluginManager', { - extend: 'Ext.AbstractManager', - alternateClassName: 'Ext.PluginMgr', - singleton: true, - typeName: 'ptype', - - /** - * Creates a new Plugin from the specified config object using the - * config object's ptype to determine the class to instantiate. - * @param {Object} config A configuration object for the Plugin you wish to create. - * @param {Constructor} defaultType The constructor to provide the default Plugin type if - * the config object does not contain a ptype. (Optional if the config contains a ptype). - * @return {Ext.Component} The newly instantiated Plugin. - */ - //create: function(plugin, defaultType) { - // if (plugin instanceof this) { - // return plugin; - // } else { - // var type, config = {}; - // - // if (Ext.isString(plugin)) { - // type = plugin; - // } - // else { - // type = plugin[this.typeName] || defaultType; - // config = plugin; - // } - // - // return Ext.createByAlias('plugin.' + type, config); - // } - //}, - - create : function(config, defaultType){ - if (config.init) { - return config; - } else { - return Ext.createByAlias('plugin.' + (config.ptype || defaultType), config); - } - - // Prior system supported Singleton plugins. - //var PluginCls = this.types[config.ptype || defaultType]; - //if (PluginCls.init) { - // return PluginCls; - //} else { - // return new PluginCls(config); - //} - }, + onRender : function(container, position) { + var me = this, + el = me.el, + styles = me.initStyles(), + renderTpl, renderData, i; - /** - * Returns all plugins registered with the given type. Here, 'type' refers to the type of plugin, not its ptype. - * @param {String} type The type to search for - * @param {Boolean} defaultsOnly True to only return plugins of this type where the plugin's isDefault property is truthy - * @return {Array} All matching plugins - */ - findByType: function(type, defaultsOnly) { - var matches = [], - types = this.types; + position = me.getInsertPosition(position); - for (var name in types) { - if (!types.hasOwnProperty(name)) { - continue; + if (!el) { + if (position) { + el = Ext.DomHelper.insertBefore(position, me.getElConfig(), true); } - var item = types[name]; - - if (item.type == type && (!defaultsOnly || (defaultsOnly === true && item.isDefault))) { - matches.push(item); + else { + el = Ext.DomHelper.append(container, me.getElConfig(), true); } } - - return matches; - } -}, function() { - /** - * Shorthand for {@link Ext.PluginManager#registerType} - * @param {String} ptype The ptype mnemonic string by which the Plugin class - * may be looked up. - * @param {Constructor} cls The new Plugin class. - * @member Ext - * @method preg - */ - Ext.preg = function() { - return Ext.PluginManager.registerType.apply(Ext.PluginManager, arguments); - }; -}); - -/** - * @class Ext.ComponentManager - * @extends Ext.AbstractManager - *

Provides a registry of all Components (instances of {@link Ext.Component} or any subclass - * thereof) on a page so that they can be easily accessed by {@link Ext.Component component} - * {@link Ext.Component#id id} (see {@link #get}, or the convenience method {@link Ext#getCmp Ext.getCmp}).

- *

This object also provides a registry of available Component classes - * indexed by a mnemonic code known as the Component's {@link Ext.Component#xtype xtype}. - * The xtype provides a way to avoid instantiating child Components - * when creating a full, nested config object for a complete Ext page.

- *

A child Component may be specified simply as a config object - * as long as the correct {@link Ext.Component#xtype xtype} is specified so that if and when the Component - * needs rendering, the correct type can be looked up for lazy instantiation.

- *

For a list of all available {@link Ext.Component#xtype xtypes}, see {@link Ext.Component}.

- * @singleton - */ -Ext.define('Ext.ComponentManager', { - extend: 'Ext.AbstractManager', - alternateClassName: 'Ext.ComponentMgr', - - singleton: true, - - typeName: 'xtype', - - /** - * Creates a new Component from the specified config object using the - * config object's xtype to determine the class to instantiate. - * @param {Object} config A configuration object for the Component you wish to create. - * @param {Constructor} defaultType The constructor to provide the default Component type if - * the config object does not contain a xtype. (Optional if the config contains a xtype). - * @return {Ext.Component} The newly instantiated Component. - */ - create: function(component, defaultType){ - if (component instanceof Ext.AbstractComponent) { - return component; - } - else if (Ext.isString(component)) { - return Ext.createByAlias('widget.' + component); + else if (me.allowDomMove !== false) { + if (position) { + container.dom.insertBefore(el.dom, position); + } else { + container.dom.appendChild(el.dom); + } } - else { - var type = component.xtype || defaultType, - config = component; + + if (Ext.scopeResetCSS && !me.ownerCt) { - return Ext.createByAlias('widget.' + type, config); + if (el.dom == Ext.getBody().dom) { + el.parent().addCls(Ext.baseCSSPrefix + 'reset'); + } + else { + + me.resetEl = el.wrap({ + cls: Ext.baseCSSPrefix + 'reset' + }); + } } - }, - registerType: function(type, cls) { - this.types[type] = cls; - cls[this.typeName] = type; - cls.prototype[this.typeName] = type; - } -}); -/** - * @class Ext.XTemplate - * @extends Ext.Template - *

A template class that supports advanced functionality like:

    - *
  • Autofilling arrays using templates and sub-templates
  • - *
  • Conditional processing with basic comparison operators
  • - *
  • Basic math function support
  • - *
  • Execute arbitrary inline code with special built-in template variables
  • - *
  • Custom member functions
  • - *
  • Many special tags and built-in operators that aren't defined as part of - * the API, but are supported in the templates that can be created
  • - *

- *

XTemplate provides the templating mechanism built into:

    - *
  • {@link Ext.view.View}
  • - *

- * - * The {@link Ext.Template} describes - * the acceptable parameters to pass to the constructor. The following - * examples demonstrate all of the supported features.

- * - *
    - * - *
  • Sample Data - *
    - *

    This is the data object used for reference in each code example:

    - *
    
    -var data = {
    -name: 'Tommy Maintz',
    -title: 'Lead Developer',
    -company: 'Sencha Inc.',
    -email: 'tommy@sencha.com',
    -address: '5 Cups Drive',
    -city: 'Palo Alto',
    -state: 'CA',
    -zip: '44102',
    -drinks: ['Coffee', 'Soda', 'Water'],
    -kids: [{
    -        name: 'Joshua',
    -        age:3
    -    },{
    -        name: 'Matthew',
    -        age:2
    -    },{
    -        name: 'Solomon',
    -        age:0
    -}]
    -};
    - 
    - *
    - *
  • - * - * - *
  • Auto filling of arrays - *
    - *

    The tpl tag and the for operator are used - * to process the provided data object: - *

      - *
    • If the value specified in for is an array, it will auto-fill, - * repeating the template block inside the tpl tag for each item in the - * array.
    • - *
    • If for="." is specified, the data object provided is examined.
    • - *
    • While processing an array, the special variable {#} - * will provide the current array index + 1 (starts at 1, not 0).
    • - *
    - *

    - *
    
    -<tpl for=".">...</tpl>       // loop through array at root node
    -<tpl for="foo">...</tpl>     // loop through array at foo node
    -<tpl for="foo.bar">...</tpl> // loop through array at foo.bar node
    - 
    - * Using the sample data above: - *
    
    -var tpl = new Ext.XTemplate(
    -    '<p>Kids: ',
    -    '<tpl for=".">',       // process the data.kids node
    -        '<p>{#}. {name}</p>',  // use current array index to autonumber
    -    '</tpl></p>'
    -);
    -tpl.overwrite(panel.body, data.kids); // pass the kids property of the data object
    - 
    - *

    An example illustrating how the for property can be leveraged - * to access specified members of the provided data object to populate the template:

    - *
    
    -var tpl = new Ext.XTemplate(
    -    '<p>Name: {name}</p>',
    -    '<p>Title: {title}</p>',
    -    '<p>Company: {company}</p>',
    -    '<p>Kids: ',
    -    '<tpl for="kids">',     // interrogate the kids property within the data
    -        '<p>{name}</p>',
    -    '</tpl></p>'
    -);
    -tpl.overwrite(panel.body, data);  // pass the root node of the data object
    - 
    - *

    Flat arrays that contain values (and not objects) can be auto-rendered - * using the special {.} variable inside a loop. This variable - * will represent the value of the array at the current index:

    - *
    
    -var tpl = new Ext.XTemplate(
    -    '<p>{name}\'s favorite beverages:</p>',
    -    '<tpl for="drinks">',
    -        '<div> - {.}</div>',
    -    '</tpl>'
    -);
    -tpl.overwrite(panel.body, data);
    - 
    - *

    When processing a sub-template, for example while looping through a child array, - * you can access the parent object's members via the parent object:

    - *
    
    -var tpl = new Ext.XTemplate(
    -    '<p>Name: {name}</p>',
    -    '<p>Kids: ',
    -    '<tpl for="kids">',
    -        '<tpl if="age &gt; 1">',
    -            '<p>{name}</p>',
    -            '<p>Dad: {parent.name}</p>',
    -        '</tpl>',
    -    '</tpl></p>'
    -);
    -tpl.overwrite(panel.body, data);
    - 
    - *
    - *
  • - * - * - *
  • Conditional processing with basic comparison operators - *
    - *

    The tpl tag and the if operator are used - * to provide conditional checks for deciding whether or not to render specific - * parts of the template. Notes:

      - *
    • Double quotes must be encoded if used within the conditional
    • - *
    • There is no else operator — if needed, two opposite - * if statements should be used.
    • - *
    - *
    
    -<tpl if="age > 1 && age < 10">Child</tpl>
    -<tpl if="age >= 10 && age < 18">Teenager</tpl>
    -<tpl if="this.isGirl(name)">...</tpl>
    -<tpl if="id==\'download\'">...</tpl>
    -<tpl if="needsIcon"><img src="{icon}" class="{iconCls}"/></tpl>
    -// no good:
    -<tpl if="name == "Tommy"">Hello</tpl>
    -// encode " if it is part of the condition, e.g.
    -<tpl if="name == &quot;Tommy&quot;">Hello</tpl>
    - * 
    - * Using the sample data above: - *
    
    -var tpl = new Ext.XTemplate(
    -    '<p>Name: {name}</p>',
    -    '<p>Kids: ',
    -    '<tpl for="kids">',
    -        '<tpl if="age &gt; 1">',
    -            '<p>{name}</p>',
    -        '</tpl>',
    -    '</tpl></p>'
    -);
    -tpl.overwrite(panel.body, data);
    - 
    - *
    - *
  • - * - * - *
  • Basic math support - *
    - *

    The following basic math operators may be applied directly on numeric - * data values:

    - * + - * /
    - * 
    - * For example: - *
    
    -var tpl = new Ext.XTemplate(
    -    '<p>Name: {name}</p>',
    -    '<p>Kids: ',
    -    '<tpl for="kids">',
    -        '<tpl if="age &gt; 1">',  // <-- Note that the > is encoded
    -            '<p>{#}: {name}</p>',  // <-- Auto-number each item
    -            '<p>In 5 Years: {age+5}</p>',  // <-- Basic math
    -            '<p>Dad: {parent.name}</p>',
    -        '</tpl>',
    -    '</tpl></p>'
    -);
    -tpl.overwrite(panel.body, data);
    - 
    - *
    - *
  • - * - * - *
  • Execute arbitrary inline code with special built-in template variables - *
    - *

    Anything between {[ ... ]} is considered code to be executed - * in the scope of the template. There are some special variables available in that code: - *

      - *
    • values: The values in the current scope. If you are using - * scope changing sub-templates, you can change what values is.
    • - *
    • parent: The scope (values) of the ancestor template.
    • - *
    • xindex: If you are in a looping template, the index of the - * loop you are in (1-based).
    • - *
    • xcount: If you are in a looping template, the total length - * of the array you are looping.
    • - *
    - * This example demonstrates basic row striping using an inline code block and the - * xindex variable:

    - *
    
    -var tpl = new Ext.XTemplate(
    -    '<p>Name: {name}</p>',
    -    '<p>Company: {[values.company.toUpperCase() + ", " + values.title]}</p>',
    -    '<p>Kids: ',
    -    '<tpl for="kids">',
    -        '<div class="{[xindex % 2 === 0 ? "even" : "odd"]}">',
    -        '{name}',
    -        '</div>',
    -    '</tpl></p>'
    - );
    -tpl.overwrite(panel.body, data);
    - 
    - *
    - *
  • - * - *
  • Template member functions - *
    - *

    One or more member functions can be specified in a configuration - * object passed into the XTemplate constructor for more complex processing:

    - *
    
    -var tpl = new Ext.XTemplate(
    -    '<p>Name: {name}</p>',
    -    '<p>Kids: ',
    -    '<tpl for="kids">',
    -        '<tpl if="this.isGirl(name)">',
    -            '<p>Girl: {name} - {age}</p>',
    -        '</tpl>',
    -         // use opposite if statement to simulate 'else' processing:
    -        '<tpl if="this.isGirl(name) == false">',
    -            '<p>Boy: {name} - {age}</p>',
    -        '</tpl>',
    -        '<tpl if="this.isBaby(age)">',
    -            '<p>{name} is a baby!</p>',
    -        '</tpl>',
    -    '</tpl></p>',
    -    {
    -        // XTemplate configuration:
    -        compiled: true,
    -        // member functions:
    -        isGirl: function(name){
    -           return name == 'Sara Grace';
    -        },
    -        isBaby: function(age){
    -           return age < 1;
    -        }
    -    }
    -);
    -tpl.overwrite(panel.body, data);
    - 
    - *
    - *
  • - * - *
- * - * @param {Mixed} config - */ + me.setUI(me.ui); -Ext.define('Ext.XTemplate', { + el.addCls(me.initCls()); + el.setStyle(styles); - /* Begin Definitions */ + + + + + + + + + + - extend: 'Ext.Template', + me.el = el; - statics: { - /** - * Creates a template from the passed element's value (display:none textarea, preferred) or innerHTML. - * @param {String/HTMLElement} el A DOM element or its id - * @return {Ext.Template} The created template - * @static - */ - from: function(el, config) { - el = Ext.getDom(el); - return new this(el.value || el.innerHTML, config || {}); + me.initFrame(); + + renderTpl = me.initRenderTpl(); + if (renderTpl) { + renderData = me.initRenderData(); + renderTpl.append(me.getTargetEl(), renderData); } - }, - + me.applyRenderSelectors(); - argsRe: /]*>((?:(?=([^<]+))\2|<(?!tpl\b[^>]*>))*?)<\/tpl>/, - nameRe: /^]*?for="(.*?)"/, - ifRe: /^]*?if="(.*?)"/, - execRe: /^]*?exec="(.*?)"/, - constructor: function() { - this.callParent(arguments); + me.rendered = true; + }, + + afterRender : function() { var me = this, - html = me.html, - argsRe = me.argsRe, - nameRe = me.nameRe, - ifRe = me.ifRe, - execRe = me.execRe, - id = 0, - tpls = [], - VALUES = 'values', - PARENT = 'parent', - XINDEX = 'xindex', - XCOUNT = 'xcount', - RETURN = 'return ', - WITHVALUES = 'with(values){ ', - m, matchName, matchIf, matchExec, exp, fn, exec, name, i; - - html = ['', html, ''].join(''); - - while ((m = html.match(argsRe))) { - exp = null; - fn = null; - exec = null; - matchName = m[0].match(nameRe); - matchIf = m[0].match(ifRe); - matchExec = m[0].match(execRe); + pos, + xy; - exp = matchIf ? matchIf[1] : null; - if (exp) { - fn = Ext.functionFactory(VALUES, PARENT, XINDEX, XCOUNT, WITHVALUES + 'try{' + RETURN + Ext.String.htmlDecode(exp) + ';}catch(e){return;}}'); - } + me.getComponentLayout(); - exp = matchExec ? matchExec[1] : null; - if (exp) { - exec = Ext.functionFactory(VALUES, PARENT, XINDEX, XCOUNT, WITHVALUES + Ext.String.htmlDecode(exp) + ';}'); - } + + + + if (me.collapsed || (!me.ownerCt || (me.height || me.width))) { + me.setSize(me.width, me.height); + } else { + + + + + me.renderChildren(); + } - name = matchName ? matchName[1] : null; - if (name) { - if (name === '.') { - name = VALUES; - } else if (name === '..') { - name = PARENT; - } - name = Ext.functionFactory(VALUES, PARENT, 'try{' + WITHVALUES + RETURN + name + ';}}catch(e){return;}'); + + + if (me.floating && (me.x === undefined || me.y === undefined)) { + if (me.floatParent) { + xy = me.el.getAlignToXY(me.floatParent.getTargetEl(), 'c-c'); + pos = me.floatParent.getTargetEl().translatePoints(xy[0], xy[1]); + } else { + xy = me.el.getAlignToXY(me.container, 'c-c'); + pos = me.container.translatePoints(xy[0], xy[1]); } + me.x = me.x === undefined ? pos.left: me.x; + me.y = me.y === undefined ? pos.top: me.y; + } - tpls.push({ - id: id, - target: name, - exec: exec, - test: fn, - body: m[1] || '' - }); - - html = html.replace(m[0], '{xtpl' + id + '}'); - id = id + 1; + if (Ext.isDefined(me.x) || Ext.isDefined(me.y)) { + me.setPosition(me.x, me.y); } - for (i = tpls.length - 1; i >= 0; --i) { - me.compileTpl(tpls[i]); + if (me.styleHtmlContent) { + me.getTargetEl().addCls(me.styleHtmlCls); } - me.master = tpls[tpls.length - 1]; - me.tpls = tpls; }, - applySubTemplate: function(id, values, parent, xindex, xcount) { - var me = this, t = me.tpls[id]; - return t.compiled.call(me, values, parent, xindex, xcount); + registerFloatingItem: function(cmp) { + var me = this; + if (!me.floatingItems) { + me.floatingItems = Ext.create('Ext.ZIndexManager', me); + } + me.floatingItems.register(cmp); }, - - codeRe: /\{\[((?:\\\]|.|\n)*?)\]\}/g, - re: /\{([\w-\.\#]+)(?:\:([\w\.]*)(?:\((.*?)?\))?)?(\s?[\+\-\*\/]\s?[\d\.\+\-\*\/\(\)]+)?\}/g, + renderChildren: function () { + var me = this, + layout = me.getComponentLayout(); + + me.suspendLayout = true; + layout.renderChildren(); + delete me.suspendLayout; + }, + + frameCls: Ext.baseCSSPrefix + 'frame', + + frameIdRegex: /[-]frame\d+[TMB][LCR]$/, + + frameElementCls: { + tl: [], + tc: [], + tr: [], + ml: [], + mc: [], + mr: [], + bl: [], + bc: [], + br: [] + }, + + frameTpl: [ + '', + '
{parent.baseCls}-{parent.ui}-{.}-tl" style="background-position: {tl}; padding-left: {frameWidth}px" role="presentation">', + '
{parent.baseCls}-{parent.ui}-{.}-tr" style="background-position: {tr}; padding-right: {frameWidth}px" role="presentation">', + '
{parent.baseCls}-{parent.ui}-{.}-tc" style="background-position: {tc}; height: {frameWidth}px" role="presentation">
', + '
', + '
', + '
', + '
{parent.baseCls}-{parent.ui}-{.}-ml" style="background-position: {ml}; padding-left: {frameWidth}px" role="presentation">', + '
{parent.baseCls}-{parent.ui}-{.}-mr" style="background-position: {mr}; padding-right: {frameWidth}px" role="presentation">', + '
{parent.baseCls}-{parent.ui}-{.}-mc" role="presentation">
', + '
', + '
', + '', + '
{parent.baseCls}-{parent.ui}-{.}-bl" style="background-position: {bl}; padding-left: {frameWidth}px" role="presentation">', + '
{parent.baseCls}-{parent.ui}-{.}-br" style="background-position: {br}; padding-right: {frameWidth}px" role="presentation">', + '
{parent.baseCls}-{parent.ui}-{.}-bc" style="background-position: {bc}; height: {frameWidth}px" role="presentation">
', + '
', + '
', + '
' + ], + + frameTableTpl: [ + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '
{parent.baseCls}-{parent.ui}-{.}-tl" style="background-position: {tl}; padding-left:{frameWidth}px" role="presentation"> {parent.baseCls}-{parent.ui}-{.}-tc" style="background-position: {tc}; height: {frameWidth}px" role="presentation"> {parent.baseCls}-{parent.ui}-{.}-tr" style="background-position: {tr}; padding-left: {frameWidth}px" role="presentation">
{parent.baseCls}-{parent.ui}-{.}-ml" style="background-position: {ml}; padding-left: {frameWidth}px" role="presentation"> {parent.baseCls}-{parent.ui}-{.}-mc" style="background-position: 0 0;" role="presentation"> {parent.baseCls}-{parent.ui}-{.}-mr" style="background-position: {mr}; padding-left: {frameWidth}px" role="presentation">
{parent.baseCls}-{parent.ui}-{.}-bl" style="background-position: {bl}; padding-left: {frameWidth}px" role="presentation"> {parent.baseCls}-{parent.ui}-{.}-bc" style="background-position: {bc}; height: {frameWidth}px" role="presentation"> {parent.baseCls}-{parent.ui}-{.}-br" style="background-position: {br}; padding-left: {frameWidth}px" role="presentation">
' + ], - compileTpl: function(tpl) { - var fm = Ext.util.Format, - me = this, - useFormat = me.disableFormats !== true, - body, bodyReturn, evaluatedFn; + initFrame : function() { + if (Ext.supports.CSS3BorderRadius) { + return false; + } - function fn(m, name, format, args, math) { - var v; + var me = this, + frameInfo = me.getFrameInfo(), + frameWidth = frameInfo.width, + frameTpl = me.getFrameTpl(frameInfo.table), + frameGenId; + + if (me.frame) { - if (name.substr(0, 4) == 'xtpl') { - return "',this.applySubTemplate(" + name.substr(4) + ", values, parent, xindex, xcount),'"; - } + me.frameGenId = frameGenId = (me.frameGenId || 0) + 1; + frameGenId = me.id + '-frame' + frameGenId; + - if (name == '.') { - - v = 'Ext.Array.indexOf(["string", "number", "boolean"], typeof values) > -1 || Ext.isDate(values) ? values : ""'; - } + frameTpl.insertFirst(me.el, Ext.apply({}, { + fgid: frameGenId, + ui: me.ui, + uiCls: me.uiCls, + frameCls: me.frameCls, + baseCls: me.baseCls, + frameWidth: frameWidth, + top: !!frameInfo.top, + left: !!frameInfo.left, + right: !!frameInfo.right, + bottom: !!frameInfo.bottom + }, me.getFramePositions(frameInfo))); - else if (name == '#') { - v = 'xindex'; - } - else if (name.substr(0, 7) == "parent.") { - v = name; - } + me.frameBody = me.el.down('.' + me.frameCls + '-mc'); + - else if (name.indexOf('.') != -1) { - v = "values." + name; - } + me.removeChildEls(function (c) { + return c.id && me.frameIdRegex.test(c.id); + }); - else { - v = "values['" + name + "']"; - } - if (math) { - v = '(' + v + math + ')'; - } - if (format && useFormat) { - args = args ? ',' + args : ""; - if (format.substr(0, 5) != "this.") { - format = "fm." + format + '('; - } - else { - format = 'this.' + format.substr(5) + '('; - } - } - else { - args = ''; - format = "(" + v + " === undefined ? '' : "; - } - return "'," + format + v + args + "),'"; + Ext.each(['TL','TC','TR','ML','MC','MR','BL','BC','BR'], function (suffix) { + me.childEls.push({ name: 'frame' + suffix, id: frameGenId + suffix }); + }); } + }, - function codeFn(m, code) { - - return "',(" + code.replace(me.compileARe, "'") + "),'"; + updateFrame: function() { + if (Ext.supports.CSS3BorderRadius) { + return false; } - bodyReturn = tpl.body.replace(me.compileBRe, '\\n').replace(me.compileCRe, "\\'").replace(me.re, fn).replace(me.codeRe, codeFn); - body = "evaluatedFn = function(values, parent, xindex, xcount){return ['" + bodyReturn + "'].join('');};"; - eval(body); + var me = this, + wasTable = this.frameSize && this.frameSize.table, + oldFrameTL = this.frameTL, + oldFrameBL = this.frameBL, + oldFrameML = this.frameML, + oldFrameMC = this.frameMC, + newMCClassName; - tpl.compiled = function(values, parent, xindex, xcount) { - var vs, - length, - buffer, - i; + this.initFrame(); - if (tpl.test && !tpl.test.call(me, values, parent, xindex, xcount)) { - return ''; - } + if (oldFrameMC) { + if (me.frame) { + + delete me.frameTL; + delete me.frameTC; + delete me.frameTR; + delete me.frameML; + delete me.frameMC; + delete me.frameMR; + delete me.frameBL; + delete me.frameBC; + delete me.frameBR; + this.applyRenderSelectors(); - vs = tpl.target ? tpl.target.call(me, values, parent) : values; - if (!vs) { - return ''; - } + + newMCClassName = this.frameMC.dom.className; - parent = tpl.target ? values : parent; - if (tpl.target && Ext.isArray(vs)) { - buffer = []; - length = vs.length; - if (tpl.exec) { - for (i = 0; i < length; i++) { - buffer[buffer.length] = evaluatedFn.call(me, vs[i], parent, i + 1, length); - tpl.exec.call(me, vs[i], parent, i + 1, length); + + oldFrameMC.insertAfter(this.frameMC); + this.frameMC.remove(); + + + this.frameBody = this.frameMC = oldFrameMC; + + + oldFrameMC.dom.className = newMCClassName; + + + if (wasTable) { + me.el.query('> table')[1].remove(); + } + else { + if (oldFrameTL) { + oldFrameTL.remove(); } - } else { - for (i = 0; i < length; i++) { - buffer[buffer.length] = evaluatedFn.call(me, vs[i], parent, i + 1, length); + if (oldFrameBL) { + oldFrameBL.remove(); } + oldFrameML.remove(); } - return buffer.join(''); } + else { + - if (tpl.exec) { - tpl.exec.call(me, vs, parent, xindex, xcount); } - return evaluatedFn.call(me, vs, parent, xindex, xcount); - }; + } + else if (me.frame) { + this.applyRenderSelectors(); + } + }, - return this; - }, - - - applyTemplate: function(values) { - return this.master.compiled.call(this, values, {}, 1, 1); - }, - - - compile: function() { - return this; - } -}, function() { - - this.createAlias('apply', 'applyTemplate'); -}); + getFrameInfo: function() { + if (Ext.supports.CSS3BorderRadius) { + return false; + } + var me = this, + left = me.el.getStyle('background-position-x'), + top = me.el.getStyle('background-position-y'), + info, frameInfo = false, max; -Ext.define('Ext.util.AbstractMixedCollection', { - requires: ['Ext.util.Filter'], - - mixins: { - observable: 'Ext.util.Observable' - }, + + + if (!left && !top) { + info = me.el.getStyle('background-position').split(' '); + left = info[0]; + top = info[1]; + } - constructor: function(allowFunctions, keyFn) { - var me = this; + + + + if (parseInt(left, 10) >= 1000000 && parseInt(top, 10) >= 1000000) { + max = Math.max; - me.items = []; - me.map = {}; - me.keys = []; - me.length = 0; + frameInfo = { + + table: left.substr(0, 3) == '110', - me.addEvents( - - 'clear', + + vertical: top.substr(0, 3) == '110', - - 'add', + + top: max(left.substr(3, 2), left.substr(5, 2)), + right: max(left.substr(5, 2), top.substr(3, 2)), + bottom: max(top.substr(3, 2), top.substr(5, 2)), + left: max(top.substr(5, 2), left.substr(3, 2)) + }; - - 'replace', + frameInfo.width = max(frameInfo.top, frameInfo.right, frameInfo.bottom, frameInfo.left); - 'remove' - ); - - me.allowFunctions = allowFunctions === true; + me.el.setStyle('background-image', 'none'); + } - if (keyFn) { - me.getKey = keyFn; + + + if (me.frame === true && !frameInfo) { } - me.mixins.observable.constructor.call(me); + me.frame = me.frame || !!frameInfo; + me.frameSize = frameInfo || false; + + return frameInfo; }, - - - allowFunctions : false, - - add : function(key, obj){ + getFramePositions: function(frameInfo) { var me = this, - myObj = obj, - myKey = key, - old; + frameWidth = frameInfo.width, + dock = me.dock, + positions, tc, bc, ml, mr; - if (arguments.length == 1) { - myObj = myKey; - myKey = me.getKey(myObj); - } - if (typeof myKey != 'undefined' && myKey !== null) { - old = me.map[myKey]; - if (typeof old != 'undefined') { - return me.replace(myKey, myObj); + if (frameInfo.vertical) { + tc = '0 -' + (frameWidth * 0) + 'px'; + bc = '0 -' + (frameWidth * 1) + 'px'; + + if (dock && dock == "right") { + tc = 'right -' + (frameWidth * 0) + 'px'; + bc = 'right -' + (frameWidth * 1) + 'px'; } - me.map[myKey] = myObj; + + positions = { + tl: '0 -' + (frameWidth * 0) + 'px', + tr: '0 -' + (frameWidth * 1) + 'px', + bl: '0 -' + (frameWidth * 2) + 'px', + br: '0 -' + (frameWidth * 3) + 'px', + + ml: '-' + (frameWidth * 1) + 'px 0', + mr: 'right 0', + + tc: tc, + bc: bc + }; + } else { + ml = '-' + (frameWidth * 0) + 'px 0'; + mr = 'right 0'; + + if (dock && dock == "bottom") { + ml = 'left bottom'; + mr = 'right bottom'; + } + + positions = { + tl: '0 -' + (frameWidth * 2) + 'px', + tr: 'right -' + (frameWidth * 3) + 'px', + bl: '0 -' + (frameWidth * 4) + 'px', + br: 'right -' + (frameWidth * 5) + 'px', + + ml: ml, + mr: mr, + + tc: '0 -' + (frameWidth * 0) + 'px', + bc: '0 -' + (frameWidth * 1) + 'px' + }; } - me.length++; - me.items.push(myObj); - me.keys.push(myKey); - me.fireEvent('add', me.length - 1, myObj, myKey); - return myObj; + + return positions; }, - getKey : function(o){ - return o.id; + getFrameTpl : function(table) { + return table ? this.getTpl('frameTableTpl') : this.getTpl('frameTpl'); }, - replace : function(key, o){ + initCls: function() { var me = this, - old, - index; + cls = []; - if (arguments.length == 1) { - o = arguments[0]; - key = me.getKey(o); + cls.push(me.baseCls); + + if (Ext.isDefined(me.cmpCls)) { + if (Ext.isDefined(Ext.global.console)) { + Ext.global.console.warn('Ext.Component: cmpCls has been deprecated. Please use componentCls.'); + } + me.componentCls = me.cmpCls; + delete me.cmpCls; } - old = me.map[key]; - if (typeof key == 'undefined' || key === null || typeof old == 'undefined') { - return me.add(key, o); + + if (me.componentCls) { + cls.push(me.componentCls); + } else { + me.componentCls = me.baseCls; } - index = me.indexOfKey(key); - me.items[index] = o; - me.map[key] = o; - me.fireEvent('replace', key, old, o); - return o; + if (me.cls) { + cls.push(me.cls); + delete me.cls; + } + + return cls.concat(me.additionalCls); }, - addAll : function(objs){ + setUI: function(ui) { var me = this, - i = 0, - args, - len, - key; + oldUICls = Ext.Array.clone(me.uiCls), + newUICls = [], + classes = [], + cls, + i; - if (arguments.length > 1 || Ext.isArray(objs)) { - args = arguments.length > 1 ? arguments : objs; - for (len = args.length; i < len; i++) { - me.add(args[i]); - } - } else { - for (key in objs) { - if (objs.hasOwnProperty(key)) { - if (me.allowFunctions || typeof objs[key] != 'function') { - me.add(key, objs[key]); - } - } - } + + for (i = 0; i < oldUICls.length; i++) { + cls = oldUICls[i]; + + classes = classes.concat(me.removeClsWithUI(cls, true)); + newUICls.push(cls); } - }, - - each : function(fn, scope){ - var items = [].concat(this.items), - i = 0, - len = items.length, - item; + if (classes.length) { + me.removeCls(classes); + } - for (; i < len; i++) { - item = items[i]; - if (fn.call(scope || item, item, i, len) === false) { - break; - } + + me.removeUIFromElement(); + + + me.ui = ui; + + + me.addUIToElement(); + + + classes = []; + for (i = 0; i < newUICls.length; i++) { + cls = newUICls[i]; + classes = classes.concat(me.addClsWithUI(cls, true)); + } + + if (classes.length) { + me.addCls(classes); } }, - eachKey : function(fn, scope){ - var keys = this.keys, - items = this.items, - i = 0, - len = keys.length; + addClsWithUI: function(cls, skip) { + var me = this, + classes = [], + i; - for (; i < len; i++) { - fn.call(scope || window, keys[i], items[i], i, len); + if (!Ext.isArray(cls)) { + cls = [cls]; } - }, - - findBy : function(fn, scope) { - var keys = this.keys, - items = this.items, - i = 0, - len = items.length; + for (i = 0; i < cls.length; i++) { + if (cls[i] && !me.hasUICls(cls[i])) { + me.uiCls = Ext.Array.clone(me.uiCls); + me.uiCls.push(cls[i]); - for (; i < len; i++) { - if (fn.call(scope || window, items[i], keys[i])) { - return items[i]; + classes = classes.concat(me.addUIClsToElement(cls[i])); } } - return null; - }, - find : function() { - if (Ext.isDefined(Ext.global.console)) { - Ext.global.console.warn('Ext.util.MixedCollection: find has been deprecated. Use findBy instead.'); + if (skip !== true) { + me.addCls(classes); } - return this.findBy.apply(this, arguments); + + return classes; }, - insert : function(index, key, obj){ + removeClsWithUI: function(cls, skip) { var me = this, - myKey = key, - myObj = obj; + classes = [], + i; - if (arguments.length == 2) { - myObj = myKey; - myKey = me.getKey(myObj); - } - if (me.containsKey(myKey)) { - me.suspendEvents(); - me.removeAtKey(myKey); - me.resumeEvents(); + if (!Ext.isArray(cls)) { + cls = [cls]; } - if (index >= me.length) { - return me.add(myKey, myObj); + + for (i = 0; i < cls.length; i++) { + if (cls[i] && me.hasUICls(cls[i])) { + me.uiCls = Ext.Array.remove(me.uiCls, cls[i]); + + classes = classes.concat(me.removeUIClsFromElement(cls[i])); + } } - me.length++; - me.items.splice(index, 0, myObj); - if (typeof myKey != 'undefined' && myKey !== null) { - me.map[myKey] = myObj; + + if (skip !== true) { + me.removeCls(classes); } - me.keys.splice(index, 0, myKey); - me.fireEvent('add', index, myObj, myKey); - return myObj; - }, - - remove : function(o){ - return this.removeAt(this.indexOf(o)); + return classes; }, - removeAll : function(items){ - Ext.each(items || [], function(item) { - this.remove(item); - }, this); + hasUICls: function(cls) { + var me = this, + uiCls = me.uiCls || []; - return this; + return Ext.Array.contains(uiCls, cls); }, - removeAt : function(index){ + addUIClsToElement: function(cls, force) { var me = this, - o, - key; + result = [], + frameElementCls = me.frameElementCls; - if (index < me.length && index >= 0) { - me.length--; - o = me.items[index]; - me.items.splice(index, 1); - key = me.keys[index]; - if (typeof key != 'undefined') { - delete me.map[key]; + result.push(Ext.baseCSSPrefix + cls); + result.push(me.baseCls + '-' + cls); + result.push(me.baseCls + '-' + me.ui + '-' + cls); + + if (!force && me.frame && !Ext.supports.CSS3BorderRadius) { + + var els = ['tl', 'tc', 'tr', 'ml', 'mc', 'mr', 'bl', 'bc', 'br'], + classes, i, j, el; + + + for (i = 0; i < els.length; i++) { + el = me['frame' + els[i].toUpperCase()]; + classes = [me.baseCls + '-' + me.ui + '-' + els[i], me.baseCls + '-' + me.ui + '-' + cls + '-' + els[i]]; + if (el && el.dom) { + el.addCls(classes); + } else { + for (j = 0; j < classes.length; j++) { + if (Ext.Array.indexOf(frameElementCls[els[i]], classes[j]) == -1) { + frameElementCls[els[i]].push(classes[j]); + } + } + } } - me.keys.splice(index, 1); - me.fireEvent('remove', o, key); - return o; } - return false; - }, - - removeAtKey : function(key){ - return this.removeAt(this.indexOfKey(key)); - }, + me.frameElementCls = frameElementCls; - - getCount : function(){ - return this.length; + return result; }, - indexOf : function(o){ - return Ext.Array.indexOf(this.items, o); - }, + removeUIClsFromElement: function(cls, force) { + var me = this, + result = [], + frameElementCls = me.frameElementCls; - - indexOfKey : function(key){ - return Ext.Array.indexOf(this.keys, key); + result.push(Ext.baseCSSPrefix + cls); + result.push(me.baseCls + '-' + cls); + result.push(me.baseCls + '-' + me.ui + '-' + cls); + + if (!force && me.frame && !Ext.supports.CSS3BorderRadius) { + + var els = ['tl', 'tc', 'tr', 'ml', 'mc', 'mr', 'bl', 'bc', 'br'], + i, el; + cls = me.baseCls + '-' + me.ui + '-' + cls + '-' + els[i]; + + for (i = 0; i < els.length; i++) { + el = me['frame' + els[i].toUpperCase()]; + if (el && el.dom) { + el.removeCls(cls); + } else { + Ext.Array.remove(frameElementCls[els[i]], cls); + } + } + } + + me.frameElementCls = frameElementCls; + + return result; }, - get : function(key) { + addUIToElement: function(force) { var me = this, - mk = me.map[key], - item = mk !== undefined ? mk : (typeof key == 'number') ? me.items[key] : undefined; - return typeof item != 'function' || me.allowFunctions ? item : null; - }, + frameElementCls = me.frameElementCls; - - getAt : function(index) { - return this.items[index]; - }, + me.addCls(me.baseCls + '-' + me.ui); - - getByKey : function(key) { - return this.map[key]; - }, + if (me.frame && !Ext.supports.CSS3BorderRadius) { + + var els = ['tl', 'tc', 'tr', 'ml', 'mc', 'mr', 'bl', 'bc', 'br'], + i, el, cls; - - contains : function(o){ - return Ext.Array.contains(this.items, o); + + for (i = 0; i < els.length; i++) { + el = me['frame' + els[i].toUpperCase()]; + cls = me.baseCls + '-' + me.ui + '-' + els[i]; + if (el) { + el.addCls(cls); + } else { + if (!Ext.Array.contains(frameElementCls[els[i]], cls)) { + frameElementCls[els[i]].push(cls); + } + } + } + } }, - containsKey : function(key){ - return typeof this.map[key] != 'undefined'; - }, + removeUIFromElement: function() { + var me = this, + frameElementCls = me.frameElementCls; - - clear : function(){ - var me = this; + me.removeCls(me.baseCls + '-' + me.ui); - me.length = 0; - me.items = []; - me.keys = []; - me.map = {}; - me.fireEvent('clear'); - }, + if (me.frame && !Ext.supports.CSS3BorderRadius) { + + var els = ['tl', 'tc', 'tr', 'ml', 'mc', 'mr', 'bl', 'bc', 'br'], + i, j, el, cls; - - first : function() { - return this.items[0]; - }, + + for (i = 0; i < els.length; i++) { + el = me['frame' + els[i].toUpperCase()]; + cls = me.baseCls + '-' + me.ui + '-' + els[i]; - - last : function() { - return this.items[this.length - 1]; + if (el) { + el.removeCls(cls); + } else { + Ext.Array.remove(frameElementCls[els[i]], cls); + } + } + } }, - - sum: function(property, root, start, end) { - var values = this.extractValues(property, root), - length = values.length, - sum = 0, - i; + getElConfig : function() { + if (Ext.isString(this.autoEl)) { + this.autoEl = { + tag: this.autoEl + }; + } - start = start || 0; - end = (end || end === 0) ? end : length - 1; + var result = this.autoEl || {tag: 'div'}; + result.id = this.id; + return result; + }, - for (i = start; i <= end; i++) { - sum += values[i]; + + getInsertPosition: function(position) { + + if (position !== undefined) { + if (Ext.isNumber(position)) { + position = this.container.dom.childNodes[position]; + } + else { + position = Ext.getDom(position); + } } - return sum; + return position; }, - collect: function(property, root, allowNull) { - var values = this.extractValues(property, root), - length = values.length, - hits = {}, - unique = [], - value, strValue, i; + initContainer: function(container) { + var me = this; - for (i = 0; i < length; i++) { - value = values[i]; - strValue = String(value); + + + + if (!container && me.el) { + container = me.el.dom.parentNode; + me.allowDomMove = false; + } - if ((allowNull || !Ext.isEmpty(value)) && !hits[strValue]) { - hits[strValue] = true; - unique.push(value); - } + me.container = Ext.get(container); + + if (me.ctCls) { + me.container.addCls(me.ctCls); } - return unique; + return me.container; }, - extractValues: function(property, root) { - var values = this.items; - - if (root) { - values = Ext.Array.pluck(values, root); - } + initRenderData: function() { + var me = this; - return Ext.Array.pluck(values, property); + return Ext.applyIf(me.renderData, { + id: me.id, + ui: me.ui, + uiCls: me.uiCls, + baseCls: me.baseCls, + componentCls: me.componentCls, + frame: me.frame + }); }, - getRange : function(start, end){ + getTpl: function(name) { var me = this, - items = me.items, - range = [], - i; + prototype = me.self.prototype, + ownerPrototype, + tpl; - if (items.length < 1) { - return range; + if (me.hasOwnProperty(name)) { + tpl = me[name]; + if (tpl && !(tpl instanceof Ext.XTemplate)) { + me[name] = Ext.ClassManager.dynInstantiate('Ext.XTemplate', tpl); + } + + return me[name]; } - start = start || 0; - end = Math.min(typeof end == 'undefined' ? me.length - 1 : end, me.length - 1); - if (start <= end) { - for (i = start; i <= end; i++) { - range[range.length] = items[i]; - } - } else { - for (i = start; i >= end; i--) { - range[range.length] = items[i]; - } + if (!(prototype[name] instanceof Ext.XTemplate)) { + ownerPrototype = prototype; + + do { + if (ownerPrototype.hasOwnProperty(name)) { + tpl = ownerPrototype[name]; + if (tpl && !(tpl instanceof Ext.XTemplate)) { + ownerPrototype[name] = Ext.ClassManager.dynInstantiate('Ext.XTemplate', tpl); + break; + } + } + + ownerPrototype = ownerPrototype.superclass; + } while (ownerPrototype); } - return range; + + return prototype[name]; }, - filter : function(property, value, anyMatch, caseSensitive) { - var filters = [], - filterFn; + initRenderTpl: function() { + return this.getTpl('renderTpl'); + }, - - if (Ext.isString(property)) { - filters.push(Ext.create('Ext.util.Filter', { - property : property, - value : value, - anyMatch : anyMatch, - caseSensitive: caseSensitive - })); - } else if (Ext.isArray(property) || property instanceof Ext.util.Filter) { - filters = filters.concat(property); + + initStyles: function() { + var style = {}, + me = this, + Element = Ext.Element; + + if (Ext.isString(me.style)) { + style = Element.parseStyles(me.style); + } else { + style = Ext.apply({}, me.style); } - filterFn = function(record) { - var isMatch = true, - length = filters.length, - i; - - for (i = 0; i < length; i++) { - var filter = filters[i], - fn = filter.filterFn, - scope = filter.scope; - - isMatch = isMatch && fn.call(scope, record); - } + if (me.padding !== undefined) { + style.padding = Element.unitizeBox((me.padding === true) ? 5 : me.padding); + } - return isMatch; - }; + if (me.margin !== undefined) { + style.margin = Element.unitizeBox((me.margin === true) ? 5 : me.margin); + } - return this.filterBy(filterFn); + delete me.style; + return style; }, - filterBy : function(fn, scope) { + initContent: function() { var me = this, - newMC = new this.self(), - keys = me.keys, - items = me.items, - length = items.length, - i; + target = me.getTargetEl(), + contentEl, + pre; - newMC.getKey = me.getKey; + if (me.html) { + target.update(Ext.DomHelper.markup(me.html)); + delete me.html; + } - for (i = 0; i < length; i++) { - if (fn.call(scope || me, items[i], keys[i])) { - newMC.add(keys[i], items[i]); - } + if (me.contentEl) { + contentEl = Ext.get(me.contentEl); + pre = Ext.baseCSSPrefix; + contentEl.removeCls([pre + 'hidden', pre + 'hide-display', pre + 'hide-offsets', pre + 'hide-nosize']); + target.appendChild(contentEl.dom); } - return newMC; + if (me.tpl) { + + if (!me.tpl.isTemplate) { + me.tpl = Ext.create('Ext.XTemplate', me.tpl); + } + + if (me.data) { + me.tpl[me.tplWriteMode](target, me.data); + delete me.data; + } + } }, - findIndex : function(property, value, start, anyMatch, caseSensitive){ - if(Ext.isEmpty(value, false)){ - return -1; + initEvents : function() { + var me = this, + afterRenderEvents = me.afterRenderEvents, + el, + property, + fn = function(listeners){ + me.mon(el, listeners); + }; + if (afterRenderEvents) { + for (property in afterRenderEvents) { + if (afterRenderEvents.hasOwnProperty(property)) { + el = me[property]; + if (el && el.on) { + Ext.each(afterRenderEvents[property], fn); + } + } + } } - value = this.createValueMatcher(value, anyMatch, caseSensitive); - return this.findIndexBy(function(o){ - return o && value.test(o[property]); - }, null, start); }, - findIndexBy : function(fn, scope, start){ + addChildEls: function () { var me = this, - keys = me.keys, - items = me.items, - i = start || 0, - len = items.length; + childEls = me.childEls || (me.childEls = []); - for (; i < len; i++) { - if (fn.call(scope || me, items[i], keys[i])) { - return i; - } - } - return -1; + childEls.push.apply(childEls, arguments); }, - createValueMatcher : function(value, anyMatch, caseSensitive, exactMatch) { - if (!value.exec) { - var er = Ext.String.escapeRegex; - value = String(value); + removeChildEls: function (testFn) { + var me = this, + old = me.childEls, + keepers = (me.childEls = []), + n, i, cel; - if (anyMatch === true) { - value = er(value); - } else { - value = '^' + er(value); - if (exactMatch === true) { - value += '$'; - } + for (i = 0, n = old.length; i < n; ++i) { + cel = old[i]; + if (!testFn(cel)) { + keepers.push(cel); } - value = new RegExp(value, caseSensitive ? '' : 'i'); } - return value; }, - clone : function() { + applyRenderSelectors: function() { var me = this, - copy = new this.self(), - keys = me.keys, - items = me.items, - i = 0, - len = items.length; + childEls = me.childEls, + selectors = me.renderSelectors, + el = me.el, + dom = el.dom, + baseId, childName, childId, i, selector; + + if (childEls) { + baseId = me.id + '-'; + for (i = childEls.length; i--; ) { + childName = childId = childEls[i]; + if (typeof(childName) != 'string') { + childId = childName.id || (baseId + childName.itemId); + childName = childName.name; + } else { + childId = baseId + childId; + } - for(; i < len; i++){ - copy.add(keys[i], items[i]); + + + me[childName] = el.getById(childId); + } } - copy.getKey = me.getKey; - return copy; - } -}); - - -Ext.define("Ext.util.Sortable", { - - isSortable: true, - - - defaultSortDirection: "ASC", - - requires: [ - 'Ext.util.Sorter' - ], - sortRoot: null, - - - initSortable: function() { - var me = this, - sorters = me.sorters; - - me.sorters = Ext.create('Ext.util.AbstractMixedCollection', false, function(item) { - return item.id || item.property; - }); - if (sorters) { - me.sorters.addAll(me.decodeSorters(sorters)); + if (selectors) { + for (selector in selectors) { + if (selectors.hasOwnProperty(selector) && selectors[selector]) { + me[selector] = Ext.get(Ext.DomQuery.selectNode(selectors[selector], dom)); + } + } } }, - sort: function(sorters, direction, where, doSort) { - var me = this, - sorter, sorterFn, - newSorters; - - if (Ext.isArray(sorters)) { - doSort = where; - where = direction; - newSorters = sorters; - } - else if (Ext.isObject(sorters)) { - doSort = where; - where = direction; - newSorters = [sorters]; - } - else if (Ext.isString(sorters)) { - sorter = me.sorters.get(sorters); + is: function(selector) { + return Ext.ComponentQuery.is(this, selector); + }, - if (!sorter) { - sorter = { - property : sorters, - direction: direction - }; - newSorters = [sorter]; - } - else if (direction === undefined) { - sorter.toggle(); - } - else { - sorter.setDirection(direction); + + up: function(selector) { + var result = this.ownerCt; + if (selector) { + for (; result; result = result.ownerCt) { + if (Ext.ComponentQuery.is(result, selector)) { + return result; + } } } - - if (newSorters && newSorters.length) { - newSorters = me.decodeSorters(newSorters); - if (Ext.isString(where)) { - if (where === 'prepend') { - sorters = me.sorters.clone().items; - - me.sorters.clear(); - me.sorters.addAll(newSorters); - me.sorters.addAll(sorters); - } - else { - me.sorters.addAll(newSorters); + return result; + }, + + + nextSibling: function(selector) { + var o = this.ownerCt, it, last, idx, c; + if (o) { + it = o.items; + idx = it.indexOf(this) + 1; + if (idx) { + if (selector) { + for (last = it.getCount(); idx < last; idx++) { + if ((c = it.getAt(idx)).is(selector)) { + return c; + } + } + } else { + if (idx < it.getCount()) { + return it.getAt(idx); + } } } - else { - me.sorters.clear(); - me.sorters.addAll(newSorters); - } - - if (doSort !== false) { - me.onBeforeSort(newSorters); - } } - - if (doSort !== false) { - sorters = me.sorters.items; - if (sorters.length) { - - sorterFn = function(r1, r2) { - var result = sorters[0].sort(r1, r2), - length = sorters.length, - i; + return null; + }, - - for (i = 1; i < length; i++) { - result = result || sorters[i].sort.call(this, r1, r2); + + previousSibling: function(selector) { + var o = this.ownerCt, it, idx, c; + if (o) { + it = o.items; + idx = it.indexOf(this); + if (idx != -1) { + if (selector) { + for (--idx; idx >= 0; idx--) { + if ((c = it.getAt(idx)).is(selector)) { + return c; } - - return result; - }; - - me.doSort(sorterFn); + } + } else { + if (idx) { + return it.getAt(--idx); + } + } } } - - return sorters; + return null; }, + - onBeforeSort: Ext.emptyFn, + previousNode: function(selector, includeSelf) { + var node = this, + result, + it, len, i; + - - decodeSorters: function(sorters) { - if (!Ext.isArray(sorters)) { - if (sorters === undefined) { - sorters = []; - } else { - sorters = [sorters]; - } + if (includeSelf && node.is(selector)) { + return node; } - var length = sorters.length, - Sorter = Ext.util.Sorter, - fields = this.model ? this.model.prototype.fields : null, - field, - config, i; - - for (i = 0; i < length; i++) { - config = sorters[i]; + result = this.prev(selector); + if (result) { + return result; + } - if (!(config instanceof Sorter)) { - if (Ext.isString(config)) { - config = { - property: config - }; + if (node.ownerCt) { + for (it = node.ownerCt.items.items, i = Ext.Array.indexOf(it, node) - 1; i > -1; i--) { + if (it[i].query) { + result = it[i].query(selector); + result = result[result.length - 1]; + if (result) { + return result; + } } - - Ext.applyIf(config, { - root : this.sortRoot, - direction: "ASC" - }); + } + return node.ownerCt.previousNode(selector, true); + } + }, - - if (config.fn) { - config.sorterFn = config.fn; - } + + nextNode: function(selector, includeSelf) { + var node = this, + result, + it, len, i; - - if (typeof config == 'function') { - config = { - sorterFn: config - }; - } + + if (includeSelf && node.is(selector)) { + return node; + } - - if (fields && !config.transform) { - field = fields.get(config.property); - config.transform = field ? field.sortType : undefined; + result = this.next(selector); + if (result) { + return result; + } + + if (node.ownerCt) { + for (it = node.ownerCt.items, i = it.indexOf(node) + 1, it = it.items, len = it.length; i < len; i++) { + if (it[i].down) { + result = it[i].down(selector); + if (result) { + return result; + } } - sorters[i] = Ext.create('Ext.util.Sorter', config); } + return node.ownerCt.nextNode(selector); } - - return sorters; }, - - getSorters: function() { - return this.sorters.items; - } -}); -Ext.define('Ext.util.MixedCollection', { - extend: 'Ext.util.AbstractMixedCollection', - mixins: { - sortable: 'Ext.util.Sortable' + + getId : function() { + return this.id || (this.id = 'ext-comp-' + (this.getAutoId())); }, - constructor: function() { - var me = this; - me.callParent(arguments); - me.addEvents('sort'); - me.mixins.sortable.initSortable.call(me); + getItemId : function() { + return this.itemId || this.id; }, - doSort: function(sorterFn) { - this.sortBy(sorterFn); + + getEl : function() { + return this.el; }, - _sort : function(property, dir, fn){ - var me = this, - i, len, - dsc = String(dir).toUpperCase() == 'DESC' ? -1 : 1, + getTargetEl: function() { + return this.frameBody || this.el; + }, + + isXType: function(xtype, shallow) { + + if (Ext.isFunction(xtype)) { + xtype = xtype.xtype; - c = [], - keys = me.keys, - items = me.items; + } else if (Ext.isObject(xtype)) { + xtype = xtype.statics().xtype; + + } - - fn = fn || function(a, b) { - return a - b; - }; + return !shallow ? ('/' + this.getXTypes() + '/').indexOf('/' + xtype + '/') != -1: this.self.xtype == xtype; + }, - - for(i = 0, len = items.length; i < len; i++){ - c[c.length] = { - key : keys[i], - value: items[i], - index: i - }; - } + + getXTypes: function() { + var self = this.self, + xtypes, parentPrototype, parentXtypes; - - Ext.Array.sort(c, function(a, b){ - var v = fn(a[property], b[property]) * dsc; - if(v === 0){ - v = (a.index < b.index ? -1 : 1); + if (!self.xtypes) { + xtypes = []; + parentPrototype = this; + + while (parentPrototype) { + parentXtypes = parentPrototype.xtypes; + + if (parentXtypes !== undefined) { + xtypes.unshift.apply(xtypes, parentXtypes); + } + + parentPrototype = parentPrototype.superclass; } - return v; - }); - - for(i = 0, len = c.length; i < len; i++){ - items[i] = c[i].value; - keys[i] = c[i].key; + self.xtypeChain = xtypes; + self.xtypes = xtypes.join('/'); } - me.fireEvent('sort', me); + return self.xtypes; }, - sortBy: function(sorterFn) { - var me = this, - items = me.items, - keys = me.keys, - length = items.length, - temp = [], - i; - - - for (i = 0; i < length; i++) { - temp[i] = { - key : keys[i], - value: items[i], - index: i - }; - } + update : function(htmlOrData, loadScripts, cb) { + var me = this; - Ext.Array.sort(temp, function(a, b) { - var v = sorterFn(a.value, b.value); - if (v === 0) { - v = (a.index < b.index ? -1 : 1); + if (me.tpl && !Ext.isString(htmlOrData)) { + me.data = htmlOrData; + if (me.rendered) { + me.tpl[me.tplWriteMode](me.getTargetEl(), htmlOrData || {}); } + } else { + me.html = Ext.isObject(htmlOrData) ? Ext.DomHelper.markup(htmlOrData) : htmlOrData; + if (me.rendered) { + me.getTargetEl().update(me.html, loadScripts, cb); + } + } - return v; - }); - - - for (i = 0; i < length; i++) { - items[i] = temp[i].value; - keys[i] = temp[i].key; + if (me.rendered) { + me.doComponentLayout(); } - - me.fireEvent('sort', me, items, keys); }, - reorder: function(mapping) { - var me = this, - items = me.items, - index = 0, - length = items.length, - order = [], - remaining = [], - oldIndex; + setVisible : function(visible) { + return this[visible ? 'show': 'hide'](); + }, - me.suspendEvents(); + + isVisible: function(deep) { + var me = this, + child = me, + visible = !me.hidden, + ancestor = me.ownerCt; - for (oldIndex in mapping) { - order[mapping[oldIndex]] = items[oldIndex]; + me.hiddenAncestor = false; + if (me.destroyed) { + return false; } - for (index = 0; index < length; index++) { - if (mapping[index] == undefined) { - remaining.push(items[index]); + if (deep && visible && me.rendered && ancestor) { + while (ancestor) { + + + + + if (ancestor.hidden || (ancestor.collapsed && + !(ancestor.getDockedItems && Ext.Array.contains(ancestor.getDockedItems(), child)))) { + + me.hiddenAncestor = ancestor; + visible = false; + break; + } + child = ancestor; + ancestor = ancestor.ownerCt; } } + return visible; + }, - for (index = 0; index < length; index++) { - if (order[index] == undefined) { - order[index] = remaining.shift(); - } + + enable: function(silent) { + var me = this; + + if (me.rendered) { + me.el.removeCls(me.disabledCls); + me.el.dom.disabled = false; + me.onEnable(); } - me.clear(); - me.addAll(order); + me.disabled = false; - me.resumeEvents(); - me.fireEvent('sort', me); + if (silent !== true) { + me.fireEvent('enable', me); + } + + return me; }, - sortByKey : function(dir, fn){ - this._sort('key', dir, fn || function(a, b){ - var v1 = String(a).toUpperCase(), v2 = String(b).toUpperCase(); - return v1 > v2 ? 1 : (v1 < v2 ? -1 : 0); - }); - } -}); + disable: function(silent) { + var me = this; + if (me.rendered) { + me.el.addCls(me.disabledCls); + me.el.dom.disabled = true; + me.onDisable(); + } -Ext.define('Ext.data.StoreManager', { - extend: 'Ext.util.MixedCollection', - alternateClassName: ['Ext.StoreMgr', 'Ext.data.StoreMgr', 'Ext.StoreManager'], - singleton: true, - uses: ['Ext.data.ArrayStore'], - - + me.disabled = true; + + if (silent !== true) { + me.fireEvent('disable', me); + } + + return me; + }, - register : function() { - for (var i = 0, s; (s = arguments[i]); i++) { - this.add(s); + onEnable: function() { + if (this.maskOnDisable) { + this.el.unmask(); } }, - unregister : function() { - for (var i = 0, s; (s = arguments[i]); i++) { - this.remove(this.lookup(s)); + onDisable : function() { + if (this.maskOnDisable) { + this.el.mask(); } }, - lookup : function(store) { - - if (Ext.isArray(store)) { - var fields = ['field1'], - expand = !Ext.isArray(store[0]), - data = store, - i, - len; - - if(expand){ - data = []; - for (i = 0, len = store.length; i < len; ++i) { - data.push([store[i]]); - } - } else { - for(i = 2, len = store[0].length; i <= len; ++i){ - fields.push('field' + i); - } - } - return Ext.create('Ext.data.ArrayStore', { - data : data, - fields: fields, - autoDestroy: true, - autoCreated: true, - expanded: expand - }); + isDisabled : function() { + return this.disabled; + }, + + + setDisabled : function(disabled) { + return this[disabled ? 'disable': 'enable'](); + }, + + + isHidden : function() { + return this.hidden; + }, + + + addCls : function(className) { + var me = this; + if (!className) { + return me; } - - if (Ext.isString(store)) { - - return this.get(store); - } else { - - return Ext.data.AbstractStore.create(store); + if (!Ext.isArray(className)){ + className = className.replace(me.trimRe, '').split(me.spacesRe); + } + if (me.rendered) { + me.el.addCls(className); + } + else { + me.additionalCls = Ext.Array.unique(me.additionalCls.concat(className)); } + return me; }, - getKey : function(o) { - return o.storeId; - } -}, function() { + addClass : function() { + return this.addCls.apply(this, arguments); + }, + - Ext.regStore = function(name, config) { - var store; + removeCls : function(className) { + var me = this; - if (Ext.isObject(name)) { - config = name; - } else { - config.storeId = name; + if (!className) { + return me; } + if (!Ext.isArray(className)){ + className = className.replace(me.trimRe, '').split(me.spacesRe); + } + if (me.rendered) { + me.el.removeCls(className); + } + else if (me.additionalCls.length) { + Ext.each(className, function(cls) { + Ext.Array.remove(me.additionalCls, cls); + }); + } + return me; + }, - if (config instanceof Ext.data.Store) { - store = config; - } else { - store = Ext.create('Ext.data.Store', config); + + addOverCls: function() { + var me = this; + if (!me.disabled) { + me.el.addCls(me.overCls); } + }, - return Ext.data.StoreManager.register(store); - }; + removeOverCls: function() { + this.el.removeCls(this.overCls); + }, - - Ext.getStore = function(name) { - return Ext.data.StoreManager.lookup(name); - }; -}); + addListener : function(element, listeners, scope, options) { + var me = this, + fn, + option; + if (Ext.isString(element) && (Ext.isObject(listeners) || options && options.element)) { + if (options.element) { + fn = listeners; + listeners = {}; + listeners[element] = fn; + element = options.element; + if (scope) { + listeners.scope = scope; + } -Ext.define('Ext.LoadMask', { + for (option in options) { + if (options.hasOwnProperty(option)) { + if (me.eventOptionsRe.test(option)) { + listeners[option] = options[option]; + } + } + } + } + + + + if (me[element] && me[element].on) { + me.mon(me[element], listeners); + } else { + me.afterRenderEvents = me.afterRenderEvents || {}; + if (!me.afterRenderEvents[element]) { + me.afterRenderEvents[element] = []; + } + me.afterRenderEvents[element].push(listeners); + } + } + + return me.mixins.observable.addListener.apply(me, arguments); + }, + removeManagedListenerItem: function(isClear, managedListener, item, ename, fn, scope){ + var me = this, + element = managedListener.options ? managedListener.options.element : null; - mixins: { - observable: 'Ext.util.Observable' + if (element) { + element = me[element]; + if (element && element.un) { + if (isClear || (managedListener.item === item && managedListener.ename === ename && (!fn || managedListener.fn === fn) && (!scope || managedListener.scope === scope))) { + element.un(managedListener.ename, managedListener.fn, managedListener.scope); + if (!isClear) { + Ext.Array.remove(me.managedListeners, managedListener); + } + } + } + } else { + return me.mixins.observable.removeManagedListenerItem.apply(me, arguments); + } }, - requires: ['Ext.data.StoreManager'], + + getBubbleTarget : function() { + return this.ownerCt; + }, + + + isFloating : function() { + return this.floating; + }, + isDraggable : function() { + return !!this.draggable; + }, + isDroppable : function() { + return !!this.droppable; + }, - msg : 'Loading...', + onAdded : function(container, pos) { + this.ownerCt = container; + this.fireEvent('added', this, container, pos); + }, + - msgCls : Ext.baseCSSPrefix + 'mask-loading', + onRemoved : function() { + var me = this; + + me.fireEvent('removed', me, me.ownerCt); + delete me.ownerCt; + }, + + beforeDestroy : Ext.emptyFn, - useMsg: true, + + onResize : Ext.emptyFn, - disabled: false, + setSize : function(width, height) { + var me = this, + layoutCollection; - constructor : function(el, config) { - var me = this; + + if (Ext.isObject(width)) { + height = width.height; + width = width.width; + } - if (el.isComponent) { - me.bindComponent(el); - } else { - me.el = Ext.get(el); + + if (Ext.isNumber(width)) { + width = Ext.Number.constrain(width, me.minWidth, me.maxWidth); + } + if (Ext.isNumber(height)) { + height = Ext.Number.constrain(height, me.minHeight, me.maxHeight); } - Ext.apply(me, config); - me.addEvents('beforeshow', 'show', 'hide'); - if (me.store) { - me.bindStore(me.store, true); + if (!me.rendered || !me.isVisible()) { + + if (me.hiddenAncestor) { + layoutCollection = me.hiddenAncestor.layoutOnShow; + layoutCollection.remove(me); + layoutCollection.add(me); + } + me.needsLayout = { + width: width, + height: height, + isSetSize: true + }; + if (!me.rendered) { + me.width = (width !== undefined) ? width : me.width; + me.height = (height !== undefined) ? height : me.height; + } + return me; } - me.mixins.observable.constructor.call(me, config); + me.doComponentLayout(width, height, true); + + return me; }, - bindComponent: function(comp) { + isFixedWidth: function() { var me = this, - listeners = { - resize: me.onComponentResize, - scope: me - }; + layoutManagedWidth = me.layoutManagedWidth; - if (comp.el) { - me.onComponentRender(comp); - } else { - listeners.render = { - fn: me.onComponentRender, - scope: me, - single: true - }; + if (Ext.isDefined(me.width) || layoutManagedWidth == 1) { + return true; + } + if (layoutManagedWidth == 2) { + return false; } - me.mon(comp, listeners); + return (me.ownerCt && me.ownerCt.isFixedWidth()); }, - - onComponentRender: function(comp) { - this.el = comp.getContentTarget(); - }, + isFixedHeight: function() { + var me = this, + layoutManagedHeight = me.layoutManagedHeight; - - onComponentResize: function(comp, w, h) { - this.el.isMasked(); + if (Ext.isDefined(me.height) || layoutManagedHeight == 1) { + return true; + } + if (layoutManagedHeight == 2) { + return false; + } + return (me.ownerCt && me.ownerCt.isFixedHeight()); }, - - bindStore : function(store, initial) { - var me = this; + setCalculatedSize : function(width, height, callingContainer) { + var me = this, + layoutCollection; - if (!initial && me.store) { - me.mun(me.store, { - scope: me, - beforeload: me.onBeforeLoad, - load: me.onLoad, - exception: me.onLoad - }); - if(!store) { - me.store = null; - } + + if (Ext.isObject(width)) { + callingContainer = width.ownerCt; + height = width.height; + width = width.width; } - if (store) { - store = Ext.data.StoreManager.lookup(store); - me.mon(store, { - scope: me, - beforeload: me.onBeforeLoad, - load: me.onLoad, - exception: me.onLoad - }); + + if (Ext.isNumber(width)) { + width = Ext.Number.constrain(width, me.minWidth, me.maxWidth); } - me.store = store; - if (store && store.isLoading()) { - me.onBeforeLoad(); + if (Ext.isNumber(height)) { + height = Ext.Number.constrain(height, me.minHeight, me.maxHeight); } - }, - - disable : function() { - var me = this; + if (!me.rendered || !me.isVisible()) { + + if (me.hiddenAncestor) { + layoutCollection = me.hiddenAncestor.layoutOnShow; + layoutCollection.remove(me); + layoutCollection.add(me); + } + me.needsLayout = { + width: width, + height: height, + isSetSize: false, + ownerCt: callingContainer + }; + return me; + } + me.doComponentLayout(width, height, false, callingContainer); - me.disabled = true; - if (me.loading) { - me.onLoad(); - } + return me; }, - enable : function() { - this.disabled = false; + doComponentLayout : function(width, height, isSetSize, callingContainer) { + var me = this, + componentLayout = me.getComponentLayout(), + lastComponentSize = componentLayout.lastComponentSize || { + width: undefined, + height: undefined + }; + + + + + if (me.rendered && componentLayout) { + + if (!Ext.isDefined(width)) { + if (me.isFixedWidth()) { + width = Ext.isDefined(me.width) ? me.width : lastComponentSize.width; + } + } + + 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, callingContainer); + } + + return me; }, - isDisabled : function() { - return this.disabled; + forceComponentLayout: function () { + this.doComponentLayout(); }, - onLoad : function() { - var me = this; - - me.loading = false; - me.el.unmask(); - me.fireEvent('hide', me, me.el, me.store); + setComponentLayout : function(layout) { + var currentLayout = this.componentLayout; + if (currentLayout && currentLayout.isLayout && currentLayout != layout) { + currentLayout.setOwner(null); + } + this.componentLayout = layout; + layout.setOwner(this); }, - - onBeforeLoad : function() { + getComponentLayout : function() { var me = this; - if (!me.disabled && !me.loading && me.fireEvent('beforeshow', me, me.el, me.store) !== false) { - if (me.useMsg) { - me.el.mask(me.msg, me.msgCls, false); - } else { - me.el.mask(); - } - - me.fireEvent('show', me, me.el, me.store); - me.loading = true; + if (!me.componentLayout || !me.componentLayout.isLayout) { + me.setComponentLayout(Ext.layout.Layout.create(me.componentLayout, 'autocomponent')); } + return me.componentLayout; }, - show: function() { - this.onBeforeLoad(); + afterComponentLayout: function(width, height, isSetSize, callingContainer) { + var me = this, + layout = me.componentLayout, + oldSize = me.preLayoutSize; + + ++me.componentLayoutCounter; + if (!oldSize || ((width !== oldSize.width) || (height !== oldSize.height))) { + me.fireEvent('resize', me, width, height); + } }, - hide: function() { - this.onLoad(); + beforeComponentLayout: function(width, height, isSetSize, callingContainer) { + this.preLayoutSize = this.componentLayout.lastComponentSize; + return true; }, - destroy : function() { - this.hide(); - this.clearListeners(); - } -}); + setPosition : function(x, y) { + var me = this; + if (Ext.isObject(x)) { + y = x.y; + x = x.x; + } -Ext.define('Ext.ComponentLoader', { + if (!me.rendered) { + return me; + } - - - extend: 'Ext.ElementLoader', - - statics: { - Renderer: { - Data: function(loader, response, active){ - var success = true; - try { - loader.getTarget().update(Ext.decode(response.responseText)); - } catch (e) { - success = false; - } - return success; - }, - - Component: function(loader, response, active){ - var success = true, - target = loader.getTarget(), - items = []; - - if (!target.isContainer) { - Ext.Error.raise({ - target: target, - msg: 'Components can only be loaded into a container' - }); - } - - try { - items = Ext.decode(response.responseText); - } catch (e) { - success = false; - } - - if (success) { - if (active.removeAll) { - target.removeAll(); - } - target.add(items); - } - return success; - } + if (x !== undefined || y !== undefined) { + me.el.setBox(x, y); + me.onPosition(x, y); + me.fireEvent('move', me, x, y); } + return me; }, + onPosition: Ext.emptyFn, - target: null, - - - loadMask: false, - - - - - renderer: 'html', - - - setTarget: function(target){ - var me = this; - - if (Ext.isString(target)) { - target = Ext.getCmp(target); - } - - if (me.target && me.target != target) { - me.abort(); - } - me.target = target; - }, - - - removeMask: function(){ - this.target.setLoading(false); - }, - - - addMask: function(mask){ - this.target.setLoading(mask); + setWidth : function(width) { + return this.setSize(width); }, - - setOptions: function(active, options){ - active.removeAll = Ext.isDefined(options.removeAll) ? options.removeAll : this.removeAll; + setHeight : function(height) { + return this.setSize(undefined, height); }, - getRenderer: function(renderer){ - if (Ext.isFunction(renderer)) { - return renderer; - } - - var renderers = this.statics().Renderer; - switch (renderer) { - case 'component': - return renderers.Component; - case 'data': - return renderers.Data; - default: - return Ext.ElementLoader.Renderer.Html; - } - } -}); - - - -Ext.define('Ext.layout.component.Auto', { - - - - alias: 'layout.autocomponent', - - extend: 'Ext.layout.component.Component', - - - - type: 'autocomponent', - - onLayout : function(width, height) { - this.setTargetSize(width, height); - } -}); - - -Ext.define('Ext.AbstractComponent', { + getSize : function() { + return this.el.getSize(); + }, - - mixins: { - observable: 'Ext.util.Observable', - animate: 'Ext.util.Animate', - state: 'Ext.state.Stateful' + getWidth : function() { + return this.el.getWidth(); }, - requires: [ - 'Ext.PluginManager', - 'Ext.ComponentManager', - 'Ext.core.Element', - 'Ext.core.DomHelper', - 'Ext.XTemplate', - 'Ext.ComponentQuery', - 'Ext.LoadMask', - 'Ext.ComponentLoader', - 'Ext.EventManager', - 'Ext.layout.Layout', - 'Ext.layout.component.Auto' - ], - - - uses: [ - 'Ext.ZIndexManager' - ], - - statics: { - AUTO_ID: 1000 + getHeight : function() { + return this.el.getHeight(); }, + getLoader: function(){ + var me = this, + autoLoad = me.autoLoad ? (Ext.isObject(me.autoLoad) ? me.autoLoad : {url: me.autoLoad}) : null, + loader = me.loader || autoLoad; - isComponent: true, + if (loader) { + if (!loader.isLoader) { + me.loader = Ext.create('Ext.ComponentLoader', Ext.apply({ + target: me, + autoLoad: autoLoad + }, loader)); + } else { + loader.setTarget(me); + } + return me.loader; - getAutoId: function() { - return ++Ext.AbstractComponent.AUTO_ID; + } + return null; }, + setLoading : function(load, targetEl) { + var me = this, + config; - - - + if (me.rendered) { + if (load !== false && !me.collapsed) { + if (Ext.isObject(load)) { + config = load; + } + else if (Ext.isString(load)) { + config = {msg: load}; + } + else { + config = {}; + } + me.loadMask = me.loadMask || Ext.create('Ext.LoadMask', targetEl ? me.getTargetEl() : me.el, config); + me.loadMask.show(); + } else if (me.loadMask) { + Ext.destroy(me.loadMask); + me.loadMask = null; + } + } - + return me.loadMask; + }, - renderTpl: null, + setDocked : function(dock, layoutParent) { + var me = this; - + me.dock = dock; + if (layoutParent && me.ownerCt && me.rendered) { + me.ownerCt.doComponentLayout(); + } + return me; + }, - + onDestroy : function() { + var me = this; - + if (me.monitorResize && Ext.EventManager.resizeEvent) { + Ext.EventManager.resizeEvent.removeListener(me.setSize, me); + } + + Ext.destroy( + me.componentLayout, + me.loadMask, + me.floatingItems + ); + }, + cleanElementRefs: function(){ + var me = this, + i = 0, + childEls = me.childEls, + selectors = me.renderSelectors, + selector, + name, + len; - + if (me.rendered) { + if (childEls) { + for (len = childEls.length; i < len; ++i) { + name = childEls[i]; + if (typeof(name) != 'string') { + name = name.name; + } + delete me[name]; + } + } - + if (selectors) { + for (selector in selectors) { + if (selectors.hasOwnProperty(selector)) { + delete me[selector]; + } + } + } + } + delete me.rendered; + delete me.el; + delete me.frameBody; + }, + destroy : function() { + var me = this; - - tplWriteMode: 'overwrite', + if (!me.isDestroyed) { + if (me.fireEvent('beforedestroy', me) !== false) { + me.destroying = true; + me.beforeDestroy(); - - baseCls: Ext.baseCSSPrefix + 'component', + if (me.floating) { + delete me.floatParent; + + + if (me.zIndexManager) { + me.zIndexManager.unregister(me); + } + } else if (me.ownerCt && me.ownerCt.remove) { + me.ownerCt.remove(me, false); + } - + me.onDestroy(); - + + Ext.destroy(me.plugins); - + if (me.rendered) { + me.el.remove(); + } - - disabledCls: Ext.baseCSSPrefix + 'item-disabled', + me.fireEvent('destroy', me); + Ext.ComponentManager.unregister(me); - - ui: 'default', - - - uiCls: [], - - + me.mixins.state.destroy.call(me); - + me.clearListeners(); + + me.cleanElementRefs(); + me.destroying = false; + me.isDestroyed = true; + } + } + }, + getPlugin: function(pluginId) { + var i = 0, + plugins = this.plugins, + ln = plugins.length; + for (; i < ln; i++) { + if (plugins[i].pluginId === pluginId) { + return plugins[i]; + } + } + }, + isDescendantOf: function(container) { + return !!this.findParentBy(function(p){ + return p === container; + }); + } +}, function() { + this.createAlias({ + on: 'addListener', + prev: 'previousSibling', + next: 'nextSibling' + }); +}); - - +Ext.define('Ext.AbstractPlugin', { + disabled: false, - - hidden: false, + constructor: function(config) { + Ext.apply(this, config); + }, - - disabled: false, + getCmp: function() { + return this.cmp; + }, + init: Ext.emptyFn, - draggable: false, + destroy: Ext.emptyFn, - floating: false, + enable: function() { + this.disabled = false; + }, - hideMode: 'display', + disable: function() { + this.disabled = true; + } +}); - +Ext.define('Ext.data.Connection', { + mixins: { + observable: 'Ext.util.Observable' + }, - + statics: { + requestId: 0 + }, - - styleHtmlContent: false, + url: null, + async: true, + method: null, + username: '', + password: '', - styleHtmlCls: Ext.baseCSSPrefix + 'html', + disableCaching: true, - - - + withCredentials: false, - - - allowDomMove: true, - - - autoShow: false, + cors: false, - autoRender: false, - - needsLayout: false, + disableCachingParam: '_dc', + timeout : 30000, - rendered: false, - - weight: 0, - trimRe: /^\s+|\s+$/g, - spacesRe: /\s+/, - - - - maskOnDisable: true, + useDefaultHeader : true, + defaultPostHeader : 'application/x-www-form-urlencoded; charset=UTF-8', + useDefaultXhrHeader : true, + defaultXhrHeader : 'XMLHttpRequest', constructor : function(config) { - var me = this, - i, len; - config = config || {}; - me.initialConfig = config; - Ext.apply(me, config); + Ext.apply(this, config); - me.addEvents( - - 'beforeactivate', - - 'activate', - - 'beforedeactivate', - - 'deactivate', - - 'added', - - 'disable', - - 'enable', - - 'beforeshow', - - 'show', - - 'beforehide', - - 'hide', - - 'removed', - - 'beforerender', - - 'render', - - 'afterrender', - - 'beforedestroy', + this.addEvents( - 'destroy', + 'beforerequest', - 'resize', + 'requestcomplete', - 'move' + 'requestexception' ); + this.requests = {}; + this.mixins.observable.constructor.call(this); + }, - me.getId(); + + request : function(options) { + options = options || {}; + var me = this, + scope = options.scope || window, + username = options.username || me.username, + password = options.password || me.password || '', + async, + requestOptions, + request, + headers, + xhr; - me.mons = []; - me.additionalCls = []; - me.renderData = me.renderData || {}; - me.renderSelectors = me.renderSelectors || {}; + if (me.fireEvent('beforerequest', me, options) !== false) { - if (me.plugins) { - me.plugins = [].concat(me.plugins); - for (i = 0, len = me.plugins.length; i < len; i++) { - me.plugins[i] = me.constructPlugin(me.plugins[i]); + requestOptions = me.setOptions(options, scope); + + if (this.isFormUpload(options) === true) { + this.upload(options.form, requestOptions.url, requestOptions.data, options); + return null; } - } - - me.initComponent(); - - Ext.ComponentManager.register(me); + + if (options.autoAbort === true || me.autoAbort) { + me.abort(); + } - - me.mixins.observable.constructor.call(me); - me.mixins.state.constructor.call(me, config); + - - if (me.plugins) { - me.plugins = [].concat(me.plugins); - for (i = 0, len = me.plugins.length; i < len; i++) { - me.plugins[i] = me.initPlugin(me.plugins[i]); + if ((options.cors === true || me.cors === true) && Ext.isIe && Ext.ieVersion >= 8) { + xhr = new XDomainRequest(); + } else { + xhr = this.getXhrInstance(); } - } - me.loader = me.getLoader(); + async = options.async !== false ? (options.async || me.async) : false; - if (me.renderTo) { - me.render(me.renderTo); + if (username) { + xhr.open(requestOptions.method, requestOptions.url, async, username, password); + } else { + xhr.open(requestOptions.method, requestOptions.url, async); + } + + if (options.withCredentials === true || me.withCredentials === true) { + xhr.withCredentials = true; + } + + headers = me.setupHeaders(xhr, options, requestOptions.data, requestOptions.params); + + request = { + id: ++Ext.data.Connection.requestId, + xhr: xhr, + headers: headers, + options: options, + async: async, + timeout: setTimeout(function() { + request.timedout = true; + me.abort(request); + }, options.timeout || me.timeout) + }; + me.requests[request.id] = request; + me.latestId = request.id; - } + if (async) { + xhr.onreadystatechange = Ext.Function.bind(me.onStateChange, me, [request]); + } - if (me.autoShow) { - me.show(); - } - - if (Ext.isDefined(me.disabledClass)) { - if (Ext.isDefined(Ext.global.console)) { - Ext.global.console.warn('Ext.Component: disabledClass has been deprecated. Please use disabledCls.'); + + xhr.send(requestOptions.data); + if (!async) { + return this.onComplete(request); } - me.disabledCls = me.disabledClass; - delete me.disabledClass; + return request; + } else { + Ext.callback(options.callback, options.scope, [options, undefined, undefined]); + return null; } }, - initComponent: Ext.emptyFn, - - show: Ext.emptyFn, + + upload: function(form, url, params, options) { + form = Ext.getDom(form); + options = options || {}; - animate: function(animObj) { - var me = this, - to; + var id = Ext.id(), + frame = document.createElement('iframe'), + hiddens = [], + encoding = 'multipart/form-data', + buf = { + target: form.target, + method: form.method, + encoding: form.encoding, + enctype: form.enctype, + action: form.action + }, hiddenItem; - animObj = animObj || {}; - to = animObj.to || {}; + + Ext.fly(frame).set({ + id: id, + name: id, + cls: Ext.baseCSSPrefix + 'hide-display', + src: Ext.SSL_SECURE_URL + }); - if (Ext.fx.Manager.hasFxBlock(me.id)) { - return me; + document.body.appendChild(frame); + + + if (document.frames) { + document.frames[id].name = id; } + + Ext.fly(form).set({ + target: id, + method: 'POST', + enctype: encoding, + encoding: encoding, + action: url || buf.action + }); + - if (!animObj.dynamic && (to.height || to.width)) { - var curWidth = me.getWidth(), - w = curWidth, - curHeight = me.getHeight(), - h = curHeight, - needsResize = false; + if (params) { + Ext.iterate(Ext.Object.fromQueryString(params), function(name, value){ + hiddenItem = document.createElement('input'); + Ext.fly(hiddenItem).set({ + type: 'hidden', + value: value, + name: name + }); + form.appendChild(hiddenItem); + hiddens.push(hiddenItem); + }); + } - if (to.height && to.height > curHeight) { - h = to.height; - needsResize = true; - } - if (to.width && to.width > curWidth) { - w = to.width; - needsResize = true; - } + Ext.fly(frame).on('load', Ext.Function.bind(this.onUploadComplete, this, [frame, options]), null, {single: true}); + form.submit(); + Ext.fly(form).set(buf); + Ext.each(hiddens, function(h) { + Ext.removeNode(h); + }); + }, + + + onUploadComplete: function(frame, options) { + var me = this, - - - if (needsResize) { - var clearWidth = !Ext.isNumber(me.width), - clearHeight = !Ext.isNumber(me.height); + response = { + responseText: '', + responseXML: null + }, doc, firstChild; - me.componentLayout.childrenChanged = true; - me.setSize(w, h, me.ownerCt); - me.el.setSize(curWidth, curHeight); - if (clearWidth) { - delete me.width; - } - if (clearHeight) { - delete me.height; + try { + doc = frame.contentWindow.document || frame.contentDocument || window.frames[frame.id].document; + if (doc) { + if (doc.body) { + if (/textarea/i.test((firstChild = doc.body.firstChild || {}).tagName)) { + response.responseText = firstChild.value; + } else { + response.responseText = doc.body.innerHTML; + } } + + response.responseXML = doc.XMLDocument || doc; } + } catch (e) { } - return me.mixins.animate.animate.apply(me, arguments); - }, - - findLayoutController: function() { - return this.findParentBy(function(c) { - - - return !c.ownerCt || (c.layout.layoutBusy && !c.ownerCt.layout.layoutBusy); - }); - }, + me.fireEvent('requestcomplete', me, response, options); - onShow : function() { - - var needsLayout = this.needsLayout; - if (Ext.isObject(needsLayout)) { - this.doComponentLayout(needsLayout.width, needsLayout.height, needsLayout.isSetSize, needsLayout.ownerCt); - } + Ext.callback(options.success, options.scope, [response, options]); + Ext.callback(options.callback, options.scope, [options, true, response]); + + setTimeout(function(){ + Ext.removeNode(frame); + }, 100); }, - constructPlugin: function(plugin) { - if (plugin.ptype && typeof plugin.init != 'function') { - plugin.cmp = this; - plugin = Ext.PluginManager.create(plugin); - } - else if (typeof plugin == 'string') { - plugin = Ext.PluginManager.create({ - ptype: plugin, - cmp: this - }); + + isFormUpload: function(options){ + var form = this.getForm(options); + if (form) { + return (options.isUpload || (/multipart\/form-data/i).test(form.getAttribute('enctype'))); } - return plugin; + return false; }, - initPlugin : function(plugin) { - plugin.init(this); - - return plugin; + getForm: function(options){ + return Ext.getDom(options.form) || null; }, - doAutoRender: function() { - var me = this; - if (me.floating) { - me.render(document.body); - } else { - me.render(Ext.isBoolean(me.autoRender) ? Ext.getBody() : me.autoRender); + setOptions: function(options, scope){ + var me = this, + params = options.params || {}, + extraParams = me.extraParams, + urlParams = options.urlParams, + url = options.url || me.url, + jsonData = options.jsonData, + method, + disableCache, + data; + + + + if (Ext.isFunction(params)) { + params = params.call(scope, options); } - }, - - render : function(container, position) { - var me = this; + + if (Ext.isFunction(url)) { + url = url.call(scope, options); + } - if (!me.rendered && me.fireEvent('beforerender', me) !== false) { - - - if (me.el) { - me.el = Ext.get(me.el); - } + url = this.setupUrl(options, url); - - if (me.floating) { - me.onFloatRender(); - } - container = me.initContainer(container); + + data = options.rawData || options.xmlData || jsonData || null; + if (jsonData && !Ext.isPrimitive(jsonData)) { + data = Ext.encode(data); + } - me.onRender(container, position); + + if (Ext.isObject(params)) { + params = Ext.Object.toQueryString(params); + } - - - me.el.setVisibilityMode(Ext.core.Element[me.hideMode.toUpperCase()]); + if (Ext.isObject(extraParams)) { + extraParams = Ext.Object.toQueryString(extraParams); + } - if (me.overCls) { - me.el.hover(me.addOverCls, me.removeOverCls, me); - } + params = params + ((extraParams) ? ((params) ? '&' : '') + extraParams : ''); - me.fireEvent('render', me); + urlParams = Ext.isObject(urlParams) ? Ext.Object.toQueryString(urlParams) : urlParams; - me.initContent(); + params = this.setupParams(options, params); - me.afterRender(container); - me.fireEvent('afterrender', me); + + method = (options.method || me.method || ((params || data) ? 'POST' : 'GET')).toUpperCase(); + this.setupMethod(options, method); - me.initEvents(); - if (me.hidden) { - - - - me.el.hide(); - } + disableCache = options.disableCaching !== false ? (options.disableCaching || me.disableCaching) : false; + + if (method === 'GET' && disableCache) { + url = Ext.urlAppend(url, (options.disableCachingParam || me.disableCachingParam) + '=' + (new Date().getTime())); + } - if (me.disabled) { - - me.disable(true); - } + + if ((method == 'GET' || data) && params) { + url = Ext.urlAppend(url, params); + params = null; } - return me; + + + if (urlParams) { + url = Ext.urlAppend(url, urlParams); + } + + return { + url: url, + method: method, + data: data || params || null + }; }, - onRender : function(container, position) { - var me = this, - el = me.el, - cls = me.initCls(), - styles = me.initStyles(), - renderTpl, renderData, i; + setupUrl: function(options, url){ + var form = this.getForm(options); + if (form) { + url = url || form.action; + } + return url; + }, - position = me.getInsertPosition(position); - if (!el) { - if (position) { - el = Ext.core.DomHelper.insertBefore(position, me.getElConfig(), true); - } - else { - el = Ext.core.DomHelper.append(container, me.getElConfig(), true); - } + + setupParams: function(options, params) { + var form = this.getForm(options), + serializedForm; + if (form && !this.isFormUpload(options)) { + serializedForm = Ext.Element.serializeForm(form); + params = params ? (params + '&' + serializedForm) : serializedForm; } - else if (me.allowDomMove !== false) { - if (position) { - container.dom.insertBefore(el.dom, position); - } else { - container.dom.appendChild(el.dom); - } + return params; + }, + + + setupMethod: function(options, method){ + if (this.isFormUpload(options)) { + return 'POST'; } + return method; + }, - if (Ext.scopeResetCSS && !me.ownerCt) { - - if (el.dom == Ext.getBody().dom) { - el.parent().addCls(Ext.baseCSSPrefix + 'reset'); - } - else { - - me.resetEl = el.wrap({ - cls: Ext.baseCSSPrefix + 'reset' - }); + + setupHeaders: function(xhr, options, data, params){ + var me = this, + headers = Ext.apply({}, options.headers || {}, me.defaultHeaders || {}), + contentType = me.defaultPostHeader, + jsonData = options.jsonData, + xmlData = options.xmlData, + key, + header; + + if (!headers['Content-Type'] && (data || params)) { + if (data) { + if (options.rawData) { + contentType = 'text/plain'; + } else { + if (xmlData && Ext.isDefined(xmlData)) { + contentType = 'text/xml'; + } else if (jsonData && Ext.isDefined(jsonData)) { + contentType = 'application/json'; + } + } } + headers['Content-Type'] = contentType; } - el.addCls(cls); - el.setStyle(styles); - - - - - - - - - - + if (me.useDefaultXhrHeader && !headers['X-Requested-With']) { + headers['X-Requested-With'] = me.defaultXhrHeader; + } + try{ + for (key in headers) { + if (headers.hasOwnProperty(key)) { + header = headers[key]; + xhr.setRequestHeader(key, header); + } - me.el = el; - - me.rendered = true; - me.addUIToElement(true); - - for (i = 0; i < me.uiCls.length; i++) { - me.addUIClsToElement(me.uiCls[i], true); + } + } catch(e) { + me.fireEvent('exception', key, header); } - me.rendered = false; - me.initFrame(); + return headers; + }, - renderTpl = me.initRenderTpl(); - if (renderTpl) { - renderData = me.initRenderData(); - renderTpl.append(me.getTargetEl(), renderData); + + getXhrInstance: (function(){ + var options = [function(){ + return new XMLHttpRequest(); + }, function(){ + return new ActiveXObject('MSXML2.XMLHTTP.3.0'); + }, function(){ + return new ActiveXObject('MSXML2.XMLHTTP'); + }, function(){ + return new ActiveXObject('Microsoft.XMLHTTP'); + }], i = 0, + len = options.length, + xhr; + + for(; i < len; ++i) { + try{ + xhr = options[i]; + xhr(); + break; + }catch(e){} } + return xhr; + })(), - me.applyRenderSelectors(); - - me.rendered = true; + + isLoading : function(request) { + if (!request) { + request = this.getLatest(); + } + if (!(request && request.xhr)) { + return false; + } - me.setUI(me.ui); + var state = request.xhr.readyState; + return !(state === 0 || state == 4); }, - afterRender : function() { - var me = this, - pos, - xy; - - me.getComponentLayout(); - + abort : function(request) { + var me = this; - if (!me.ownerCt || (me.height || me.width)) { - me.setSize(me.width, me.height); + if (!request) { + request = me.getLatest(); } + if (request && me.isLoading(request)) { + + request.xhr.onreadystatechange = null; + request.xhr.abort(); + me.clearTimeout(request); + if (!request.timedout) { + request.aborted = true; + } + me.onComplete(request); + me.cleanup(request); + } + }, + + + abortAll: function(){ + var requests = this.requests, + id; - - if (me.floating && (me.x === undefined || me.y === undefined)) { - if (me.floatParent) { - xy = me.el.getAlignToXY(me.floatParent.getTargetEl(), 'c-c'); - pos = me.floatParent.getTargetEl().translatePoints(xy[0], xy[1]); - } else { - xy = me.el.getAlignToXY(me.container, 'c-c'); - pos = me.container.translatePoints(xy[0], xy[1]); + for (id in requests) { + if (requests.hasOwnProperty(id)) { + this.abort(requests[id]); } - me.x = me.x === undefined ? pos.left: me.x; - me.y = me.y === undefined ? pos.top: me.y; } - - if (Ext.isDefined(me.x) || Ext.isDefined(me.y)) { - me.setPosition(me.x, me.y); + }, + + + getLatest: function(){ + var id = this.latestId, + request; + + if (id) { + request = this.requests[id]; } + return request || null; + }, - if (me.styleHtmlContent) { - me.getTargetEl().addCls(me.styleHtmlCls); + + onStateChange : function(request) { + if (request.xhr.readyState == 4) { + this.clearTimeout(request); + this.onComplete(request); + this.cleanup(request); } }, - frameCls: Ext.baseCSSPrefix + 'frame', - - frameTpl: [ - '', - '
{parent.baseCls}-{parent.ui}-{.}-tl" style="background-position: {tl}; padding-left: {frameWidth}px" role="presentation">', - '
{parent.baseCls}-{parent.ui}-{.}-tr" style="background-position: {tr}; padding-right: {frameWidth}px" role="presentation">', - '
{parent.baseCls}-{parent.ui}-{.}-tc" style="background-position: {tc}; height: {frameWidth}px" role="presentation">
', - '
', - '
', - '
', - '
{parent.baseCls}-{parent.ui}-{.}-ml" style="background-position: {ml}; padding-left: {frameWidth}px" role="presentation">', - '
{parent.baseCls}-{parent.ui}-{.}-mr" style="background-position: {mr}; padding-right: {frameWidth}px" role="presentation">', - '
{parent.baseCls}-{parent.ui}-{.}-mc" role="presentation">
', - '
', - '
', - '', - '
{parent.baseCls}-{parent.ui}-{.}-bl" style="background-position: {bl}; padding-left: {frameWidth}px" role="presentation">', - '
{parent.baseCls}-{parent.ui}-{.}-br" style="background-position: {br}; padding-right: {frameWidth}px" role="presentation">', - '
{parent.baseCls}-{parent.ui}-{.}-bc" style="background-position: {bc}; height: {frameWidth}px" role="presentation">
', - '
', - '
', - '
' - ], + + clearTimeout: function(request){ + clearTimeout(request.timeout); + delete request.timeout; + }, - frameTableTpl: [ - '', - '', - '', - '', - '', - '', - '', - '', - '', - '', - '', - '', - '', - '', - '', - '', - '', - '', - '', - '', - '
{parent.baseCls}-{parent.ui}-{.}-tl" style="background-position: {tl}; padding-left:{frameWidth}px" role="presentation"> {parent.baseCls}-{parent.ui}-{.}-tc" style="background-position: {tc}; height: {frameWidth}px" role="presentation"> {parent.baseCls}-{parent.ui}-{.}-tr" style="background-position: {tr}; padding-left: {frameWidth}px" role="presentation">
{parent.baseCls}-{parent.ui}-{.}-ml" style="background-position: {ml}; padding-left: {frameWidth}px" role="presentation"> {parent.baseCls}-{parent.ui}-{.}-mc" style="background-position: 0 0;" role="presentation"> {parent.baseCls}-{parent.ui}-{.}-mr" style="background-position: {mr}; padding-left: {frameWidth}px" role="presentation">
{parent.baseCls}-{parent.ui}-{.}-bl" style="background-position: {bl}; padding-left: {frameWidth}px" role="presentation"> {parent.baseCls}-{parent.ui}-{.}-bc" style="background-position: {bc}; height: {frameWidth}px" role="presentation"> {parent.baseCls}-{parent.ui}-{.}-br" style="background-position: {br}; padding-left: {frameWidth}px" role="presentation">
' - ], + cleanup: function(request){ + request.xhr = null; + delete request.xhr; + }, + - initFrame : function() { - if (Ext.supports.CSS3BorderRadius) { - return false; - } - + onComplete : function(request) { var me = this, - frameInfo = me.getFrameInfo(), - frameWidth = frameInfo.width, - frameTpl = me.getFrameTpl(frameInfo.table); - - if (me.frame) { - - frameTpl.insertFirst(me.el, Ext.apply({}, { - ui: me.ui, - uiCls: me.uiCls, - frameCls: me.frameCls, - baseCls: me.baseCls, - frameWidth: frameWidth, - top: !!frameInfo.top, - left: !!frameInfo.left, - right: !!frameInfo.right, - bottom: !!frameInfo.bottom - }, me.getFramePositions(frameInfo))); + options = request.options, + result, + success, + response; + try { + result = me.parseStatus(request.xhr.status); + } catch (e) { - me.frameBody = me.el.down('.' + me.frameCls + '-mc'); - - - Ext.apply(me.renderSelectors, { - frameTL: '.' + me.baseCls + '-tl', - frameTC: '.' + me.baseCls + '-tc', - frameTR: '.' + me.baseCls + '-tr', - frameML: '.' + me.baseCls + '-ml', - frameMC: '.' + me.baseCls + '-mc', - frameMR: '.' + me.baseCls + '-mr', - frameBL: '.' + me.baseCls + '-bl', - frameBC: '.' + me.baseCls + '-bc', - frameBR: '.' + me.baseCls + '-br' - }); - } - }, - - updateFrame: function() { - if (Ext.supports.CSS3BorderRadius) { - return false; + result = { + success : false, + isException : false + }; } - - var me = this, - wasTable = this.frameSize && this.frameSize.table, - oldFrameTL = this.frameTL, - oldFrameBL = this.frameBL, - oldFrameML = this.frameML, - oldFrameMC = this.frameMC, - newMCClassName; - - this.initFrame(); - - if (oldFrameMC) { - if (me.frame) { - - delete me.frameTL; - delete me.frameTC; - delete me.frameTR; - delete me.frameML; - delete me.frameMC; - delete me.frameMR; - delete me.frameBL; - delete me.frameBC; - delete me.frameBR; - this.applyRenderSelectors(); - - - newMCClassName = this.frameMC.dom.className; - - - oldFrameMC.insertAfter(this.frameMC); - this.frameMC.remove(); - - - this.frameBody = this.frameMC = oldFrameMC; - - - oldFrameMC.dom.className = newMCClassName; - - - if (wasTable) { - me.el.query('> table')[1].remove(); - } - else { - if (oldFrameTL) { - oldFrameTL.remove(); - } - if (oldFrameBL) { - oldFrameBL.remove(); - } - oldFrameML.remove(); - } - } - else { - - + success = result.success; + + if (success) { + response = me.createResponse(request); + me.fireEvent('requestcomplete', me, response, options); + Ext.callback(options.success, options.scope, [response, options]); + } else { + if (result.isException || request.aborted || request.timedout) { + response = me.createException(request); + } else { + response = me.createResponse(request); } + me.fireEvent('requestexception', me, response, options); + Ext.callback(options.failure, options.scope, [response, options]); } - else if (me.frame) { - this.applyRenderSelectors(); - } + Ext.callback(options.callback, options.scope, [options, success, response]); + delete me.requests[request.id]; + return response; }, + - getFrameInfo: function() { - if (Ext.supports.CSS3BorderRadius) { - return false; - } + parseStatus: function(status) { - var me = this, - left = me.el.getStyle('background-position-x'), - top = me.el.getStyle('background-position-y'), - info, frameInfo = false, max; + status = status == 1223 ? 204 : status; - - - if (!left && !top) { - info = me.el.getStyle('background-position').split(' '); - left = info[0]; - top = info[1]; - } - - - - - if (parseInt(left, 10) >= 1000000 && parseInt(top, 10) >= 1000000) { - max = Math.max; - - frameInfo = { - - table: left.substr(0, 3) == '110', - - - vertical: top.substr(0, 3) == '110', - - - top: max(left.substr(3, 2), left.substr(5, 2)), - right: max(left.substr(5, 2), top.substr(3, 2)), - bottom: max(top.substr(3, 2), top.substr(5, 2)), - left: max(top.substr(5, 2), left.substr(3, 2)) - }; - - frameInfo.width = max(frameInfo.top, frameInfo.right, frameInfo.bottom, frameInfo.left); + var success = (status >= 200 && status < 300) || status == 304, + isException = false; - - me.el.setStyle('background-image', 'none'); - } - - - - if (me.frame === true && !frameInfo) { - Ext.Error.raise("You have set frame: true explicity on this component while it doesn't have any " + - "framing defined in the CSS template. In this case IE can't figure out what sizes " + - "to use and thus framing on this component will be disabled."); + if (!success) { + switch (status) { + case 12002: + case 12029: + case 12030: + case 12031: + case 12152: + case 13030: + isException = true; + break; + } } - - me.frame = me.frame || !!frameInfo; - me.frameSize = frameInfo || false; - - return frameInfo; + return { + success: success, + isException: isException + }; }, - - getFramePositions: function(frameInfo) { - var me = this, - frameWidth = frameInfo.width, - dock = me.dock, - positions, tc, bc, ml, mr; - - if (frameInfo.vertical) { - tc = '0 -' + (frameWidth * 0) + 'px'; - bc = '0 -' + (frameWidth * 1) + 'px'; - - if (dock && dock == "right") { - tc = 'right -' + (frameWidth * 0) + 'px'; - bc = 'right -' + (frameWidth * 1) + 'px'; - } - - positions = { - tl: '0 -' + (frameWidth * 0) + 'px', - tr: '0 -' + (frameWidth * 1) + 'px', - bl: '0 -' + (frameWidth * 2) + 'px', - br: '0 -' + (frameWidth * 3) + 'px', - ml: '-' + (frameWidth * 1) + 'px 0', - mr: 'right 0', + + createResponse : function(request) { + var xhr = request.xhr, + headers = {}, + lines = xhr.getAllResponseHeaders().replace(/\r\n/g, '\n').split('\n'), + count = lines.length, + line, index, key, value, response; - tc: tc, - bc: bc - }; - } else { - ml = '-' + (frameWidth * 0) + 'px 0'; - mr = 'right 0'; - - if (dock && dock == "bottom") { - ml = 'left bottom'; - mr = 'right bottom'; + while (count--) { + line = lines[count]; + index = line.indexOf(':'); + if(index >= 0) { + key = line.substr(0, index).toLowerCase(); + if (line.charAt(index + 1) == ' ') { + ++index; + } + headers[key] = line.substr(index + 1); } - - positions = { - tl: '0 -' + (frameWidth * 2) + 'px', - tr: 'right -' + (frameWidth * 3) + 'px', - bl: '0 -' + (frameWidth * 4) + 'px', - br: 'right -' + (frameWidth * 5) + 'px', + } - ml: ml, - mr: mr, + request.xhr = null; + delete request.xhr; + + response = { + request: request, + requestId : request.id, + status : xhr.status, + statusText : xhr.statusText, + getResponseHeader : function(header){ return headers[header.toLowerCase()]; }, + getAllResponseHeaders : function(){ return headers; }, + responseText : xhr.responseText, + responseXML : xhr.responseXML + }; - tc: '0 -' + (frameWidth * 0) + 'px', - bc: '0 -' + (frameWidth * 1) + 'px' - }; - } - return positions; - }, - - - getFrameTpl : function(table) { - return table ? this.getTpl('frameTableTpl') : this.getTpl('frameTpl'); + + xhr = null; + return response; }, - initCls: function() { - var me = this, - cls = []; - - cls.push(me.baseCls); + createException : function(request) { + return { + request : request, + requestId : request.id, + status : request.aborted ? -1 : 0, + statusText : request.aborted ? 'transaction aborted' : 'communication failure', + aborted: request.aborted, + timedout: request.timedout + }; + } +}); - if (Ext.isDefined(me.cmpCls)) { - if (Ext.isDefined(Ext.global.console)) { - Ext.global.console.warn('Ext.Component: cmpCls has been deprecated. Please use componentCls.'); - } - me.componentCls = me.cmpCls; - delete me.cmpCls; - } - if (me.componentCls) { - cls.push(me.componentCls); - } else { - me.componentCls = me.baseCls; - } - if (me.cls) { - cls.push(me.cls); - delete me.cls; - } +Ext.define('Ext.Ajax', { + extend: 'Ext.data.Connection', + singleton: true, - return cls.concat(me.additionalCls); - }, - setUI: function(ui) { - var me = this, - oldUICls = Ext.Array.clone(me.uiCls), - newUICls = [], - cls, - i; - - - for (i = 0; i < oldUICls.length; i++) { - cls = oldUICls[i]; - - me.removeClsWithUI(cls); - newUICls.push(cls); - } - - - me.removeUIFromElement(); - - - me.ui = ui; - - - me.addUIToElement(); - - - for (i = 0; i < newUICls.length; i++) { - cls = newUICls[i]; - - me.addClsWithUI(cls); - } - }, - addClsWithUI: function(cls) { - var me = this, - i; - - if (!Ext.isArray(cls)) { - cls = [cls]; - } - - for (i = 0; i < cls.length; i++) { - if (cls[i] && !me.hasUICls(cls[i])) { - me.uiCls = Ext.Array.clone(me.uiCls); - me.uiCls.push(cls[i]); - me.addUIClsToElement(cls[i]); - } - } - }, - removeClsWithUI: function(cls) { - var me = this, - i; - - if (!Ext.isArray(cls)) { - cls = [cls]; - } - - for (i = 0; i < cls.length; i++) { - if (cls[i] && me.hasUICls(cls[i])) { - me.uiCls = Ext.Array.remove(me.uiCls, cls[i]); - me.removeUIClsFromElement(cls[i]); - } - } - }, + + - hasUICls: function(cls) { - var me = this, - uiCls = me.uiCls || []; - - return Ext.Array.contains(uiCls, cls); - }, - addUIClsToElement: function(cls, force) { - var me = this; - - me.addCls(Ext.baseCSSPrefix + cls); - me.addCls(me.baseCls + '-' + cls); - me.addCls(me.baseCls + '-' + me.ui + '-' + cls); - - if (!force && me.rendered && me.frame && !Ext.supports.CSS3BorderRadius) { - - var els = ['tl', 'tc', 'tr', 'ml', 'mc', 'mr', 'bl', 'bc', 'br'], - i, el; - - - for (i = 0; i < els.length; i++) { - el = me['frame' + els[i].toUpperCase()]; - - if (el && el.dom) { - el.addCls(me.baseCls + '-' + me.ui + '-' + els[i]); - el.addCls(me.baseCls + '-' + me.ui + '-' + cls + '-' + els[i]); - } - } - } - }, - removeUIClsFromElement: function(cls, force) { - var me = this; - - me.removeCls(Ext.baseCSSPrefix + cls); - me.removeCls(me.baseCls + '-' + cls); - me.removeCls(me.baseCls + '-' + me.ui + '-' + cls); - - if (!force &&me.rendered && me.frame && !Ext.supports.CSS3BorderRadius) { - - var els = ['tl', 'tc', 'tr', 'ml', 'mc', 'mr', 'bl', 'bc', 'br'], - i, el; - - - for (i = 0; i < els.length; i++) { - el = me['frame' + els[i].toUpperCase()]; - if (el && el.dom) { - el.removeCls(me.baseCls + '-' + me.ui + '-' + cls + '-' + els[i]); - } - } - } - }, + - addUIToElement: function(force) { - var me = this; - - me.addCls(me.baseCls + '-' + me.ui); - - if (me.rendered && me.frame && !Ext.supports.CSS3BorderRadius) { - - var els = ['tl', 'tc', 'tr', 'ml', 'mc', 'mr', 'bl', 'bc', 'br'], - i, el; - - - for (i = 0; i < els.length; i++) { - el = me['frame' + els[i].toUpperCase()]; - - if (el) { - el.addCls(me.baseCls + '-' + me.ui + '-' + els[i]); - } + autoAbort : false +}); + +Ext.define('Ext.ElementLoader', { + + + + mixins: { + observable: 'Ext.util.Observable' + }, + + uses: [ + 'Ext.data.Connection', + 'Ext.Ajax' + ], + + statics: { + Renderer: { + Html: function(loader, response, active){ + loader.getTarget().update(response.responseText, active.scripts === true); + return true; } } }, + + - removeUIFromElement: function() { - var me = this; - - me.removeCls(me.baseCls + '-' + me.ui); - - if (me.rendered && me.frame && !Ext.supports.CSS3BorderRadius) { - - var els = ['tl', 'tc', 'tr', 'ml', 'mc', 'mr', 'bl', 'bc', 'br'], - i, el; - - - for (i = 0; i < els.length; i++) { - el = me['frame' + els[i].toUpperCase()]; - if (el) { - el.removeCls(me.baseCls + '-' + me.ui + '-' + els[i]); - } - } - } - }, + url: null, + - getElConfig : function() { - var result = this.autoEl || {tag: 'div'}; - result.id = this.id; - return result; - }, + params: null, - getInsertPosition: function(position) { - - if (position !== undefined) { - if (Ext.isNumber(position)) { - position = this.container.dom.childNodes[position]; - } - else { - position = Ext.getDom(position); - } - } + baseParams: null, - return position; - }, + + autoLoad: false, - initContainer: function(container) { - var me = this; + target: null, - - - - if (!container && me.el) { - container = me.el.dom.parentNode; - me.allowDomMove = false; - } + + loadMask: false, - me.container = Ext.get(container); + + ajaxOptions: null, - if (me.ctCls) { - me.container.addCls(me.ctCls); - } + + scripts: false, - return me.container; - }, + - initRenderData: function() { - var me = this; - return Ext.applyIf(me.renderData, { - ui: me.ui, - uiCls: me.uiCls, - baseCls: me.baseCls, - componentCls: me.componentCls, - frame: me.frame - }); - }, + - getTpl: function(name) { - var prototype = this.self.prototype, - ownerPrototype; - if (this.hasOwnProperty(name)) { - if (!(this[name] instanceof Ext.XTemplate)) { - this[name] = Ext.ClassManager.dynInstantiate('Ext.XTemplate', this[name]); - } + - return this[name]; - } + isLoader: true, - if (!(prototype[name] instanceof Ext.XTemplate)) { - ownerPrototype = prototype; + constructor: function(config) { + var me = this, + autoLoad; - do { - if (ownerPrototype.hasOwnProperty(name)) { - ownerPrototype[name] = Ext.ClassManager.dynInstantiate('Ext.XTemplate', ownerPrototype[name]); - break; - } + config = config || {}; + Ext.apply(me, config); + me.setTarget(me.target); + me.addEvents( + + 'beforeload', - ownerPrototype = ownerPrototype.superclass; - } while (ownerPrototype); - } + + 'exception', - return prototype[name]; + + 'load' + ); + + + me.mixins.observable.constructor.call(me); + + if (me.autoLoad) { + autoLoad = me.autoLoad; + if (autoLoad === true) { + autoLoad = {}; + } + me.load(autoLoad); + } }, - initRenderTpl: function() { - return this.getTpl('renderTpl'); + setTarget: function(target){ + var me = this; + target = Ext.get(target); + if (me.target && me.target != target) { + me.abort(); + } + me.target = target; }, - initStyles: function() { - var style = {}, - me = this, - Element = Ext.core.Element; - - if (Ext.isString(me.style)) { - style = Element.parseStyles(me.style); - } else { - style = Ext.apply({}, me.style); - } + getTarget: function(){ + return this.target || null; + }, - - - if (me.padding !== undefined) { - style.padding = Element.unitizeBox((me.padding === true) ? 5 : me.padding); + + abort: function(){ + var active = this.active; + if (active !== undefined) { + Ext.Ajax.abort(active.request); + if (active.mask) { + this.removeMask(); + } + delete this.active; } + }, - if (me.margin !== undefined) { - style.margin = Element.unitizeBox((me.margin === true) ? 5 : me.margin); - } + + removeMask: function(){ + this.target.unmask(); + }, - delete me.style; - return style; + + addMask: function(mask){ + this.target.mask(mask === true ? null : mask); }, - initContent: function() { + load: function(options) { + + options = Ext.apply({}, options); + var me = this, - target = me.getTargetEl(), - contentEl, - pre; + target = me.target, + mask = Ext.isDefined(options.loadMask) ? options.loadMask : me.loadMask, + params = Ext.apply({}, options.params), + ajaxOptions = Ext.apply({}, options.ajaxOptions), + callback = options.callback || me.callback, + scope = options.scope || me.scope || me, + request; - if (me.html) { - target.update(Ext.core.DomHelper.markup(me.html)); - delete me.html; - } + Ext.applyIf(ajaxOptions, me.ajaxOptions); + Ext.applyIf(options, ajaxOptions); - if (me.contentEl) { - contentEl = Ext.get(me.contentEl); - pre = Ext.baseCSSPrefix; - contentEl.removeCls([pre + 'hidden', pre + 'hide-display', pre + 'hide-offsets', pre + 'hide-nosize']); - target.appendChild(contentEl.dom); - } + Ext.applyIf(params, me.params); + Ext.apply(params, me.baseParams); - if (me.tpl) { - - if (!me.tpl.isTemplate) { - me.tpl = Ext.create('Ext.XTemplate', me.tpl); - } + Ext.applyIf(options, { + url: me.url + }); - if (me.data) { - me.tpl[me.tplWriteMode](target, me.data); - delete me.data; - } + + Ext.apply(options, { + scope: me, + params: params, + callback: me.onComplete + }); + + if (me.fireEvent('beforeload', me, options) === false) { + return; + } + + if (mask) { + me.addMask(mask); } + + request = Ext.Ajax.request(options); + me.active = { + request: request, + options: options, + mask: mask, + scope: scope, + callback: callback, + success: options.success || me.success, + failure: options.failure || me.failure, + renderer: options.renderer || me.renderer, + scripts: Ext.isDefined(options.scripts) ? options.scripts : me.scripts + }; + me.setOptions(me.active, options); }, - initEvents : function() { + setOptions: Ext.emptyFn, + + + onComplete: function(options, success, response) { var me = this, - afterRenderEvents = me.afterRenderEvents, - property, listeners; - if (afterRenderEvents) { - for (property in afterRenderEvents) { - if (afterRenderEvents.hasOwnProperty(property)) { - listeners = afterRenderEvents[property]; - if (me[property] && me[property].on) { - me.mon(me[property], listeners); - } - } - } + active = me.active, + scope = active.scope, + renderer = me.getRenderer(active.renderer); + + + if (success) { + success = renderer.call(me, me, response, active); } - }, - - applyRenderSelectors: function() { - var selectors = this.renderSelectors || {}, - el = this.el.dom, - selector; + if (success) { + Ext.callback(active.success, scope, [me, response, options]); + me.fireEvent('load', me, response, options); + } else { + Ext.callback(active.failure, scope, [me, response, options]); + me.fireEvent('exception', me, response, options); + } + Ext.callback(active.callback, scope, [me, success, response, options]); - for (selector in selectors) { - if (selectors.hasOwnProperty(selector) && selectors[selector]) { - this[selector] = Ext.get(Ext.DomQuery.selectNode(selectors[selector], el)); - } + if (active.mask) { + me.removeMask(); } + + delete me.active; }, - is: function(selector) { - return Ext.ComponentQuery.is(this, selector); + getRenderer: function(renderer){ + if (Ext.isFunction(renderer)) { + return renderer; + } + return this.statics().Renderer.Html; }, - up: function(selector) { - var result = this.ownerCt; - if (selector) { - for (; result; result = result.ownerCt) { - if (Ext.ComponentQuery.is(result, selector)) { - return result; - } - } - } - return result; + startAutoRefresh: function(interval, options){ + var me = this; + me.stopAutoRefresh(); + me.autoRefresh = setInterval(function(){ + me.load(options); + }, interval); }, - nextSibling: function(selector) { - var o = this.ownerCt, it, last, idx, c; - if (o) { - it = o.items; - idx = it.indexOf(this) + 1; - if (idx) { - if (selector) { - for (last = it.getCount(); idx < last; idx++) { - if ((c = it.getAt(idx)).is(selector)) { - return c; - } - } - } else { - if (idx < it.getCount()) { - return it.getAt(idx); - } - } - } - } - return null; + stopAutoRefresh: function(){ + clearInterval(this.autoRefresh); + delete this.autoRefresh; }, - previousSibling: function(selector) { - var o = this.ownerCt, it, idx, c; - if (o) { - it = o.items; - idx = it.indexOf(this); - if (idx != -1) { - if (selector) { - for (--idx; idx >= 0; idx--) { - if ((c = it.getAt(idx)).is(selector)) { - return c; - } - } - } else { - if (idx) { - return it.getAt(--idx); - } - } - } - } - return null; + isAutoRefreshing: function(){ + return Ext.isDefined(this.autoRefresh); }, - previousNode: function(selector, includeSelf) { - var node = this, - result, - it, len, i; + destroy: function(){ + var me = this; + me.stopAutoRefresh(); + delete me.target; + me.abort(); + me.clearListeners(); + } +}); - - if (includeSelf && node.is(selector)) { - return node; - } - result = this.prev(selector); - if (result) { - return result; - } +Ext.define('Ext.ComponentLoader', { - if (node.ownerCt) { - for (it = node.ownerCt.items.items, i = Ext.Array.indexOf(it, node) - 1; i > -1; i--) { - if (it[i].query) { - result = it[i].query(selector); - result = result[result.length - 1]; - if (result) { - return result; - } + + + extend: 'Ext.ElementLoader', + + statics: { + Renderer: { + Data: function(loader, response, active){ + var success = true; + try { + loader.getTarget().update(Ext.decode(response.responseText)); + } catch (e) { + success = false; } - } - return node.ownerCt.previousNode(selector, true); - } - }, + return success; + }, - - nextNode: function(selector, includeSelf) { - var node = this, - result, - it, len, i; + Component: function(loader, response, active){ + var success = true, + target = loader.getTarget(), + items = []; - - if (includeSelf && node.is(selector)) { - return node; - } - result = this.next(selector); - if (result) { - return result; - } + try { + items = Ext.decode(response.responseText); + } catch (e) { + success = false; + } - if (node.ownerCt) { - for (it = node.ownerCt.items, i = it.indexOf(node) + 1, it = it.items, len = it.length; i < len; i++) { - if (it[i].down) { - result = it[i].down(selector); - if (result) { - return result; + if (success) { + if (active.removeAll) { + target.removeAll(); } + target.add(items); } + return success; } - return node.ownerCt.nextNode(selector); } }, - getId : function() { - return this.id || (this.id = 'ext-comp-' + (this.getAutoId())); - }, - getItemId : function() { - return this.itemId || this.id; - }, + + target: null, - getEl : function() { - return this.el; - }, + loadMask: false, - getTargetEl: function() { - return this.frameBody || this.el; - }, - isXType: function(xtype, shallow) { - - if (Ext.isFunction(xtype)) { - xtype = xtype.xtype; - - } else if (Ext.isObject(xtype)) { - xtype = xtype.statics().xtype; - + renderer: 'html', + + + setTarget: function(target){ + var me = this; + + if (Ext.isString(target)) { + target = Ext.getCmp(target); } - return !shallow ? ('/' + this.getXTypes() + '/').indexOf('/' + xtype + '/') != -1: this.self.xtype == xtype; + if (me.target && me.target != target) { + me.abort(); + } + me.target = target; }, - getXTypes: function() { - var self = this.self, - xtypes = [], - parentPrototype = this, - xtype; - - if (!self.xtypes) { - while (parentPrototype && Ext.getClass(parentPrototype)) { - xtype = Ext.getClass(parentPrototype).xtype; - - if (xtype !== undefined) { - xtypes.unshift(xtype); - } + removeMask: function(){ + this.target.setLoading(false); + }, - parentPrototype = parentPrototype.superclass; - } + + addMask: function(mask){ + this.target.setLoading(mask); + }, - self.xtypeChain = xtypes; - self.xtypes = xtypes.join('/'); - } + - return self.xtypes; + setOptions: function(active, options){ + active.removeAll = Ext.isDefined(options.removeAll) ? options.removeAll : this.removeAll; }, - update : function(htmlOrData, loadScripts, cb) { - var me = this; - - if (me.tpl && !Ext.isString(htmlOrData)) { - me.data = htmlOrData; - if (me.rendered) { - me.tpl[me.tplWriteMode](me.getTargetEl(), htmlOrData || {}); - } - } else { - me.html = Ext.isObject(htmlOrData) ? Ext.core.DomHelper.markup(htmlOrData) : htmlOrData; - if (me.rendered) { - me.getTargetEl().update(me.html, loadScripts, cb); - } + getRenderer: function(renderer){ + if (Ext.isFunction(renderer)) { + return renderer; } - if (me.rendered) { - me.doComponentLayout(); + var renderers = this.statics().Renderer; + switch (renderer) { + case 'component': + return renderers.Component; + case 'data': + return renderers.Data; + default: + return Ext.ElementLoader.Renderer.Html; } - }, + } +}); + +Ext.define('Ext.data.Association', { - setVisible : function(visible) { - return this[visible ? 'show': 'hide'](); - }, - isVisible: function(deep) { - var me = this, - child = me, - visible = !me.hidden, - ancestor = me.ownerCt; - - me.hiddenAncestor = false; - if (me.destroyed) { - return false; - } + + primaryKey: 'id', - if (deep && visible && me.rendered && ancestor) { - while (ancestor) { - - - - - if (ancestor.hidden || (ancestor.collapsed && - !(ancestor.getDockedItems && Ext.Array.contains(ancestor.getDockedItems(), child)))) { + + + + + defaultReaderType: 'json', + + statics: { + create: function(association){ + if (!association.isAssociation) { + if (Ext.isString(association)) { + association = { + type: association + }; + } + + switch (association.type) { + case 'belongsTo': + return Ext.create('Ext.data.BelongsToAssociation', association); + case 'hasMany': + return Ext.create('Ext.data.HasManyAssociation', association); - me.hiddenAncestor = ancestor; - visible = false; - break; + + + default: } - child = ancestor; - ancestor = ancestor.ownerCt; } + return association; } - return visible; }, - enable: function(silent) { - var me = this; + constructor: function(config) { + Ext.apply(this, config); - if (me.rendered) { - me.el.removeCls(me.disabledCls); - me.el.dom.disabled = false; - me.onEnable(); - } + var types = Ext.ModelManager.types, + ownerName = config.ownerModel, + associatedName = config.associatedModel, + ownerModel = types[ownerName], + associatedModel = types[associatedName], + ownerProto; - me.disabled = false; - if (silent !== true) { - me.fireEvent('enable', me); - } + this.ownerModel = ownerModel; + this.associatedModel = associatedModel; - return me; + + + + + Ext.applyIf(this, { + ownerName : ownerName, + associatedName: associatedName + }); }, - disable: function(silent) { - var me = this; + getReader: function(){ + var me = this, + reader = me.reader, + model = me.associatedModel; - if (me.rendered) { - me.el.addCls(me.disabledCls); - me.el.dom.disabled = true; - me.onDisable(); + if (reader) { + if (Ext.isString(reader)) { + reader = { + type: reader + }; + } + if (reader.isReader) { + reader.setModel(model); + } else { + Ext.applyIf(reader, { + model: model, + type : me.defaultReaderType + }); + } + me.reader = Ext.createByAlias('reader.' + reader.type, reader); } + return me.reader || null; + } +}); - me.disabled = true; - if (silent !== true) { - me.fireEvent('disable', me); - } +Ext.define('Ext.ModelManager', { + extend: 'Ext.AbstractManager', + alternateClassName: 'Ext.ModelMgr', + requires: ['Ext.data.Association'], + + singleton: true, + + typeName: 'mtype', - return me; - }, - - onEnable: function() { - if (this.maskOnDisable) { - this.el.unmask(); - } - }, + associationStack: [], - onDisable : function() { - if (this.maskOnDisable) { - this.el.mask(); - } - }, - - - isDisabled : function() { - return this.disabled; + registerType: function(name, config) { + var proto = config.prototype, + model; + if (proto && proto.isModel) { + + model = config; + } else { + + if (!config.extend) { + config.extend = 'Ext.data.Model'; + } + model = Ext.define(name, config); + } + this.types[name] = model; + return model; }, - setDisabled : function(disabled) { - return this[disabled ? 'disable': 'enable'](); - }, + onModelDefined: function(model) { + var stack = this.associationStack, + length = stack.length, + create = [], + association, i, created; - - isHidden : function() { - return this.hidden; - }, + for (i = 0; i < length; i++) { + association = stack[i]; - - addCls : function(className) { - var me = this; - if (!className) { - return me; - } - if (!Ext.isArray(className)){ - className = className.replace(me.trimRe, '').split(me.spacesRe); - } - if (me.rendered) { - me.el.addCls(className); + if (association.associatedModel == model.modelName) { + create.push(association); + } } - else { - me.additionalCls = Ext.Array.unique(me.additionalCls.concat(className)); + + for (i = 0, length = create.length; i < length; i++) { + created = create[i]; + this.types[created.ownerModel].prototype.associations.add(Ext.data.Association.create(created)); + Ext.Array.remove(stack, created); } - return me; }, - addClass : function() { - return this.addCls.apply(this, arguments); + registerDeferredAssociation: function(association){ + this.associationStack.push(association); }, - removeCls : function(className) { - var me = this; - - if (!className) { - return me; - } - if (!Ext.isArray(className)){ - className = className.replace(me.trimRe, '').split(me.spacesRe); - } - if (me.rendered) { - me.el.removeCls(className); - } - else if (me.additionalCls.length) { - Ext.each(className, function(cls) { - Ext.Array.remove(me.additionalCls, cls); - }); - } - return me; - }, - - removeClass : function() { - if (Ext.isDefined(Ext.global.console)) { - Ext.global.console.warn('Ext.Component: removeClass has been deprecated. Please use removeCls.'); - } - return this.removeCls.apply(this, arguments); - }, - - addOverCls: function() { - var me = this; - if (!me.disabled) { - me.el.addCls(me.overCls); + getModel: function(id) { + var model = id; + if (typeof model == 'string') { + model = this.types[model]; } + return model; }, - removeOverCls: function() { - this.el.removeCls(this.overCls); - }, - - addListener : function(element, listeners, scope, options) { - var me = this, - fn, - option; + + create: function(config, name, id) { + var con = typeof name == 'function' ? name : this.types[name || config.name]; - if (Ext.isString(element) && (Ext.isObject(listeners) || options && options.element)) { - if (options.element) { - fn = listeners; + return new con(config, id); + } +}, function() { - listeners = {}; - listeners[element] = fn; - element = options.element; - if (scope) { - listeners.scope = scope; - } + + Ext.regModel = function() { + return this.ModelManager.registerType.apply(this.ModelManager, arguments); + }; +}); - for (option in options) { - if (options.hasOwnProperty(option)) { - if (me.eventOptionsRe.test(option)) { - listeners[option] = options[option]; - } - } - } - } - - - if (me[element] && me[element].on) { - me.mon(me[element], listeners); - } else { - me.afterRenderEvents = me.afterRenderEvents || {}; - me.afterRenderEvents[element] = listeners; - } - } +Ext.define('Ext.PluginManager', { + extend: 'Ext.AbstractManager', + alternateClassName: 'Ext.PluginMgr', + singleton: true, + typeName: 'ptype', - return me.mixins.observable.addListener.apply(me, arguments); - }, - 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) { - if (isClear || (managedListener.item === item && managedListener.ename === ename && (!fn || managedListener.fn === fn) && (!scope || managedListener.scope === scope))) { - element.un(managedListener.ename, managedListener.fn, managedListener.scope); - if (!isClear) { - Ext.Array.remove(me.managedListeners, managedListener); - } - } - } - } else { - return me.mixins.observable.removeManagedListenerItem.apply(me, arguments); - } - }, - - getBubbleTarget : function() { - return this.ownerCt; - }, - - isFloating : function() { - return this.floating; - }, - - isDraggable : function() { - return !!this.draggable; - }, - - isDroppable : function() { - return !!this.droppable; - }, - - onAdded : function(container, pos) { - this.ownerCt = container; - this.fireEvent('added', this, container, pos); - }, - - onRemoved : function() { - var me = this; - - me.fireEvent('removed', me, me.ownerCt); - delete me.ownerCt; - }, - - beforeDestroy : Ext.emptyFn, - onResize : Ext.emptyFn, - - setSize : function(width, height) { - var me = this, - layoutCollection; + + + + + + - - if (Ext.isObject(width)) { - height = width.height; - width = width.width; + create : function(config, defaultType){ + if (config.init) { + return config; + } else { + return Ext.createByAlias('plugin.' + (config.ptype || defaultType), config); } - if (Ext.isNumber(width)) { - width = Ext.Number.constrain(width, me.minWidth, me.maxWidth); - } - if (Ext.isNumber(height)) { - height = Ext.Number.constrain(height, me.minHeight, me.maxHeight); - } - - if (!me.rendered || !me.isVisible()) { - - if (me.hiddenAncestor) { - layoutCollection = me.hiddenAncestor.layoutOnShow; - layoutCollection.remove(me); - layoutCollection.add(me); - } - me.needsLayout = { - width: width, - height: height, - isSetSize: true - }; - if (!me.rendered) { - me.width = (width !== undefined) ? width : me.width; - me.height = (height !== undefined) ? height : me.height; - } - return me; - } - me.doComponentLayout(width, height, true); - - return me; + + + + + + }, - setCalculatedSize : function(width, height, ownerCt) { - var me = this, - layoutCollection; - - - if (Ext.isObject(width)) { - ownerCt = width.ownerCt; - height = width.height; - width = width.width; - } + + findByType: function(type, defaultsOnly) { + var matches = [], + types = this.types; - - if (Ext.isNumber(width)) { - width = Ext.Number.constrain(width, me.minWidth, me.maxWidth); - } - if (Ext.isNumber(height)) { - height = Ext.Number.constrain(height, me.minHeight, me.maxHeight); - } + for (var name in types) { + if (!types.hasOwnProperty(name)) { + continue; + } + var item = types[name]; - if (!me.rendered || !me.isVisible()) { - - if (me.hiddenAncestor) { - layoutCollection = me.hiddenAncestor.layoutOnShow; - layoutCollection.remove(me); - layoutCollection.add(me); + if (item.type == type && (!defaultsOnly || (defaultsOnly === true && item.isDefault))) { + matches.push(item); } - me.needsLayout = { - width: width, - height: height, - isSetSize: false, - ownerCt: ownerCt - }; - return me; } - me.doComponentLayout(width, height, false, ownerCt); - - return me; - }, + return matches; + } +}, function() { - doComponentLayout : function(width, height, isSetSize, ownerCt) { - var me = this, - componentLayout = me.getComponentLayout(); + Ext.preg = function() { + return Ext.PluginManager.registerType.apply(Ext.PluginManager, arguments); + }; +}); - - - - if (me.rendered && componentLayout) { - width = (width !== undefined) ? width : me.width; - height = (height !== undefined) ? height : me.height; - if (isSetSize) { - me.width = width; - me.height = height; - } - componentLayout.layout(width, height, isSetSize, ownerCt); - } - return me; - }, +Ext.define('Ext.Template', { - setComponentLayout : function(layout) { - var currentLayout = this.componentLayout; - if (currentLayout && currentLayout.isLayout && currentLayout != layout) { - currentLayout.setOwner(null); - } - this.componentLayout = layout; - layout.setOwner(this); - }, - getComponentLayout : function() { - var me = this; + requires: ['Ext.DomHelper', 'Ext.util.Format'], - if (!me.componentLayout || !me.componentLayout.isLayout) { - me.setComponentLayout(Ext.layout.Layout.create(me.componentLayout, 'autocomponent')); + inheritableStatics: { + + from: function(el, config) { + el = Ext.getDom(el); + return new this(el.value || el.innerHTML, config || ''); } - return me.componentLayout; }, - afterComponentLayout: function(width, height, isSetSize, layoutOwner) { - this.fireEvent('resize', this, width, height); - }, - beforeComponentLayout: function(width, height, isSetSize, layoutOwner) { - return true; - }, + constructor: function(html) { + var me = this, + args = arguments, + buffer = [], + i = 0, + length = args.length, + value; - - setPosition : function(x, y) { - var me = this; + me.initialConfig = {}; - if (Ext.isObject(x)) { - y = x.y; - x = x.x; + if (length > 1) { + for (; i < length; i++) { + value = args[i]; + if (typeof value == 'object') { + Ext.apply(me.initialConfig, value); + Ext.apply(me, value); + } else { + buffer.push(value); + } + } + html = buffer.join(''); + } else { + if (Ext.isArray(html)) { + buffer.push(html.join('')); + } else { + buffer.push(html); + } } - if (!me.rendered) { - return me; - } + + me.html = buffer.join(''); - if (x !== undefined || y !== undefined) { - me.el.setBox(x, y); - me.onPosition(x, y); - me.fireEvent('move', me, x, y); + if (me.compiled) { + me.compile(); } - return me; - }, - - - onPosition: Ext.emptyFn, - - - setWidth : function(width) { - return this.setSize(width); }, - - setHeight : function(height) { - return this.setSize(undefined, height); - }, + isTemplate: true, - getSize : function() { - return this.el.getSize(); - }, - getWidth : function() { - return this.el.getWidth(); - }, + disableFormats: false, - - getHeight : function() { - return this.el.getHeight(); - }, + re: /\{([\w\-]+)(?:\:([\w\.]*)(?:\((.*?)?\))?)?\}/g, - getLoader: function(){ + applyTemplate: function(values) { var me = this, - autoLoad = me.autoLoad ? (Ext.isObject(me.autoLoad) ? me.autoLoad : {url: me.autoLoad}) : null, - loader = me.loader || autoLoad; - - if (loader) { - if (!loader.isLoader) { - me.loader = Ext.create('Ext.ComponentLoader', Ext.apply({ - target: me, - autoLoad: autoLoad - }, loader)); - } else { - loader.setTarget(me); - } - return me.loader; + useFormat = me.disableFormats !== true, + fm = Ext.util.Format, + tpl = me; + if (me.compiled) { + return me.compiled(values); } - return null; - }, - - - setLoading : function(load, targetEl) { - var me = this, - config; - - if (me.rendered) { - if (load !== false && !me.collapsed) { - if (Ext.isObject(load)) { - config = load; + function fn(m, name, format, args) { + if (format && useFormat) { + if (args) { + args = [values[name]].concat(Ext.functionFactory('return ['+ args +'];')()); + } else { + args = [values[name]]; } - else if (Ext.isString(load)) { - config = {msg: load}; + if (format.substr(0, 5) == "this.") { + return tpl[format.substr(5)].apply(tpl, args); } else { - config = {}; + return fm[format].apply(fm, args); } - me.loadMask = me.loadMask || Ext.create('Ext.LoadMask', targetEl ? me.getTargetEl() : me.el, config); - me.loadMask.show(); - } else if (me.loadMask) { - Ext.destroy(me.loadMask); - me.loadMask = null; + } + else { + return values[name] !== undefined ? values[name] : ""; } } - - return me.loadMask; + return me.html.replace(me.re, fn); }, - setDocked : function(dock, layoutParent) { + set: function(html, compile) { var me = this; + me.html = html; + me.compiled = null; + return compile ? me.compile() : me; + }, - me.dock = dock; - if (layoutParent && me.ownerCt && me.rendered) { - me.ownerCt.doComponentLayout(); + compileARe: /\\/g, + compileBRe: /(\r\n|\n)/g, + compileCRe: /'/g, + + /** + * Compiles the template into an internal function, eliminating the RegEx overhead. + * @return {Ext.Template} this + */ + compile: function() { + var me = this, + fm = Ext.util.Format, + useFormat = me.disableFormats !== true, + body, bodyReturn; + + function fn(m, name, format, args) { + if (format && useFormat) { + args = args ? ',' + args: ""; + if (format.substr(0, 5) != "this.") { + format = "fm." + format + '('; + } + else { + format = 'this.' + format.substr(5) + '('; + } + } + else { + args = ''; + format = "(values['" + name + "'] == undefined ? '' : "; + } + return "'," + format + "values['" + name + "']" + args + ") ,'"; } + + bodyReturn = me.html.replace(me.compileARe, '\\\\').replace(me.compileBRe, '\\n').replace(me.compileCRe, "\\'").replace(me.re, fn); + body = "this.compiled = function(values){ return ['" + bodyReturn + "'].join('');};"; + eval(body); return me; }, - onDestroy : function() { - var me = this; + /** + * Applies the supplied values to the template and inserts the new node(s) as the first child of el. + * + * @param {String/HTMLElement/Ext.Element} el The context element + * @param {Object/Array} values The template values. See {@link #applyTemplate} for details. + * @param {Boolean} returnElement (optional) true to return a Ext.Element. + * @return {HTMLElement/Ext.Element} The new node or Element + */ + insertFirst: function(el, values, returnElement) { + return this.doInsert('afterBegin', el, values, returnElement); + }, - if (me.monitorResize && Ext.EventManager.resizeEvent) { - Ext.EventManager.resizeEvent.removeListener(me.setSize, me); - } - Ext.destroy(me.componentLayout, me.loadMask); + /** + * Applies the supplied values to the template and inserts the new node(s) before el. + * + * @param {String/HTMLElement/Ext.Element} el The context element + * @param {Object/Array} values The template values. See {@link #applyTemplate} for details. + * @param {Boolean} returnElement (optional) true to return a Ext.Element. + * @return {HTMLElement/Ext.Element} The new node or Element + */ + insertBefore: function(el, values, returnElement) { + return this.doInsert('beforeBegin', el, values, returnElement); }, - - destroy : function() { - var me = this; + /** + * Applies the supplied values to the template and inserts the new node(s) after el. + * + * @param {String/HTMLElement/Ext.Element} el The context element + * @param {Object/Array} values The template values. See {@link #applyTemplate} for details. + * @param {Boolean} returnElement (optional) true to return a Ext.Element. + * @return {HTMLElement/Ext.Element} The new node or Element + */ + insertAfter: function(el, values, returnElement) { + return this.doInsert('afterEnd', el, values, returnElement); + }, - if (!me.isDestroyed) { - if (me.fireEvent('beforedestroy', me) !== false) { - me.destroying = true; - me.beforeDestroy(); + /** + * Applies the supplied `values` to the template and appends the new node(s) to the specified `el`. + * + * For example usage see {@link Ext.Template Ext.Template class docs}. + * + * @param {String/HTMLElement/Ext.Element} el The context element + * @param {Object/Array} values The template values. See {@link #applyTemplate} for details. + * @param {Boolean} returnElement (optional) true to return an Ext.Element. + * @return {HTMLElement/Ext.Element} The new node or Element + */ + append: function(el, values, returnElement) { + return this.doInsert('beforeEnd', el, values, returnElement); + }, - if (me.floating) { - delete me.floatParent; - - - if (me.zIndexManager) { - me.zIndexManager.unregister(me); - } - } else if (me.ownerCt && me.ownerCt.remove) { - me.ownerCt.remove(me, false); - } + doInsert: function(where, el, values, returnEl) { + el = Ext.getDom(el); + var newNode = Ext.DomHelper.insertHtml(where, el, this.applyTemplate(values)); + return returnEl ? Ext.get(newNode, true) : newNode; + }, - if (me.rendered) { - me.el.remove(); - } + /** + * Applies the supplied values to the template and overwrites the content of el with the new node(s). + * + * @param {String/HTMLElement/Ext.Element} el The context element + * @param {Object/Array} values The template values. See {@link #applyTemplate} for details. + * @param {Boolean} returnElement (optional) true to return a Ext.Element. + * @return {HTMLElement/Ext.Element} The new node or Element + */ + overwrite: function(el, values, returnElement) { + el = Ext.getDom(el); + el.innerHTML = this.applyTemplate(values); + return returnElement ? Ext.get(el.firstChild, true) : el.firstChild; + } +}, function() { - me.onDestroy(); + /** + * @method apply + * @member Ext.Template + * Alias for {@link #applyTemplate}. + * @alias Ext.Template#applyTemplate + */ + this.createAlias('apply', 'applyTemplate'); +}); - - Ext.destroy(me.plugins); +/** + * A template class that supports advanced functionality like: + * + * - Autofilling arrays using templates and sub-templates + * - Conditional processing with basic comparison operators + * - Basic math function support + * - Execute arbitrary inline code with special built-in template variables + * - Custom member functions + * - Many special tags and built-in operators that aren't defined as part of the API, but are supported in the templates that can be created + * + * XTemplate provides the templating mechanism built into: + * + * - {@link Ext.view.View} + * + * The {@link Ext.Template} describes the acceptable parameters to pass to the constructor. The following examples + * demonstrate all of the supported features. + * + * # Sample Data + * + * This is the data object used for reference in each code example: + * + * var data = { + * name: 'Tommy Maintz', + * title: 'Lead Developer', + * company: 'Sencha Inc.', + * email: 'tommy@sencha.com', + * address: '5 Cups Drive', + * city: 'Palo Alto', + * state: 'CA', + * zip: '44102', + * drinks: ['Coffee', 'Soda', 'Water'], + * kids: [ + * { + * name: 'Joshua', + * age:3 + * }, + * { + * name: 'Matthew', + * age:2 + * }, + * { + * name: 'Solomon', + * age:0 + * } + * ] + * }; + * + * # Auto filling of arrays + * + * The **tpl** tag and the **for** operator are used to process the provided data object: + * + * - If the value specified in for is an array, it will auto-fill, repeating the template block inside the tpl + * tag for each item in the array. + * - If for="." is specified, the data object provided is examined. + * - While processing an array, the special variable {#} will provide the current array index + 1 (starts at 1, not 0). + * + * Examples: + * + * ... // loop through array at root node + * ... // loop through array at foo node + * ... // loop through array at foo.bar node + * + * Using the sample data above: + * + * var tpl = new Ext.XTemplate( + * '

Kids: ', + * '', // process the data.kids node + * '

{#}. {name}

', // use current array index to autonumber + * '

' + * ); + * tpl.overwrite(panel.body, data.kids); // pass the kids property of the data object + * + * An example illustrating how the **for** property can be leveraged to access specified members of the provided data + * object to populate the template: + * + * var tpl = new Ext.XTemplate( + * '

Name: {name}

', + * '

Title: {title}

', + * '

Company: {company}

', + * '

Kids: ', + * '', // interrogate the kids property within the data + * '

{name}

', + * '

' + * ); + * tpl.overwrite(panel.body, data); // pass the root node of the data object + * + * Flat arrays that contain values (and not objects) can be auto-rendered using the special **`{.}`** variable inside a + * loop. This variable will represent the value of the array at the current index: + * + * var tpl = new Ext.XTemplate( + * '

{name}\'s favorite beverages:

', + * '', + * '
- {.}
', + * '
' + * ); + * tpl.overwrite(panel.body, data); + * + * When processing a sub-template, for example while looping through a child array, you can access the parent object's + * members via the **parent** object: + * + * var tpl = new Ext.XTemplate( + * '

Name: {name}

', + * '

Kids: ', + * '', + * '', + * '

{name}

', + * '

Dad: {parent.name}

', + * '', + * '

' + * ); + * tpl.overwrite(panel.body, data); + * + * # Conditional processing with basic comparison operators + * + * The **tpl** tag and the **if** operator are used to provide conditional checks for deciding whether or not to render + * specific parts of the template. Notes: + * + * - Double quotes must be encoded if used within the conditional + * - There is no else operator -- if needed, two opposite if statements should be used. + * + * Examples: + * + * Child + * Teenager + * ... + * ... + * + * // no good: + * Hello + * // encode " if it is part of the condition, e.g. + * Hello + * + * Using the sample data above: + * + * var tpl = new Ext.XTemplate( + * '

Name: {name}

', + * '

Kids: ', + * '', + * '', + * '

{name}

', + * '', + * '

' + * ); + * tpl.overwrite(panel.body, data); + * + * # Basic math support + * + * The following basic math operators may be applied directly on numeric data values: + * + * + - * / + * + * For example: + * + * var tpl = new Ext.XTemplate( + * '

Name: {name}

', + * '

Kids: ', + * '', + * '', // <-- Note that the > is encoded + * '

{#}: {name}

', // <-- Auto-number each item + * '

In 5 Years: {age+5}

', // <-- Basic math + * '

Dad: {parent.name}

', + * '', + * '

' + * ); + * tpl.overwrite(panel.body, data); + * + * # Execute arbitrary inline code with special built-in template variables + * + * Anything between `{[ ... ]}` is considered code to be executed in the scope of the template. There are some special + * variables available in that code: + * + * - **values**: The values in the current scope. If you are using scope changing sub-templates, + * you can change what values is. + * - **parent**: The scope (values) of the ancestor template. + * - **xindex**: If you are in a looping template, the index of the loop you are in (1-based). + * - **xcount**: If you are in a looping template, the total length of the array you are looping. + * + * This example demonstrates basic row striping using an inline code block and the xindex variable: + * + * var tpl = new Ext.XTemplate( + * '

Name: {name}

', + * '

Company: {[values.company.toUpperCase() + ", " + values.title]}

', + * '

Kids: ', + * '', + * '

', + * '{name}', + * '
', + * '

' + * ); + * tpl.overwrite(panel.body, data); + * + * # Template member functions + * + * One or more member functions can be specified in a configuration object passed into the XTemplate constructor for + * more complex processing: + * + * var tpl = new Ext.XTemplate( + * '

Name: {name}

', + * '

Kids: ', + * '', + * '', + * '

Girl: {name} - {age}

', + * '', + * // use opposite if statement to simulate 'else' processing: + * '', + * '

Boy: {name} - {age}

', + * '
', + * '', + * '

{name} is a baby!

', + * '
', + * '

', + * { + * // XTemplate configuration: + * disableFormats: true, + * // member functions: + * isGirl: function(name){ + * return name == 'Sara Grace'; + * }, + * isBaby: function(age){ + * return age < 1; + * } + * } + * ); + * tpl.overwrite(panel.body, data); + */ +Ext.define('Ext.XTemplate', { - Ext.ComponentManager.unregister(me); - me.fireEvent('destroy', me); + /* Begin Definitions */ - me.mixins.state.destroy.call(me); + extend: 'Ext.Template', - me.clearListeners(); - me.destroying = false; - me.isDestroyed = true; - } - } - }, + /* End Definitions */ - - getPlugin: function(pluginId) { - var i = 0, - plugins = this.plugins, - ln = plugins.length; - for (; i < ln; i++) { - if (plugins[i].pluginId === pluginId) { - return plugins[i]; - } - } - }, - - - isDescendantOf: function(container) { - return !!this.findParentBy(function(p){ - return p === container; - }); - } -}, function() { - this.createAlias({ - on: 'addListener', - prev: 'previousSibling', - next: 'nextSibling' - }); -}); + argsRe: /]*>((?:(?=([^<]+))\2|<(?!tpl\b[^>]*>))*?)<\/tpl>/, + nameRe: /^]*?for="(.*?)"/, + ifRe: /^]*?if="(.*?)"/, + execRe: /^]*?exec="(.*?)"/, + constructor: function() { + this.callParent(arguments); + var me = this, + html = me.html, + argsRe = me.argsRe, + nameRe = me.nameRe, + ifRe = me.ifRe, + execRe = me.execRe, + id = 0, + tpls = [], + VALUES = 'values', + PARENT = 'parent', + XINDEX = 'xindex', + XCOUNT = 'xcount', + RETURN = 'return ', + WITHVALUES = 'with(values){ ', + m, matchName, matchIf, matchExec, exp, fn, exec, name, i; -Ext.define('Ext.AbstractPlugin', { - disabled: false, - - constructor: function(config) { - if (!config.cmp && Ext.global.console) { - Ext.global.console.warn("Attempted to attach a plugin "); - } - Ext.apply(this, config); - }, - - getCmp: function() { - return this.cmp; - }, + html = ['', html, ''].join(''); - - init: Ext.emptyFn, + while ((m = html.match(argsRe))) { + exp = null; + fn = null; + exec = null; + matchName = m[0].match(nameRe); + matchIf = m[0].match(ifRe); + matchExec = m[0].match(execRe); - - destroy: Ext.emptyFn, + exp = matchIf ? matchIf[1] : null; + if (exp) { + fn = Ext.functionFactory(VALUES, PARENT, XINDEX, XCOUNT, WITHVALUES + 'try{' + RETURN + Ext.String.htmlDecode(exp) + ';}catch(e){return;}}'); + } - - enable: function() { - this.disabled = false; - }, + exp = matchExec ? matchExec[1] : null; + if (exp) { + exec = Ext.functionFactory(VALUES, PARENT, XINDEX, XCOUNT, WITHVALUES + Ext.String.htmlDecode(exp) + ';}'); + } - - disable: function() { - this.disabled = true; - } -}); + name = matchName ? matchName[1] : null; + if (name) { + if (name === '.') { + name = VALUES; + } else if (name === '..') { + name = PARENT; + } + name = Ext.functionFactory(VALUES, PARENT, 'try{' + WITHVALUES + RETURN + name + ';}}catch(e){return;}'); + } + + tpls.push({ + id: id, + target: name, + exec: exec, + test: fn, + body: m[1] || '' + }); + html = html.replace(m[0], '{xtpl' + id + '}'); + id = id + 1; + } -Ext.define('Ext.data.Connection', { - mixins: { - observable: 'Ext.util.Observable' + for (i = tpls.length - 1; i >= 0; --i) { + me.compileTpl(tpls[i]); + } + me.master = tpls[tpls.length - 1]; + me.tpls = tpls; }, - statics: { - requestId: 0 + // @private + applySubTemplate: function(id, values, parent, xindex, xcount) { + var me = this, t = me.tpls[id]; + return t.compiled.call(me, values, parent, xindex, xcount); }, - url: null, - async: true, - method: null, - username: '', - password: '', + /** + * @cfg {RegExp} codeRe + * The regular expression used to match code variables. Default: matches {[expression]}. + */ + codeRe: /\{\[((?:\\\]|.|\n)*?)\]\}/g, - - disableCaching: true, + /** + * @cfg {Boolean} compiled + * Only applies to {@link Ext.Template}, XTemplates are compiled automatically. + */ - - disableCachingParam: '_dc', + re: /\{([\w-\.\#]+)(?:\:([\w\.]*)(?:\((.*?)?\))?)?(\s?[\+\-\*\/]\s?[\d\.\+\-\*\/\(\)]+)?\}/g, - - timeout : 30000, + // @private + compileTpl: function(tpl) { + var fm = Ext.util.Format, + me = this, + useFormat = me.disableFormats !== true, + body, bodyReturn, evaluatedFn; - + function fn(m, name, format, args, math) { + var v; + // name is what is inside the {} + // Name begins with xtpl, use a Sub Template + if (name.substr(0, 4) == 'xtpl') { + return "',this.applySubTemplate(" + name.substr(4) + ", values, parent, xindex, xcount),'"; + } + // name = "." - Just use the values object. + if (name == '.') { + // filter to not include arrays/objects/nulls + v = 'Ext.Array.indexOf(["string", "number", "boolean"], typeof values) > -1 || Ext.isDate(values) ? values : ""'; + } - useDefaultHeader : true, - defaultPostHeader : 'application/x-www-form-urlencoded; charset=UTF-8', - useDefaultXhrHeader : true, - defaultXhrHeader : 'XMLHttpRequest', + // name = "#" - Use the xindex + else if (name == '#') { + v = 'xindex'; + } + else if (name.substr(0, 7) == "parent.") { + v = name; + } + // name has a . in it - Use object literal notation, starting from values + else if (name.indexOf('.') != -1) { + v = "values." + name; + } - constructor : function(config) { - config = config || {}; - Ext.apply(this, config); + // name is a property of values + else { + v = "values['" + name + "']"; + } + if (math) { + v = '(' + v + math + ')'; + } + if (format && useFormat) { + args = args ? ',' + args : ""; + if (format.substr(0, 5) != "this.") { + format = "fm." + format + '('; + } + else { + format = 'this.' + format.substr(5) + '('; + } + } + else { + args = ''; + format = "(" + v + " === undefined ? '' : "; + } + return "'," + format + v + args + "),'"; + } - this.addEvents( - - 'beforerequest', - - 'requestcomplete', - - 'requestexception' - ); - this.requests = {}; - this.mixins.observable.constructor.call(this); - }, + function codeFn(m, code) { + // Single quotes get escaped when the template is compiled, however we want to undo this when running code. + return "',(" + code.replace(me.compileARe, "'") + "),'"; + } - - request : function(options) { - options = options || {}; - var me = this, - scope = options.scope || window, - username = options.username || me.username, - password = options.password || me.password || '', - async, - requestOptions, - request, - headers, - xhr; + bodyReturn = tpl.body.replace(me.compileBRe, '\\n').replace(me.compileCRe, "\\'").replace(me.re, fn).replace(me.codeRe, codeFn); + body = "evaluatedFn = function(values, parent, xindex, xcount){return ['" + bodyReturn + "'].join('');};"; + eval(body); - if (me.fireEvent('beforerequest', me, options) !== false) { + tpl.compiled = function(values, parent, xindex, xcount) { + var vs, + length, + buffer, + i; - requestOptions = me.setOptions(options, scope); + if (tpl.test && !tpl.test.call(me, values, parent, xindex, xcount)) { + return ''; + } - if (this.isFormUpload(options) === true) { - this.upload(options.form, requestOptions.url, requestOptions.data, options); - return null; + vs = tpl.target ? tpl.target.call(me, values, parent) : values; + if (!vs) { + return ''; } - - if (options.autoAbort === true || me.autoAbort) { - me.abort(); + parent = tpl.target ? values : parent; + if (tpl.target && Ext.isArray(vs)) { + buffer = []; + length = vs.length; + if (tpl.exec) { + for (i = 0; i < length; i++) { + buffer[buffer.length] = evaluatedFn.call(me, vs[i], parent, i + 1, length); + tpl.exec.call(me, vs[i], parent, i + 1, length); + } + } else { + for (i = 0; i < length; i++) { + buffer[buffer.length] = evaluatedFn.call(me, vs[i], parent, i + 1, length); + } + } + return buffer.join(''); } - - xhr = this.getXhrInstance(); + if (tpl.exec) { + tpl.exec.call(me, vs, parent, xindex, xcount); + } + return evaluatedFn.call(me, vs, parent, xindex, xcount); + }; - async = options.async !== false ? (options.async || me.async) : false; + return this; + }, - - if (username) { - xhr.open(requestOptions.method, requestOptions.url, async, username, password); - } else { - xhr.open(requestOptions.method, requestOptions.url, async); - } + // inherit docs from Ext.Template + applyTemplate: function(values) { + return this.master.compiled.call(this, values, {}, 1, 1); + }, - headers = me.setupHeaders(xhr, options, requestOptions.data, requestOptions.params); + /** + * Does nothing. XTemplates are compiled automatically, so this function simply returns this. + * @return {Ext.XTemplate} this + */ + compile: function() { + return this; + } +}, function() { + // re-create the alias, inheriting it from Ext.Template doesn't work as intended. + this.createAlias('apply', 'applyTemplate'); +}); - - request = { - id: ++Ext.data.Connection.requestId, - xhr: xhr, - headers: headers, - options: options, - async: async, - timeout: setTimeout(function() { - request.timedout = true; - me.abort(request); - }, options.timeout || me.timeout) - }; - me.requests[request.id] = request; - - if (async) { - xhr.onreadystatechange = Ext.Function.bind(me.onStateChange, me, [request]); - } +Ext.define('Ext.app.Controller', { - - xhr.send(requestOptions.data); - if (!async) { - return this.onComplete(request); - } - return request; - } else { - Ext.callback(options.callback, options.scope, [options, undefined, undefined]); - return null; - } + mixins: { + observable: 'Ext.util.Observable' }, - upload: function(form, url, params, options){ - form = Ext.getDom(form); - options = options || {}; + + - var id = Ext.id(), - frame = document.createElement('iframe'), - hiddens = [], - encoding = 'multipart/form-data', - buf = { - target: form.target, - method: form.method, - encoding: form.encoding, - enctype: form.enctype, - action: form.action - }, hiddenItem; + - - Ext.fly(frame).set({ - id: id, - name: id, - cls: Ext.baseCSSPrefix + 'hide-display', - src: Ext.SSL_SECURE_URL - }); + - document.body.appendChild(frame); + onClassExtended: function(cls, data) { + var className = Ext.getClassName(cls), + match = className.match(/^(.*)\.controller\./); - - if (document.frames) { - document.frames[id].name = id; - } + if (match !== null) { + var namespace = Ext.Loader.getPrefix(className) || match[1], + onBeforeClassCreated = data.onBeforeClassCreated, + requires = [], + modules = ['model', 'view', 'store'], + prefix; - Ext.fly(form).set({ - target: id, - method: 'POST', - enctype: encoding, - encoding: encoding, - action: url || buf.action - }); + data.onBeforeClassCreated = function(cls, data) { + var i, ln, module, + items, j, subLn, item; - - if (params) { - Ext.iterate(Ext.Object.fromQueryString(params), function(name, value){ - hiddenItem = document.createElement('input'); - Ext.fly(hiddenItem).set({ - type: 'hidden', - value: value, - name: name - }); - form.appendChild(hiddenItem); - hiddens.push(hiddenItem); - }); - } + for (i = 0,ln = modules.length; i < ln; i++) { + module = modules[i]; - Ext.fly(frame).on('load', Ext.Function.bind(this.onUploadComplete, this, [frame, options]), null, {single: true}); - form.submit(); + items = Ext.Array.from(data[module + 's']); - Ext.fly(form).set(buf); - Ext.each(hiddens, function(h) { - Ext.removeNode(h); - }); - }, + for (j = 0,subLn = items.length; j < subLn; j++) { + item = items[j]; - onUploadComplete: function(frame, options){ - var me = this, - - response = { - responseText: '', - responseXML: null - }, doc, firstChild; + prefix = Ext.Loader.getPrefix(item); - try { - doc = frame.contentWindow.document || frame.contentDocument || window.frames[id].document; - if (doc) { - if (doc.body) { - if (/textarea/i.test((firstChild = doc.body.firstChild || {}).tagName)) { - response.responseText = firstChild.value; - } else { - response.responseText = doc.body.innerHTML; + if (prefix === '' || prefix === item) { + requires.push(namespace + '.' + module + '.' + item); + } + else { + requires.push(item); + } } } - - response.responseXML = doc.XMLDocument || doc; - } - } catch (e) { + + Ext.require(requires, Ext.Function.pass(onBeforeClassCreated, arguments, this)); + }; } + }, - me.fireEvent('requestcomplete', me, response, options); + + constructor: function(config) { + this.mixins.observable.constructor.call(this, config); - Ext.callback(options.success, options.scope, [response, options]); - Ext.callback(options.callback, options.scope, [options, true, response]); + Ext.apply(this, config || {}); - setTimeout(function(){ - Ext.removeNode(frame); - }, 100); - }, + this.createGetters('model', this.models); + this.createGetters('store', this.stores); + this.createGetters('view', this.views); - - isFormUpload: function(options){ - var form = this.getForm(options); - if (form) { - return (options.isUpload || (/multipart\/form-data/i).test(form.getAttribute('enctype'))); + if (this.refs) { + this.ref(this.refs); } - return false; }, - getForm: function(options){ - return Ext.getDom(options.form) || null; - }, + init: function(application) {}, - setOptions: function(options, scope){ - var me = this, - params = options.params || {}, - extraParams = me.extraParams, - urlParams = options.urlParams, - url = options.url || me.url, - jsonData = options.jsonData, - method, - disableCache, - data; - - - - if (Ext.isFunction(params)) { - params = params.call(scope, options); - } - - - if (Ext.isFunction(url)) { - url = url.call(scope, options); - } + onLaunch: function(application) {}, - url = this.setupUrl(options, url); + createGetters: function(type, refs) { + type = Ext.String.capitalize(type); + Ext.Array.each(refs, function(ref) { + var fn = 'get', + parts = ref.split('.'); - if (!url) { - Ext.Error.raise({ - options: options, - msg: 'No URL specified' + + Ext.Array.each(parts, function(part) { + fn += Ext.String.capitalize(part); }); - } - - - data = options.rawData || options.xmlData || jsonData || null; - if (jsonData && !Ext.isPrimitive(jsonData)) { - data = Ext.encode(data); - } - - - if (Ext.isObject(params)) { - params = Ext.Object.toQueryString(params); - } - - if (Ext.isObject(extraParams)) { - extraParams = Ext.Object.toQueryString(extraParams); - } - - params = params + ((extraParams) ? ((params) ? '&' : '') + extraParams : ''); + fn += type; - urlParams = Ext.isObject(urlParams) ? Ext.Object.toQueryString(urlParams) : urlParams; + if (!this[fn]) { + this[fn] = Ext.Function.pass(this['get' + type], [ref], this); + } + + this[fn](ref); + }, + this); + }, - params = this.setupParams(options, params); + ref: function(refs) { + var me = this; + refs = Ext.Array.from(refs); + Ext.Array.each(refs, function(info) { + var ref = info.ref, + fn = 'get' + Ext.String.capitalize(ref); + if (!me[fn]) { + me[fn] = Ext.Function.pass(me.getRef, [ref, info], me); + } + }); + }, - - method = (options.method || me.method || ((params || data) ? 'POST' : 'GET')).toUpperCase(); - this.setupMethod(options, method); + getRef: function(ref, info, config) { + this.refCache = this.refCache || {}; + info = info || {}; + config = config || {}; + Ext.apply(info, config); - disableCache = options.disableCaching !== false ? (options.disableCaching || me.disableCaching) : false; - - if (method === 'GET' && disableCache) { - url = Ext.urlAppend(url, (options.disableCachingParam || me.disableCachingParam) + '=' + (new Date().getTime())); + if (info.forceCreate) { + return Ext.ComponentManager.create(info, 'component'); } - - if ((method == 'GET' || data) && params) { - url = Ext.urlAppend(url, params); - params = null; - } + var me = this, + selector = info.selector, + cached = me.refCache[ref]; - - if (urlParams) { - url = Ext.urlAppend(url, urlParams); + if (!cached) { + me.refCache[ref] = cached = Ext.ComponentQuery.query(info.selector)[0]; + if (!cached && info.autoCreate) { + me.refCache[ref] = cached = Ext.ComponentManager.create(info, 'component'); + } + if (cached) { + cached.on('beforedestroy', function() { + me.refCache[ref] = null; + }); + } } - return { - url: url, - method: method, - data: data || params || null - }; + return cached; }, - setupUrl: function(options, url){ - var form = this.getForm(options); - if (form) { - url = url || form.action; - } - return url; + control: function(selectors, listeners) { + this.application.control(selectors, listeners, this); }, + + getController: function(name) { + return this.application.getController(name); + }, - setupParams: function(options, params) { - var form = this.getForm(options), - serializedForm; - if (form && !this.isFormUpload(options)) { - serializedForm = Ext.core.Element.serializeForm(form); - params = params ? (params + '&' + serializedForm) : serializedForm; - } - return params; + getStore: function(name) { + return this.application.getStore(name); }, - setupMethod: function(options, method){ - if (this.isFormUpload(options)) { - return 'POST'; - } - return method; + getModel: function(model) { + return this.application.getModel(model); }, - setupHeaders: function(xhr, options, data, params){ - var me = this, - headers = Ext.apply({}, options.headers || {}, me.defaultHeaders || {}), - contentType = me.defaultPostHeader, - jsonData = options.jsonData, - xmlData = options.xmlData, - key, - header; + getView: function(view) { + return this.application.getView(view); + } +}); - if (!headers['Content-Type'] && (data || params)) { - if (data) { - if (options.rawData) { - contentType = 'text/plain'; - } else { - if (xmlData && Ext.isDefined(xmlData)) { - contentType = 'text/xml'; - } else if (jsonData && Ext.isDefined(jsonData)) { - contentType = 'application/json'; - } - } - } - headers['Content-Type'] = contentType; - } - if (me.useDefaultXhrHeader && !headers['X-Requested-With']) { - headers['X-Requested-With'] = me.defaultXhrHeader; - } - - try{ - for (key in headers) { - if (headers.hasOwnProperty(key)) { - header = headers[key]; - xhr.setRequestHeader(key, header); - } +Ext.define('Ext.data.IdGenerator', { - } - } catch(e) { - me.fireEvent('exception', key, header); - } - return headers; - }, + isGenerator: true, - getXhrInstance: (function(){ - var options = [function(){ - return new XMLHttpRequest(); - }, function(){ - return new ActiveXObject('MSXML2.XMLHTTP.3.0'); - }, function(){ - return new ActiveXObject('MSXML2.XMLHTTP'); - }, function(){ - return new ActiveXObject('Microsoft.XMLHTTP'); - }], i = 0, - len = options.length, - xhr; + constructor: function(config) { + var me = this; - for(; i < len; ++i) { - try{ - xhr = options[i]; - xhr(); - break; - }catch(e){} + Ext.apply(me, config); + + if (me.id) { + Ext.data.IdGenerator.all[me.id] = me; } - return xhr; - })(), + }, - isLoading : function(request) { - if (!(request && request.xhr)) { - return false; - } - - var state = request.xhr.readyState; - return !(state === 0 || state == 4); + + getRecId: function (rec) { + return rec.modelName + '-' + rec.internalId; }, - abort : function(request) { - var me = this, - requests = me.requests, - id; - if (request && me.isLoading(request)) { - - request.xhr.onreadystatechange = null; - request.xhr.abort(); - me.clearTimeout(request); - if (!request.timedout) { - request.aborted = true; + statics: { + + all: {}, + + + get: function (config) { + var generator, + id, + type; + + if (typeof config == 'string') { + id = type = config; + config = null; + } else if (config.isGenerator) { + return config; + } else { + id = config.id || config.type; + type = config.type; } - me.onComplete(request); - me.cleanup(request); - } else if (!request) { - for(id in requests) { - if (requests.hasOwnProperty(id)) { - me.abort(requests[id]); - } + + generator = this.all[id]; + if (!generator) { + generator = Ext.create('idgen.' + type, config); } + + return generator; } - }, + } +}); + +Ext.define('Ext.data.SortTypes', { - onStateChange : function(request) { - if (request.xhr.readyState == 4) { - this.clearTimeout(request); - this.onComplete(request); - this.cleanup(request); - } + singleton: true, + + + none : function(s) { + return s; }, - clearTimeout: function(request){ - clearTimeout(request.timeout); - delete request.timeout; - }, + stripTagsRE : /<\/?[^>]+>/gi, - cleanup: function(request){ - request.xhr = null; - delete request.xhr; + asText : function(s) { + return String(s).replace(this.stripTagsRE, ""); }, - onComplete : function(request) { - var me = this, - options = request.options, - result = me.parseStatus(request.xhr.status), - success = result.success, - response; - - if (success) { - response = me.createResponse(request); - me.fireEvent('requestcomplete', me, response, options); - Ext.callback(options.success, options.scope, [response, options]); - } else { - if (result.isException || request.aborted || request.timedout) { - response = me.createException(request); - } else { - response = me.createResponse(request); - } - me.fireEvent('requestexception', me, response, options); - Ext.callback(options.failure, options.scope, [response, options]); - } - Ext.callback(options.callback, options.scope, [options, success, response]); - delete me.requests[request.id]; - return response; + asUCText : function(s) { + return String(s).toUpperCase().replace(this.stripTagsRE, ""); }, - parseStatus: function(status) { - - status = status == 1223 ? 204 : status; - - var success = (status >= 200 && status < 300) || status == 304, - isException = false; - - if (!success) { - switch (status) { - case 12002: - case 12029: - case 12030: - case 12031: - case 12152: - case 13030: - isException = true; - break; - } - } - return { - success: success, - isException: isException - }; + asUCString : function(s) { + return String(s).toUpperCase(); }, - createResponse : function(request) { - var xhr = request.xhr, - headers = {}, - lines = xhr.getAllResponseHeaders().replace(/\r\n/g, '\n').split('\n'), - count = lines.length, - line, index, key, value, response; - - while (count--) { - line = lines[count]; - index = line.indexOf(':'); - if(index >= 0) { - key = line.substr(0, index).toLowerCase(); - if (line.charAt(index + 1) == ' ') { - ++index; - } - headers[key] = line.substr(index + 1); - } + asDate : function(s) { + if(!s){ + return 0; } + if(Ext.isDate(s)){ + return s.getTime(); + } + return Date.parse(String(s)); + }, - request.xhr = null; - delete request.xhr; - - response = { - request: request, - requestId : request.id, - status : xhr.status, - statusText : xhr.statusText, - getResponseHeader : function(header){ return headers[header.toLowerCase()]; }, - getAllResponseHeaders : function(){ return headers; }, - responseText : xhr.responseText, - responseXML : xhr.responseXML - }; - - - - xhr = null; - return response; + + asFloat : function(s) { + var val = parseFloat(String(s).replace(/,/g, "")); + return isNaN(val) ? 0 : val; }, - createException : function(request) { - return { - request : request, - requestId : request.id, - status : request.aborted ? -1 : 0, - statusText : request.aborted ? 'transaction aborted' : 'communication failure', - aborted: request.aborted, - timedout: request.timedout - }; + asInt : function(s) { + var val = parseInt(String(s).replace(/,/g, ""), 10); + return isNaN(val) ? 0 : val; } }); - -Ext.define('Ext.Ajax', { - extend: 'Ext.data.Connection', - singleton: true, +Ext.define('Ext.util.Filter', { + - - + anyMatch: false, + exactMatch: false, + caseSensitive: false, - autoAbort : false -}); - -Ext.define('Ext.data.Association', { + constructor: function(config) { + var me = this; + Ext.apply(me, config); + + + + me.filter = me.filter || me.filterFn; + + if (me.filter === undefined) { + if (me.property === undefined || me.value === undefined) { + + + + + } else { + me.filter = me.createFilterFn(); + } + + me.filterFn = me.filter; + } + }, - - + createFilterFn: function() { + var me = this, + matcher = me.createValueMatcher(), + property = me.property; + + return function(item) { + var value = me.getRoot.call(me, item)[property]; + return matcher === null ? value === null : matcher.test(value); + }; + }, - primaryKey: 'id', - + getRoot: function(item) { + var root = this.root; + return root === undefined ? item : item[root]; + }, + createValueMatcher : function() { + var me = this, + value = me.value, + anyMatch = me.anyMatch, + exactMatch = me.exactMatch, + caseSensitive = me.caseSensitive, + escapeRe = Ext.String.escapeRegex; + + if (value === null) { + return value; + } + + if (!value.exec) { + value = String(value); - defaultReaderType: 'json', - - statics: { - create: function(association){ - if (!association.isAssociation) { - if (Ext.isString(association)) { - association = { - type: association - }; - } - - switch (association.type) { - case 'belongsTo': - return Ext.create('Ext.data.BelongsToAssociation', association); - case 'hasMany': - return Ext.create('Ext.data.HasManyAssociation', association); - - - - default: - Ext.Error.raise('Unknown Association type: "' + association.type + '"'); + if (anyMatch === true) { + value = escapeRe(value); + } else { + value = '^' + escapeRe(value); + if (exactMatch === true) { + value += '$'; } } - return association; - } - }, - - constructor: function(config) { - Ext.apply(this, config); - - var types = Ext.ModelManager.types, - ownerName = config.ownerModel, - associatedName = config.associatedModel, - ownerModel = types[ownerName], - associatedModel = types[associatedName], - ownerProto; + value = new RegExp(value, caseSensitive ? '' : 'i'); + } + + return value; + } +}); - if (ownerModel === undefined) { - Ext.Error.raise("The configured ownerModel was not valid (you tried " + ownerName + ")"); - } - if (associatedModel === undefined) { - Ext.Error.raise("The configured associatedModel was not valid (you tried " + associatedName + ")"); - } - - this.ownerModel = ownerModel; - this.associatedModel = associatedModel; - - - - - - Ext.applyIf(this, { - ownerName : ownerName, - associatedName: associatedName - }); - }, +Ext.define('Ext.util.Sorter', { - getReader: function(){ - var me = this, - reader = me.reader, - model = me.associatedModel; - - if (reader) { - if (Ext.isString(reader)) { - reader = { - type: reader - }; - } - if (reader.isReader) { - reader.setModel(model); - } else { - Ext.applyIf(reader, { - model: model, - type : me.defaultReaderType - }); - } - me.reader = Ext.createByAlias('reader.' + reader.type, reader); - } - return me.reader || null; - } -}); - - -Ext.define('Ext.ModelManager', { - extend: 'Ext.AbstractManager', - alternateClassName: 'Ext.ModelMgr', - requires: ['Ext.data.Association'], - singleton: true, - typeName: 'mtype', - associationStack: [], - registerType: function(name, config) { - var proto = config.prototype, - model; - if (proto && proto.isModel) { - - model = config; - } else { - - if (!config.extend) { - config.extend = 'Ext.data.Model'; - } - model = Ext.define(name, config); - } - this.types[name] = model; - return model; - }, - onModelDefined: function(model) { - var stack = this.associationStack, - length = stack.length, - create = [], - association, i, created; + direction: "ASC", + + constructor: function(config) { + var me = this; - for (i = 0; i < length; i++) { - association = stack[i]; - - if (association.associatedModel == model.modelName) { - create.push(association); - } - } + Ext.apply(me, config); - for (i = 0, length = create.length; i < length; i++) { - created = create[i]; - this.types[created.ownerModel].prototype.associations.add(Ext.data.Association.create(created)); - Ext.Array.remove(stack, created); - } - }, - - - registerDeferredAssociation: function(association){ - this.associationStack.push(association); - }, - - - getModel: function(id) { - var model = id; - if (typeof model == 'string') { - model = this.types[model]; - } - return model; + + me.updateSortFunction(); }, - create: function(config, name, id) { - var con = typeof name == 'function' ? name : this.types[name || config.name]; + createSortFunction: function(sorterFn) { + var me = this, + property = me.property, + direction = me.direction || "ASC", + modifier = direction.toUpperCase() == "DESC" ? -1 : 1; - return new con(config, id); - } -}, function() { - - - Ext.regModel = function() { - if (Ext.isDefined(Ext.global.console)) { - Ext.global.console.warn('Ext.regModel has been deprecated. Models can now be created by extending Ext.data.Model: Ext.define("MyModel", {extend: "Ext.data.Model", fields: []});.'); - } - return this.ModelManager.registerType.apply(this.ModelManager, arguments); - }; -}); - - -Ext.define('Ext.app.Controller', { - - - mixins: { - observable: 'Ext.util.Observable' - }, - - onClassExtended: function(cls, data) { - var className = Ext.getClassName(cls), - match = className.match(/^(.*)\.controller\./); - - if (match !== null) { - var namespace = Ext.Loader.getPrefix(className) || match[1], - onBeforeClassCreated = data.onBeforeClassCreated, - requires = [], - modules = ['model', 'view', 'store'], - prefix; - - data.onBeforeClassCreated = function(cls, data) { - var i, ln, module, - items, j, subLn, item; - - for (i = 0,ln = modules.length; i < ln; i++) { - module = modules[i]; - - items = Ext.Array.from(data[module + 's']); - - for (j = 0,subLn = items.length; j < subLn; j++) { - item = items[j]; - - prefix = Ext.Loader.getPrefix(item); - - if (prefix === '' || prefix === item) { - requires.push(namespace + '.' + module + '.' + item); - } - else { - requires.push(item); - } - } - } - - Ext.require(requires, Ext.Function.pass(onBeforeClassCreated, arguments, this)); - }; - } - }, - - constructor: function(config) { - this.mixins.observable.constructor.call(this, config); - - Ext.apply(this, config || {}); - - this.createGetters('model', this.models); - this.createGetters('store', this.stores); - this.createGetters('view', this.views); - - if (this.refs) { - this.ref(this.refs); - } + + + return function(o1, o2) { + return modifier * sorterFn.call(me, o1, o2); + }; }, - - init: function(application) {}, - onLaunch: function(application) {}, - - createGetters: function(type, refs) { - type = Ext.String.capitalize(type); - Ext.Array.each(refs, function(ref) { - var fn = 'get', - parts = ref.split('.'); - - - Ext.Array.each(parts, function(part) { - fn += Ext.String.capitalize(part); - }); - fn += type; - - if (!this[fn]) { - this[fn] = Ext.Function.pass(this['get' + type], [ref], this); - } - - this[fn](ref); - }, - this); - }, - - ref: function(refs) { - var me = this; - refs = Ext.Array.from(refs); - Ext.Array.each(refs, function(info) { - var ref = info.ref, - fn = 'get' + Ext.String.capitalize(ref); - if (!me[fn]) { - me[fn] = Ext.Function.pass(me.getRef, [ref, info], me); - } - }); - }, - - getRef: function(ref, info, config) { - this.refCache = this.refCache || {}; - info = info || {}; - config = config || {}; - - Ext.apply(info, config); - - if (info.forceCreate) { - return Ext.ComponentManager.create(info, 'component'); - } - + defaultSorterFn: function(o1, o2) { var me = this, - selector = info.selector, - cached = me.refCache[ref]; - - if (!cached) { - me.refCache[ref] = cached = Ext.ComponentQuery.query(info.selector)[0]; - if (!cached && info.autoCreate) { - me.refCache[ref] = cached = Ext.ComponentManager.create(info, 'component'); - } - if (cached) { - cached.on('beforedestroy', function() { - me.refCache[ref] = null; - }); - } + transform = me.transform, + v1 = me.getRoot(o1)[me.property], + v2 = me.getRoot(o2)[me.property]; + + if (transform) { + v1 = transform(v1); + v2 = transform(v2); } - return cached; - }, - - control: function(selectors, listeners) { - this.application.control(selectors, listeners, this); - }, - - getController: function(name) { - return this.application.getController(name); - }, - - getStore: function(name) { - return this.application.getStore(name); - }, - - getModel: function(model) { - return this.application.getModel(model); - }, - - getView: function(view) { - return this.application.getView(view); - } -}); - - -Ext.define('Ext.data.SortTypes', { - - singleton: true, - - - none : function(s) { - return s; - }, - - - stripTagsRE : /<\/?[^>]+>/gi, - - - asText : function(s) { - return String(s).replace(this.stripTagsRE, ""); + return v1 > v2 ? 1 : (v1 < v2 ? -1 : 0); }, - - asUCText : function(s) { - return String(s).toUpperCase().replace(this.stripTagsRE, ""); - }, - - asUCString : function(s) { - return String(s).toUpperCase(); + getRoot: function(item) { + return this.root === undefined ? item : item[this.root]; }, - - asDate : function(s) { - if(!s){ - return 0; - } - if(Ext.isDate(s)){ - return s.getTime(); - } - return Date.parse(String(s)); - }, - - asFloat : function(s) { - var val = parseFloat(String(s).replace(/,/g, "")); - return isNaN(val) ? 0 : val; + setDirection: function(direction) { + var me = this; + me.direction = direction; + me.updateSortFunction(); }, - - - asInt : function(s) { - var val = parseInt(String(s).replace(/,/g, ""), 10); - return isNaN(val) ? 0 : val; - } -}); - -Ext.define('Ext.data.Errors', { - extend: 'Ext.util.MixedCollection', - isValid: function() { - return this.length === 0; + toggle: function() { + var me = this; + me.direction = Ext.String.toggle(me.direction, "ASC", "DESC"); + me.updateSortFunction(); }, - getByField: function(fieldName) { - var errors = [], - error, field, i; - - for (i = 0; i < this.length; i++) { - error = this.items[i]; - - if (error.field == fieldName) { - errors.push(error); - } - } - - return errors; + updateSortFunction: function(fn) { + var me = this; + fn = fn || me.sorterFn || me.defaultSorterFn; + me.sort = me.createSortFunction(fn); } }); - Ext.define('Ext.data.Operation', { synchronous: true, - + action: undefined, - + filters: undefined, - + sorters: undefined, - + group: undefined, - + start: undefined, - + limit: undefined, - + batch: undefined, - + - started: false, + callback: undefined, + + scope: undefined, + - running: false, + started: false, + + running: false, + complete: false, - + success: undefined, - + exception: false, - + error: undefined, + + + actionCommitRecordsRe: /^(?:create|update)$/i, + + + actionSkipSyncRe: /^destroy$/i, + constructor: function(config) { Ext.apply(this, config || {}); }, + + commitRecords: function (serverRecords) { + var me = this, + mc, index, clientRecords, serverRec, clientRec; + + if (!me.actionSkipSyncRe.test(me.action)) { + clientRecords = me.records; + + if (clientRecords && clientRecords.length) { + mc = Ext.create('Ext.util.MixedCollection', true, function(r) {return r.getId();}); + mc.addAll(clientRecords); + + for (index = serverRecords ? serverRecords.length : 0; index--; ) { + serverRec = serverRecords[index]; + clientRec = mc.get(serverRec.getId()); + + if (clientRec) { + clientRec.beginEdit(); + clientRec.set(serverRec.data); + clientRec.endEdit(true); + } + } + + if (me.actionCommitRecordsRe.test(me.action)) { + for (index = clientRecords.length; index--; ) { + clientRecords[index].commit(); + } + } + } + } + }, + setStarted: function() { this.started = true; this.running = true; }, - + setCompleted: function() { this.complete = true; this.running = false; }, - + setSuccessful: function() { this.success = true; }, - + setException: function(error) { this.exception = true; @@ -21534,54 +20160,54 @@ Ext.define('Ext.data.Operation', { this.running = false; this.error = error; }, - + hasException: function() { return this.exception === true; }, - + getError: function() { return this.error; }, - + getRecords: function() { var resultSet = this.getResultSet(); - + return (resultSet === undefined ? this.records : resultSet.records); }, - + getResultSet: function() { return this.resultSet; }, - + isStarted: function() { return this.started === true; }, - + isRunning: function() { return this.running === true; }, - + isComplete: function() { return this.complete === true; }, - + wasSuccessful: function() { return this.isComplete() && this.success === true; }, - + setBatch: function(batch) { this.batch = batch; }, - + allowWrite: function() { return this.action != 'read'; @@ -21607,17 +20233,24 @@ Ext.define('Ext.data.validations', { exclusionMessage: 'is not an acceptable value', + emailMessage: 'is not a valid email address', + + + emailRe: /^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/, + + presence: function(config, value) { if (value === undefined) { value = config; } - return !!value; + + return !!value || value === 0; }, length: function(config, value) { - if (value === undefined) { + if (value === undefined || value === null) { return false; } @@ -21633,6 +20266,11 @@ Ext.define('Ext.data.validations', { }, + email: function(config, email) { + return Ext.data.validations.emailRe.test(email); + }, + + format: function(config, value) { return !!(config.matcher && config.matcher.test(value)); }, @@ -21651,24 +20289,25 @@ Ext.define('Ext.data.validations', { Ext.define('Ext.data.ResultSet', { loaded: true, - + count: 0, - + total: 0, - + success: false, - + + constructor: function(config) { Ext.apply(this, config); - + this.totalRecords = this.total; - + if (config.count === undefined) { this.count = this.records.length; } @@ -21685,6 +20324,7 @@ Ext.define('Ext.data.writer.Writer', { nameProperty: 'name', + constructor: function(config) { Ext.apply(this, config); }, @@ -21753,15 +20393,17 @@ Ext.define('Ext.util.Floating', { shadow: 'sides', constructor: function(config) { - this.floating = true; - this.el = Ext.create('Ext.Layer', Ext.apply({}, config, { - hideMode: this.hideMode, - hidden: this.hidden, - shadow: Ext.isDefined(this.shadow) ? this.shadow : 'sides', - shadowOffset: this.shadowOffset, + var me = this; + + me.floating = true; + me.el = Ext.create('Ext.Layer', Ext.apply({}, config, { + hideMode: me.hideMode, + hidden: me.hidden, + shadow: Ext.isDefined(me.shadow) ? me.shadow : 'sides', + shadowOffset: me.shadowOffset, constrain: false, - shim: this.shim === false ? false : undefined - }), this.el); + shim: me.shim === false ? false : undefined + }), me.el); }, onFloatRender: function() { @@ -21808,8 +20450,12 @@ Ext.define('Ext.util.Floating', { }, onFloatParentHide: function() { - this.showOnParentShow = this.isVisible(); - this.hide(); + var me = this; + + if (me.hideOnParentHide !== false) { + me.showOnParentShow = me.isVisible(); + me.hide(); + } }, onFloatParentShow: function() { @@ -21842,7 +20488,7 @@ Ext.define('Ext.util.Floating', { setZIndex: function(index) { var me = this; - this.el.setZIndex(index); + me.el.setZIndex(index); index += 10; @@ -21858,7 +20504,7 @@ Ext.define('Ext.util.Floating', { doConstrain: function(constrainTo) { var me = this, - vector = me.getConstrainVector(constrainTo), + vector = me.getConstrainVector(constrainTo || me.el.getScopeParent()), xy; if (vector) { @@ -21868,13 +20514,13 @@ Ext.define('Ext.util.Floating', { me.setPosition(xy); } }, - - + + 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; @@ -21917,18 +20563,20 @@ Ext.define('Ext.util.Floating', { setActive: function(active, newActive) { + var me = this; + if (active) { - if ((this instanceof Ext.window.Window) && !this.maximized) { - this.el.enableShadow(true); + if (me.el.shadow && !me.maximized) { + me.el.enableShadow(true); } - this.fireEvent('activate', this); + me.fireEvent('activate', me); } else { - if ((this instanceof Ext.window.Window) && (newActive instanceof Ext.window.Window)) { - this.el.disableShadow(); + if ((me instanceof Ext.window.Window) && (newActive instanceof Ext.window.Window)) { + me.el.disableShadow(); } - this.fireEvent('deactivate', this); + me.fireEvent('deactivate', me); } }, @@ -21940,9 +20588,10 @@ Ext.define('Ext.util.Floating', { center: function() { - var xy = this.el.getAlignToXY(this.container, 'c-c'); - this.setPagePosition(xy); - return this; + var me = this, + xy = me.el.getAlignToXY(me.container, 'c-c'); + me.setPagePosition(xy); + return me; }, @@ -21962,90 +20611,198 @@ Ext.define('Ext.util.Floating', { } }); - -Ext.define('Ext.layout.container.AbstractContainer', { - - - - extend: 'Ext.layout.Layout', - - - - type: 'container', - - fixedLayout: true, - - - managedHeight: true, - - managedWidth: true, - - - bindToOwnerCtComponent: false, +Ext.define('Ext.layout.Layout', { - bindToOwnerCtContainer: false, - isManaged: function(dimension) { - dimension = Ext.String.capitalize(dimension); - var me = this, - child = me, - managed = me['managed' + dimension], - ancestor = me.owner.ownerCt; + isLayout: true, + initialized: false, - if (ancestor && ancestor.layout) { - while (ancestor && ancestor.layout) { - if (managed === false || ancestor.layout['managed' + dimension] === false) { - managed = false; - break; + statics: { + create: function(layout, defaultType) { + var type; + if (layout instanceof Ext.layout.Layout) { + return Ext.createByAlias('layout.' + layout); + } else { + if (!layout || typeof layout === 'string') { + type = layout || defaultType; + layout = {}; } - ancestor = ancestor.ownerCt; + else { + type = layout.type || defaultType; + } + return Ext.createByAlias('layout.' + type, layout || {}); } } - 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); - }, + constructor : function(config) { + this.id = Ext.id(null, this.type + '-'); + Ext.apply(this, config); + }, - setItemSize: function(item, width, height) { - if (Ext.isObject(width)) { - height = width.height; - width = width.width; + layout : function() { + var me = this; + me.layoutBusy = true; + me.initLayout(); + + if (me.beforeLayout.apply(me, arguments) !== false) { + me.layoutCancelled = false; + me.onLayout.apply(me, arguments); + me.childrenChanged = false; + me.owner.needsLayout = false; + me.layoutBusy = false; + me.afterLayout.apply(me, arguments); } - item.setCalculatedSize(width, height, this.owner); + else { + me.layoutCancelled = true; + } + me.layoutBusy = false; + me.doOwnerCtLayouts(); + }, + + beforeLayout : function() { + this.renderChildren(); + return true; + }, + + renderChildren: function () { + this.renderItems(this.getLayoutItems(), this.getRenderTarget()); }, - getLayoutItems: function() { - return this.owner && this.owner.items && this.owner.items.items || []; + renderItems : function(items, target) { + var me = this, + ln = items.length, + i = 0, + item; + + for (; i < ln; i++) { + item = items[i]; + if (item && !item.rendered) { + me.renderItem(item, target, i); + } else if (!me.isValidParent(item, target, i)) { + me.moveItem(item, target, i); + } else { + + me.configureItem(item); + } + } }, - afterLayout: function() { - this.owner.afterLayout(this); + + isValidParent : function(item, target, position) { + var dom = item.el ? item.el.dom : Ext.getDom(item); + if (dom && target && target.dom) { + if (Ext.isNumber(position) && dom !== target.dom.childNodes[position]) { + return false; + } + return (dom.parentNode == (target.dom || target)); + } + return false; }, + - getTarget: function() { - return this.owner.getTargetEl(); - }, + renderItem : function(item, target, position) { + var me = this; + if (!item.rendered) { + if (me.itemCls) { + item.addCls(me.itemCls); + } + if (me.owner.itemCls) { + item.addCls(me.owner.itemCls); + } + item.render(target, position); + me.configureItem(item); + me.childrenChanged = true; + } + }, + - getRenderTarget: function() { - return this.owner.getTargetEl(); - } -}); + moveItem : function(item, target, position) { + + target = target.dom || target; + if (typeof position == 'number') { + position = target.childNodes[position]; + } + target.insertBefore(item.el.dom, position || null); + item.container = Ext.get(target); + this.configureItem(item); + this.childrenChanged = true; + }, + + + initLayout : function() { + var me = this, + targetCls = me.targetCls; + + if (!me.initialized && !Ext.isEmpty(targetCls)) { + me.getTarget().addCls(targetCls); + } + me.initialized = true; + }, + + + setOwner : function(owner) { + this.owner = owner; + }, + + getLayoutItems : function() { + return []; + }, + + + configureItem: Ext.emptyFn, + + + onLayout : Ext.emptyFn, + afterLayout : Ext.emptyFn, + onRemove : Ext.emptyFn, + onDestroy : Ext.emptyFn, + doOwnerCtLayouts : Ext.emptyFn, + + + afterRemove : function(item) { + var el = item.el, + owner = this.owner, + itemCls = this.itemCls, + ownerCls = owner.itemCls; + + + if (item.rendered && !item.isDestroyed) { + if (itemCls) { + el.removeCls(itemCls); + } + if (ownerCls) { + el.removeCls(ownerCls); + } + } + + + + + delete item.layoutManagedWidth; + delete item.layoutManagedHeight; + }, + + + destroy : function() { + var targetCls = this.targetCls, + target; + + if (!Ext.isEmpty(targetCls)) { + target = this.getTarget(); + if (target) { + target.removeCls(targetCls); + } + } + this.onDestroy(); + } +}); Ext.define('Ext.ZIndexManager', { @@ -22127,7 +20884,7 @@ Ext.define('Ext.ZIndexManager', { _setActiveChild: function(comp) { - if (comp != this.front) { + if (comp !== this.front) { if (this.front) { this.front.setActive(false, comp); @@ -22136,7 +20893,7 @@ Ext.define('Ext.ZIndexManager', { if (comp) { comp.setActive(true); if (comp.modal) { - this._showModalMask(comp.el.getStyle('zIndex') - 4); + this._showModalMask(comp); } } } @@ -22161,7 +20918,7 @@ Ext.define('Ext.ZIndexManager', { if (comp.modal) { - this._showModalMask(comp.el.getStyle('zIndex') - 4); + this._showModalMask(comp); return; } } @@ -22175,23 +20932,36 @@ Ext.define('Ext.ZIndexManager', { } }, - _showModalMask: function(zIndex) { + _showModalMask: function(comp) { + var zIndex = comp.el.getStyle('zIndex') - 4, + maskTarget = comp.floatParent ? comp.floatParent.getTargetEl() : Ext.get(comp.getEl().dom.parentNode), + parentBox; + + if (!maskTarget) { + return; + } + + parentBox = maskTarget.getBox(); + if (!this.mask) { - this.mask = this.targetEl.createChild({ + this.mask = Ext.getBody().createChild({ cls: Ext.baseCSSPrefix + 'mask' }); - this.mask.setVisibilityMode(Ext.core.Element.DISPLAY); + this.mask.setVisibilityMode(Ext.Element.DISPLAY); this.mask.on('click', this._onMaskClick, this); } - Ext.getBody().addCls(Ext.baseCSSPrefix + 'body-masked'); - this.mask.setSize(this.targetEl.getViewSize(true)); + if (maskTarget.dom === document.body) { + parentBox.height = Ext.Element.getViewHeight(); + } + maskTarget.addCls(Ext.baseCSSPrefix + 'body-masked'); + this.mask.setBox(parentBox); this.mask.setStyle('zIndex', zIndex); this.mask.show(); }, _hideModalMask: function() { - if (this.mask) { - Ext.getBody().removeCls(Ext.baseCSSPrefix + 'body-masked'); + if (this.mask && this.mask.dom.parentNode) { + Ext.get(this.mask.dom.parentNode).removeCls(Ext.baseCSSPrefix + 'body-masked'); this.mask.hide(); } }, @@ -22204,7 +20974,7 @@ Ext.define('Ext.ZIndexManager', { _onContainerResize: function() { if (this.mask && this.mask.isVisible()) { - this.mask.setSize(this.targetEl.getViewSize(true)); + this.mask.setSize(Ext.get(this.mask.dom.parentNode).getViewSize(true)); } }, @@ -22241,16 +21011,14 @@ Ext.define('Ext.ZIndexManager', { bringToFront : function(comp) { comp = this.get(comp); - if (comp != this.front) { + if (comp !== this.front) { Ext.Array.remove(this.zIndexStack, comp); this.zIndexStack.push(comp); this.assignZIndices(); return true; } if (comp.modal) { - Ext.getBody().addCls(Ext.baseCSSPrefix + 'body-masked'); - this.mask.setSize(Ext.core.Element.getViewWidth(true), Ext.core.Element.getViewHeight(true)); - this.mask.show(); + this._showModalMask(comp); } return false; }, @@ -22368,6 +21136,9 @@ Ext.define('Ext.ZIndexManager', { }, destroy: function() { + this.each(function(c) { + c.destroy(); + }); delete this.zIndexStack; delete this.list; delete this.container; @@ -22404,10 +21175,11 @@ Ext.define('Ext.layout.container.boxOverflow.None', { Ext.define('Ext.util.KeyMap', { alternateClassName: 'Ext.KeyMap', + constructor: function(el, binding, eventName){ var me = this; - + Ext.apply(me, { el: Ext.get(el), eventName: eventName || me.eventName, @@ -22418,7 +21190,7 @@ Ext.define('Ext.util.KeyMap', { } me.enable(); }, - + eventName: 'keydown', @@ -22427,7 +21199,7 @@ Ext.define('Ext.util.KeyMap', { Ext.each(binding, this.addBinding, this); return; } - + var keyCode = binding.key, processed = false, key, @@ -22438,52 +21210,52 @@ Ext.define('Ext.util.KeyMap', { if (Ext.isString(keyCode)) { keys = []; - keyString = keyCode.toLowerCase(); - + keyString = keyCode.toUpperCase(); + for (i = 0, len = keyString.length; i < len; ++i){ keys.push(keyString.charCodeAt(i)); } keyCode = keys; processed = true; } - + if (!Ext.isArray(keyCode)) { keyCode = [keyCode]; } - + if (!processed) { for (i = 0, len = keyCode.length; i < len; ++i) { key = keyCode[i]; if (Ext.isString(key)) { - keyCode[i] = key.toLowerCase().charCodeAt(0); + keyCode[i] = key.toUpperCase().charCodeAt(0); } } } - + this.bindings.push(Ext.apply({ keyCode: keyCode }, binding)); }, - + handleKeyDown: function(event) { if (this.enabled) { var bindings = this.bindings, i = 0, len = bindings.length; - + event = this.processEvent(event); for(; i < len; ++i){ this.processBinding(bindings[i], event); } } }, - + processEvent: function(event){ return event; }, - + processBinding: function(binding, event){ if (this.checkModifiers(binding, event)) { @@ -22495,8 +21267,8 @@ Ext.define('Ext.util.KeyMap', { i, len, keydownEvent = new Ext.EventObjectImpl(event); - - + + for (i = 0, len = keyCode.length; i < len; ++i) { if (key === keyCode[i]) { if (handler.call(scope, key, event) !== true && defaultEventAction) { @@ -22507,14 +21279,14 @@ Ext.define('Ext.util.KeyMap', { } } }, - + checkModifiers: function(binding, e){ var keys = ['shift', 'ctrl', 'alt'], i = 0, len = keys.length, val, key; - + for (; i < len; ++i){ key = keys[i]; val = binding[key]; @@ -22553,17 +21325,21 @@ Ext.define('Ext.util.KeyMap', { enable: function(){ - if(!this.enabled){ - this.el.on(this.eventName, this.handleKeyDown, this); - this.enabled = true; + var me = this; + + if (!me.enabled) { + me.el.on(me.eventName, me.handleKeyDown, me); + me.enabled = true; } }, disable: function(){ - if(this.enabled){ - this.el.removeListener(this.eventName, this.handleKeyDown, this); - this.enabled = false; + var me = this; + + if (me.enabled) { + me.el.removeListener(me.eventName, me.handleKeyDown, me); + me.enabled = false; } }, @@ -22575,11 +21351,11 @@ Ext.define('Ext.util.KeyMap', { this.enable(); } }, - + destroy: function(removeEl){ var me = this; - + me.bindings = []; me.disable(); if (removeEl === true) { @@ -22589,10 +21365,10 @@ Ext.define('Ext.util.KeyMap', { } }); - Ext.define('Ext.util.ClickRepeater', { extend: 'Ext.util.Observable', + constructor : function(el, config){ this.el = Ext.get(el); this.el.unselectable(); @@ -22770,133 +21546,253 @@ Ext.define('Ext.util.ClickRepeater', { }); -Ext.define('Ext.layout.component.Button', { +Ext.define('Ext.layout.component.Component', { - alias: ['layout.button'], - - extend: 'Ext.layout.component.Component', + extend: 'Ext.layout.Layout', - type: 'button', - - cellClsRE: /-btn-(tl|br)\b/, - htmlRE: /<.*>/, + type: 'component', - beforeLayout: function() { - return this.callParent(arguments) || this.lastText !== this.owner.text; - }, + monitorChildren: true, - - onLayout: function(width, height) { + initLayout : function() { var me = this, - isNum = Ext.isNumber, owner = me.owner, - ownerEl = owner.el, - btnEl = owner.btnEl, - btnInnerEl = owner.btnInnerEl, - minWidth = owner.minWidth, - maxWidth = owner.maxWidth, - ownerWidth, btnFrameWidth, metrics; + ownerEl = owner.el; - me.getTargetInfo(); + if (!me.initialized) { + if (owner.frameSize) { + me.frameSize = owner.frameSize; + } + else { + owner.frameSize = me.frameSize = { + top: 0, + left: 0, + bottom: 0, + right: 0 + }; + } + } me.callParent(arguments); + }, - btnInnerEl.unclip(); - me.setTargetSize(width, height); + beforeLayout : function(width, height, isSetSize, callingContainer) { + this.callParent(arguments); - if (!isNum(width)) { - + var me = this, + owner = me.owner, + ownerCt = owner.ownerCt, + layout = owner.layout, + isVisible = owner.isVisible(true), + ownerElChild = owner.el.child, + layoutCollection; + + + me.previousComponentSize = me.lastComponentSize; + + + if (!isSetSize + && ((!Ext.isNumber(width) && owner.isFixedWidth()) || + (!Ext.isNumber(height) && owner.isFixedHeight())) + && callingContainer && callingContainer !== ownerCt) { - if (owner.text && Ext.isIE7 && Ext.isStrict && btnEl && btnEl.getWidth() > 20) { - btnFrameWidth = me.btnFrameWidth; - metrics = Ext.util.TextMetrics.measure(btnInnerEl, owner.text); - ownerEl.setWidth(metrics.width + btnFrameWidth + me.adjWidth); - btnEl.setWidth(metrics.width + btnFrameWidth); - btnInnerEl.setWidth(metrics.width + btnFrameWidth); - } else { - - ownerEl.setWidth(null); - btnEl.setWidth(null); - btnInnerEl.setWidth(null); - } + me.doContainerLayout(); + return false; + } - - if (minWidth || maxWidth) { - ownerWidth = ownerEl.getWidth(); - if (minWidth && (ownerWidth < minWidth)) { - me.setTargetSize(minWidth, height); - } - else if (maxWidth && (ownerWidth > maxWidth)) { - btnInnerEl.clip(); - me.setTargetSize(maxWidth, height); - } + + + if (!isVisible && (owner.hiddenAncestor || owner.floating)) { + if (owner.hiddenAncestor) { + layoutCollection = owner.hiddenAncestor.layoutOnShow; + layoutCollection.remove(owner); + layoutCollection.add(owner); } + owner.needsLayout = { + width: width, + height: height, + isSetSize: false + }; } - this.lastText = owner.text; + if (isVisible && this.needsLayout(width, height)) { + return owner.beforeComponentLayout(width, height, isSetSize, callingContainer); + } + else { + return false; + } }, - setTargetSize: function(width, height) { + + needsLayout : function(width, height) { var me = this, - owner = me.owner, - isNum = Ext.isNumber, - btnInnerEl = owner.btnInnerEl, - btnWidth = (isNum(width) ? width - me.adjWidth : width), - btnHeight = (isNum(height) ? height - me.adjHeight : height), - btnFrameHeight = me.btnFrameHeight, - text = owner.getText(), - textHeight; - - me.callParent(arguments); - me.setElementSize(owner.btnEl, btnWidth, btnHeight); - me.setElementSize(btnInnerEl, btnWidth, btnHeight); - if (isNum(btnHeight)) { - btnInnerEl.setStyle('line-height', btnHeight - btnFrameHeight + 'px'); - } + widthBeingChanged, + heightBeingChanged; + me.lastComponentSize = me.lastComponentSize || { + width: -Infinity, + height: -Infinity + }; + widthBeingChanged = !Ext.isDefined(width) || me.lastComponentSize.width !== width; + + heightBeingChanged = !Ext.isDefined(height) || me.lastComponentSize.height !== height; + + + return !me.isSizing && (me.childrenChanged || widthBeingChanged || heightBeingChanged); + }, + + + setElementSize: function(el, width, height) { + if (width !== undefined && height !== undefined) { + el.setSize(width, height); + } + else if (height !== undefined) { + el.setHeight(height); + } + else if (width !== undefined) { + el.setWidth(width); + } + }, + + + getTarget : function() { + return this.owner.el; + }, + + + getRenderTarget : function() { + return this.owner.el; + }, + + + setTargetSize : function(width, height) { + var me = this; + me.setElementSize(me.owner.el, width, height); + + if (me.owner.frameBody) { + var targetInfo = me.getTargetInfo(), + padding = targetInfo.padding, + border = targetInfo.border, + frameSize = me.frameSize; + + me.setElementSize(me.owner.frameBody, + Ext.isNumber(width) ? (width - frameSize.left - frameSize.right - padding.left - padding.right - border.left - border.right) : width, + Ext.isNumber(height) ? (height - frameSize.top - frameSize.bottom - padding.top - padding.bottom - border.top - border.bottom) : height + ); + } + + me.autoSized = { + width: !Ext.isNumber(width), + height: !Ext.isNumber(height) + }; + + me.lastComponentSize = { + width: width, + height: height + }; + }, + + getTargetInfo : function() { + if (!this.targetInfo) { + var target = this.getTarget(), + body = this.owner.getTargetEl(); + + this.targetInfo = { + padding: { + top: target.getPadding('t'), + right: target.getPadding('r'), + bottom: target.getPadding('b'), + left: target.getPadding('l') + }, + border: { + top: target.getBorderWidth('t'), + right: target.getBorderWidth('r'), + bottom: target.getBorderWidth('b'), + left: target.getBorderWidth('l') + }, + bodyMargin: { + top: body.getMargin('t'), + right: body.getMargin('r'), + bottom: body.getMargin('b'), + left: body.getMargin('l') + } + }; + } + return this.targetInfo; + }, + + + doOwnerCtLayouts: function() { + var owner = this.owner, + ownerCt = owner.ownerCt, + ownerCtComponentLayout, ownerCtContainerLayout, + curSize = this.lastComponentSize, + prevSize = this.previousComponentSize, + widthChange = (prevSize && curSize && Ext.isNumber(curSize.width )) ? curSize.width !== prevSize.width : true, + heightChange = (prevSize && curSize && Ext.isNumber(curSize.height)) ? curSize.height !== prevSize.height : true; + - - if (text && this.htmlRE.test(text)) { - btnInnerEl.setStyle('line-height', 'normal'); - textHeight = Ext.util.TextMetrics.measure(btnInnerEl, text).height; - btnInnerEl.setStyle('padding-top', me.btnFrameTop + Math.max(btnInnerEl.getHeight() - btnFrameHeight - textHeight, 0) / 2 + 'px'); - me.setElementSize(btnInnerEl, btnWidth, btnHeight); + if (!ownerCt || (!widthChange && !heightChange)) { + return; + } + + ownerCtComponentLayout = ownerCt.componentLayout; + ownerCtContainerLayout = ownerCt.layout; + + if (!owner.floating && ownerCtComponentLayout && ownerCtComponentLayout.monitorChildren && !ownerCtComponentLayout.layoutBusy) { + if (!ownerCt.suspendLayout && ownerCtContainerLayout && !ownerCtContainerLayout.layoutBusy) { + + + if (((widthChange && !ownerCt.isFixedWidth()) || (heightChange && !ownerCt.isFixedHeight()))) { + + this.isSizing = true; + ownerCt.doComponentLayout(); + this.isSizing = false; + } + + else if (ownerCtContainerLayout.bindToOwnerCtContainer === true) { + ownerCtContainerLayout.layout(); + } + } } }, - getTargetInfo: function() { + doContainerLayout: function() { var me = this, owner = me.owner, - ownerEl = owner.el, - frameSize = me.frameSize, - frameBody = owner.frameBody, - btnWrap = owner.btnWrap, - innerEl = owner.btnInnerEl; + ownerCt = owner.ownerCt, + layout = owner.layout, + ownerCtComponentLayout; - if (!('adjWidth' in me)) { - Ext.apply(me, { - - adjWidth: frameSize.left + frameSize.right + ownerEl.getBorderWidth('lr') + ownerEl.getPadding('lr') + - btnWrap.getPadding('lr') + (frameBody ? frameBody.getFrameWidth('lr') : 0), - adjHeight: frameSize.top + frameSize.bottom + ownerEl.getBorderWidth('tb') + ownerEl.getPadding('tb') + - btnWrap.getPadding('tb') + (frameBody ? frameBody.getFrameWidth('tb') : 0), - btnFrameWidth: innerEl.getFrameWidth('lr'), - btnFrameHeight: innerEl.getFrameWidth('tb'), - btnFrameTop: innerEl.getFrameWidth('t') - }); + + + if (!owner.suspendLayout && layout && layout.isLayout && !layout.layoutBusy && !layout.isAutoDock) { + layout.layout(); } - return me.callParent(); + + if (ownerCt && ownerCt.componentLayout) { + ownerCtComponentLayout = ownerCt.componentLayout; + if (!owner.floating && ownerCtComponentLayout.monitorChildren && !ownerCtComponentLayout.layoutBusy) { + ownerCtComponentLayout.childrenChanged = true; + } + } + }, + + afterLayout : function(width, height, isSetSize, layoutOwner) { + this.doContainerLayout(); + this.owner.afterComponentLayout(width, height, isSetSize, layoutOwner); } }); + Ext.define('Ext.util.TextMetrics', { statics: { shared: null, @@ -22982,7 +21878,7 @@ Ext.define('Ext.util.TextMetrics', { delete me.measure; } }, function(){ - Ext.core.Element.addMethods({ + Ext.Element.addMethods({ 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); @@ -22996,7 +21892,7 @@ Ext.define('Ext.layout.container.boxOverflow.Scroller', { extend: 'Ext.layout.container.boxOverflow.None', - requires: ['Ext.util.ClickRepeater', 'Ext.core.Element'], + requires: ['Ext.util.ClickRepeater', 'Ext.Element'], alternateClassName: 'Ext.layout.boxOverflow.Scroller', mixins: { observable: 'Ext.util.Observable' @@ -23134,8 +22030,8 @@ Ext.define('Ext.layout.container.boxOverflow.Scroller', { before.addClsOnOver(this.beforeScrollerCls + '-hover'); after.addClsOnOver(this.afterScrollerCls + '-hover'); - before.setVisibilityMode(Ext.core.Element.DISPLAY); - after.setVisibilityMode(Ext.core.Element.DISPLAY); + before.setVisibilityMode(Ext.Element.DISPLAY); + after.setVisibilityMode(Ext.Element.DISPLAY); this.beforeRepeater = Ext.create('Ext.util.ClickRepeater', before, { interval: this.scrollRepeatInterval, @@ -23321,9 +22217,6 @@ Ext.define('Ext.util.Offset', { }, equals: function(offset) { - if(!(offset instanceof this.statics())) { - Ext.Error.raise('Offset must be an instance of Ext.util.Offset'); - } return (this.x == offset.x && this.y == offset.y); }, @@ -23369,6 +22262,7 @@ Ext.define('Ext.util.KeyNav', { tab: 9 } }, + constructor: function(el, config){ this.setConfig(el, config || {}); @@ -23566,11 +22460,11 @@ Ext.define('Ext.fx.Queue', { } }); - Ext.define('Ext.fx.target.Target', { isAnimTarget: true, + constructor: function(target) { this.target = target; this.id = this.getId(); @@ -23780,7 +22674,7 @@ Ext.define('Ext.fx.target.Component', { o = meth.setPagePosition; o.target.setPagePosition(o.x, o.y); } - if (meth.setSize.target) { + if (meth.setSize.target && meth.setSize.target.el) { o = meth.setSize; w = (o.width === undefined) ? o.target.getWidth() : parseInt(o.width, 10); @@ -24120,11 +23014,13 @@ Ext.define('Ext.draw.Color', { Ext.define('Ext.dd.StatusProxy', { animRepair: false, + constructor: function(config){ Ext.apply(this, config); this.id = this.id || Ext.id(); this.proxy = Ext.createWidget('component', { floating: true, + stateful: false, id: this.id, html: '
' + '
', @@ -24135,7 +23031,7 @@ Ext.define('Ext.dd.StatusProxy', { this.el = this.proxy.el; this.el.show(); - this.el.setVisibilityMode(Ext.core.Element.VISIBILITY); + this.el.setVisibilityMode(Ext.Element.VISIBILITY); this.el.hide(); this.ghost = Ext.get(this.el.dom.childNodes[1]); @@ -24173,7 +23069,7 @@ Ext.define('Ext.dd.StatusProxy', { html.style.margin = "0"; this.ghost.dom.appendChild(html); } - var el = this.ghost.dom.firstChild; + var el = this.ghost.dom.firstChild; if(el){ Ext.fly(el).setStyle('float', 'none'); } @@ -24254,8 +23150,9 @@ Ext.define('Ext.dd.StatusProxy', { }); Ext.define('Ext.panel.Proxy', { - + alternateClassName: 'Ext.dd.PanelProxy', + constructor: function(panel, config){ @@ -24307,7 +23204,7 @@ Ext.define('Ext.panel.Proxy', { show: function(){ if (!this.ghost) { var panelSize = this.panel.getSize(); - this.panel.el.setVisibilityMode(Ext.core.Element.DISPLAY); + this.panel.el.setVisibilityMode(Ext.Element.DISPLAY); this.ghost = this.panel.ghost(); if (this.insertProxy) { @@ -24444,6 +23341,10 @@ Ext.define('Ext.layout.component.AbstractDock', { onLayout: function(width, height) { + if (this.onLayout_running) { + return; + } + this.onLayout_running = true; var me = this, owner = me.owner, body = owner.body, @@ -24462,6 +23363,8 @@ Ext.define('Ext.layout.component.AbstractDock', { }, bodyBox: {} }; + + delete layout.isAutoDock; Ext.applyIf(info, me.getTargetInfo()); @@ -24476,20 +23379,20 @@ Ext.define('Ext.layout.component.AbstractDock', { } - if (height === undefined || height === null || width === undefined || width === null) { + if (height == null || width == null) { padding = info.padding; border = info.border; frameSize = me.frameSize; - if ((height === undefined || height === null) && (width === undefined || width === null)) { + if ((height == null) && (width == null)) { autoHeight = true; autoWidth = true; me.setTargetSize(null); me.setBodyBox({width: null, height: null}); } - else if (height === undefined || height === null) { + else if (height == null) { autoHeight = true; me.setTargetSize(width); @@ -24507,6 +23410,8 @@ Ext.define('Ext.layout.component.AbstractDock', { if (layout && layout.isLayout) { layout.bindToOwnerCtComponent = true; + + layout.isAutoDock = layout.autoSize !== true; layout.layout(); @@ -24522,6 +23427,8 @@ Ext.define('Ext.layout.component.AbstractDock', { info.autoSizedCtLayout = layout.autoSize === true; + info.autoHeight = autoHeight; + info.autoWidth = autoWidth; } @@ -24529,7 +23436,7 @@ Ext.define('Ext.layout.component.AbstractDock', { - me.dockItems(autoWidth, autoHeight); + me.dockItems(); me.setTargetSize(info.size.width, info.size.height); } else { @@ -24537,28 +23444,32 @@ Ext.define('Ext.layout.component.AbstractDock', { me.dockItems(); } me.callParent(arguments); + this.onLayout_running = false; }, - dockItems : function(autoWidth, autoHeight) { - this.calculateDockBoxes(autoWidth, autoHeight); + dockItems : function() { + this.calculateDockBoxes(); var info = this.info, + autoWidth = info.autoWidth, + autoHeight = info.autoHeight, boxes = info.boxes, ln = boxes.length, - dock, i; + dock, i, item; for (i = 0; i < ln; i++) { dock = boxes[i]; - dock.item.setPosition(dock.x, dock.y); - if ((autoWidth || autoHeight) && dock.layout && dock.layout.isLayout) { + item = dock.item; + item.setPosition(dock.x, dock.y); + if ((autoWidth || autoHeight) && item.layout && item.layout.isLayout) { - dock.layout.bindToOwnerCtComponent = true; + item.layout.bindToOwnerCtComponent = true; } } @@ -24579,7 +23490,12 @@ Ext.define('Ext.layout.component.AbstractDock', { }, - calculateDockBoxes : function(autoWidth, autoHeight) { + calculateDockBoxes : function() { + if (this.calculateDockBoxes_running) { + + return; + } + this.calculateDockBoxes_running = true; @@ -24589,6 +23505,8 @@ Ext.define('Ext.layout.component.AbstractDock', { owner = me.owner, bodyEl = owner.body, info = me.info, + autoWidth = info.autoWidth, + autoHeight = info.autoHeight, size = info.size, ln = items.length, padding = info.padding, @@ -24638,6 +23556,7 @@ Ext.define('Ext.layout.component.AbstractDock', { info.boxes.push(box); } + this.calculateDockBoxes_running = false; }, @@ -24710,6 +23629,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, @@ -24740,20 +23660,30 @@ Ext.define('Ext.layout.component.AbstractDock', { box.y = bodyBox.y; if (!box.overlay) { bodyBox.y += box.height; + if (info.autoHeight) { + size.height += box.height; + } else { + bodyBox.height -= box.height; + } } - size.height += box.height; break; case 'bottom': + if (!box.overlay) { + if (info.autoHeight) { + size.height += box.height; + } else { + bodyBox.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) { + if (info.autoWidth) { size.width += box.width; } else { bodyBox.width -= box.width; @@ -24763,7 +23693,7 @@ Ext.define('Ext.layout.component.AbstractDock', { case 'right': if (!box.overlay) { - if (autoSizedCtLayout) { + if (info.autoWidth) { size.width += box.width; } else { bodyBox.width -= box.width; @@ -24804,7 +23734,7 @@ Ext.define('Ext.layout.component.AbstractDock', { item: item, overlay: item.overlay, type: item.dock, - offsets: Ext.core.Element.parseBox(item.offsets || {}), + offsets: Ext.Element.parseBox(item.offsets || {}), ignoreFrame: item.ignoreParentFrame }; @@ -24846,10 +23776,10 @@ Ext.define('Ext.layout.component.AbstractDock', { - if (box.width == undefined) { + if (box.width === undefined) { box.width = item.getWidth() + item.el.getMargin('lr'); } - if (box.height == undefined) { + if (box.height === undefined) { box.height = item.getHeight() + item.el.getMargin('tb'); } @@ -24883,7 +23813,7 @@ Ext.define('Ext.layout.component.AbstractDock', { cn = Ext.get(cns[i]); for (j = 0; j < ln; j++) { item = items[j]; - if (item.rendered && (cn.id == item.el.id || cn.down('#' + item.el.id))) { + if (item.rendered && (cn.id == item.el.id || cn.contains(item.el.id))) { break; } } @@ -24955,6 +23885,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); @@ -24974,6 +23911,95 @@ Ext.define('Ext.layout.component.AbstractDock', { } }); +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 { + + data: null, + + + target: null, + + + constructor: function (target, props) { + if (target) { + this.target = target; + if (props) { + this.capture(props); + } + } + }, + + + capture: function (props, target) { + doMany(captureOne, this.data || (this.data = {}), target || this.target, props); + }, + + + remove: function (props) { + doMany(removeOne, this.data, null, props); + }, + + + restore: function (props, clear, target) { + doMany(restoreOne, this.data, target || this.target, props); + if (clear !== false) { + this.remove(props); + } + }, + + + 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; + } + } + }; +}()); + + Ext.define('Ext.app.EventBus', { requires: [ 'Ext.util.Event' @@ -24981,12 +24007,12 @@ Ext.define('Ext.app.EventBus', { mixins: { observable: 'Ext.util.Observable' }, - + constructor: function() { this.mixins.observable.constructor.call(this); - + this.bus = {}; - + var me = this; Ext.override(Ext.Component, { fireEvent: function(ev) { @@ -25002,7 +24028,7 @@ Ext.define('Ext.app.EventBus', { var bus = this.bus, selectors = bus[ev], selector, controllers, id, events, event, i, ln; - + if (selectors) { for (selector in selectors) { @@ -25016,18 +24042,20 @@ Ext.define('Ext.app.EventBus', { for (i = 0, ln = events.length; i < ln; i++) { event = events[i]; - 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; + }; } } } } } }, - + control: function(selectors, listeners, controller) { var bus = this.bus, selector, fn; - + if (Ext.isString(selectors)) { selector = selectors; selectors = {}; @@ -25035,13 +24063,13 @@ Ext.define('Ext.app.EventBus', { this.control(selectors, null, controller); return; } - + Ext.Object.each(selectors, function(selector, listeners) { Ext.Object.each(listeners, function(ev, listener) { - var options = {}, + var options = {}, scope = controller, event = Ext.create('Ext.util.Event', controller, ev); - + if (Ext.isObject(listener)) { options = listener; @@ -25050,14 +24078,14 @@ Ext.define('Ext.app.EventBus', { delete options.fn; delete options.scope; } - + event.addListener(listener, scope, options); bus[ev] = bus[ev] || {}; bus[ev][selector] = bus[ev][selector] || {}; - bus[ev][selector][controller.id] = bus[ev][selector][controller.id] || []; - + bus[ev][selector][controller.id] = bus[ev][selector][controller.id] || []; + bus[ev][selector][controller.id].push(event); }); @@ -25070,11 +24098,11 @@ Ext.define('Ext.data.Types', { requires: ['Ext.data.SortTypes'] }, function() { var st = Ext.data.SortTypes; - + Ext.apply(Ext.data.Types, { stripRe: /[\$,%]/g, - + AUTO: { convert: function(v) { @@ -25103,7 +24131,7 @@ Ext.define('Ext.data.Types', { sortType: st.none, type: 'int' }, - + FLOAT: { convert: function(v) { @@ -25113,11 +24141,11 @@ Ext.define('Ext.data.Types', { sortType: st.none, type: 'float' }, - + BOOL: { convert: function(v) { - if (this.useNull && v === undefined || v === null || v === '') { + if (this.useNull && (v === undefined || v === null || v === '')) { return null; } return v === true || v === 'true' || v == 1; @@ -25125,11 +24153,13 @@ Ext.define('Ext.data.Types', { sortType: st.none, type: 'bool' }, - + DATE: { convert: function(v) { - var df = this.dateFormat; + var df = this.dateFormat, + parsed; + if (!v) { return null; } @@ -25145,24 +24175,24 @@ Ext.define('Ext.data.Types', { } return Ext.Date.parse(v, df); } - - var parsed = Date.parse(v); + + parsed = Date.parse(v); return parsed ? new Date(parsed) : null; }, sortType: st.asDate, type: 'date' } }); - + Ext.apply(Ext.data.Types, { BOOLEAN: this.BOOL, - + INTEGER: this.INT, + - - NUMBER: this.FLOAT + NUMBER: this.FLOAT }); }); @@ -25206,6 +24236,7 @@ Ext.define('Ext.data.Field', { + dateFormat: null, @@ -25214,655 +24245,1498 @@ Ext.define('Ext.data.Field', { defaultValue: "", + mapping: null, + sortType : null, + sortDir : "ASC", + allowBlank : true, - + persist: true }); -Ext.define('Ext.data.reader.Reader', { - requires: ['Ext.data.ResultSet'], - alternateClassName: ['Ext.data.Reader', 'Ext.data.DataReader'], - - - - - totalProperty: 'total', +Ext.define('Ext.util.AbstractMixedCollection', { + requires: ['Ext.util.Filter'], - - successProperty: 'success', + mixins: { + observable: 'Ext.util.Observable' + }, - - root: '', - - - - - implicitIncludes: true, - - isReader: true, - - constructor: function(config) { + constructor: function(allowFunctions, keyFn) { var me = this; - - Ext.apply(me, config || {}); - me.fieldCount = 0; - me.model = Ext.ModelManager.getModel(config.model); - if (me.model) { - me.buildExtractors(); + + me.items = []; + me.map = {}; + me.keys = []; + me.length = 0; + + me.addEvents( + + 'clear', + + + 'add', + + + 'replace', + + + 'remove' + ); + + me.allowFunctions = allowFunctions === true; + + if (keyFn) { + me.getKey = keyFn; } + + me.mixins.observable.constructor.call(me); }, - setModel: function(model, setOnProxy) { - var me = this; - - me.model = Ext.ModelManager.getModel(model); - me.buildExtractors(true); - - if (setOnProxy && me.proxy) { - me.proxy.setModel(me.model, true); - } - }, + allowFunctions : false, - read: function(response) { - var data = response; - - if (response && response.responseText) { - data = this.getResponseData(response); + add : function(key, obj){ + var me = this, + myObj = obj, + myKey = key, + old; + + if (arguments.length == 1) { + myObj = myKey; + myKey = me.getKey(myObj); } - - if (data) { - return this.readRecords(data); - } else { - return this.nullResultSet; + if (typeof myKey != 'undefined' && myKey !== null) { + old = me.map[myKey]; + if (typeof old != 'undefined') { + return me.replace(myKey, myObj); + } + me.map[myKey] = myObj; } + me.length++; + me.items.push(myObj); + me.keys.push(myKey); + me.fireEvent('add', me.length - 1, myObj, myKey); + return myObj; }, - readRecords: function(data) { - var me = this; - - - if (me.fieldCount !== me.getFields().length) { - me.buildExtractors(true); - } - - - me.rawData = data; + getKey : function(o){ + return o.id; + }, - data = me.getData(data); + + replace : function(key, o){ + var me = this, + old, + index; - - - var root = Ext.isArray(data) ? data : me.getRoot(data), - success = true, - recordCount = 0, - total, value, records, message; - - if (root) { - total = root.length; + if (arguments.length == 1) { + o = arguments[0]; + key = me.getKey(o); } - - if (me.totalProperty) { - value = parseInt(me.getTotal(data), 10); - if (!isNaN(value)) { - total = value; - } + old = me.map[key]; + if (typeof key == 'undefined' || key === null || typeof old == 'undefined') { + return me.add(key, o); } + index = me.indexOfKey(key); + me.items[index] = o; + me.map[key] = o; + me.fireEvent('replace', key, old, o); + return o; + }, - if (me.successProperty) { - value = me.getSuccess(data); - if (value === false || value === 'false') { - success = false; + + addAll : function(objs){ + var me = this, + i = 0, + args, + len, + key; + + if (arguments.length > 1 || Ext.isArray(objs)) { + args = arguments.length > 1 ? arguments : objs; + for (len = args.length; i < len; i++) { + me.add(args[i]); } - } - - if (me.messageProperty) { - message = me.getMessage(data); - } - - if (root) { - records = me.extractData(root); - recordCount = records.length; } else { - recordCount = 0; - records = []; + for (key in objs) { + if (objs.hasOwnProperty(key)) { + if (me.allowFunctions || typeof objs[key] != 'function') { + me.add(key, objs[key]); + } + } + } } + }, - return Ext.create('Ext.data.ResultSet', { - total : total || recordCount, - count : recordCount, - records: records, - success: success, - message: message - }); + + each : function(fn, scope){ + var items = [].concat(this.items), + i = 0, + len = items.length, + item; + + for (; i < len; i++) { + item = items[i]; + if (fn.call(scope || item, item, i, len) === false) { + break; + } + } }, - extractData : function(root) { - var me = this, - values = [], - records = [], - Model = me.model, - i = 0, - length = root.length, - idProp = me.getIdProperty(), - node, id, record; - - if (!root.length && Ext.isObject(root)) { - root = [root]; - length = 1; + eachKey : function(fn, scope){ + var keys = this.keys, + items = this.items, + i = 0, + len = keys.length; + + for (; i < len; i++) { + fn.call(scope || window, keys[i], items[i], i, len); } + }, - for (; i < length; i++) { - node = root[i]; - values = me.extractValues(node); - id = me.getId(node); + + findBy : function(fn, scope) { + var keys = this.keys, + items = this.items, + i = 0, + len = items.length; - - record = new Model(values, id, node); - records.push(record); - - if (me.implicitIncludes) { - me.readAssociated(record, node); + for (; i < len; i++) { + if (fn.call(scope || window, items[i], keys[i])) { + return items[i]; } } + return null; + }, - return records; + find : function() { + if (Ext.isDefined(Ext.global.console)) { + Ext.global.console.warn('Ext.util.MixedCollection: find has been deprecated. Use findBy instead.'); + } + return this.findBy.apply(this, arguments); }, + - - readAssociated: function(record, data) { - var associations = record.associations.items, - i = 0, - length = associations.length, - association, associationData, proxy, reader; - - for (; i < length; i++) { - association = associations[i]; - associationData = this.getAssociatedDataRoot(data, association.associationKey || association.name); - - if (associationData) { - reader = association.getReader(); - if (!reader) { - proxy = association.associatedModel.proxy; - - if (proxy) { - reader = proxy.getReader(); - } else { - reader = new this.constructor({ - model: association.associatedName - }); - } - } - association.read(record, reader, associationData); - } + insert : function(index, key, obj){ + var me = this, + myKey = key, + myObj = obj; + + if (arguments.length == 2) { + myObj = myKey; + myKey = me.getKey(myObj); + } + if (me.containsKey(myKey)) { + me.suspendEvents(); + me.removeAtKey(myKey); + me.resumeEvents(); } + if (index >= me.length) { + return me.add(myKey, myObj); + } + me.length++; + Ext.Array.splice(me.items, index, 0, myObj); + if (typeof myKey != 'undefined' && myKey !== null) { + me.map[myKey] = myObj; + } + Ext.Array.splice(me.keys, index, 0, myKey); + me.fireEvent('add', index, myObj, myKey); + return myObj; }, + - - getAssociatedDataRoot: function(data, associationName) { - return data[associationName]; + remove : function(o){ + return this.removeAt(this.indexOf(o)); }, + - getFields: function() { - return this.model.prototype.fields.items; + removeAll : function(items){ + Ext.each(items || [], function(item) { + this.remove(item); + }, this); + + return this; }, - extractValues: function(data) { - var fields = this.getFields(), - i = 0, - length = fields.length, - output = {}, - field, value; - - for (; i < length; i++) { - field = fields[i]; - value = this.extractorFunctions[i](data); + removeAt : function(index){ + var me = this, + o, + key; - output[field.name] = value; + if (index < me.length && index >= 0) { + me.length--; + o = me.items[index]; + Ext.Array.erase(me.items, index, 1); + key = me.keys[index]; + if (typeof key != 'undefined') { + delete me.map[key]; + } + Ext.Array.erase(me.keys, index, 1); + me.fireEvent('remove', o, key); + return o; } - - return output; + return false; }, - getData: function(data) { - return data; + removeAtKey : function(key){ + return this.removeAt(this.indexOfKey(key)); }, - getRoot: function(data) { - return data; + getCount : function(){ + return this.length; }, - getResponseData: function(response) { - Ext.Error.raise("getResponseData must be implemented in the Ext.data.reader.Reader subclass"); + indexOf : function(o){ + return Ext.Array.indexOf(this.items, o); }, - onMetaChange : function(meta) { - var fields = meta.fields, - newModel; - - Ext.apply(this, meta); - - if (fields) { - newModel = Ext.define("Ext.data.reader.Json-Model" + Ext.id(), { - extend: 'Ext.data.Model', - fields: fields - }); - this.setModel(newModel, true); - } else { - this.buildExtractors(true); - } + indexOfKey : function(key){ + return Ext.Array.indexOf(this.keys, key); }, + + get : function(key) { + var me = this, + mk = me.map[key], + item = mk !== undefined ? mk : (typeof key == 'number') ? me.items[key] : undefined; + return typeof item != 'function' || me.allowFunctions ? item : null; + }, + - getIdProperty: function(){ - var prop = this.idProperty; - if (Ext.isEmpty(prop)) { - prop = this.model.prototype.idProperty; - } - return prop; + getAt : function(index) { + return this.items[index]; }, - buildExtractors: function(force) { - var me = this, - idProp = me.getIdProperty(), - totalProp = me.totalProperty, - successProp = me.successProperty, - messageProp = me.messageProperty, - accessor; - - if (force === true) { - delete me.extractorFunctions; - } - - if (me.extractorFunctions) { - return; - } + getByKey : function(key) { + return this.map[key]; + }, - - if (totalProp) { - me.getTotal = me.createAccessor(totalProp); - } + + contains : function(o){ + return Ext.Array.contains(this.items, o); + }, - if (successProp) { - me.getSuccess = me.createAccessor(successProp); - } + + containsKey : function(key){ + return typeof this.map[key] != 'undefined'; + }, - if (messageProp) { - me.getMessage = me.createAccessor(messageProp); - } + + clear : function(){ + var me = this; - if (idProp) { - accessor = me.createAccessor(idProp); + me.length = 0; + me.items = []; + me.keys = []; + me.map = {}; + me.fireEvent('clear'); + }, - me.getId = function(record) { - var id = accessor.call(me, record); - return (id === undefined || id === '') ? null : id; - }; - } else { - me.getId = function() { - return null; - }; - } - me.buildFieldExtractors(); + + first : function() { + return this.items[0]; }, - buildFieldExtractors: function() { - - var me = this, - fields = me.getFields(), - ln = fields.length, - i = 0, - extractorFunctions = [], - field, map; + last : function() { + return this.items[this.length - 1]; + }, - for (; i < ln; i++) { - field = fields[i]; - map = (field.mapping !== undefined && field.mapping !== null) ? field.mapping : field.name; + + sum: function(property, root, start, end) { + var values = this.extractValues(property, root), + length = values.length, + sum = 0, + i; - extractorFunctions.push(me.createAccessor(map)); + start = start || 0; + end = (end || end === 0) ? end : length - 1; + + for (i = start; i <= end; i++) { + sum += values[i]; } - me.fieldCount = ln; - me.extractorFunctions = extractorFunctions; - } -}, function() { - Ext.apply(this, { - - nullResultSet: Ext.create('Ext.data.ResultSet', { - total : 0, - count : 0, - records: [], - success: true - }) - }); -}); + return sum; + }, -Ext.define('Ext.data.reader.Json', { - extend: 'Ext.data.reader.Reader', - alternateClassName: 'Ext.data.JsonReader', - alias : 'reader.json', - - root: '', - - - - - useSimpleAccessors: false, - - readRecords: function(data) { - - if (data.metaData) { - this.onMetaChange(data.metaData); + collect: function(property, root, allowNull) { + var values = this.extractValues(property, root), + length = values.length, + hits = {}, + unique = [], + value, strValue, i; + + for (i = 0; i < length; i++) { + value = values[i]; + strValue = String(value); + + if ((allowNull || !Ext.isEmpty(value)) && !hits[strValue]) { + hits[strValue] = true; + unique.push(value); + } } - - this.jsonData = data; - return this.callParent([data]); + return unique; }, - getResponseData: function(response) { - try { - var data = Ext.decode(response.responseText); - } - catch (ex) { - Ext.Error.raise({ - response: response, - json: response.responseText, - parseError: ex, - msg: 'Unable to parse the JSON returned by the server: ' + ex.toString() - }); - } - if (!data) { - Ext.Error.raise('JSON object not found'); + extractValues: function(property, root) { + var values = this.items; + + if (root) { + values = Ext.Array.pluck(values, root); } - return data; + return Ext.Array.pluck(values, property); }, - buildExtractors : function() { - var me = this; - - me.callParent(arguments); + getRange : function(start, end){ + var me = this, + items = me.items, + range = [], + i; - if (me.root) { - me.getRoot = me.createAccessor(me.root); - } else { - me.getRoot = function(root) { - return root; - }; + if (items.length < 1) { + return range; } - }, - - - extractData: function(root) { - var recordName = this.record, - data = [], - length, i; - - if (recordName) { - length = root.length; - - for (i = 0; i < length; i++) { - data[i] = root[i][recordName]; + + start = start || 0; + end = Math.min(typeof end == 'undefined' ? me.length - 1 : end, me.length - 1); + if (start <= end) { + for (i = start; i <= end; i++) { + range[range.length] = items[i]; } } else { - data = root; + for (i = start; i >= end; i--) { + range[range.length] = items[i]; + } } - return this.callParent([data]); + return range; }, - createAccessor: function() { - var re = /[\[\.]/; - - return function(expr) { - if (Ext.isEmpty(expr)) { - return Ext.emptyFn; - } - if (Ext.isFunction(expr)) { - return expr; - } - if (this.useSimpleAccessors !== true) { - var i = String(expr).search(re); - if (i >= 0) { - return Ext.functionFactory('obj', 'return obj' + (i > 0 ? '.' : '') + expr); - } - } - return function(obj) { - return obj[expr]; - }; - }; - }() -}); + filter : function(property, value, anyMatch, caseSensitive) { + var filters = [], + filterFn; -Ext.define('Ext.data.writer.Json', { - extend: 'Ext.data.writer.Writer', - alternateClassName: 'Ext.data.JsonWriter', - alias: 'writer.json', - - - root: undefined, - - - encode: false, - - - allowSingle: true, - - - writeRecords: function(request, data) { - var root = this.root; - if (this.allowSingle && data.length == 1) { - - data = data[0]; + if (Ext.isString(property)) { + filters.push(Ext.create('Ext.util.Filter', { + property : property, + value : value, + anyMatch : anyMatch, + caseSensitive: caseSensitive + })); + } else if (Ext.isArray(property) || property instanceof Ext.util.Filter) { + filters = filters.concat(property); } + - if (this.encode) { - if (root) { - - request.params[root] = Ext.encode(data); - } else { - Ext.Error.raise('Must specify a root when using encode'); - } - } else { - - request.jsonData = request.jsonData || {}; - if (root) { - request.jsonData[root] = data; - } else { - request.jsonData = data; + + filterFn = function(record) { + var isMatch = true, + length = filters.length, + i; + + for (i = 0; i < length; i++) { + var filter = filters[i], + fn = filter.filterFn, + scope = filter.scope; + + isMatch = isMatch && fn.call(scope, record); } - } - return request; - } -}); + return isMatch; + }; -Ext.define('Ext.data.proxy.Proxy', { - alias: 'proxy.proxy', - alternateClassName: ['Ext.data.DataProxy', 'Ext.data.Proxy'], - requires: [ - 'Ext.data.reader.Json', - 'Ext.data.writer.Json' - ], - uses: [ - 'Ext.data.Batch', - 'Ext.data.Operation', - 'Ext.data.Model' - ], - mixins: { - observable: 'Ext.util.Observable' + return this.filterBy(filterFn); }, + - - batchOrder: 'create,update,destroy', - - - batchActions: true, - - - defaultReaderType: 'json', - - - defaultWriterType: 'json', - - - - isProxy: true, - - constructor: function(config) { - config = config || {}; - - if (config.model === undefined) { - delete config.model; - } + filterBy : function(fn, scope) { + var me = this, + newMC = new this.self(), + keys = me.keys, + items = me.items, + length = items.length, + i; - this.mixins.observable.constructor.call(this, config); - - if (this.model !== undefined && !(this.model instanceof Ext.data.Model)) { - this.setModel(this.model); + newMC.getKey = me.getKey; + + for (i = 0; i < length; i++) { + if (fn.call(scope || me, items[i], keys[i])) { + newMC.add(keys[i], items[i]); + } } + + return newMC; }, + - - setModel: function(model, setOnStore) { - this.model = Ext.ModelManager.getModel(model); - - var reader = this.reader, - writer = this.writer; - - this.setReader(reader); - this.setWriter(writer); - - if (setOnStore && this.store) { - this.store.setModel(this.model); + findIndex : function(property, value, start, anyMatch, caseSensitive){ + if(Ext.isEmpty(value, false)){ + return -1; } + value = this.createValueMatcher(value, anyMatch, caseSensitive); + return this.findIndexBy(function(o){ + return o && value.test(o[property]); + }, null, start); }, + - - getModel: function() { - return this.model; + findIndexBy : function(fn, scope, start){ + var me = this, + keys = me.keys, + items = me.items, + i = start || 0, + len = items.length; + + for (; i < len; i++) { + if (fn.call(scope || me, items[i], keys[i])) { + return i; + } + } + return -1; }, + - - setReader: function(reader) { - var me = this; - - if (reader === undefined || typeof reader == 'string') { - reader = { - type: reader - }; + createValueMatcher : function(value, anyMatch, caseSensitive, exactMatch) { + if (!value.exec) { + var er = Ext.String.escapeRegex; + value = String(value); + + if (anyMatch === true) { + value = er(value); + } else { + value = '^' + er(value); + if (exactMatch === true) { + value += '$'; + } + } + value = new RegExp(value, caseSensitive ? '' : 'i'); } + return value; + }, - if (reader.isReader) { - reader.setModel(me.model); - } else { - Ext.applyIf(reader, { - proxy: me, - model: me.model, - type : me.defaultReaderType - }); + + clone : function() { + var me = this, + copy = new this.self(), + keys = me.keys, + items = me.items, + i = 0, + len = items.length; - reader = Ext.createByAlias('reader.' + reader.type, reader); + for(; i < len; i++){ + copy.add(keys[i], items[i]); } - - me.reader = reader; - return me.reader; - }, + copy.getKey = me.getKey; + return copy; + } +}); + + +Ext.define("Ext.util.Sortable", { + isSortable: true, + - getReader: function() { - return this.reader; - }, + defaultSortDirection: "ASC", + + requires: [ + 'Ext.util.Sorter' + ], + + - setWriter: function(writer) { - if (writer === undefined || typeof writer == 'string') { - writer = { - type: writer - }; - } + initSortable: function() { + var me = this, + sorters = me.sorters; - if (!(writer instanceof Ext.data.writer.Writer)) { - Ext.applyIf(writer, { - model: this.model, - type : this.defaultWriterType - }); + + me.sorters = Ext.create('Ext.util.AbstractMixedCollection', false, function(item) { + return item.id || item.property; + }); - writer = Ext.createByAlias('writer.' + writer.type, writer); + if (sorters) { + me.sorters.addAll(me.decodeSorters(sorters)); } - - this.writer = writer; - - return this.writer; - }, - - - getWriter: function() { - return this.writer; }, + - - create: Ext.emptyFn, - - - read: Ext.emptyFn, - - - update: Ext.emptyFn, - - - destroy: Ext.emptyFn, - - - batch: function(operations, listeners) { + sort: function(sorters, direction, where, doSort) { var me = this, - batch = Ext.create('Ext.data.Batch', { - proxy: me, - listeners: listeners || {} - }), - useBatch = me.batchActions, - records; - - Ext.each(me.batchOrder.split(','), function(action) { - records = operations[action]; - if (records) { - if (useBatch) { - batch.add(Ext.create('Ext.data.Operation', { - action: action, - records: records - })); - } else { - Ext.each(records, function(record){ - batch.add(Ext.create('Ext.data.Operation', { - action : action, - records: [record] - })); - }); - } + sorter, sorterFn, + newSorters; + + if (Ext.isArray(sorters)) { + doSort = where; + where = direction; + newSorters = sorters; + } + else if (Ext.isObject(sorters)) { + doSort = where; + where = direction; + newSorters = [sorters]; + } + else if (Ext.isString(sorters)) { + sorter = me.sorters.get(sorters); + + if (!sorter) { + sorter = { + property : sorters, + direction: direction + }; + newSorters = [sorter]; + } + else if (direction === undefined) { + sorter.toggle(); + } + else { + sorter.setDirection(direction); + } + } + + if (newSorters && newSorters.length) { + newSorters = me.decodeSorters(newSorters); + if (Ext.isString(where)) { + if (where === 'prepend') { + sorters = me.sorters.clone().items; + + me.sorters.clear(); + me.sorters.addAll(newSorters); + me.sorters.addAll(sorters); + } + else { + me.sorters.addAll(newSorters); + } + } + else { + me.sorters.clear(); + me.sorters.addAll(newSorters); + } + } + + if (doSort !== false) { + me.onBeforeSort(newSorters); + + sorters = me.sorters.items; + if (sorters.length) { + + sorterFn = function(r1, r2) { + var result = sorters[0].sort(r1, r2), + length = sorters.length, + i; + + + for (i = 1; i < length; i++) { + result = result || sorters[i].sort.call(this, r1, r2); + } + + return result; + }; + + me.doSort(sorterFn); + } + } + + return sorters; + }, + + onBeforeSort: Ext.emptyFn, + + + decodeSorters: function(sorters) { + if (!Ext.isArray(sorters)) { + if (sorters === undefined) { + sorters = []; + } else { + sorters = [sorters]; + } + } + + var length = sorters.length, + Sorter = Ext.util.Sorter, + fields = this.model ? this.model.prototype.fields : null, + field, + config, i; + + for (i = 0; i < length; i++) { + config = sorters[i]; + + if (!(config instanceof Sorter)) { + if (Ext.isString(config)) { + config = { + property: config + }; + } + + Ext.applyIf(config, { + root : this.sortRoot, + direction: "ASC" + }); + + + if (config.fn) { + config.sorterFn = config.fn; + } + + + if (typeof config == 'function') { + config = { + sorterFn: config + }; + } + + + if (fields && !config.transform) { + field = fields.get(config.property); + config.transform = field ? field.sortType : undefined; + } + sorters[i] = Ext.create('Ext.util.Sorter', config); + } + } + + return sorters; + }, + + getSorters: function() { + return this.sorters.items; + } +}); + +Ext.define('Ext.util.MixedCollection', { + extend: 'Ext.util.AbstractMixedCollection', + mixins: { + sortable: 'Ext.util.Sortable' + }, + + + constructor: function() { + var me = this; + me.callParent(arguments); + me.addEvents('sort'); + me.mixins.sortable.initSortable.call(me); + }, + + doSort: function(sorterFn) { + this.sortBy(sorterFn); + }, + + + _sort : function(property, dir, fn){ + var me = this, + i, len, + dsc = String(dir).toUpperCase() == 'DESC' ? -1 : 1, + + + c = [], + keys = me.keys, + items = me.items; + + + fn = fn || function(a, b) { + return a - b; + }; + + + for(i = 0, len = items.length; i < len; i++){ + c[c.length] = { + key : keys[i], + value: items[i], + index: i + }; + } + + + Ext.Array.sort(c, function(a, b){ + var v = fn(a[property], b[property]) * dsc; + if(v === 0){ + v = (a.index < b.index ? -1 : 1); + } + return v; + }); + + + for(i = 0, len = c.length; i < len; i++){ + items[i] = c[i].value; + keys[i] = c[i].key; + } + + me.fireEvent('sort', me); + }, + + + sortBy: function(sorterFn) { + var me = this, + items = me.items, + keys = me.keys, + length = items.length, + temp = [], + i; + + + for (i = 0; i < length; i++) { + temp[i] = { + key : keys[i], + value: items[i], + index: i + }; + } + + Ext.Array.sort(temp, function(a, b) { + var v = sorterFn(a.value, b.value); + if (v === 0) { + v = (a.index < b.index ? -1 : 1); + } + + return v; + }); + + + for (i = 0; i < length; i++) { + items[i] = temp[i].value; + keys[i] = temp[i].key; + } + + me.fireEvent('sort', me, items, keys); + }, + + + reorder: function(mapping) { + var me = this, + items = me.items, + index = 0, + length = items.length, + order = [], + remaining = [], + oldIndex; + + me.suspendEvents(); + + + for (oldIndex in mapping) { + order[mapping[oldIndex]] = items[oldIndex]; + } + + for (index = 0; index < length; index++) { + if (mapping[index] == undefined) { + remaining.push(items[index]); + } + } + + for (index = 0; index < length; index++) { + if (order[index] == undefined) { + order[index] = remaining.shift(); + } + } + + me.clear(); + me.addAll(order); + + me.resumeEvents(); + me.fireEvent('sort', me); + }, + + + sortByKey : function(dir, fn){ + this._sort('key', dir, fn || function(a, b){ + var v1 = String(a).toUpperCase(), v2 = String(b).toUpperCase(); + return v1 > v2 ? 1 : (v1 < v2 ? -1 : 0); + }); + } +}); + + +Ext.define('Ext.data.Errors', { + extend: 'Ext.util.MixedCollection', + + + isValid: function() { + return this.length === 0; + }, + + + getByField: function(fieldName) { + var errors = [], + error, field, i; + + for (i = 0; i < this.length; i++) { + error = this.items[i]; + + if (error.field == fieldName) { + errors.push(error); + } + } + + return errors; + } +}); + + +Ext.define('Ext.data.reader.Reader', { + requires: ['Ext.data.ResultSet'], + alternateClassName: ['Ext.data.Reader', 'Ext.data.DataReader'], + + + + + totalProperty: 'total', + + + successProperty: 'success', + + + root: '', + + + + + implicitIncludes: true, + + isReader: true, + + + constructor: function(config) { + var me = this; + + Ext.apply(me, config || {}); + me.fieldCount = 0; + me.model = Ext.ModelManager.getModel(config.model); + if (me.model) { + me.buildExtractors(); + } + }, + + + setModel: function(model, setOnProxy) { + var me = this; + + me.model = Ext.ModelManager.getModel(model); + me.buildExtractors(true); + + if (setOnProxy && me.proxy) { + me.proxy.setModel(me.model, true); + } + }, + + + read: function(response) { + var data = response; + + if (response && response.responseText) { + data = this.getResponseData(response); + } + + if (data) { + return this.readRecords(data); + } else { + return this.nullResultSet; + } + }, + + + readRecords: function(data) { + var me = this; + + + if (me.fieldCount !== me.getFields().length) { + me.buildExtractors(true); + } + + + me.rawData = data; + + data = me.getData(data); + + + + var root = Ext.isArray(data) ? data : me.getRoot(data), + success = true, + recordCount = 0, + total, value, records, message; + + if (root) { + total = root.length; + } + + if (me.totalProperty) { + value = parseInt(me.getTotal(data), 10); + if (!isNaN(value)) { + total = value; + } + } + + if (me.successProperty) { + value = me.getSuccess(data); + if (value === false || value === 'false') { + success = false; + } + } + + if (me.messageProperty) { + message = me.getMessage(data); + } + + if (root) { + records = me.extractData(root); + recordCount = records.length; + } else { + recordCount = 0; + records = []; + } + + return Ext.create('Ext.data.ResultSet', { + total : total || recordCount, + count : recordCount, + records: records, + success: success, + message: message + }); + }, + + + extractData : function(root) { + var me = this, + values = [], + records = [], + Model = me.model, + i = 0, + length = root.length, + idProp = me.getIdProperty(), + node, id, record; + + if (!root.length && Ext.isObject(root)) { + root = [root]; + length = 1; + } + + for (; i < length; i++) { + node = root[i]; + values = me.extractValues(node); + id = me.getId(node); + + + record = new Model(values, id, node); + records.push(record); + + if (me.implicitIncludes) { + me.readAssociated(record, node); + } + } + + return records; + }, + + + readAssociated: function(record, data) { + var associations = record.associations.items, + i = 0, + length = associations.length, + association, associationData, proxy, reader; + + for (; i < length; i++) { + association = associations[i]; + associationData = this.getAssociatedDataRoot(data, association.associationKey || association.name); + + if (associationData) { + reader = association.getReader(); + if (!reader) { + proxy = association.associatedModel.proxy; + + if (proxy) { + reader = proxy.getReader(); + } else { + reader = new this.constructor({ + model: association.associatedName + }); + } + } + association.read(record, reader, associationData); + } + } + }, + + + getAssociatedDataRoot: function(data, associationName) { + return data[associationName]; + }, + + getFields: function() { + return this.model.prototype.fields.items; + }, + + + extractValues: function(data) { + var fields = this.getFields(), + i = 0, + length = fields.length, + output = {}, + field, value; + + for (; i < length; i++) { + field = fields[i]; + value = this.extractorFunctions[i](data); + + output[field.name] = value; + } + + return output; + }, + + + getData: function(data) { + return data; + }, + + + getRoot: function(data) { + return data; + }, + + + getResponseData: function(response) { + }, + + + onMetaChange : function(meta) { + var fields = meta.fields, + newModel; + + Ext.apply(this, meta); + + if (fields) { + newModel = Ext.define("Ext.data.reader.Json-Model" + Ext.id(), { + extend: 'Ext.data.Model', + fields: fields + }); + this.setModel(newModel, true); + } else { + this.buildExtractors(true); + } + }, + + + getIdProperty: function(){ + var prop = this.idProperty; + if (Ext.isEmpty(prop)) { + prop = this.model.prototype.idProperty; + } + return prop; + }, + + + buildExtractors: function(force) { + var me = this, + idProp = me.getIdProperty(), + totalProp = me.totalProperty, + successProp = me.successProperty, + messageProp = me.messageProperty, + accessor; + + if (force === true) { + delete me.extractorFunctions; + } + + if (me.extractorFunctions) { + return; + } + + + if (totalProp) { + me.getTotal = me.createAccessor(totalProp); + } + + if (successProp) { + me.getSuccess = me.createAccessor(successProp); + } + + if (messageProp) { + me.getMessage = me.createAccessor(messageProp); + } + + if (idProp) { + accessor = me.createAccessor(idProp); + + me.getId = function(record) { + var id = accessor.call(me, record); + return (id === undefined || id === '') ? null : id; + }; + } else { + me.getId = function() { + return null; + }; + } + me.buildFieldExtractors(); + }, + + + buildFieldExtractors: function() { + + var me = this, + fields = me.getFields(), + ln = fields.length, + i = 0, + extractorFunctions = [], + field, map; + + for (; i < ln; i++) { + field = fields[i]; + map = (field.mapping !== undefined && field.mapping !== null) ? field.mapping : field.name; + + extractorFunctions.push(me.createAccessor(map)); + } + me.fieldCount = ln; + + me.extractorFunctions = extractorFunctions; + } +}, function() { + Ext.apply(this, { + + nullResultSet: Ext.create('Ext.data.ResultSet', { + total : 0, + count : 0, + records: [], + success: true + }) + }); +}); + +Ext.define('Ext.data.reader.Json', { + extend: 'Ext.data.reader.Reader', + alternateClassName: 'Ext.data.JsonReader', + alias : 'reader.json', + + root: '', + + + + + useSimpleAccessors: false, + + + readRecords: function(data) { + + if (data.metaData) { + this.onMetaChange(data.metaData); + } + + + this.jsonData = data; + return this.callParent([data]); + }, + + + getResponseData: function(response) { + var data; + try { + data = Ext.decode(response.responseText); + } + catch (ex) { + Ext.Error.raise({ + response: response, + json: response.responseText, + parseError: ex, + msg: 'Unable to parse the JSON returned by the server: ' + ex.toString() + }); + } + + return data; + }, + + + buildExtractors : function() { + var me = this; + + me.callParent(arguments); + + if (me.root) { + me.getRoot = me.createAccessor(me.root); + } else { + me.getRoot = function(root) { + return root; + }; + } + }, + + + extractData: function(root) { + var recordName = this.record, + data = [], + length, i; + + if (recordName) { + length = root.length; + + if (!length && Ext.isObject(root)) { + length = 1; + root = [root]; + } + + for (i = 0; i < length; i++) { + data[i] = root[i][recordName]; + } + } else { + data = root; + } + return this.callParent([data]); + }, + + + createAccessor: function() { + var re = /[\[\.]/; + + return function(expr) { + if (Ext.isEmpty(expr)) { + return Ext.emptyFn; + } + if (Ext.isFunction(expr)) { + return expr; + } + if (this.useSimpleAccessors !== true) { + var i = String(expr).search(re); + if (i >= 0) { + return Ext.functionFactory('obj', 'return obj' + (i > 0 ? '.' : '') + expr); + } + } + return function(obj) { + return obj[expr]; + }; + }; + }() +}); + +Ext.define('Ext.data.writer.Json', { + extend: 'Ext.data.writer.Writer', + alternateClassName: 'Ext.data.JsonWriter', + alias: 'writer.json', + + + root: undefined, + + + encode: false, + + + allowSingle: true, + + + writeRecords: function(request, data) { + var root = this.root; + + if (this.allowSingle && data.length == 1) { + + data = data[0]; + } + + if (this.encode) { + if (root) { + + request.params[root] = Ext.encode(data); + } else { + } + } else { + + request.jsonData = request.jsonData || {}; + if (root) { + request.jsonData[root] = data; + } else { + request.jsonData = data; + } + } + return request; + } +}); + + +Ext.define('Ext.data.proxy.Proxy', { + alias: 'proxy.proxy', + alternateClassName: ['Ext.data.DataProxy', 'Ext.data.Proxy'], + requires: [ + 'Ext.data.reader.Json', + 'Ext.data.writer.Json' + ], + uses: [ + 'Ext.data.Batch', + 'Ext.data.Operation', + 'Ext.data.Model' + ], + mixins: { + observable: 'Ext.util.Observable' + }, + + + batchOrder: 'create,update,destroy', + + + batchActions: true, + + + defaultReaderType: 'json', + + + defaultWriterType: 'json', + + + + + + + + isProxy: true, + + + constructor: function(config) { + config = config || {}; + + if (config.model === undefined) { + delete config.model; + } + + this.mixins.observable.constructor.call(this, config); + + if (this.model !== undefined && !(this.model instanceof Ext.data.Model)) { + this.setModel(this.model); + } + }, + + + setModel: function(model, setOnStore) { + this.model = Ext.ModelManager.getModel(model); + + var reader = this.reader, + writer = this.writer; + + this.setReader(reader); + this.setWriter(writer); + + if (setOnStore && this.store) { + this.store.setModel(this.model); + } + }, + + + getModel: function() { + return this.model; + }, + + + setReader: function(reader) { + var me = this; + + if (reader === undefined || typeof reader == 'string') { + reader = { + type: reader + }; + } + + if (reader.isReader) { + reader.setModel(me.model); + } else { + Ext.applyIf(reader, { + proxy: me, + model: me.model, + type : me.defaultReaderType + }); + + reader = Ext.createByAlias('reader.' + reader.type, reader); + } + + me.reader = reader; + return me.reader; + }, + + + getReader: function() { + return this.reader; + }, + + + setWriter: function(writer) { + if (writer === undefined || typeof writer == 'string') { + writer = { + type: writer + }; + } + + if (!(writer instanceof Ext.data.writer.Writer)) { + Ext.applyIf(writer, { + model: this.model, + type : this.defaultWriterType + }); + + writer = Ext.createByAlias('writer.' + writer.type, writer); + } + + this.writer = writer; + + return this.writer; + }, + + + getWriter: function() { + return this.writer; + }, + + + create: Ext.emptyFn, + + + read: Ext.emptyFn, + + + update: Ext.emptyFn, + + + destroy: Ext.emptyFn, + + + batch: function(operations, listeners) { + var me = this, + batch = Ext.create('Ext.data.Batch', { + proxy: me, + listeners: listeners || {} + }), + useBatch = me.batchActions, + records; + + Ext.each(me.batchOrder.split(','), function(action) { + records = operations[action]; + if (records) { + if (useBatch) { + batch.add(Ext.create('Ext.data.Operation', { + action: action, + records: records + })); + } else { + Ext.each(records, function(record){ + batch.add(Ext.create('Ext.data.Operation', { + action : action, + records: [record] + })); + }); + } } }, me); @@ -25885,97 +25759,92 @@ Ext.define('Ext.data.proxy.Server', { alias : 'proxy.server', alternateClassName: 'Ext.data.ServerProxy', uses : ['Ext.data.Request'], + - - - - - - + pageParam: 'page', - + startParam: 'start', limitParam: 'limit', - + groupParam: 'group', - + sortParam: 'sort', - + filterParam: 'filter', - + directionParam: 'dir', - + simpleSortMode: false, - + noCache : true, - + cacheString: "_dc", - + timeout : 30000, + - - - + constructor: function(config) { var me = this; - + config = config || {}; this.addEvents( 'exception' ); me.callParent([config]); - + me.extraParams = config.extraParams || {}; - + me.api = config.api || {}; - + me.nocache = me.noCache; }, - + create: function() { return this.doRequest.apply(this, arguments); }, - + read: function() { return this.doRequest.apply(this, arguments); }, - + update: function() { return this.doRequest.apply(this, arguments); }, - + destroy: function() { return this.doRequest.apply(this, arguments); }, - + buildRequest: function(operation) { var params = Ext.applyIf(operation.params || {}, this.extraParams || {}), request; + - - params = Ext.applyIf(params, this.getParams(params, operation)); - + params = Ext.applyIf(params, this.getParams(operation)); + if (operation.id && !params.id) { params.id = operation.id; } - + request = Ext.create('Ext.data.Request', { params : params, action : operation.action, @@ -25983,51 +25852,33 @@ Ext.define('Ext.data.proxy.Server', { operation: operation, url : operation.url }); - + request.url = this.buildUrl(request); - + operation.request = request; - + return request; }, - + processResponse: function(success, operation, request, response, callback, scope){ var me = this, reader, - result, - records, - length, - mc, - record, - i; - + result; + if (success === true) { reader = me.getReader(); result = reader.read(me.extractResponseData(response)); - records = result.records; - length = records.length; - + if (result.success !== false) { - mc = Ext.create('Ext.util.MixedCollection', true, function(r) {return r.getId();}); - mc.addAll(operation.records); - for (i = 0; i < length; i++) { - record = mc.get(records[i].getId()); - - if (record) { - record.beginEdit(); - record.set(record.data); - record.endEdit(true); - } - } - Ext.apply(operation, { response: response, resultSet: result }); - + + operation.commitRecords(result.records); operation.setCompleted(); operation.setSuccessful(); } else { @@ -26036,41 +25887,41 @@ Ext.define('Ext.data.proxy.Server', { } } else { me.setException(operation, response); - me.fireEvent('exception', this, response, operation); + me.fireEvent('exception', this, response, operation); } - + if (typeof callback == 'function') { callback.call(scope || me, operation); } - + me.afterRequest(request, success); }, - + setException: function(operation, response){ operation.setException({ status: response.status, statusText: response.statusText - }); + }); }, - + extractResponseData: function(response){ - return response; + return response; }, - + applyEncoding: function(value){ return Ext.encode(value); }, - + encodeSorters: function(sorters) { var min = [], length = sorters.length, i = 0; - + for (; i < length; i++) { min[i] = { property : sorters[i].property, @@ -26078,15 +25929,15 @@ Ext.define('Ext.data.proxy.Server', { }; } return this.applyEncoding(min); - + }, - + encodeFilters: function(filters) { var min = [], length = filters.length, i = 0; - + for (; i < length; i++) { min[i] = { property: filters[i].property, @@ -26095,12 +25946,11 @@ Ext.define('Ext.data.proxy.Server', { } return this.applyEncoding(min); }, + - - getParams: function(params, operation) { - params = params || {}; - + getParams: function(operation) { var me = this, + params = {}, isDef = Ext.isDefined, groupers = operation.groupers, sorters = operation.sorters, @@ -26108,34 +25958,34 @@ Ext.define('Ext.data.proxy.Server', { page = operation.page, start = operation.start, limit = operation.limit, - + simpleSortMode = me.simpleSortMode, - + pageParam = me.pageParam, startParam = me.startParam, limitParam = me.limitParam, groupParam = me.groupParam, sortParam = me.sortParam, filterParam = me.filterParam, - directionParam = me.directionParam; - + directionParam = me.directionParam; + if (pageParam && isDef(page)) { params[pageParam] = page; } - + if (startParam && isDef(start)) { params[startParam] = start; } - + if (limitParam && isDef(limit)) { params[limitParam] = limit; } - + if (groupParam && groupers && groupers.length > 0) { params[groupParam] = me.encodeSorters(groupers); } - + if (sortParam && sorters && sorters.length > 0) { if (simpleSortMode) { params[sortParam] = sorters[0].property; @@ -26143,45 +25993,41 @@ Ext.define('Ext.data.proxy.Server', { } else { params[sortParam] = me.encodeSorters(sorters); } - + } - + if (filterParam && filters && filters.length > 0) { params[filterParam] = me.encodeFilters(filters); } - + return params; }, - + buildUrl: function(request) { var me = this, url = me.getUrl(request); - - if (!url) { - Ext.Error.raise("You are using a ServerProxy but have not supplied it with a url."); - } - + + if (me.noCache) { url = Ext.urlAppend(url, Ext.String.format("{0}={1}", me.cacheString, Ext.Date.now())); } - + return url; }, - + getUrl: function(request){ return request.url || this.api[request.action] || this.url; }, - + doRequest: function(operation, callback, scope) { - Ext.Error.raise("The doRequest function has not been implemented on your Ext.data.proxy.Server subclass. See src/data/ServerProxy.js for details"); }, - + afterRequest: Ext.emptyFn, - + onDestroy: function() { Ext.destroy(this.reader, this.writer); } @@ -26248,13 +26094,14 @@ Ext.define('Ext.data.proxy.Ajax', { Ext.define('Ext.data.Model', { alternateClassName: 'Ext.data.Record', - + mixins: { observable: 'Ext.util.Observable' }, requires: [ 'Ext.ModelManager', + 'Ext.data.IdGenerator', 'Ext.data.Field', 'Ext.data.Errors', 'Ext.data.Operation', @@ -26277,6 +26124,7 @@ Ext.define('Ext.data.Model', { associations = data.associations || [], belongsTo = data.belongsTo, hasMany = data.hasMany, + idgen = data.idgen, fieldsMixedCollection = new Ext.util.MixedCollection(false, function(field) { return field.name; @@ -26315,6 +26163,10 @@ Ext.define('Ext.data.Model', { data.fields = fieldsMixedCollection; + if (idgen) { + data.idgen = Ext.data.IdGenerator.get(idgen); + } + if (belongsTo) { @@ -26462,7 +26314,20 @@ Ext.define('Ext.data.Model', { return id; } }, + + idgen: { + isGenerator: true, + type: 'default', + + generate: function () { + return null; + }, + getRecId: function (rec) { + return rec.modelName + '-' + rec.internalId; + } + }, + editing : false, @@ -26470,7 +26335,7 @@ Ext.define('Ext.data.Model', { dirty : false, - persistanceProperty: 'data', + persistenceProperty: 'data', evented: false, isModel: true, @@ -26485,34 +26350,51 @@ Ext.define('Ext.data.Model', { defaultProxyType: 'ajax', + + + + + + + + + + + + constructor: function(data, id, raw) { data = data || {}; - + var me = this, fields, length, field, name, i, + newId, isArray = Ext.isArray(data), newData = isArray ? {} : null; me.internalId = (id || id === 0) ? id : Ext.data.Model.id(me); - + me.raw = raw; Ext.applyIf(me, { - data: {} + data: {} }); - + me.modified = {}; - me[me.persistanceProperty] = {}; + + if (me.persistanceProperty) { + me.persistenceProperty = me.persistanceProperty; + } + me[me.persistenceProperty] = {}; me.mixins.observable.constructor.call(me); @@ -26524,7 +26406,7 @@ Ext.define('Ext.data.Model', { field = fields[i]; name = field.name; - if (isArray){ + if (isArray){ newData[name] = data[i]; @@ -26535,41 +26417,47 @@ Ext.define('Ext.data.Model', { } me.set(newData || data); - - me.dirty = false; - me.modified = {}; if (me.getId()) { me.phantom = false; + } else if (me.phantom) { + newId = me.idgen.generate(); + if (newId !== null) { + me.setId(newId); + } } + + me.dirty = false; + me.modified = {}; + if (typeof me.init == 'function') { me.init(); } - me.id = me.modelName + '-' + me.internalId; - - Ext.ModelManager.register(me); + me.id = me.idgen.getRecId(me); }, - + get: function(field) { - return this[this.persistanceProperty][field]; + return this[this.persistenceProperty][field]; }, - + set: function(fieldName, value) { var me = this, fields = me.fields, modified = me.modified, convertFields = [], - field, key, i, currentValue; + field, key, i, currentValue, notEditing, count, length; if (arguments.length == 1 && Ext.isObject(fieldName)) { + notEditing = !me.editing; + count = 0; for (key in fieldName) { if (fieldName.hasOwnProperty(key)) { - + field = fields.get(key); @@ -26577,16 +26465,30 @@ Ext.define('Ext.data.Model', { convertFields.push(key); continue; } - + + if (!count && notEditing) { + me.beginEdit(); + } + ++count; me.set(key, fieldName[key]); } } - for (i = 0; i < convertFields.length; i++) { - field = convertFields[i]; - me.set(field, fieldName[field]); + length = convertFields.length; + if (length) { + if (!count && notEditing) { + me.beginEdit(); + } + count += length; + for (i = 0; i < length; i++) { + field = convertFields[i]; + me.set(field, fieldName[field]); + } } + if (notEditing && count) { + me.endEdit(); + } } else { if (fields) { field = fields.get(fieldName); @@ -26596,11 +26498,28 @@ Ext.define('Ext.data.Model', { } } currentValue = me.get(fieldName); - me[me.persistanceProperty][fieldName] = value; - + me[me.persistenceProperty][fieldName] = value; + if (field && field.persist && !me.isEqual(currentValue, value)) { - me.dirty = true; - me.modified[fieldName] = currentValue; + if (me.isModified(fieldName)) { + if (me.isEqual(modified[fieldName], value)) { + + + delete modified[fieldName]; + + + me.dirty = false; + for (key in modified) { + if (modified.hasOwnProperty(key)){ + me.dirty = true; + break; + } + } + } + } else { + me.dirty = true; + modified[fieldName] = currentValue; + } } if (!me.editing) { @@ -26608,7 +26527,7 @@ Ext.define('Ext.data.Model', { } } }, - + isEqual: function(a, b){ if (Ext.isDate(a) && Ext.isDate(b)) { @@ -26616,18 +26535,18 @@ Ext.define('Ext.data.Model', { } return a === b; }, - + beginEdit : function(){ var me = this; if (!me.editing) { me.editing = true; me.dirtySave = me.dirty; - me.dataSave = Ext.apply({}, me[me.persistanceProperty]); + me.dataSave = Ext.apply({}, me[me.persistenceProperty]); me.modifiedSave = Ext.apply({}, me.modified); } }, - + cancelEdit : function(){ var me = this; @@ -26635,29 +26554,49 @@ Ext.define('Ext.data.Model', { me.editing = false; me.modified = me.modifiedSave; - me[me.persistanceProperty] = me.dataSave; + me[me.persistenceProperty] = me.dataSave; me.dirty = me.dirtySave; delete me.modifiedSave; delete me.dataSave; delete me.dirtySave; } }, - + endEdit : function(silent){ - var me = this; + var me = this, + didChange; + if (me.editing) { me.editing = false; + didChange = me.dirty || me.changedWhileEditing(); delete me.modifiedSave; delete me.dataSave; delete me.dirtySave; - if (silent !== true && me.dirty) { + if (silent !== true && didChange) { me.afterEdit(); } } }, + changedWhileEditing: function(){ + var me = this, + saved = me.dataSave, + data = me[me.persistenceProperty], + key; + + for (key in data) { + if (data.hasOwnProperty(key)) { + if (!me.isEqual(data[key], saved[key])) { + return true; + } + } + } + return false; + }, + + getChanges : function(){ var modified = this.modified, changes = {}, @@ -26671,17 +26610,17 @@ Ext.define('Ext.data.Model', { return changes; }, - + isModified : function(fieldName) { return this.modified.hasOwnProperty(fieldName); }, - + setDirty : function() { var me = this, name; - + me.dirty = true; me.fields.each(function(field) { @@ -26692,13 +26631,7 @@ Ext.define('Ext.data.Model', { }, me); }, - markDirty : function() { - if (Ext.isDefined(Ext.global.console)) { - Ext.global.console.warn('Ext.data.Model: markDirty has been deprecated. Use setDirty instead.'); - } - return this.setDirty.apply(this, arguments); - }, - + reject : function(silent) { var me = this, @@ -26708,7 +26641,7 @@ Ext.define('Ext.data.Model', { for (field in modified) { if (modified.hasOwnProperty(field)) { if (typeof modified[field] != "function") { - me[me.persistanceProperty][field] = modified[field]; + me[me.persistenceProperty][field] = modified[field]; } } } @@ -26725,10 +26658,8 @@ Ext.define('Ext.data.Model', { commit : function(silent) { var me = this; - - me.dirty = false; - me.editing = false; + me.phantom = me.dirty = me.editing = false; me.modified = {}; if (silent !== true) { @@ -26739,8 +26670,8 @@ Ext.define('Ext.data.Model', { copy : function(newId) { var me = this; - - return new me.self(Ext.apply({}, me[me.persistanceProperty]), newId || me.internalId); + + return new me.self(Ext.apply({}, me[me.persistenceProperty]), newId || me.internalId); }, @@ -26883,7 +26814,7 @@ Ext.define('Ext.data.Model', { }, - unjoin: function() { + unjoin: function(store) { delete this.store; }, @@ -26979,6 +26910,96 @@ Ext.define('Ext.data.Model', { }); +Ext.define('Ext.data.StoreManager', { + extend: 'Ext.util.MixedCollection', + alternateClassName: ['Ext.StoreMgr', 'Ext.data.StoreMgr', 'Ext.StoreManager'], + singleton: true, + uses: ['Ext.data.ArrayStore'], + + + + + register : function() { + for (var i = 0, s; (s = arguments[i]); i++) { + this.add(s); + } + }, + + + unregister : function() { + for (var i = 0, s; (s = arguments[i]); i++) { + this.remove(this.lookup(s)); + } + }, + + + lookup : function(store) { + + if (Ext.isArray(store)) { + var fields = ['field1'], + expand = !Ext.isArray(store[0]), + data = store, + i, + len; + + if(expand){ + data = []; + for (i = 0, len = store.length; i < len; ++i) { + data.push([store[i]]); + } + } else { + for(i = 2, len = store[0].length; i <= len; ++i){ + fields.push('field' + i); + } + } + return Ext.create('Ext.data.ArrayStore', { + data : data, + fields: fields, + autoDestroy: true, + autoCreated: true, + expanded: expand + }); + } + + if (Ext.isString(store)) { + + return this.get(store); + } else { + + return Ext.data.AbstractStore.create(store); + } + }, + + + getKey : function(o) { + return o.storeId; + } +}, function() { + + Ext.regStore = function(name, config) { + var store; + + if (Ext.isObject(name)) { + config = name; + } else { + config.storeId = name; + } + + if (config instanceof Ext.data.Store) { + store = config; + } else { + store = Ext.create('Ext.data.Store', config); + } + + return Ext.data.StoreManager.register(store); + }; + + + Ext.getStore = function(name) { + return Ext.data.StoreManager.lookup(name); + }; +}); + Ext.define('Ext.Component', { @@ -27007,7 +27028,13 @@ Ext.define('Ext.Component', { DIRECTION_TOP: 'top', DIRECTION_RIGHT: 'right', DIRECTION_BOTTOM: 'bottom', - DIRECTION_LEFT: 'left' + DIRECTION_LEFT: 'left', + + VERTICAL_DIRECTION_Re: /^(?:top|bottom)$/, + + + + INVALID_ID_CHARS_Re: /[\.,\s]/g }, @@ -27027,7 +27054,7 @@ Ext.define('Ext.Component', { - + @@ -27050,13 +27077,17 @@ Ext.define('Ext.Component', { + + constructor: function(config) { + var me = this; + config = config || {}; if (config.initialConfig) { if (config.isAction) { - this.baseAction = config; + me.baseAction = config; } config = config.initialConfig; @@ -27069,18 +27100,21 @@ Ext.define('Ext.Component', { }; } - this.callParent([config]); + me.callParent([config]); - if (this.baseAction){ - this.baseAction.addComponent(this); + if (me.baseAction){ + me.baseAction.addComponent(me); } }, + initComponent: function() { var me = this; + me.callParent(); + if (me.listeners) { me.on(me.listeners); delete me.listeners; @@ -27097,7 +27131,7 @@ Ext.define('Ext.Component', { if (me.floating) { me.makeFloating(me.floating); } else { - me.el.setVisibilityMode(Ext.core.Element[me.hideMode.toUpperCase()]); + me.el.setVisibilityMode(Ext.Element[me.hideMode.toUpperCase()]); } if (Ext.isDefined(me.autoScroll)) { @@ -27152,14 +27186,16 @@ Ext.define('Ext.Component', { }, initResizable: function(resizable) { + var me = this; + resizable = Ext.apply({ - target: this, + target: me, dynamic: false, - constrainTo: this.constrainTo, - handles: this.resizeHandles + constrainTo: me.constrainTo || (me.floatParent ? me.floatParent.getTargetEl() : me.el.getScopeParent()), + handles: me.resizeHandles }, resizable); - resizable.target = this; - this.resizer = Ext.create('Ext.resizer.Resizer', resizable); + resizable.target = me; + me.resizer = Ext.create('Ext.resizer.Resizer', resizable); }, getDragEl: function() { @@ -27169,9 +27205,9 @@ Ext.define('Ext.Component', { initDraggable: function() { var me = this, ddConfig = Ext.applyIf({ - el: this.getDragEl(), - constrainTo: me.constrainTo || (me.floatParent ? me.floatParent.getTargetEl() : me.el.dom.parentNode) - }, this.draggable); + el: me.getDragEl(), + constrainTo: me.constrain ? (me.constrainTo || (me.floatParent ? me.floatParent.getTargetEl() : me.el.getScopeParent())) : undefined + }, me.draggable); if (me.constrain || me.constrainDelegate) { @@ -27179,7 +27215,7 @@ Ext.define('Ext.Component', { ddConfig.constrainDelegate = me.constrainDelegate; } - this.dd = Ext.create('Ext.util.ComponentDragger', this, ddConfig); + me.dd = Ext.create('Ext.util.ComponentDragger', me, ddConfig); }, @@ -27247,14 +27283,16 @@ Ext.define('Ext.Component', { this.fireEvent('move', this, ax, ay); }, + showAt: function(x, y, animate) { - - if (this.floating) { - this.setPosition(x, y, animate); + var me = this; + + if (me.floating) { + me.setPosition(x, y, animate); } else { - this.setPagePosition(x, y, animate); + me.setPagePosition(x, y, animate); } - this.show(); + me.show(); }, @@ -27288,11 +27326,12 @@ Ext.define('Ext.Component', { getBox : function(local){ - var pos = this.getPosition(local); - var s = this.getSize(); - s.x = pos[0]; - s.y = pos[1]; - return s; + var pos = this.getPosition(local), + size = this.getSize(); + + size.x = pos[0]; + size.y = pos[1]; + return size; }, @@ -27312,22 +27351,6 @@ Ext.define('Ext.Component', { }, - adjustSize: function(w, h) { - if (this.autoWidth) { - w = 'auto'; - } - - if (this.autoHeight) { - h = 'auto'; - } - - return { - width: w, - height: h - }; - }, - - adjustPosition: function(x, y) { @@ -27345,26 +27368,36 @@ Ext.define('Ext.Component', { getPosition: function(local) { - var el = this.el, - xy; + var me = this, + el = me.el, + xy, + o; - if (local === true) { + + if ((local === true) || (me.floating && !me.floatParent)) { return [el.getLeft(true), el.getTop(true)]; } - xy = this.xy || el.getXY(); + xy = me.xy || el.getXY(); - if (this.floating && this.floatParent) { - var o = this.floatParent.getTargetEl().getViewRegion(); + if (me.floating) { + o = me.floatParent.getTargetEl().getViewRegion(); xy[0] -= o.left; xy[1] -= o.top; } return xy; }, - getId: function() { - return this.id || (this.id = (this.getXType() || 'ext-comp') + '-' + this.getAutoId()); + var me = this, + xtype; + + if (!me.id) { + xtype = me.getXType(); + xtype = xtype ? xtype.replace(Ext.Component.INVALID_ID_CHARS_Re, '-') : 'ext-comp'; + me.id = xtype + '-' + me.getAutoId(); + } + return me.id; }, onEnable: function() { @@ -27383,30 +27416,32 @@ Ext.define('Ext.Component', { show: function(animateTarget, cb, scope) { - if (this.rendered && this.isVisible()) { - if (this.toFrontOnShow && this.floating) { - this.toFront(); + var me = this; + + if (me.rendered && me.isVisible()) { + if (me.toFrontOnShow && me.floating) { + me.toFront(); } - } else if (this.fireEvent('beforeshow', this) !== false) { - this.hidden = false; + } else if (me.fireEvent('beforeshow', me) !== false) { + me.hidden = false; - if (!this.rendered && (this.autoRender || this.floating)) { - this.doAutoRender(); + if (!me.rendered && (me.autoRender || me.floating)) { + me.doAutoRender(); } - if (this.rendered) { - this.beforeShow(); - this.onShow.apply(this, arguments); + if (me.rendered) { + me.beforeShow(); + me.onShow.apply(me, arguments); - if (this.ownerCt && !this.floating && !(this.ownerCt.suspendLayout || this.ownerCt.layout.layoutBusy)) { - this.ownerCt.doLayout(); + if (me.ownerCt && !me.floating && !(me.ownerCt.suspendLayout || me.ownerCt.layout.layoutBusy)) { + me.ownerCt.doLayout(); } - this.afterShow.apply(this, arguments); + me.afterShow.apply(me, arguments); } } - return this; + return me; }, beforeShow: Ext.emptyFn, @@ -27416,10 +27451,10 @@ Ext.define('Ext.Component', { var me = this; me.el.show(); - if (this.floating && this.constrain) { - this.doConstrain(); - } me.callParent(arguments); + if (me.floating && me.constrain) { + me.doConstrain(); + } }, afterShow: function(animateTarget, cb, scope) { @@ -27440,14 +27475,13 @@ Ext.define('Ext.Component', { animateTarget = animateTarget.el ? animateTarget.el : Ext.get(animateTarget); toBox = me.el.getBox(); fromBox = animateTarget.getBox(); - fromBox.width += 'px'; - fromBox.height += 'px'; - toBox.width += 'px'; - toBox.height += 'px'; me.el.addCls(Ext.baseCSSPrefix + 'hide-offsets'); ghostPanel = me.ghost(); ghostPanel.el.stopAnimation(); + + ghostPanel.el.setX(-10000); + ghostPanel.el.animate({ from: fromBox, to: toBox, @@ -27456,43 +27490,46 @@ Ext.define('Ext.Component', { delete ghostPanel.componentLayout.lastComponentSize; me.unghost(); me.el.removeCls(Ext.baseCSSPrefix + 'hide-offsets'); - if (me.floating) { - me.toFront(); - } - Ext.callback(cb, scope || me); + me.onShowComplete(cb, scope); } } }); } else { - if (me.floating) { - me.toFront(); - } - Ext.callback(cb, scope || me); + me.onShowComplete(cb, scope); + } + }, + + onShowComplete: function(cb, scope) { + var me = this; + if (me.floating) { + me.toFront(); } + Ext.callback(cb, scope || me); me.fireEvent('show', me); }, hide: function() { + var me = this; - this.showOnParentShow = false; + me.showOnParentShow = false; - if (!(this.rendered && !this.isVisible()) && this.fireEvent('beforehide', this) !== false) { - this.hidden = true; - if (this.rendered) { - this.onHide.apply(this, arguments); + if (!(me.rendered && !me.isVisible()) && me.fireEvent('beforehide', me) !== false) { + me.hidden = true; + if (me.rendered) { + me.onHide.apply(me, arguments); - if (this.ownerCt && !this.floating && !(this.ownerCt.suspendLayout || this.ownerCt.layout.layoutBusy)) { - this.ownerCt.doLayout(); + if (me.ownerCt && !me.floating && !(me.ownerCt.suspendLayout || me.ownerCt.layout.layoutBusy)) { + me.ownerCt.doLayout(); } } } - return this; + return me; }, @@ -27546,6 +27583,7 @@ Ext.define('Ext.Component', { if (me.rendered) { Ext.destroy( me.proxy, + me.proxyWrap, me.resizer ); @@ -27649,11 +27687,13 @@ Ext.define('Ext.Component', { cloneConfig: function(overrides) { overrides = overrides || {}; - var id = overrides.id || Ext.id(); - var cfg = Ext.applyIf(overrides, this.initialConfig); + var id = overrides.id || Ext.id(), + cfg = Ext.applyIf(overrides, this.initialConfig), + self; + cfg.id = id; - var self = Ext.getClass(this); + self = Ext.getClass(this); return new self(cfg); @@ -27696,29 +27736,89 @@ Ext.define('Ext.Component', { }, getProxy: function() { - if (!this.proxy) { - this.proxy = this.el.createProxy(Ext.baseCSSPrefix + 'proxy-el', Ext.getBody(), true); + var me = this, + target; + + if (!me.proxy) { + target = Ext.getBody(); + if (Ext.scopeResetCSS) { + me.proxyWrap = target = Ext.getBody().createChild({ + cls: Ext.baseCSSPrefix + 'reset' + }); + } + me.proxy = me.el.createProxy(Ext.baseCSSPrefix + 'proxy-el', target, true); } - return this.proxy; + return me.proxy; } }); +Ext.define('Ext.layout.container.AbstractContainer', { + + + + extend: 'Ext.layout.Layout', + + + + type: 'container', + + + bindToOwnerCtComponent: false, + + + bindToOwnerCtContainer: false, + + + + + setItemSize: function(item, width, height) { + if (Ext.isObject(width)) { + height = width.height; + width = width.width; + } + item.setCalculatedSize(width, height, this.owner); + }, + + + getLayoutItems: function() { + return this.owner && this.owner.items && this.owner.items.items || []; + }, + + + beforeLayout: function() { + return !this.owner.collapsed && this.callParent(arguments); + }, + + afterLayout: function() { + this.owner.afterLayout(this); + }, + + getTarget: function() { + return this.owner.getTargetEl(); + }, + + getRenderTarget: function() { + return this.owner.getTargetEl(); + } +}); + + Ext.define('Ext.layout.container.Container', { extend: 'Ext.layout.container.AbstractContainer', alternateClassName: 'Ext.layout.ContainerLayout', - + layoutItem: function(item, box) { - box = box || {}; - if (item.componentLayout.initialized !== true) { - this.setItemSize(item, box.width || item.width || undefined, box.height || item.height || undefined); - + if (box) { + item.doComponentLayout(box.width, box.height); + } else { + item.doComponentLayout(); } }, @@ -27751,11 +27851,6 @@ Ext.define('Ext.layout.container.Container', { } }, - afterLayout: function() { - this.owner.afterLayout(arguments); - this.callParent(arguments); - }, - getRenderedItems: function() { var me = this, @@ -27794,7 +27889,6 @@ Ext.define('Ext.layout.container.Container', { } }); - Ext.define('Ext.layout.container.Auto', { @@ -27807,8 +27901,6 @@ Ext.define('Ext.layout.container.Auto', { type: 'autocontainer', - fixedLayout: false, - bindToOwnerCtComponent: true, @@ -27835,6 +27927,14 @@ Ext.define('Ext.layout.container.Auto', { me.setItemSize(items[i]); } } + }, + + configureItem: function(item) { + this.callParent(arguments); + + + item.layoutManagedHeight = 2; + item.layoutManagedWidth = 2; } }); @@ -27868,11 +27968,14 @@ Ext.define('Ext.container.AbstractContainer', { isContainer : true, + + layoutCounter : 0, + baseCls: Ext.baseCSSPrefix + 'container', bubbleEvents: ['add', 'remove'], - + initComponent : function(){ var me = this; @@ -27886,11 +27989,7 @@ Ext.define('Ext.container.AbstractContainer', { 'add', - 'remove', - - 'beforecardswitch', - - 'cardswitch' + 'remove' ); @@ -27922,6 +28021,20 @@ Ext.define('Ext.container.AbstractContainer', { this.callParent(); }, + renderChildren: function () { + var me = this, + layout = me.getLayout(); + + me.callParent(); + + + if (layout) { + me.suspendLayout = true; + layout.renderChildren(); + delete me.suspendLayout; + } + }, + setLayout : function(layout) { var currentLayout = this.layout; @@ -27951,7 +28064,7 @@ Ext.define('Ext.container.AbstractContainer', { if (me.rendered && layout && !me.suspendLayout) { - if ((!Ext.isNumber(me.width) || !Ext.isNumber(me.height)) && me.componentLayout.type !== 'autocomponent') { + if (!me.isFixedWidth() || !me.isFixedHeight()) { if (me.componentLayout.layoutBusy !== true) { me.doComponentLayout(); @@ -27974,6 +28087,7 @@ Ext.define('Ext.container.AbstractContainer', { afterLayout : function(layout) { + ++this.layoutCounter; this.fireEvent('afterlayout', this, layout); }, @@ -28009,12 +28123,8 @@ Ext.define('Ext.container.AbstractContainer', { if (Ext.isString(config)) { config = Ext.ComponentManager.get(config); - Ext.applyIf(config, defaults); - } else if (!config.isComponent) { - Ext.applyIf(config, defaults); - } else { - Ext.applyIf(config, defaults); } + Ext.applyIf(config, defaults); } return config; @@ -28067,11 +28177,8 @@ Ext.define('Ext.container.AbstractContainer', { me.suspendLayout = true; for (i = 0, ln = items.length; i < ln; i++) { item = items[i]; - - if (!item) { - Ext.Error.raise("Trying to add a null item as a child of Container with itemId/id: " + me.getItemId()); - } - + + if (index != -1) { item = me.add(index + i, item); } else { @@ -28105,15 +28212,6 @@ Ext.define('Ext.container.AbstractContainer', { return cmp; }, - - registerFloatingItem: function(cmp) { - var me = this; - if (!me.floatingItems) { - me.floatingItems = Ext.create('Ext.ZIndexManager', me); - } - me.floatingItems.register(cmp); - }, - onAdd : Ext.emptyFn, onRemove : Ext.emptyFn, @@ -28138,7 +28236,7 @@ Ext.define('Ext.container.AbstractContainer', { onBeforeAdd : function(item) { var me = this; - + if (item.ownerCt) { item.ownerCt.remove(item, false); } @@ -28152,9 +28250,6 @@ Ext.define('Ext.container.AbstractContainer', { remove : function(comp, autoDestroy) { var me = this, c = me.getComponent(comp); - if (Ext.isDefined(Ext.global.console) && !c) { - console.warn("Attempted to remove a component that does not exist. Ext.container.Container: remove takes an argument of the component to remove. cmp.remove() is incorrect usage."); - } if (c && me.fireEvent('beforeremove', me, c) !== false) { me.doRemove(c, autoDestroy); @@ -28214,7 +28309,9 @@ Ext.define('Ext.container.AbstractContainer', { me.suspendLayout = false; - me.doLayout(); + if (len) { + me.doLayout(); + } return items; }, @@ -28286,11 +28383,13 @@ Ext.define('Ext.container.AbstractContainer', { query : function(selector) { + selector = selector || '*'; return Ext.ComponentQuery.query(selector, this); }, child : function(selector) { + selector = selector || ''; return this.query('> ' + selector)[0] || null; }, @@ -28324,8 +28423,8 @@ Ext.define('Ext.container.AbstractContainer', { } } layoutCollection.clear(); - }, - + }, + //@private @@ -28333,12 +28432,12 @@ Ext.define('Ext.container.AbstractContainer', { Ext.Array.each(this.query('[isFormField]'), function(item) { if (item.resetDisable) { item.enable(); - delete item.resetDisable; + delete item.resetDisable; } }); this.callParent(); }, - + onDisable: function() { @@ -28369,13 +28468,13 @@ Ext.define('Ext.container.AbstractContainer', { } Ext.destroy( - me.layout, - me.floatingItems + me.layout ); me.callParent(); } }); + Ext.define('Ext.container.Container', { extend: 'Ext.container.AbstractContainer', alias: 'widget.container', @@ -28522,10 +28621,16 @@ Ext.define('Ext.menu.Manager', { onMouseDown: function(e) { var me = this, active = me.active, - lastShow = me.lastShow; + lastShow = me.lastShow, + target = e.target; if (Ext.Date.getElapsed(lastShow) > 50 && active.length > 0 && !e.getTarget('.' + Ext.baseCSSPrefix + 'menu')) { me.hideAll(); + + + if (Ext.isIE && Ext.fly(target).focusable()) { + target.focus(); + } } }, @@ -28627,6 +28732,140 @@ Ext.define('Ext.menu.Manager', { } }); +Ext.define('Ext.layout.component.Button', { + + + + alias: ['layout.button'], + + extend: 'Ext.layout.component.Component', + + + + type: 'button', + + cellClsRE: /-btn-(tl|br)\b/, + htmlRE: /<.*>/, + + beforeLayout: function() { + return this.callParent(arguments) || this.lastText !== this.owner.text; + }, + + + onLayout: function(width, height) { + var me = this, + isNum = Ext.isNumber, + owner = me.owner, + 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; + + me.getTargetInfo(); + me.callParent(arguments); + + btnInnerEl.unclip(); + me.setTargetSize(width, height); + + if (!isNum(width)) { + + + + if (owner.text && (Ext.isIE6 || Ext.isIE7) && Ext.isStrict && btnEl && btnEl.getWidth() > 20) { + btnFrameWidth = me.btnFrameWidth; + metrics = Ext.util.TextMetrics.measure(btnInnerEl, owner.text); + 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 { + + ownerEl.setWidth(null); + btnEl.setWidth(null); + btnInnerEl.setWidth(null); + btnIconEl.setWidth(null); + } + + + if (minWidth || maxWidth) { + ownerWidth = ownerEl.getWidth(); + if (minWidth && (ownerWidth < minWidth)) { + me.setTargetSize(minWidth, height); + } + else if (maxWidth && (ownerWidth > maxWidth)) { + btnInnerEl.clip(); + me.setTargetSize(maxWidth, height); + } + } + } + + this.lastText = owner.text; + }, + + setTargetSize: function(width, height) { + var me = this, + owner = me.owner, + isNum = Ext.isNumber, + btnInnerEl = owner.btnInnerEl, + btnWidth = (isNum(width) ? width - me.adjWidth : width), + btnHeight = (isNum(height) ? height - me.adjHeight : height), + btnFrameHeight = me.btnFrameHeight, + text = owner.getText(), + textHeight; + + me.callParent(arguments); + me.setElementSize(owner.btnEl, btnWidth, btnHeight); + me.setElementSize(btnInnerEl, btnWidth, btnHeight); + if (btnHeight >= 0) { + btnInnerEl.setStyle('line-height', btnHeight - btnFrameHeight + 'px'); + } + + + + + + + if (text && this.htmlRE.test(text)) { + btnInnerEl.setStyle('line-height', 'normal'); + textHeight = Ext.util.TextMetrics.measure(btnInnerEl, text).height; + btnInnerEl.setStyle('padding-top', me.btnFrameTop + Math.max(btnInnerEl.getHeight() - btnFrameHeight - textHeight, 0) / 2 + 'px'); + me.setElementSize(btnInnerEl, btnWidth, btnHeight); + } + }, + + getTargetInfo: function() { + var me = this, + owner = me.owner, + ownerEl = owner.el, + frameSize = me.frameSize, + frameBody = owner.frameBody, + btnWrap = owner.btnWrap, + innerEl = owner.btnInnerEl; + + if (!('adjWidth' in me)) { + Ext.apply(me, { + + adjWidth: frameSize.left + frameSize.right + ownerEl.getBorderWidth('lr') + ownerEl.getPadding('lr') + + btnWrap.getPadding('lr') + (frameBody ? frameBody.getFrameWidth('lr') : 0), + adjHeight: frameSize.top + frameSize.bottom + ownerEl.getBorderWidth('tb') + ownerEl.getPadding('tb') + + btnWrap.getPadding('tb') + (frameBody ? frameBody.getFrameWidth('tb') : 0), + btnFrameWidth: innerEl.getFrameWidth('lr'), + btnFrameHeight: innerEl.getFrameWidth('tb'), + btnFrameTop: innerEl.getFrameWidth('t') + }); + } + + return me.callParent(); + } +}); + Ext.define('Ext.button.Button', { @@ -28691,6 +28930,9 @@ Ext.define('Ext.button.Button', { menuAlign: 'tl-bl?', + textAlign: 'center', + + @@ -28699,7 +28941,7 @@ Ext.define('Ext.button.Button', { clickEvent: 'click', - + preventDefault: true, @@ -28714,46 +28956,54 @@ Ext.define('Ext.button.Button', { pressedCls: 'pressed', - + overCls: 'over', - + focusCls: 'focus', - + menuActiveCls: 'menu-active', + + - + ariaRole: 'button', renderTpl: - '' + + '' + '' + - ' tabIndex="{tabIndex}" role="link">' + - '{text}' + + ' tabIndex="{tabIndex}" role="link">' + + '' + + '{text}' + + '' + + '' + '' + '' + '' + - '' + '' + '' , scale: 'small', - + allowedScales: ['small', 'medium', 'large'], - + @@ -28772,7 +29022,7 @@ Ext.define('Ext.button.Button', { - + maskOnDisable: false, @@ -28853,15 +29103,16 @@ Ext.define('Ext.button.Button', { setButtonCls: function() { var me = this, - el = me.el, - cls = []; + cls = [], + btnIconEl = me.btnIconEl, + hide = 'x-hide-display'; if (me.useSetClass) { if (!Ext.isEmpty(me.oldCls)) { me.removeClsWithUI(me.oldCls); me.removeClsWithUI(me.pressedCls); } - + if (me.iconCls || me.icon) { if (me.text) { @@ -28869,32 +29120,35 @@ Ext.define('Ext.button.Button', { } else { cls.push('icon'); } - } else if (me.text) { - cls.push('noicon'); + if (btnIconEl) { + btnIconEl.removeCls(hide); + } + } else { + if (me.text) { + cls.push('noicon'); + } + if (btnIconEl) { + btnIconEl.addCls(hide); + } } - + me.oldCls = cls; me.addClsWithUI(cls); me.addClsWithUI(me.pressed ? me.pressedCls : null); } }, - + onRender: function(ct, position) { var me = this, repeater, btn; - + Ext.applyIf(me.renderData, me.getTemplateArgs()); - - Ext.applyIf(me.renderSelectors, { - btnEl : me.href ? 'a' : 'button', - btnWrap: 'em', - btnInnerEl: '.' + me.baseCls + '-inner' - }); - + me.addChildEls('btnEl', 'btnWrap', 'btnInnerEl', 'btnIconEl'); + if (me.scale) { me.ui = me.ui + '-' + me.scale; } @@ -28904,7 +29158,7 @@ Ext.define('Ext.button.Button', { if (me.split && me.arrowTooltip) { - me.arrowEl.dom[me.tooltipType] = me.arrowTooltip; + me.arrowEl.dom.setAttribute(me.getTipAttr(), me.arrowTooltip); } @@ -28929,6 +29183,10 @@ Ext.define('Ext.button.Button', { me.setTooltip(me.tooltip, true); } + if (me.textAlign) { + me.setTextAlign(me.textAlign); + } + if (me.handleMouseEvents) { me.mon(btn, { @@ -28992,6 +29250,7 @@ Ext.define('Ext.button.Button', { type : me.type, splitCls : me.getSplitCls(), cls : me.cls, + iconCls : me.iconCls || '', text : me.text || ' ', tabIndex : me.tabIndex, innerSpanStyle: innerSpanStyle @@ -29002,7 +29261,7 @@ Ext.define('Ext.button.Button', { getHref: function() { var me = this, params = Ext.apply({}, me.baseParams); - + params = Ext.apply(params, me.params); return me.href ? Ext.urlAppend(me.href, Ext.Object.toQueryString(params)) : false; @@ -29031,14 +29290,16 @@ Ext.define('Ext.button.Button', { setIconCls: function(cls) { var me = this, - btnInnerEl = me.btnInnerEl; - if (btnInnerEl) { + btnIconEl = me.btnIconEl, + oldCls = me.iconCls; + + me.iconCls = cls; + if (btnIconEl) { - btnInnerEl.removeCls(me.iconCls); - btnInnerEl.addCls(cls || ''); + btnIconEl.removeCls(oldCls); + btnIconEl.addCls(cls || ''); me.setButtonCls(); } - me.iconCls = cls; return me; }, @@ -29057,7 +29318,7 @@ Ext.define('Ext.button.Button', { tooltip)); me.tooltip = tooltip; } else { - me.btnEl.dom.setAttribute('data-' + this.tooltipType, tooltip); + me.btnEl.dom.setAttribute(me.getTipAttr(), tooltip); } } else { me.tooltip = tooltip; @@ -29066,10 +29327,27 @@ Ext.define('Ext.button.Button', { }, + setTextAlign: function(align) { + var me = this, + btnEl = me.btnEl; + + if (btnEl) { + btnEl.removeCls(me.baseCls + '-' + me.textAlign); + btnEl.addCls(me.baseCls + '-' + align); + } + me.textAlign = align; + return me; + }, + + getTipAttr: function(){ + return this.tooltipType == 'qtip' ? 'data-qtip' : 'title'; + }, + + getRefItems: function(deep){ var menu = this.menu, items; - + if (menu) { items = menu.getRefItems(deep); items.unshift(menu); @@ -29091,9 +29369,10 @@ Ext.define('Ext.button.Button', { me.clearTip(); } if (me.menu && me.destroyMenu !== false) { - Ext.destroy(me.btnEl, me.btnInnerEl, me.menu); + Ext.destroy(me.menu); } - Ext.destroy(me.repeater); + Ext.destroy(me.btnInnerEl, me.repeater); + me.callParent(); }, @@ -29103,10 +29382,8 @@ Ext.define('Ext.button.Button', { me.doc.un('mouseover', me.monitorMouseOver, me); me.doc.un('mouseup', me.onMouseUp, me); delete me.doc; - delete me.btnEl; - delete me.btnInnerEl; Ext.ButtonToggleManager.unregister(me); - + Ext.destroy(me.keyMap); delete me.keyMap; } @@ -29135,10 +29412,11 @@ Ext.define('Ext.button.Button', { setIcon: function(icon) { var me = this, - btnInnerEl = me.btnInnerEl; + iconEl = me.btnIconEl; + me.icon = icon; - if (btnInnerEl) { - btnInnerEl.setStyle('background-image', icon ? 'url(' + icon + ')': ''); + if (iconEl) { + iconEl.setStyle('background-image', icon ? 'url(' + icon + ')': ''); me.setButtonCls(); } return me; @@ -29152,7 +29430,7 @@ Ext.define('Ext.button.Button', { toggle: function(state, suppressEvent) { var me = this; - state = state === undefined ? !me.pressed: !!state; + state = state === undefined ? !me.pressed : !!state; if (state !== me.pressed) { if (me.rendered) { me[state ? 'addClsWithUI': 'removeClsWithUI'](me.pressedCls); @@ -29166,12 +29444,19 @@ Ext.define('Ext.button.Button', { } return me; }, + + maybeShowMenu: function(){ + var me = this; + if (me.menu && !me.hasVisibleMenu() && !me.ignoreNextClick) { + me.showMenu(); + } + }, showMenu: function() { var me = this; if (me.rendered && me.menu) { - if (me.tooltip) { + if (me.tooltip && me.getTipAttr() != 'title') { Ext.tip.QuickTipManager.getQuickTip().cancelShow(me.btnEl); } if (me.menu.isVisible()) { @@ -29212,17 +29497,27 @@ Ext.define('Ext.button.Button', { return; } if (!me.disabled) { - if (me.enableToggle && (me.allowDepress !== false || !me.pressed)) { - me.toggle(); - } - if (me.menu && !me.hasVisibleMenu() && !me.ignoreNextClick) { - me.showMenu(); - } - me.fireEvent('click', me, e); - if (me.handler) { - me.handler.call(me.scope || me, me, e); - } - me.onBlur(); + me.doToggle(); + me.maybeShowMenu(); + me.fireHandler(e); + } + }, + + fireHandler: function(e){ + var me = this, + handler = me.handler; + + me.fireEvent('click', me, e); + if (handler) { + handler.call(me.scope || me, me, e); + } + me.onBlur(); + }, + + doToggle: function(){ + var me = this; + if (me.enableToggle && (me.allowDepress !== false || !me.pressed)) { + me.toggle(); } }, @@ -29278,7 +29573,7 @@ Ext.define('Ext.button.Button', { var me = this, size = me.triggerSize, side, sideFirstLetter, undef; - + if (size === undef) { side = me.arrowAlign; sideFirstLetter = side.charAt(0); @@ -29314,13 +29609,13 @@ Ext.define('Ext.button.Button', { delete me.overMenuTrigger; me.fireEvent('menutriggerout', me, me.menu, e); }, - + enable : function(silent) { var me = this; me.callParent(arguments); - + me.removeClsWithUI('disabled'); return me; @@ -29329,43 +29624,44 @@ Ext.define('Ext.button.Button', { disable : function(silent) { var me = this; - + me.callParent(arguments); - + me.addClsWithUI('disabled'); + me.removeClsWithUI(me.overCls); return me; }, - + setScale: function(scale) { var me = this, ui = me.ui.replace('-' + me.scale, ''); - + if (!Ext.Array.contains(me.allowedScales, scale)) { throw('#setScale: scale must be an allowed scale (' + me.allowedScales.join(', ') + ')'); } - + me.scale = scale; me.setUI(ui); }, - + setUI: function(ui) { var me = this; - + if (me.scale && !ui.match(me.scale)) { ui = ui + '-' + me.scale; } - + me.callParent([ui]); - + }, - + onFocus: function(e) { var me = this; @@ -29464,10 +29760,10 @@ Ext.define('Ext.button.Button', { } }, function() { - var groups = {}, - g, i, l; + var groups = {}; function toggleGroup(btn, state) { + var g, i, l; if (state) { g = groups[btn.toggleGroup]; for (i = 0, l = g.length; i < l; i++) { @@ -29477,6 +29773,7 @@ Ext.define('Ext.button.Button', { } } } + Ext.ButtonToggleManager = { register: function(btn) { @@ -29728,7 +30025,6 @@ Ext.define('Ext.layout.container.boxOverflow.Menu', { me.menu = Ext.create('Ext.menu.Menu', { - hideMode: 'offsets', listeners: { scope: me, beforeshow: me.beforeMenuShow @@ -29738,7 +30034,7 @@ Ext.define('Ext.layout.container.boxOverflow.Menu', { me.menuTrigger = Ext.create('Ext.button.Button', { ownerCt : me.layout.owner, - iconCls : Ext.baseCSSPrefix + layout.owner.getXType() + '-more-icon', + iconCls : me.layout.owner.menuTriggerCls, ui : layout.owner instanceof Ext.toolbar.Toolbar ? 'default-toolbar' : 'default', menu : me.menu, getSplitCls: function() { return '';}, @@ -29777,7 +30073,6 @@ Ext.define('Ext.layout.container.boxOverflow.Menu', { } }); - Ext.define('Ext.util.Region', { @@ -30018,7 +30313,6 @@ Ext.define('Ext.util.Region', { return "Region[" + this.top + "," + this.right + "," + this.bottom + "," + this.left + "]"; }, - translateBy: function(x, y) { if (arguments.length == 1) { @@ -30064,7 +30358,7 @@ Ext.define('Ext.dd.DragDropManager', { alternateClassName: ['Ext.dd.DragDropMgr', 'Ext.dd.DDM'], - + ids: {}, @@ -30280,7 +30574,7 @@ Ext.define('Ext.dd.DragDropManager', { this.handleMouseUp(e); } - + this.currentTarget = e.getTarget(); this.dragCurrent = oDD; @@ -30316,7 +30610,7 @@ Ext.define('Ext.dd.DragDropManager', { handleMouseUp: function(e) { - if(Ext.tip.QuickTipManager){ + if(Ext.tip && Ext.tip.QuickTipManager){ Ext.tip.QuickTipManager.ddEnable(); } if (! this.dragCurrent) { @@ -30620,7 +30914,7 @@ Ext.define('Ext.dd.DragDropManager', { var el = oDD.getEl(), pos, x1, x2, y1, y2, t, r, b, l; try { - pos= Ext.core.Element.getXY(el); + pos= Ext.Element.getXY(el); } catch (e) { } if (!pos) { @@ -30740,22 +31034,25 @@ Ext.define('Ext.dd.DragDropManager', { ElementWrapper: function(el) { - - this.el = el || null; - - this.id = this.el && el.id; - - this.css = this.el && el.style; - }, + + this.el = el || null; + + this.id = this.el && el.id; + + this.css = this.el && el.style; + }, + + + getPosX: function(el) { - return Ext.core.Element.getX(el); + return Ext.Element.getX(el); }, getPosY: function(el) { - return Ext.core.Element.getY(el); + return Ext.Element.getY(el); }, @@ -30784,7 +31081,7 @@ Ext.define('Ext.dd.DragDropManager', { body = doc.body, top = 0, left = 0; - + if (Ext.isGecko4) { top = window.scrollYOffset; left = window.scrollXOffset; @@ -30795,7 +31092,7 @@ Ext.define('Ext.dd.DragDropManager', { } else if (body) { top = body.scrollTop; left = body.scrollLeft; - } + } } return { top: top, @@ -30820,8 +31117,8 @@ Ext.define('Ext.dd.DragDropManager', { moveToEl: function (moveEl, targetEl) { - var aCoord = Ext.core.Element.getXY(targetEl); - Ext.core.Element.setXY(moveEl, aCoord); + var aCoord = Ext.Element.getXY(targetEl); + Ext.Element.setXY(moveEl, aCoord); }, @@ -30879,7 +31176,7 @@ Ext.define('Ext.layout.container.Box', { alias: ['layout.box'], extend: 'Ext.layout.container.Container', alternateClassName: 'Ext.layout.BoxLayout', - + requires: [ 'Ext.layout.container.boxOverflow.None', 'Ext.layout.container.boxOverflow.Menu', @@ -30916,15 +31213,16 @@ Ext.define('Ext.layout.container.Box', { bindToOwnerCtContainer: true, - fixedLayout: false, - availableSpaceOffset: 0, - + reserveOffset: true, + + shrinkToFit: true, + clearInnerCtOnLayout: false, @@ -30959,11 +31257,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 }; }, @@ -31007,6 +31306,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', @@ -31022,16 +31323,21 @@ Ext.define('Ext.layout.container.Box', { minSizes = [], calculatedWidth, - i, child, childParallel, childPerpendicular, childMargins, childSize, minParallel, tmpObj, shortfall, - tooNarrow, availableSpace, minSize, item, length, itemIndex, box, oldSize, newSize, reduction, diff, - flexedBoxes, remainingSpace, remainingFlex, flexedSize, parallelMargins, calcs, offset, + i, child, childParallel, childPerpendicular, childMargins, childSize, minParallel, tmpObj, shortfall, + tooNarrow, availableSpace, minSize, item, length, itemIndex, box, oldSize, newSize, reduction, diff, + flexedBoxes, remainingSpace, remainingFlex, flexedSize, parallelMargins, calcs, offset, perpendicularMargins, stretchSize; for (i = 0; i < visibleCount; i++) { child = visibleItems[i]; childPerpendicular = child[perpendicularPrefix]; - me.layoutItem(child); + if (!child.flex || !(me.align == 'stretch' || me.align == 'stretchmax')) { + if (child.componentLayout.initialized !== true) { + me.layoutItem(child); + } + } + childMargins = child.margins; parallelMargins = childMargins[me.parallelBefore] + childMargins[me.parallelAfter]; @@ -31067,14 +31373,20 @@ Ext.define('Ext.layout.container.Box', { } - maxSize = mmax(maxSize, childPerpendicular + childMargins[me.perpendicularLeftTop] + childMargins[me.perpendicularRightBottom]); + + maxSize = mmax(maxSize, mmax(childPerpendicular, child[perpendicularMinString]||0) + childMargins[me.perpendicularLeftTop] + childMargins[me.perpendicularRightBottom]); tmpObj[parallelPrefix] = childParallel || undefinedValue; + tmpObj.dirtySize = child.componentLayout.lastComponentSize ? (tmpObj[parallelPrefix] !== child.componentLayout.lastComponentSize[parallelPrefix]) : false; tmpObj[perpendicularPrefix] = childPerpendicular || undefinedValue; boxes.push(tmpObj); } - shortfall = desiredSize - parallelSize; - tooNarrow = minimumSize > parallelSize; + + + if (!me.autoSize) { + shortfall = desiredSize - parallelSize; + tooNarrow = minimumSize > parallelSize; + } availableSpace = mmax(0, parallelSize - nonFlexSize - paddingParallel - (me.reserveOffset ? me.availableSpaceOffset : 0)); @@ -31102,8 +31414,7 @@ Ext.define('Ext.layout.container.Box', { box = boxes[i]; box.dirtySize = box.dirtySize || box[parallelPrefix] != minSize; box[parallelPrefix] = minSize; - } - else { + } else if (me.shrinkToFit) { minSizes.push({ minSize: minSize, available: boxes[i][parallelPrefix] - minSize, @@ -31134,6 +31445,7 @@ Ext.define('Ext.layout.container.Box', { box[parallelPrefix] = newSize; shortfall -= reduction; } + tooNarrow = (shortfall > 0); } else { remainingSpace = availableSpace; @@ -31223,7 +31535,7 @@ Ext.define('Ext.layout.container.Box', { - 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); } @@ -31246,7 +31558,7 @@ Ext.define('Ext.layout.container.Box', { } }; }, - + onRemove: function(comp){ this.callParent(arguments); if (this.overflowHandler) { @@ -31310,7 +31622,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; } @@ -31329,6 +31641,8 @@ Ext.define('Ext.layout.container.Box', { me.updateChildBoxes(boxes); me.handleTargetOverflow(targetSize); }, + + animCallback: Ext.emptyFn, updateChildBoxes: function(boxes) { @@ -31417,6 +31731,7 @@ Ext.define('Ext.layout.container.Box', { length -= 1; if (!length) { + me.animCallback(anim); me.layoutBusy = false; if (Ext.isFunction(animCallback)) { animCallback(); @@ -31561,6 +31876,8 @@ Ext.define('Ext.layout.container.Box', { margins.right += itemEl.getMargin('r'); margins.bottom += itemEl.getMargin('b'); margins.left += itemEl.getMargin('l'); + margins.height = margins.top + margins.bottom; + margins.width = margins.left + margins.right; style.marginTop = style.marginRight = style.marginBottom = style.marginLeft = '0'; @@ -31569,7 +31886,7 @@ Ext.define('Ext.layout.container.Box', { destroy: function() { - Ext.destroy(this.overflowHandler); + Ext.destroy(this.innerCt, this.overflowHandler); this.callParent(arguments); } }); @@ -31581,7 +31898,7 @@ Ext.define('Ext.layout.container.HBox', { alias: ['layout.hbox'], extend: 'Ext.layout.container.Box', alternateClassName: 'Ext.layout.HBoxLayout', - + @@ -31614,7 +31931,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); + } }); Ext.define('Ext.layout.container.VBox', { @@ -31624,7 +31955,7 @@ Ext.define('Ext.layout.container.VBox', { alias: ['layout.vbox'], extend: 'Ext.layout.container.Box', alternateClassName: 'Ext.layout.VBoxLayout', - + @@ -31657,7 +31988,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); + } }); Ext.define('Ext.FocusManager', { @@ -31949,8 +32294,8 @@ Ext.define('Ext.FocusManager', { ], style: 'top: -100px; left: -100px;' }); - me.focusFrame.setVisibilityMode(Ext.core.Element.DISPLAY); - me.focusFrameWidth = me.focusFrame.child('.' + cls + '-top').getHeight(); + me.focusFrame.setVisibilityMode(Ext.Element.DISPLAY); + me.focusFrameWidth = 2; me.focusFrame.hide().setLeftTop(0, 0); } }, @@ -31996,10 +32341,14 @@ Ext.define('Ext.FocusManager', { if (!me.focusedCmp || !(parent = me.focusedCmp.up(':focusable'))) { me.focusEl.focus(); - return; + } else { + parent.focus(); } - parent.focus(); + + + + return true; }, navigateSiblings: function(e, source, parent) { @@ -32118,10 +32467,10 @@ Ext.define('Ext.FocusManager', { fl = ff.child(cls + 'left'), fr = ff.child(cls + 'right'); - ft.setWidth(bw - 2).setLeftTop(bl + 1, bt); - fb.setWidth(bw - 2).setLeftTop(bl + 1, bt + bh - fw); - fl.setHeight(bh - 2).setLeftTop(bl, bt + 1); - fr.setHeight(bh - 2).setLeftTop(bl + bw - fw, bt + 1); + ft.setWidth(bw).setLeftTop(bl, bt); + fb.setWidth(bw).setLeftTop(bl, bt + bh - fw); + fl.setHeight(bh - fw - fw).setLeftTop(bl, bt + fw); + fr.setHeight(bh - fw - fw).setLeftTop(bl + bw - fw, bt + fw); ff.show(); } @@ -32417,13 +32766,13 @@ Ext.define('Ext.toolbar.Toolbar', { ], alias: 'widget.toolbar', alternateClassName: 'Ext.Toolbar', - + isToolbar: true, baseCls : Ext.baseCSSPrefix + 'toolbar', ariaRole : 'toolbar', - + defaultType: 'button', - + vertical: false, @@ -32431,12 +32780,15 @@ Ext.define('Ext.toolbar.Toolbar', { enableOverflow: false, + + menuTriggerCls: Ext.baseCSSPrefix + 'toolbar-more-icon', - trackMenus: true, + trackMenus: true, + itemCls: Ext.baseCSSPrefix + 'toolbar-item', - + initComponent: function() { var me = this, keys; @@ -32445,7 +32797,7 @@ Ext.define('Ext.toolbar.Toolbar', { if (!me.layout && me.enableOverflow) { me.layout = { overflowHandler: 'Menu' }; } - + if (me.dock === 'right' || me.dock === 'left') { me.vertical = true; } @@ -32454,23 +32806,24 @@ Ext.define('Ext.toolbar.Toolbar', { type: me.layout } : me.layout || {}, { type: me.vertical ? 'vbox' : 'hbox', - align: me.vertical ? 'stretchmax' : 'middle' + align: me.vertical ? 'stretchmax' : 'middle', + clearInnerCtOnLayout: true }); - + if (me.vertical) { me.addClsWithUI('vertical'); } - + if (me.ui === 'footer') { me.ignoreBorderManagement = true; } - + me.callParent(); me.addEvents('overflowchange'); - + keys = me.vertical ? ['up', 'down'] : ['left', 'right']; Ext.FocusManager.subscribe(me, { @@ -32478,6 +32831,21 @@ Ext.define('Ext.toolbar.Toolbar', { }); }, + getRefItems: function(deep) { + var me = this, + items = me.callParent(arguments), + layout = me.layout, + handler; + + if (deep && me.enableOverflow) { + handler = layout.overflowHandler; + if (handler && handler.menu) { + items = items.concat(handler.menu.getRefItems(deep)); + } + } + return items; + }, + @@ -32520,7 +32888,7 @@ Ext.define('Ext.toolbar.Toolbar', { var method = remove ? 'mun' : 'mon', me = this; - me[method](item, 'menutriggerover', me.onButtonTriggerOver, me); + me[method](item, 'mouseover', me.onButtonOver, me); me[method](item, 'menushow', me.onButtonMenuShow, me); me[method](item, 'menuhide', me.onButtonMenuHide, me); } @@ -32536,12 +32904,12 @@ Ext.define('Ext.toolbar.Toolbar', { if (component.is('field') || (component.is('button') && this.ui != 'footer')) { component.ui = component.ui + '-toolbar'; } - + if (component instanceof Ext.toolbar.Separator) { component.setUI((this.vertical) ? 'vertical' : 'horizontal'); } - + this.callParent(arguments); }, @@ -32562,7 +32930,7 @@ Ext.define('Ext.toolbar.Toolbar', { }, - onButtonTriggerOver: function(btn){ + onButtonOver: function(btn){ if (this.activeMenuBtn && this.activeMenuBtn != btn) { this.activeMenuBtn.hideMenu(); btn.showMenu(); @@ -32593,7 +32961,7 @@ Ext.define('Ext.panel.AbstractPanel', { extend: 'Ext.container.Container', - requires: ['Ext.util.MixedCollection', 'Ext.core.Element', 'Ext.toolbar.Toolbar'], + requires: ['Ext.util.MixedCollection', 'Ext.Element', 'Ext.toolbar.Toolbar'], @@ -32603,25 +32971,34 @@ Ext.define('Ext.panel.AbstractPanel', { + - - + isPanel: true, componentLayout: 'dock', - renderTpl: ['
{bodyCls} {baseCls}-body-{ui} {parent.baseCls}-body-{parent.ui}-{.}" style="{bodyStyle}">
'], + + defaultDockWeights: { top: 1, left: 3, right: 5, bottom: 7 }, + + renderTpl: [ + '
{bodyCls}', + ' {baseCls}-body-{ui}', + ' {parent.baseCls}-body-{parent.ui}-{.}', + '" style="{bodyStyle}">', + '
' + ], - + border: true, initComponent : function() { var me = this; - + me.addEvents( 'bodyresize' @@ -32631,20 +33008,18 @@ Ext.define('Ext.panel.AbstractPanel', { ); - Ext.applyIf(me.renderSelectors, { - body: '.' + me.baseCls + '-body' - }); - - + me.addChildEls('body'); + + if (me.frame && me.border && me.bodyBorder === undefined) { me.bodyBorder = false; } if (me.frame && me.border && (me.bodyBorder === false || me.bodyBorder === 0)) { me.manageBodyBorders = true; } - + me.callParent(); }, @@ -32652,7 +33027,7 @@ Ext.define('Ext.panel.AbstractPanel', { initItems : function() { var me = this, items = me.dockedItems; - + me.callParent(); me.dockedItems = Ext.create('Ext.util.MixedCollection', false, me.getComponentId); if (items) { @@ -32683,7 +33058,7 @@ Ext.define('Ext.panel.AbstractPanel', { var me = this, bodyStyle = me.bodyStyle, styles = [], - Element = Ext.core.Element, + Element = Ext.Element, prop; if (Ext.isFunction(bodyStyle)) { @@ -32711,13 +33086,13 @@ Ext.define('Ext.panel.AbstractPanel', { delete me.bodyStyle; return styles.length ? styles.join(';') : undefined; }, - + initBodyCls: function() { var me = this, cls = '', bodyCls = me.bodyCls; - + if (bodyCls) { Ext.each(bodyCls, function(v) { cls += " " + v; @@ -32726,7 +33101,7 @@ Ext.define('Ext.panel.AbstractPanel', { } return cls.length > 0 ? cls : undefined; }, - + initRenderData: function() { return Ext.applyIf(this.callParent(), { @@ -32762,6 +33137,9 @@ Ext.define('Ext.panel.AbstractPanel', { item.onAdded(me, i); me.onDockedAdd(item); } + + + me.componentLayout.childrenChanged = true; if (me.rendered && !me.suspendLayout) { me.doComponentLayout(); } @@ -32782,7 +33160,7 @@ Ext.define('Ext.panel.AbstractPanel', { var me = this, layout, hasLayout; - + if (!me.dockedItems.contains(item)) { return item; } @@ -32800,13 +33178,15 @@ Ext.define('Ext.panel.AbstractPanel', { if (autoDestroy === true || (autoDestroy !== false && me.autoDestroy)) { item.destroy(); + } else if (hasLayout) { + + layout.afterRemove(item); } - if (hasLayout && !autoDestroy) { - layout.afterRemove(item); - } + - if (!this.destroying) { + me.componentLayout.childrenChanged = true; + if (!me.destroying && !me.suspendLayout) { me.doComponentLayout(); } @@ -32816,9 +33196,7 @@ Ext.define('Ext.panel.AbstractPanel', { getDockedItems : function(cqSelector) { var me = this, - - - defaultWeight = { top: 1, left: 3, right: 5, bottom: 7 }, + defaultWeight = me.defaultDockWeights, dockedItems; if (me.dockedItems && me.dockedItems.items.length) { @@ -32831,7 +33209,6 @@ Ext.define('Ext.panel.AbstractPanel', { Ext.Array.sort(dockedItems, function(a, b) { - var aw = a.weight || defaultWeight[a.dock], bw = b.weight || defaultWeight[b.dock]; if (Ext.isNumber(aw) && Ext.isNumber(bw)) { @@ -32839,57 +33216,123 @@ Ext.define('Ext.panel.AbstractPanel', { } return 0; }); - + return dockedItems; } return []; }, - + addUIClsToElement: function(cls, force) { - var me = this; - - me.callParent(arguments); - + var me = this, + result = me.callParent(arguments), + classes = [Ext.baseCSSPrefix + cls, me.baseCls + '-body-' + cls, me.baseCls + '-body-' + me.ui + '-' + cls], + array, i; + if (!force && me.rendered) { - me.body.addCls(Ext.baseCSSPrefix + cls); - me.body.addCls(me.baseCls + '-body-' + cls); - me.body.addCls(me.baseCls + '-body-' + me.ui + '-' + cls); + if (me.bodyCls) { + me.body.addCls(me.bodyCls); + } else { + me.body.addCls(classes); + } + } else { + if (me.bodyCls) { + array = me.bodyCls.split(' '); + + for (i = 0; i < classes.length; i++) { + if (!Ext.Array.contains(array, classes[i])) { + array.push(classes[i]); + } + } + + me.bodyCls = array.join(' '); + } else { + me.bodyCls = classes.join(' '); + } } + + return result; }, - + removeUIClsFromElement: function(cls, force) { - var me = this; - - me.callParent(arguments); - + var me = this, + result = me.callParent(arguments), + classes = [Ext.baseCSSPrefix + cls, me.baseCls + '-body-' + cls, me.baseCls + '-body-' + me.ui + '-' + cls], + array, i; + if (!force && me.rendered) { - me.body.removeCls(Ext.baseCSSPrefix + cls); - me.body.removeCls(me.baseCls + '-body-' + cls); - me.body.removeCls(me.baseCls + '-body-' + me.ui + '-' + cls); + if (me.bodyCls) { + me.body.removeCls(me.bodyCls); + } else { + me.body.removeCls(classes); + } + } else { + if (me.bodyCls) { + array = me.bodyCls.split(' '); + + for (i = 0; i < classes.length; i++) { + Ext.Array.remove(array, classes[i]); + } + + me.bodyCls = array.join(' '); + } } + + return result; }, - + addUIToElement: function(force) { - var me = this; - + var me = this, + cls = me.baseCls + '-body-' + me.ui, + array; + me.callParent(arguments); - + if (!force && me.rendered) { - me.body.addCls(me.baseCls + '-body-' + me.ui); + if (me.bodyCls) { + me.body.addCls(me.bodyCls); + } else { + me.body.addCls(cls); + } + } else { + if (me.bodyCls) { + array = me.bodyCls.split(' '); + + if (!Ext.Array.contains(array, cls)) { + array.push(cls); + } + + me.bodyCls = array.join(' '); + } else { + me.bodyCls = cls; + } } }, - + removeUIFromElement: function() { - var me = this; - + var me = this, + cls = me.baseCls + '-body-' + me.ui, + array; + me.callParent(arguments); - + if (me.rendered) { - me.body.removeCls(me.baseCls + '-body-' + me.ui); + if (me.bodyCls) { + me.body.removeCls(me.bodyCls); + } else { + me.body.removeCls(cls); + } + } else { + if (me.bodyCls) { + array = me.bodyCls.split(' '); + Ext.Array.remove(array, cls); + me.bodyCls = array.join(' '); + } else { + me.bodyCls = cls; + } } }, @@ -32905,7 +33348,7 @@ Ext.define('Ext.panel.AbstractPanel', { ln = dockedItems.length, i = 0, item; - + for (; i < ln; i++) { item = dockedItems[i]; @@ -32913,11 +33356,11 @@ Ext.define('Ext.panel.AbstractPanel', { break; } } + - - return dockedItems.splice(0, i).concat(items).concat(dockedItems); + return Ext.Array.splice(dockedItems, 0, i).concat(items).concat(dockedItems); }, beforeDestroy: function(){ @@ -32931,7 +33374,7 @@ Ext.define('Ext.panel.AbstractPanel', { } this.callParent(); }, - + setBorder: function(border) { var me = this; me.border = (border !== undefined) ? border : true; @@ -32951,10 +33394,20 @@ Ext.define('Ext.panel.Header', { indicateDrag : false, weight : -1, - renderTpl: ['
{bodyCls} {parent.baseCls}-body-{parent.ui}-{.}" style="{bodyStyle}">
'], + renderTpl: [ + '
{bodyCls}', + '', + ' {parent.baseCls}-body-{parent.ui}-{.}', + '"', + ' style="{bodyStyle}">
'], + + + + initComponent: function() { var me = this, + ruleStyle, rule, style, titleTextEl, @@ -32972,9 +33425,7 @@ Ext.define('Ext.panel.Header', { me.addClsWithUI(me.orientation); me.addClsWithUI(me.dock); - Ext.applyIf(me.renderSelectors, { - body: '.' + me.baseCls + '-body' - }); + me.addChildEls('body'); if (!Ext.isEmpty(me.iconCls)) { @@ -33009,7 +33460,11 @@ Ext.define('Ext.panel.Header', { if (Ext.isArray(ui)) { ui = ui[0]; } - rule = Ext.util.CSS.getRule('.' + me.baseCls + '-text-' + ui); + ruleStyle = '.' + me.baseCls + '-text-' + ui; + if (Ext.scopeResetCSS) { + ruleStyle = '.' + Ext.baseCSSPrefix + 'reset ' + ruleStyle; + } + rule = Ext.util.CSS.getRule(ruleStyle); if (rule) { style = rule.style; } @@ -33025,9 +33480,12 @@ Ext.define('Ext.panel.Header', { ariaRole : 'heading', focusable: false, viewBox: false, + flex : 1, autoSize: true, margins: '5 0 0 0', items: [ me.textConfig ], + + renderSelectors: { textEl: '.' + me.baseCls + '-text' } @@ -33043,28 +33501,22 @@ Ext.define('Ext.panel.Header', { xtype : 'component', ariaRole : 'heading', focusable: false, - renderTpl : ['{title}'], + flex : 1, + cls: me.baseCls + '-text-container', + renderTpl : [ + '{title}' + ], renderData: { title: me.title, cls : me.baseCls, ui : me.ui }, - renderSelectors: { - textEl: '.' + me.baseCls + '-text' - } + childEls: ['textEl'] }); } me.items.push(me.titleCmp); - me.items.push({ - xtype: 'component', - html : ' ', - flex : 1, - focusable: false - }); - - me.items = me.items.concat(me.tools); this.callParent(); }, @@ -33072,16 +33524,16 @@ Ext.define('Ext.panel.Header', { initIconCmp: function() { this.iconCmp = Ext.create('Ext.Component', { focusable: false, - renderTpl : [''], + renderTpl : [ + '' + ], renderData: { blank : Ext.BLANK_IMAGE_URL, cls : this.baseCls, iconCls: this.iconCls, orientation: this.orientation }, - renderSelectors: { - iconEl: '.' + this.baseCls + '-icon' - }, + childEls: ['iconEl'], iconCls: this.iconCls }); }, @@ -33112,36 +33564,90 @@ Ext.define('Ext.panel.Header', { addUIClsToElement: function(cls, force) { - var me = this; - - me.callParent(arguments); + var me = this, + result = me.callParent(arguments), + classes = [me.baseCls + '-body-' + cls, me.baseCls + '-body-' + me.ui + '-' + cls], + array, i; if (!force && me.rendered) { - me.body.addCls(me.baseCls + '-body-' + cls); - me.body.addCls(me.baseCls + '-body-' + me.ui + '-' + cls); + if (me.bodyCls) { + me.body.addCls(me.bodyCls); + } else { + me.body.addCls(classes); + } + } else { + if (me.bodyCls) { + array = me.bodyCls.split(' '); + + for (i = 0; i < classes.length; i++) { + if (!Ext.Array.contains(array, classes[i])) { + array.push(classes[i]); + } + } + + me.bodyCls = array.join(' '); + } else { + me.bodyCls = classes.join(' '); + } } + + return result; }, removeUIClsFromElement: function(cls, force) { - var me = this; - - me.callParent(arguments); + var me = this, + result = me.callParent(arguments), + classes = [me.baseCls + '-body-' + cls, me.baseCls + '-body-' + me.ui + '-' + cls], + array, i; if (!force && me.rendered) { - me.body.removeCls(me.baseCls + '-body-' + cls); - me.body.removeCls(me.baseCls + '-body-' + me.ui + '-' + cls); + if (me.bodyCls) { + me.body.removeCls(me.bodyCls); + } else { + me.body.removeCls(classes); + } + } else { + if (me.bodyCls) { + array = me.bodyCls.split(' '); + + for (i = 0; i < classes.length; i++) { + Ext.Array.remove(array, classes[i]); + } + + me.bodyCls = array.join(' '); + } } + + return result; }, addUIToElement: function(force) { - var me = this; + var me = this, + array, cls; me.callParent(arguments); + cls = me.baseCls + '-body-' + me.ui; if (!force && me.rendered) { - me.body.addCls(me.baseCls + '-body-' + me.ui); + if (me.bodyCls) { + me.body.addCls(me.bodyCls); + } else { + me.body.addCls(cls); + } + } else { + if (me.bodyCls) { + array = me.bodyCls.split(' '); + + if (!Ext.Array.contains(array, cls)) { + array.push(cls); + } + + me.bodyCls = array.join(' '); + } else { + me.bodyCls = cls; + } } if (!force && me.titleCmp && me.titleCmp.rendered && me.titleCmp.textEl) { @@ -33151,12 +33657,26 @@ Ext.define('Ext.panel.Header', { removeUIFromElement: function() { - var me = this; + var me = this, + array, cls; me.callParent(arguments); + cls = me.baseCls + '-body-' + me.ui; if (me.rendered) { - me.body.removeCls(me.baseCls + '-body-' + me.ui); + if (me.bodyCls) { + me.body.removeCls(me.bodyCls); + } else { + me.body.removeCls(cls); + } + } else { + if (me.bodyCls) { + array = me.bodyCls.split(' '); + Ext.Array.remove(array, cls); + me.bodyCls = array.join(' '); + } else { + me.bodyCls = cls; + } } if (me.titleCmp && me.titleCmp.rendered && me.titleCmp.textEl) { @@ -33219,19 +33739,20 @@ Ext.define('Ext.panel.Header', { setIconCls: function(cls) { - this.iconCls = cls; - if (!this.iconCmp) { - this.initIconCmp(); - this.insert(0, this.iconCmp); - } - else { - if (!cls || !cls.length) { - this.iconCmp.destroy(); - } - else { - var iconCmp = this.iconCmp, - el = iconCmp.iconEl; - + var me = this, + isEmpty = !cls || !cls.length, + iconCmp = me.iconCmp, + el; + + me.iconCls = cls; + if (!me.iconCmp && !isEmpty) { + me.initIconCmp(); + me.insert(0, me.iconCmp); + } else if (iconCmp) { + if (isEmpty) { + me.iconCmp.destroy(); + } else { + el = iconCmp.iconEl; el.removeCls(iconCmp.iconCls); el.addCls(cls); iconCmp.iconCls = cls; @@ -33959,7 +34480,6 @@ Ext.require('Ext.fx.CubicBezier', function() { }); }); - Ext.define('Ext.draw.Draw', { @@ -34053,12 +34573,12 @@ Ext.define('Ext.draw.Draw', { b && params.push(+b); }); if (name == "m" && params.length > 2) { - data.push([b].concat(params.splice(0, 2))); + data.push([b].concat(Ext.Array.splice(params, 0, 2))); name = "l"; b = (b == "m") ? "l" : "L"; } while (params.length >= paramCounts[name]) { - data.push([b].concat(params.splice(0, paramCounts[name]))); + data.push([b].concat(Ext.Array.splice(params, 0, paramCounts[name]))); if (!paramCounts[name]) { break; } @@ -34288,9 +34808,9 @@ Ext.define('Ext.draw.Draw', { points[i].shift(); point = points[i]; while (point.length) { - points.splice(i++, 0, ["C"].concat(point.splice(0, 6))); + Ext.Array.splice(points, i++, 0, ["C"].concat(Ext.Array.splice(point, 0, 6))); } - points.splice(i, 1); + Ext.Array.erase(points, i, 1); ln = points.length; } seg = points[i]; @@ -34314,15 +34834,15 @@ Ext.define('Ext.draw.Draw', { pp[i].shift(); var pi = pp[i]; while (pi.length) { - pp.splice(i++, 0, ["C"].concat(pi.splice(0, 6))); + Ext.Array.splice(pp, i++, 0, ["C"].concat(Ext.Array.splice(pi, 0, 6))); } - pp.splice(i, 1); + Ext.Array.erase(pp, i, 1); ii = Math.max(p.length, p2.length || 0); } }, fixM = function (path1, path2, a1, a2, i) { if (path1 && path2 && path1[i][0] == "M" && path2[i][0] != "M") { - path2.splice(i, 0, ["M", a2.x, a2.y]); + Ext.Array.splice(path2, i, 0, ["M", a2.x, a2.y]); a1.bx = 0; a1.by = 0; a1.x = path1[i][1]; @@ -34723,27 +35243,74 @@ Ext.define('Ext.draw.Draw', { }; }, - getAnchors: function (p1x, p1y, p2x, p2y, p3x, p3y, value) { + + getAnchors: function (prevX, prevY, curX, curY, nextX, nextY, value) { value = value || 4; - var l = Math.min(Math.sqrt(Math.pow(p1x - p2x, 2) + Math.pow(p1y - p2y, 2)) / value, Math.sqrt(Math.pow(p3x - p2x, 2) + Math.pow(p3y - p2y, 2)) / value), - a = Math.atan((p2x - p1x) / Math.abs(p2y - p1y)), - b = Math.atan((p3x - p2x) / Math.abs(p2y - p3y)), - pi = Math.PI; - a = p1y < p2y ? pi - a : a; - b = p3y < p2y ? pi - b : b; - var alpha = pi / 2 - ((a + b) % (pi * 2)) / 2; - alpha > pi / 2 && (alpha -= pi); - var dx1 = l * Math.sin(alpha + a), - dy1 = l * Math.cos(alpha + a), - dx2 = l * Math.sin(alpha + b), - dy2 = l * Math.cos(alpha + b), - out = { - x1: p2x - dx1, - y1: p2y + dy1, - x2: p2x + dx2, - y2: p2y + dy2 - }; - return out; + var M = Math, + PI = M.PI, + halfPI = PI / 2, + abs = M.abs, + sin = M.sin, + cos = M.cos, + atan = M.atan, + control1Length, control2Length, control1Angle, control2Angle, + control1X, control1Y, control2X, control2Y, alpha; + + + + control1Length = (curX - prevX) / value; + control2Length = (nextX - curX) / value; + + + + + + if ((curY >= prevY && curY >= nextY) || (curY <= prevY && curY <= nextY)) { + control1Angle = control2Angle = halfPI; + } else { + control1Angle = atan((curX - prevX) / abs(curY - prevY)); + if (prevY < curY) { + control1Angle = PI - control1Angle; + } + control2Angle = atan((nextX - curX) / abs(curY - nextY)); + if (nextY < curY) { + control2Angle = PI - control2Angle; + } + } + + + alpha = halfPI - ((control1Angle + control2Angle) % (PI * 2)) / 2; + if (alpha > halfPI) { + alpha -= PI; + } + control1Angle += alpha; + control2Angle += alpha; + + + control1X = curX - control1Length * sin(control1Angle); + control1Y = curY + control1Length * cos(control1Angle); + control2X = curX + control2Length * sin(control2Angle); + control2Y = curY + control2Length * cos(control2Angle); + + + + + + if ((curY > prevY && control1Y < prevY) || (curY < prevY && control1Y > prevY)) { + control1X += abs(prevY - control1Y) * (control1X - curX) / (control1Y - curY); + control1Y = prevY; + } + if ((curY > nextY && control2Y < nextY) || (curY < nextY && control2Y > nextY)) { + control2X -= abs(nextY - control2Y) * (control2X - curX) / (control2Y - curY); + control2Y = nextY; + } + + return { + x1: control1X, + y1: control1Y, + x2: control2X, + y2: control2Y + }; }, @@ -34812,7 +35379,11 @@ Ext.define('Ext.draw.Draw', { }; }, + snapEnds: function (from, to, stepsMax) { + if (Ext.isDate(from)) { + return this.snapEndsByDate(from, to, stepsMax); + } var step = (to - from) / stepsMax, level = Math.floor(Math.log(step) / Math.LN10) + 1, m = Math.pow(10, level), @@ -34850,6 +35421,90 @@ Ext.define('Ext.draw.Draw', { }; }, + + snapEndsByDate: function (from, to, stepsMax, lockEnds) { + var selectedStep = false, scales = [ + [Ext.Date.MILLI, [1, 2, 3, 5, 10, 20, 30, 50, 100, 200, 300, 500]], + [Ext.Date.SECOND, [1, 2, 3, 5, 10, 15, 30]], + [Ext.Date.MINUTE, [1, 2, 3, 5, 10, 20, 30]], + [Ext.Date.HOUR, [1, 2, 3, 4, 6, 12]], + [Ext.Date.DAY, [1, 2, 3, 7, 14]], + [Ext.Date.MONTH, [1, 2, 3, 4, 6]] + ], j, yearDiff; + + + Ext.each(scales, function(scale, i) { + for (j = 0; j < scale[1].length; j++) { + if (to < Ext.Date.add(from, scale[0], scale[1][j] * stepsMax)) { + selectedStep = [scale[0], scale[1][j]]; + return false; + } + } + }); + if (!selectedStep) { + yearDiff = this.snapEnds(from.getFullYear(), to.getFullYear() + 1, stepsMax, lockEnds); + selectedStep = [Date.YEAR, Math.round(yearDiff.step)]; + } + return this.snapEndsByDateAndStep(from, to, selectedStep, lockEnds); + }, + + + + snapEndsByDateAndStep: function(from, to, step, lockEnds) { + var fromStat = [from.getFullYear(), from.getMonth(), from.getDate(), + from.getHours(), from.getMinutes(), from.getSeconds(), from.getMilliseconds()], + steps = 0, testFrom, testTo; + if (lockEnds) { + testFrom = from; + } else { + switch (step[0]) { + case Ext.Date.MILLI: + testFrom = new Date(fromStat[0], fromStat[1], fromStat[2], fromStat[3], + fromStat[4], fromStat[5], Math.floor(fromStat[6] / step[1]) * step[1]); + break; + case Ext.Date.SECOND: + testFrom = new Date(fromStat[0], fromStat[1], fromStat[2], fromStat[3], + fromStat[4], Math.floor(fromStat[5] / step[1]) * step[1], 0); + break; + case Ext.Date.MINUTE: + testFrom = new Date(fromStat[0], fromStat[1], fromStat[2], fromStat[3], + Math.floor(fromStat[4] / step[1]) * step[1], 0, 0); + break; + case Ext.Date.HOUR: + testFrom = new Date(fromStat[0], fromStat[1], fromStat[2], + Math.floor(fromStat[3] / step[1]) * step[1], 0, 0, 0); + break; + case Ext.Date.DAY: + testFrom = new Date(fromStat[0], fromStat[1], + Math.floor(fromStat[2] - 1 / step[1]) * step[1] + 1, 0, 0, 0, 0); + break; + case Ext.Date.MONTH: + testFrom = new Date(fromStat[0], Math.floor(fromStat[1] / step[1]) * step[1], 1, 0, 0, 0, 0); + break; + default: + testFrom = new Date(Math.floor(fromStat[0] / step[1]) * step[1], 0, 1, 0, 0, 0, 0); + break; + } + } + + testTo = testFrom; + + while (testTo < to) { + testTo = Ext.Date.add(testTo, step[0], step[1]); + steps++; + } + + if (lockEnds) { + testTo = to; + } + return { + from : +testFrom, + to : +testTo, + step : (testTo - testFrom) / steps, + steps : steps + }; + }, + sorter: function (a, b) { return a.offset - b.offset; }, @@ -34931,6 +35586,7 @@ Ext.define('Ext.draw.Draw', { }); + Ext.define('Ext.fx.PropertyHandler', { @@ -34939,23 +35595,25 @@ Ext.define('Ext.fx.PropertyHandler', { statics: { defaultHandler: { - pixelDefaults: ['width', 'height', 'top', 'left'], + pixelDefaultsRE: /width|height|top$|bottom$|left$|right$/i, unitRE: /^(-?\d*\.?\d*){1}(em|ex|px|in|cm|mm|pt|pc|%)*$/, + scrollRE: /^scroll/i, computeDelta: function(from, end, damper, initial, attr) { damper = (typeof damper == 'number') ? damper : 1; - var match = this.unitRE.exec(from), + var unitRE = this.unitRE, + match = unitRE.exec(from), start, units; if (match) { from = match[1]; units = match[2]; - if (!units && Ext.Array.contains(this.pixelDefaults, attr)) { + if (!this.scrollRE.test(attr) && !units && this.pixelDefaultsRE.test(attr)) { units = 'px'; } } from = +from || 0; - match = this.unitRE.exec(end); + match = unitRE.exec(end); if (match) { end = match[1]; units = match[2] || units; @@ -35271,6 +35929,11 @@ Ext.define('Ext.fx.Anim', { isAnimation: true, + + + + + duration: 250, @@ -35325,7 +35988,9 @@ Ext.define('Ext.fx.Anim', { constructor: function(config) { - var me = this; + var me = this, + curve; + config = config || {}; if (config.keyframes) { @@ -35345,8 +36010,8 @@ Ext.define('Ext.fx.Anim', { if (!me.easingFn) { me.easingFn = String(me.easing).match(me.bezierRE); if (me.easingFn && me.easingFn.length == 5) { - var curve = me.easingFn; - me.easingFn = Ext.fx.cubicBezier(+curve[1], +curve[2], +curve[3], +curve[4]); + curve = me.easingFn; + me.easingFn = Ext.fx.CubicBezier.cubicBezier(+curve[1], +curve[2], +curve[3], +curve[4]); } } me.id = Ext.id(null, 'ext-anim-'); @@ -35501,15 +36166,16 @@ Ext.enableFx = true; - Ext.define('Ext.dd.DragDrop', { requires: ['Ext.dd.DragDropManager'], + + constructor: function(id, sGroup, config) { if(id) { this.init(id, sGroup, config); } }, - + @@ -35678,10 +36344,10 @@ Ext.define('Ext.dd.DragDrop', { var b = Ext.get(this.getEl()).getBox(), ce = Ext.get(constrainTo), s = ce.getScroll(), - c, + c, cd = ce.dom; if(cd == document.body){ - c = { x: s.left, y: s.top, width: Ext.core.Element.getViewWidth(), height: Ext.core.Element.getViewHeight()}; + c = { x: s.left, y: s.top, width: Ext.Element.getViewWidth(), height: Ext.Element.getViewHeight()}; }else{ var xy = ce.getXY(); c = {x : xy[0], y: xy[1], width: cd.clientWidth, height: cd.clientHeight}; @@ -35725,7 +36391,6 @@ Ext.define('Ext.dd.DragDrop', { initTarget: function(id, sGroup, config) { - this.config = config || {}; @@ -35782,7 +36447,7 @@ Ext.define('Ext.dd.DragDrop', { this.onAvailable(); }, - + setPadding: function(iTop, iRight, iBot, iLeft) { if (!iRight && 0 !== iRight) { @@ -35805,7 +36470,7 @@ Ext.define('Ext.dd.DragDrop', { var dx = diffX || 0; var dy = diffY || 0; - var p = Ext.core.Element.getXY( el ); + var p = Ext.Element.getXY( el ); this.initPageX = p[0] - dx; this.initPageY = p[1] - dy; @@ -35818,7 +36483,7 @@ Ext.define('Ext.dd.DragDrop', { setStartPosition: function(pos) { - var p = pos || Ext.core.Element.getXY( this.getEl() ); + var p = pos || Ext.Element.getXY( this.getEl() ); this.deltaSetXY = null; this.startPageX = p[0]; @@ -36141,6 +36806,8 @@ Ext.define('Ext.dd.DragDrop', { Ext.define('Ext.dd.DD', { extend: 'Ext.dd.DragDrop', requires: ['Ext.dd.DragDropManager'], + + constructor: function(id, sGroup, config) { if (id) { this.init(id, sGroup, config); @@ -36177,7 +36844,7 @@ Ext.define('Ext.dd.DD', { var oCoord = this.getTargetCoord(iPageX, iPageY), fly = el.dom ? el : Ext.fly(el, '_dd'), elSize = fly.getSize(), - EL = Ext.core.Element, + EL = Ext.Element, vpSize; if (!this.deltaSetXY) { @@ -36209,7 +36876,7 @@ Ext.define('Ext.dd.DD', { this.lastPageX = iPageX; this.lastPageY = iPageY; } else { - var aCoord = Ext.core.Element.getXY(this.getEl()); + var aCoord = Ext.Element.getXY(this.getEl()); this.lastPageX = aCoord[0]; this.lastPageY = aCoord[1]; } @@ -36220,10 +36887,10 @@ Ext.define('Ext.dd.DD', { if (this.scroll) { - var clientH = Ext.core.Element.getViewHeight(); + var clientH = Ext.Element.getViewHeight(); - var clientW = Ext.core.Element.getViewWidth(); + var clientW = Ext.Element.getViewWidth(); var st = this.DDMInstance.getScrollTop(); @@ -36350,6 +37017,7 @@ Ext.define('Ext.dd.DDProxy', { dragElId: "ygddfdiv" }, + constructor: function(id, sGroup, config) { if (id) { this.init(id, sGroup, config); @@ -36498,7 +37166,6 @@ Ext.define('Ext.dd.DragSource', { - dropAllowed : Ext.baseCSSPrefix + 'dd-drop-ok', dropNotAllowed : Ext.baseCSSPrefix + 'dd-drop-nodrop', @@ -36509,6 +37176,7 @@ Ext.define('Ext.dd.DragSource', { repairHighlightColor: 'c3daf9', + constructor: function(el, config) { this.el = Ext.get(el); if(!this.dragData){ @@ -36833,7 +37501,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', @@ -36865,9 +37534,9 @@ Ext.define('Ext.panel.Panel', { floatable: true, + - - + collapsible: false, @@ -36895,32 +37564,54 @@ Ext.define('Ext.panel.Panel', { + + + initComponent: function() { var me = this, cls; me.addEvents( - + + + 'beforeclose', + + + "beforeexpand", + + + "beforecollapse", + + + "expand", + + + "collapse", + + 'titlechange', - + + 'iconchange' ); + + this.addStateEvents('expand', 'collapse'); + if (me.unstyled) { me.setUI('plain'); } if (me.frame) { - me.setUI('default-framed'); + me.setUI(me.ui + '-framed'); } - me.callParent(); - - me.collapseDirection = me.collapseDirection || me.headerPosition || Ext.Component.DIRECTION_TOP; - me.bridgeToolbars(); + + me.callParent(); + me.collapseDirection = me.collapseDirection || me.headerPosition || Ext.Component.DIRECTION_TOP; }, setBorder: function(border) { @@ -36939,7 +37630,7 @@ Ext.define('Ext.panel.Panel', { - + this.callParent(arguments); }, @@ -37002,11 +37693,12 @@ Ext.define('Ext.panel.Panel', { bridgeToolbars: function() { var me = this, + docked = [], fbar, fbarDefaults, minButtonWidth = me.minButtonWidth; - function initToolbar (toolbar, pos) { + function initToolbar (toolbar, pos, useButtonAlign) { if (Ext.isArray(toolbar)) { toolbar = { xtype: 'toolbar', @@ -37020,20 +37712,30 @@ Ext.define('Ext.panel.Panel', { if (pos == 'left' || pos == 'right') { toolbar.vertical = true; } + + + if (useButtonAlign) { + toolbar.layout = Ext.applyIf(toolbar.layout || {}, { + + pack: { left:'start', center:'center' }[me.buttonAlign] || 'end' + }); + } return toolbar; } + + if (me.tbar) { - me.addDocked(initToolbar(me.tbar, 'top')); + docked.push(initToolbar(me.tbar, 'top')); me.tbar = null; } if (me.bbar) { - me.addDocked(initToolbar(me.bbar, 'bottom')); + docked.push(initToolbar(me.bbar, 'bottom')); me.bbar = null; } @@ -37045,7 +37747,7 @@ Ext.define('Ext.panel.Panel', { if (me.fbar) { - fbar = initToolbar(me.fbar, 'bottom'); + fbar = initToolbar(me.fbar, 'bottom', true); fbar.ui = 'footer'; @@ -37061,33 +37763,37 @@ Ext.define('Ext.panel.Panel', { }; } - fbar = me.addDocked(fbar)[0]; - fbar.insert(0, { - flex: 1, - xtype: 'component', - focusable: false - }); + docked.push(fbar); me.fbar = null; } if (me.lbar) { - me.addDocked(initToolbar(me.lbar, 'left')); + docked.push(initToolbar(me.lbar, 'left')); me.lbar = null; } if (me.rbar) { - me.addDocked(initToolbar(me.rbar, 'right')); + docked.push(initToolbar(me.rbar, 'right')); me.rbar = null; } + + if (me.dockedItems) { + if (!Ext.isArray(me.dockedItems)) { + me.dockedItems = [me.dockedItems]; + } + me.dockedItems = me.dockedItems.concat(docked); + } else { + me.dockedItems = docked; + } }, initTools: function() { var me = this; - me.tools = me.tools || []; + me.tools = me.tools ? Ext.Array.clone(me.tools) : []; @@ -37153,28 +37859,21 @@ Ext.define('Ext.panel.Panel', { me.updateHeader(); + 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); } - - - me.callParent(arguments); }, @@ -37238,13 +37937,52 @@ Ext.define('Ext.panel.Panel', { return this.body || this.frameBody || this.el; }, + + + + isVisible: function(deep){ + var me = this; + if (me.collapsed && me.placeholder) { + return me.placeholder.isVisible(deep); + } + return me.callParent(arguments); + }, + + + onHide: function(){ + var me = this; + if (me.collapsed && me.placeholder) { + me.placeholder.hide(); + } else { + me.callParent(arguments); + } + }, + + + onShow: function(){ + var me = this; + if (me.collapsed && me.placeholder) { + + me.hidden = true; + me.placeholder.show(); + } else { + me.callParent(arguments); + } + }, + addTool: function(tool) { - this.tools.push(tool); - var header = this.header; + var me = this, + header = me.header; + + if (Ext.isArray(tool)) { + Ext.each(tool, me.addTool, me); + return; + } + me.tools.push(tool); if (header) { header.addTool(tool); } - this.updateHeader(); + me.updateHeader(); }, getOppositeDirection: function(d) { @@ -37293,7 +38031,6 @@ Ext.define('Ext.panel.Panel', { reExpanderOrientation, reExpanderDock, getDimension, - setDimension, collapseDimension; if (!direction) { @@ -37316,23 +38053,22 @@ Ext.define('Ext.panel.Panel', { switch (direction) { case c.DIRECTION_TOP: case c.DIRECTION_BOTTOM: - me.expandedSize = me.getHeight(); reExpanderOrientation = 'horizontal'; collapseDimension = 'height'; getDimension = 'getHeight'; - setDimension = 'setHeight'; - for (; i < dockedItemCount; i++) { comp = dockedItems[i]; if (comp.isVisible()) { - if (comp.isHeader && (!comp.dock || comp.dock == 'top' || comp.dock == 'bottom')) { + if (comp.isXType('header', true) && (!comp.dock || comp.dock == 'top' || comp.dock == 'bottom')) { reExpander = comp; } else { me.hiddenDocked.push(comp); } + } else if (comp === me.reExpander) { + reExpander = comp; } } @@ -37344,15 +38080,12 @@ Ext.define('Ext.panel.Panel', { case c.DIRECTION_LEFT: case c.DIRECTION_RIGHT: - me.expandedSize = me.getWidth(); reExpanderOrientation = 'vertical'; collapseDimension = 'width'; getDimension = 'getWidth'; - setDimension = 'setWidth'; - for (; i < dockedItemCount; i++) { comp = dockedItems[i]; if (comp.isVisible()) { @@ -37361,6 +38094,8 @@ Ext.define('Ext.panel.Panel', { } else { me.hiddenDocked.push(comp); } + } else if (comp === me.reExpander) { + reExpander = comp; } } @@ -37375,12 +38110,6 @@ Ext.define('Ext.panel.Panel', { } - - me.setAutoScroll(false); - me.suspendLayout = true; - me.body.setVisibilityMode(Ext.core.Element.DISPLAY); - - if (animate && me.collapseTool) { me.collapseTool.disable(); } @@ -37392,7 +38121,8 @@ Ext.define('Ext.panel.Panel', { - if (reExpander) { + if (reExpander && reExpander.rendered) { + reExpander.addClsWithUI(me.collapsedCls); reExpander.addClsWithUI(me.collapsedCls + '-' + reExpander.dock); @@ -37401,13 +38131,13 @@ Ext.define('Ext.panel.Panel', { } frameInfo = reExpander.getFrameInfo(); - + newSize = reExpander[getDimension]() + (frameInfo ? frameInfo[direction] : 0); reExpander.removeClsWithUI(me.collapsedCls); - reExpander.removeClsWithUI(me.collapsedCls + '-' + reExpander.dock); + reExpander.removeClsWithUI(me.collapsedCls + '-' + reExpander.dock); if (me.border && (!me.frame || (me.frame && Ext.supports.CSS3BorderRadius))) { reExpander.removeClsWithUI(me.collapsedCls + '-border-' + reExpander.dock); } @@ -37467,20 +38197,25 @@ Ext.define('Ext.panel.Panel', { anim.to[collapseDimension] = newSize; + + + + + if (!me.collapseMemento) { + me.collapseMemento = new Ext.util.Memento(me); + } + me.collapseMemento.capture(['width', 'height', 'minWidth', 'minHeight', 'layoutManagedHeight', 'layoutManagedWidth']); + + me.savedFlex = me.flex; - me.savedMinWidth = me.minWidth; - me.savedMinHeight = me.minHeight; me.minWidth = 0; me.minHeight = 0; delete me.flex; + me.suspendLayout = true; if (animate) { me.animate(anim); } else { - - - me.uncollapsedSize = { width: me.width, height: me.height }; - me.setSize(anim.to.width, anim.to.height); if (Ext.isDefined(anim.to.left) || Ext.isDefined(anim.to.top)) { me.setPosition(anim.to.left, anim.to.top); @@ -37495,10 +38230,24 @@ Ext.define('Ext.panel.Panel', { i = 0, l = me.hiddenDocked.length; - me.minWidth = me.savedMinWidth; - me.minHeight = me.savedMinHeight; + me.collapseMemento.restore(['minWidth', 'minHeight']); + + + + + if (Ext.Component.VERTICAL_DIRECTION_Re.test(me.expandDirection)) { + me.layoutManagedHeight = 2; + me.collapseMemento.restore('width', false); + } else { + me.layoutManagedWidth = 2; + me.collapseMemento.restore('height', false); + } + + + + me.saveScrollTop = me.body.dom.scrollTop; + me.body.setStyle('display', 'none'); - me.body.hide(); for (; i < l; i++) { me.hiddenDocked[i].hide(); } @@ -37507,9 +38256,18 @@ Ext.define('Ext.panel.Panel', { me.reExpander.show(); } me.collapsed = true; + me.suspendLayout = false; if (!internal) { - me.doComponentLayout(); + if (me.ownerCt) { + + + if (animated) { + me.ownerCt.layout.layout(); + } + } else if (me.reExpander.temporary) { + me.doComponentLayout(); + } } if (me.resizer) { @@ -37532,29 +38290,17 @@ Ext.define('Ext.panel.Panel', { expand: function(animate) { - if (!this.collapsed || this.fireEvent('beforeexpand', this, animate) === false) { + var me = this; + if (!me.collapsed || me.fireEvent('beforeexpand', me, animate) === false) { return false; } - - if (this.uncollapsedSize) { - Ext.Object.each(this.uncollapsedSize, function (name, value) { - if (Ext.isDefined(value)) { - this[name] = value; - } else { - delete this[name]; - } - }, this); - delete this.uncollapsedSize; - } - - var me = this, - i = 0, + var i = 0, l = me.hiddenDocked.length, direction = me.expandDirection, height = me.getHeight(), width = me.getWidth(), - pos, anim, satisfyJSLint; + pos, anim; if (animate && me.collapseTool) { @@ -37586,10 +38332,11 @@ Ext.define('Ext.panel.Panel', { } - me.collapsed = false; + me.body.setStyle('display', ''); + me.body.dom.scrollTop = me.saveScrollTop; - me.body.show(); + me.collapsed = false; me.removeClsWithUI(me.collapsedCls); @@ -37613,7 +38360,11 @@ Ext.define('Ext.panel.Panel', { if ((direction == Ext.Component.DIRECTION_TOP) || (direction == Ext.Component.DIRECTION_BOTTOM)) { - if (me.autoHeight) { + + me.collapseMemento.restore('height', false); + + + if (me.height === undefined) { me.setCalculatedSize(me.width, null); anim.to.height = me.getHeight(); @@ -37629,7 +38380,7 @@ Ext.define('Ext.panel.Panel', { } else { - anim.to.height = me.expandedSize; + anim.to.height = me.height; } @@ -37641,7 +38392,11 @@ Ext.define('Ext.panel.Panel', { } else if ((direction == Ext.Component.DIRECTION_LEFT) || (direction == Ext.Component.DIRECTION_RIGHT)) { - if (me.autoWidth) { + + me.collapseMemento.restore('width', false); + + + if (me.width === undefined) { me.setCalculatedSize(null, me.height); anim.to.width = me.getWidth(); @@ -37657,7 +38412,7 @@ Ext.define('Ext.panel.Panel', { } else { - anim.to.width = me.expandedSize; + anim.to.width = me.width; } @@ -37671,7 +38426,7 @@ Ext.define('Ext.panel.Panel', { if (animate) { me.animate(anim); } else { - me.setSize(anim.to.width, anim.to.height); + me.setCalculatedSize(anim.to.width, anim.to.height); if (anim.to.x) { me.setLeft(anim.to.x); } @@ -37686,7 +38441,6 @@ Ext.define('Ext.panel.Panel', { afterExpand: function(animated) { var me = this; - me.setAutoScroll(me.initialConfig.autoScroll); if (me.savedFlex) { @@ -37697,9 +38451,14 @@ Ext.define('Ext.panel.Panel', { } - delete me.suspendLayout; + if (me.collapseMemento) { + me.collapseMemento.restoreAll(); + } + if (animated && me.ownerCt) { - me.ownerCt.doLayout(); + + + Ext.defer(me.ownerCt.doLayout, Ext.isIE6 ? 1 : 0, me); } if (me.resizer) { @@ -37741,10 +38500,10 @@ Ext.define('Ext.panel.Panel', { ghostTools : function() { var tools = [], - origTools = this.initialConfig.tools; + headerTools = this.header.query('tool[hidden=false]'); - if (origTools) { - Ext.each(origTools, function(tool) { + if (headerTools.length) { + Ext.each(headerTools, function(tool) { @@ -37753,8 +38512,7 @@ Ext.define('Ext.panel.Panel', { type: tool.type }); }); - } - else { + } else { tools = [{ type: 'placeholder' }]; @@ -37766,23 +38524,19 @@ Ext.define('Ext.panel.Panel', { ghost: function(cls) { var me = this, ghostPanel = me.ghostPanel, - box = me.getBox(); + box = me.getBox(), + header; if (!ghostPanel) { ghostPanel = Ext.create('Ext.panel.Panel', { - renderTo: document.body, + renderTo: me.floating ? me.el.dom.parentNode : document.body, floating: { shadow: false }, frame: Ext.supports.CSS3BorderRadius ? me.frame : false, - title: me.title, overlapHeader: me.overlapHeader, headerPosition: me.headerPosition, - width: me.getWidth(), - height: me.getHeight(), - iconCls: me.iconCls, baseCls: me.baseCls, - tools: me.ghostTools(), cls: me.baseCls + '-ghost ' + (cls ||'') }); me.ghostPanel = ghostPanel; @@ -37793,6 +38547,19 @@ Ext.define('Ext.panel.Panel', { } else { ghostPanel.toFront(); } + header = ghostPanel.header; + + if (header) { + header.suspendLayout = true; + Ext.Array.forEach(header.query('tool'), function(tool){ + header.remove(tool); + }); + header.suspendLayout = false; + } + ghostPanel.addTool(me.ghostTools()); + ghostPanel.setTitle(me.title); + ghostPanel.setIconCls(me.iconCls); + ghostPanel.el.show(); ghostPanel.setPosition(box.x, box.y); ghostPanel.setSize(box.width, box.height); @@ -37828,6 +38595,8 @@ Ext.define('Ext.panel.Panel', { } this.callParent([resizable]); } +}, function(){ + this.prototype.animCollapse = Ext.enableFx; }); @@ -37936,21 +38705,25 @@ Ext.define('Ext.tip.Tip', { focusOnToFront: false, componentLayout: 'tip', + closeAction: 'hide', ariaRole: 'tooltip', initComponent: function() { - this.callParent(arguments); + var me = this; + + me.floating = Ext.apply({}, {shadow: me.shadow}, me.self.prototype.floating); + me.callParent(arguments); - this.constrain = this.constrain || this.constrainPosition; + me.constrain = me.constrain || me.constrainPosition; }, showAt : function(xy){ var me = this; - this.callParent(); + this.callParent(arguments); if (me.isVisible()) { me.setPagePosition(xy[0], xy[1]); @@ -37973,7 +38746,7 @@ Ext.define('Ext.tip.Tip', { el: me.getDragEl(), delegate: me.header.el, constrain: me, - constrainTo: me.el.dom.parentNode + constrainTo: me.el.getScopeParent() }; Ext.Component.prototype.initDraggable.call(me); @@ -38038,7 +38811,7 @@ Ext.define('Ext.tip.ToolTip', { me.callParent(arguments); zIndex = parseInt(me.el.getZIndex(), 10) || 0; - me.anchorEl.setStyle('z-index', zIndex + 1).setVisibilityMode(Ext.core.Element.DISPLAY); + me.anchorEl.setStyle('z-index', zIndex + 1).setVisibilityMode(Ext.Element.DISPLAY); }, @@ -38053,10 +38826,10 @@ Ext.define('Ext.tip.ToolTip', { me.mun(tg, 'mouseout', me.onTargetOut, me); me.mun(tg, 'mousemove', me.onMouseMove, me); } - + me.target = t; if (t) { - + me.mon(t, { @@ -38084,7 +38857,7 @@ Ext.define('Ext.tip.ToolTip', { if (!me.hidden && me.trackMouse) { xy = me.getTargetXY(); if (me.constrainPosition) { - xy = me.el.adjustForConstraints(xy, me.el.dom.parentNode); + xy = me.el.adjustForConstraints(xy, me.el.getScopeParent()); } me.setPagePosition(xy); } @@ -38109,8 +38882,8 @@ Ext.define('Ext.tip.ToolTip', { me.targetCounter++; var offsets = me.getOffsets(), xy = (me.anchorToTarget && !me.trackMouse) ? me.el.getAlignToXY(me.anchorTarget, me.getAnchorAlign()) : me.targetXY, - dw = Ext.core.Element.getViewWidth() - 5, - dh = Ext.core.Element.getViewHeight() - 5, + dw = Ext.Element.getViewWidth() - 5, + dh = Ext.Element.getViewHeight() - 5, de = document.documentElement, bd = document.body, scrollX = (de.scrollLeft || bd.scrollLeft || 0) + 5, @@ -38192,9 +38965,6 @@ Ext.define('Ext.tip.ToolTip', { me.tipAnchor = me.anchor.charAt(0); } else { m = me.defaultAlign.match(/^([a-z]+)-([a-z]+)(\?)?$/); - if (!m) { - Ext.Error.raise('The AnchorTip.defaultAlign value "' + me.defaultAlign + '" is invalid.'); - } me.tipAnchor = m[1].charAt(0); } @@ -38525,7 +39295,7 @@ Ext.define('Ext.tip.QuickTip', { initComponent : function(){ var me = this; - + me.target = me.target || Ext.getDoc(); me.targets = me.targets || {}; me.callParent(); @@ -38537,7 +39307,7 @@ Ext.define('Ext.tip.QuickTip', { i = 0, len = configs.length, target, j, targetLen; - + for (; i < len; i++) { config = configs[i]; target = config.target; @@ -38557,12 +39327,12 @@ Ext.define('Ext.tip.QuickTip', { unregister : function(el){ delete this.targets[Ext.id(el)]; }, - + cancelShow: function(el){ var me = this, activeTarget = me.activeTarget; - + el = Ext.get(el).dom; if (me.isVisible()) { if (activeTarget && activeTarget.el == el) { @@ -38572,26 +39342,31 @@ Ext.define('Ext.tip.QuickTip', { me.clearTimer('show'); } }, + getTipCfg: function(e) { var t = e.getTarget(), - ttp, + titleText = t.title, cfg; - - if(this.interceptTitles && t.title && Ext.isString(t.title)){ - ttp = t.title; - t.qtip = ttp; + + if (this.interceptTitles && titleText && Ext.isString(titleText)) { + t.qtip = titleText; t.removeAttribute("title"); e.preventDefault(); - } - else { + return { + text: titleText + }; + } + else { cfg = this.tagConfig; t = e.getTarget('[' + cfg.namespace + cfg.attribute + ']'); if (t) { - ttp = t.getAttribute(cfg.namespace + cfg.attribute); + return { + target: t, + text: t.getAttribute(cfg.namespace + cfg.attribute) + }; } } - return ttp; }, @@ -38601,9 +39376,9 @@ Ext.define('Ext.tip.QuickTip', { elTarget, cfg, ns, - ttp, + tipConfig, autoHide; - + if (me.disabled) { return; } @@ -38616,13 +39391,13 @@ Ext.define('Ext.tip.QuickTip', { if(!target || target.nodeType !== 1 || target == document || target == document.body){ return; } - + if (me.activeTarget && ((target == me.activeTarget.el) || Ext.fly(me.activeTarget.el).contains(target))) { me.clearTimer('hide'); me.show(); return; } - + if (target) { Ext.Object.each(me.targets, function(key, value) { var targetEl = Ext.fly(value.target); @@ -38645,21 +39420,28 @@ Ext.define('Ext.tip.QuickTip', { elTarget = Ext.get(target); cfg = me.tagConfig; - ns = cfg.namespace; - ttp = me.getTipCfg(e); - - if (ttp) { + ns = cfg.namespace; + tipConfig = me.getTipCfg(e); + + if (tipConfig) { + + + + if (tipConfig.target) { + target = tipConfig.target; + elTarget = Ext.get(target); + } autoHide = elTarget.getAttribute(ns + cfg.hide); - + me.activeTarget = { el: target, - text: ttp, + text: tipConfig.text, width: +elTarget.getAttribute(ns + cfg.width) || null, autoHide: autoHide != "user" && autoHide !== 'false', title: elTarget.getAttribute(ns + cfg.title), cls: elTarget.getAttribute(ns + cfg.cls), align: elTarget.getAttribute(ns + cfg.align) - + }; me.anchor = elTarget.getAttribute(ns + cfg.anchor); if (me.anchor) { @@ -38672,7 +39454,7 @@ Ext.define('Ext.tip.QuickTip', { onTargetOut : function(e){ var me = this; - + if (me.activeTarget && e.within(me.activeTarget.el) && !me.getTipCfg(e)) { return; @@ -38688,7 +39470,7 @@ Ext.define('Ext.tip.QuickTip', { showAt : function(xy){ var me = this, target = me.activeTarget; - + if (target) { if (!me.rendered) { me.render(Ext.getBody()); @@ -38713,7 +39495,7 @@ Ext.define('Ext.tip.QuickTip', { } me.setWidth(target.width); - + if (me.anchor) { me.constrainPosition = false; } else if (target.align) { @@ -38767,13 +39549,6 @@ Ext.define('Ext.tip.QuickTipManager', function() { if (autoRender !== false) { tipConfig.renderTo = document.body; - if (tipConfig.renderTo.tagName != 'BODY') { - Ext.Error.raise({ - sourceClass: 'Ext.tip.QuickTipManager', - sourceMethod: 'init', - msg: 'Cannot init QuickTipManager: no document body' - }); - } } tip = Ext.create(className || 'Ext.tip.QuickTip', tipConfig); @@ -38876,6 +39651,7 @@ Ext.define('Ext.app.Application', { autoCreateViewport: false, + constructor: function(config) { config = config || {}; Ext.apply(this, config); @@ -39221,7 +39997,7 @@ Ext.define('Ext.draw.CompositeSprite', { mouseout: me.onMouseOut, click: me.onClick }); - me.callParent(arguments); + return me.callParent(arguments); }, @@ -39377,21 +40153,20 @@ Ext.define('Ext.draw.CompositeSprite', { -Ext.define('Ext.layout.component.Draw', { +Ext.define('Ext.layout.component.Auto', { - alias: 'layout.draw', + alias: 'layout.autocomponent', - extend: 'Ext.layout.component.Auto', + extend: 'Ext.layout.component.Component', - type: 'draw', + type: 'autocomponent', onLayout : function(width, height) { - this.owner.surface.setSize(width, height); - this.callParent(arguments); + this.setTargetSize(width, height); } }); @@ -39427,7 +40202,6 @@ Ext.define('Ext.chart.theme.Theme', { return; } } - Ext.Error.raise('No theme found named "' + theme + '"'); } } }, @@ -39531,6 +40305,8 @@ function() { Ext.define('Ext.chart.Mask', { + require: ['Ext.chart.MaskLayer'], + constructor: function(config) { var me = this; @@ -39673,12 +40449,7 @@ Ext.define('Ext.chart.Mask', { width: abs(width), height: abs(height) }; - me.mask.updateBox({ - x: posX - abs(width), - y: posY - abs(height), - width: abs(width), - height: abs(height) - }); + me.mask.updateBox(me.maskSelection); me.mask.show(); me.maskSprite.setAttributes({ hidden: true @@ -39719,50 +40490,46 @@ Ext.define('Ext.chart.Navigation', { constructor: function() { this.originalStore = this.store; }, - + setZoom: function(zoomConfig) { var me = this, - store = me.substore || me.store, + axes = me.axes, bbox = me.chartBBox, - len = store.getCount(), - from = (zoomConfig.x / bbox.width * len) >> 0, - to = Math.ceil(((zoomConfig.x + zoomConfig.width) / bbox.width * len)), - recFieldsLen, recFields = [], curField, json = [], obj; - - store.each(function(rec, i) { - if (i < from || i > to) { - return; - } - obj = {}; - - if (!recFields.length) { - rec.fields.each(function(f) { - recFields.push(f.name); - }); - recFieldsLen = recFields.length; - } - - for (i = 0; i < recFieldsLen; i++) { - curField = recFields[i]; - obj[curField] = rec.get(curField); + xScale = 1 / bbox.width, + yScale = 1 / bbox.height, + zoomer = { + x : zoomConfig.x * xScale, + y : zoomConfig.y * yScale, + width : zoomConfig.width * xScale, + height : zoomConfig.height * yScale + }; + axes.each(function(axis) { + var ends = axis.calcEnds(); + if (axis.position == 'bottom' || axis.position == 'top') { + var from = (ends.to - ends.from) * zoomer.x + ends.from, + to = (ends.to - ends.from) * zoomer.width + from; + axis.minimum = from; + axis.maximum = to; + } else { + var to = (ends.to - ends.from) * (1 - zoomer.y) + ends.from, + from = to - (ends.to - ends.from) * zoomer.height; + axis.minimum = from; + axis.maximum = to; } - json.push(obj); }); - me.store = me.substore = Ext.create('Ext.data.JsonStore', { - fields: recFields, - data: json - }); - me.redraw(true); + me.redraw(false); }, + restoreZoom: function() { this.store = this.substore = this.originalStore; this.redraw(true); } - + }); + Ext.define('Ext.chart.Shape', { @@ -39943,21 +40710,27 @@ Ext.define('Ext.draw.Surface', { zIndex: 0 }, - - + + + container: undefined, height: 352, width: 512, x: 0, y: 0, + + orderSpritesByZIndex: true, + + + constructor: function(config) { var me = this; config = config || {}; Ext.apply(me, config); me.domRef = Ext.getDoc().dom; - + me.customAttributes = {}; me.addEvents( @@ -39995,7 +40768,12 @@ Ext.define('Ext.draw.Surface', { renderItems: Ext.emptyFn, - setViewBox: Ext.emptyFn, + setViewBox: function (x, y, width, height) { + if (isFinite(x) && isFinite(y) && isFinite(width) && isFinite(height)) { + this.viewBox = {x: x, y: y, width: width, height: height}; + this.applyViewBox(); + } + }, addCls: Ext.emptyFn, @@ -40023,7 +40801,7 @@ Ext.define('Ext.draw.Surface', { this.add(items); } }, - + initBackground: function(config) { var me = this, @@ -40064,7 +40842,7 @@ Ext.define('Ext.draw.Surface', { } } }, - + setSize: function(w, h) { if (this.background) { @@ -40074,6 +40852,7 @@ Ext.define('Ext.draw.Surface', { hidden: false }, true); } + this.applyViewBox(); }, @@ -40082,7 +40861,7 @@ Ext.define('Ext.draw.Surface', { attrs = {}, exclude = {}, sattr = sprite.attr; - for (i in sattr) { + for (i in sattr) { if (this.translateAttrs.hasOwnProperty(i)) { @@ -40157,28 +40936,45 @@ Ext.define('Ext.draw.Surface', { return results; } sprite = this.prepareItems(args[0], true)[0]; - this.normalizeSpriteCollection(sprite); + this.insertByZIndex(sprite); this.onAdd(sprite); return sprite; }, - normalizeSpriteCollection: function(sprite) { - var items = this.items, + insertByZIndex: function(sprite) { + var me = this, + sprites = me.items.items, + len = sprites.length, + ceil = Math.ceil, zIndex = sprite.attr.zIndex, - idx = items.indexOf(sprite); + idx = len, + high = idx - 1, + low = 0, + otherZIndex; - if (idx < 0 || (idx > 0 && items.getAt(idx - 1).attr.zIndex > zIndex) || - (idx < items.length - 1 && items.getAt(idx + 1).attr.zIndex < zIndex)) { - items.removeAt(idx); - idx = items.findIndexBy(function(otherSprite) { - return otherSprite.attr.zIndex > zIndex; - }); - if (idx < 0) { - idx = items.length; + if (me.orderSpritesByZIndex && len && zIndex < sprites[high].attr.zIndex) { + + while (low <= high) { + idx = ceil((low + high) / 2); + otherZIndex = sprites[idx].attr.zIndex; + if (otherZIndex > zIndex) { + high = idx - 1; + } + else if (otherZIndex < zIndex) { + low = idx + 1; + } + else { + break; + } + } + + while (idx < len && sprites[idx].attr.zIndex <= zIndex) { + idx++; } - items.insert(idx, sprite); } + + me.items.insert(idx, sprite); return idx; }, @@ -40229,6 +41025,49 @@ Ext.define('Ext.draw.Surface', { onDestroy: Ext.emptyFn, + applyViewBox: function() { + var me = this, + viewBox = me.viewBox, + width = me.width, + height = me.height, + viewBoxX, viewBoxY, viewBoxWidth, viewBoxHeight, + relativeHeight, relativeWidth, size; + + if (viewBox && (width || height)) { + 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.min(viewBoxWidth, relativeHeight); + + me.viewBoxShift = { + dx: -viewBoxX, + dy: -viewBoxY, + scale: size + }; + } + }, + + transformToViewBox: function (x, y) { + if (this.viewBoxShift) { + var me = this, shift = me.viewBoxShift; + return [x * shift.scale - shift.dx, y * shift.scale - shift.dy]; + } else { + return [x, y]; + } + }, + + applyTransformations: function(sprite) { sprite.bbox.transform = 0; this.transform(sprite); @@ -40403,10 +41242,10 @@ Ext.define('Ext.draw.Surface', { } return items; }, - + setText: Ext.emptyFn, - + //@private Creates an item and appends it to the surface. Called @@ -40424,6 +41263,25 @@ Ext.define('Ext.draw.Surface', { } }); + +Ext.define('Ext.layout.component.Draw', { + + + + alias: 'layout.draw', + + extend: 'Ext.layout.component.Auto', + + + + type: 'draw', + + onLayout : function(width, height) { + this.owner.surface.setSize(width, height); + this.callParent(arguments); + } +}); + Ext.define('Ext.draw.Component', { @@ -40451,9 +41309,8 @@ Ext.define('Ext.draw.Component', { autoSize: false, - - + initComponent: function() { this.callParent(arguments); @@ -40475,22 +41332,22 @@ Ext.define('Ext.draw.Component', { bbox, items, width, height, x, y; me.callParent(arguments); - me.createSurface(); - - items = me.surface.items; + if (me.createSurface() !== false) { + items = me.surface.items; - if (viewBox || autoSize) { - bbox = items.getBBox(); - width = bbox.width; - height = bbox.height; - x = bbox.x; - y = bbox.y; - if (me.viewBox) { - me.surface.setViewBox(x, y, width, height); - } - else { - - me.autoSizeSurface(); + if (viewBox || autoSize) { + bbox = items.getBBox(); + width = bbox.width; + height = bbox.height; + x = bbox.x; + y = bbox.y; + if (me.viewBox) { + me.surface.setViewBox(x, y, width, height); + } + else { + + me.autoSizeSurface(); + } } } }, @@ -40527,8 +41384,13 @@ Ext.define('Ext.draw.Component', { height: this.height, renderTo: this.el }, this.initialConfig)); + if (!surface) { + + return false; + } this.surface = surface; + function refire(eventName) { return function(e) { this.fireEvent(eventName, e); @@ -40758,6 +41620,7 @@ Ext.define('Ext.chart.LegendItem', { } }); + Ext.define('Ext.chart.Legend', { @@ -40804,6 +41667,7 @@ Ext.define('Ext.chart.Legend', { boxZIndex: 100, + constructor: function(config) { var me = this; if (config) { @@ -40812,7 +41676,7 @@ Ext.define('Ext.chart.Legend', { me.items = []; me.isVertical = ("left|right|float".indexOf(me.position) !== -1); - + me.origX = me.x; me.origY = me.y; @@ -40821,9 +41685,9 @@ Ext.define('Ext.chart.Legend', { create: function() { var me = this; + me.createBox(); me.createItems(); if (!me.created && me.isDisplayed()) { - me.createBox(); me.created = true; @@ -40858,8 +41722,8 @@ Ext.define('Ext.chart.Legend', { math = Math, mfloor = math.floor, mmax = math.max, - index = 0, - i = 0, + index = 0, + i = 0, len = items ? items.length : 0, x, y, spacing, item, bbox, height, width; @@ -40885,7 +41749,7 @@ Ext.define('Ext.chart.Legend', { bbox = item.getBBox(); - width = bbox.width; + width = bbox.width; height = bbox.height; if (i + j === 0) { @@ -40932,13 +41796,20 @@ Ext.define('Ext.chart.Legend', { createBox: function() { var me = this, - box = me.boxSprite = me.chart.surface.add(Ext.apply({ - type: 'rect', - stroke: me.boxStroke, - "stroke-width": me.boxStrokeWidth, - fill: me.boxFill, - zIndex: me.boxZIndex - }, me.getBBox())); + box; + + if (me.boxSprite) { + me.boxSprite.destroy(); + } + + box = me.boxSprite = me.chart.surface.add(Ext.apply({ + type: 'rect', + stroke: me.boxStroke, + "stroke-width": me.boxStrokeWidth, + fill: me.boxFill, + zIndex: me.boxZIndex + }, me.getBBox())); + box.redraw(); }, @@ -40958,7 +41829,7 @@ Ext.define('Ext.chart.Legend', { chartY = chartBBox.y + insets, surface = chart.surface, mfloor = Math.floor; - + if (me.isDisplayed()) { switch(me.position) { @@ -41041,10 +41912,17 @@ Ext.define('Ext.chart.Chart', { + + + + + constructor: function(config) { var me = this, defaultAnim; + + config = Ext.apply({}, config); me.initTheme(config.theme || me.theme); if (me.gradients) { Ext.apply(config, { gradients: me.gradients }); @@ -41068,6 +41946,10 @@ Ext.define('Ext.chart.Chart', { me.mixins.navigation.constructor.call(me, config); me.callParent([config]); }, + + getChartStore: function(){ + return this.substore || this.store; + }, initComponent: function() { var me = this, @@ -41344,7 +42226,7 @@ Ext.define('Ext.chart.Chart', { refresh: function() { var me = this; - if (me.rendered && me.curWidth != undefined && me.curHeight != undefined) { + if (me.rendered && me.curWidth !== undefined && me.curHeight !== undefined) { if (me.fireEvent('beforerefresh', me) !== false) { me.redraw(); me.fireEvent('refresh', me); @@ -41357,7 +42239,7 @@ Ext.define('Ext.chart.Chart', { var me = this; if (!initial && me.store) { if (store !== me.store && me.store.autoDestroy) { - me.store.destroy(); + me.store.destroyStore(); } else { me.store.un('datachanged', me.refresh, me); @@ -41588,7 +42470,7 @@ Ext.define('Ext.chart.Chart', { destroy: function() { - this.surface.destroy(); + Ext.destroy(this.surface); this.bindStore(null); this.callParent(arguments); } @@ -41635,10 +42517,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; @@ -41648,8 +42527,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) { @@ -41679,6 +42557,7 @@ Ext.define('Ext.chart.Highlight', { } sprite._from = from; sprite._to = to; + sprite._endStyle = to; } if (animate) { sprite._anim = Ext.create('Ext.fx.Anim', { @@ -41704,9 +42583,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]) { @@ -41728,6 +42605,8 @@ Ext.define('Ext.chart.Highlight', { } } if (animate) { + + sprite._endStyle = obj; sprite._anim = Ext.create('Ext.fx.Anim', { target: sprite, to: obj, @@ -41768,18 +42647,6 @@ Ext.define('Ext.chart.Label', { requires: ['Ext.draw.Color'], - - - - - - - - - - - - @@ -41788,7 +42655,7 @@ Ext.define('Ext.chart.Label', { //@private a regex to parse url type colors. colorStringRe: /url\s*\(\s*#([^\/)]+)\s*\)/, - + //@private the mixin constructor. Used internally by Series. constructor: function(config) { @@ -41817,7 +42684,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, @@ -41825,93 +42691,111 @@ Ext.define('Ext.chart.Label', { color = config.color, field = [].concat(config.field), group = me.labelsGroup, + groupLength = (group || 0) && group.length, 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; + hides = [], + gradient, i, count, groupIndex, index, j, k, colorStopTotal, colorStopIndex, colorStop, item, label, + storeItem, sprite, spriteColor, spriteBrightness, labelColor, colorString; if (display == 'none') { return; } + + if(itemLength == 0){ + while(groupLength--) + hides.push(groupLength); + }else{ + for (i = 0, count = 0, groupIndex = 0; i < len; i++) { + index = 0; + for (j = 0; j < ratio; j++) { + item = items[count]; + label = group.getAt(groupIndex); + storeItem = store.getAt(i); + + while(this.__excludes && this.__excludes[index] && ratio > 1) { + if(field[j]){ + hides.push(groupIndex); + } + index++; - for (i = 0, count = 0; i < len; i++) { - index = 0; - for (j = 0; j < ratio; j++) { - item = items[count]; - label = group.getAt(count); - storeItem = store.getAt(i); - - - while(this.__excludes && this.__excludes[index]) { - index++; - } - - if (!item && label) { - label.hide(true); - } + } - if (item && field[j]) { - if (!label) { - label = me.onCreateLabel(storeItem, item, i, display, j, index); + if (!item && label) { + label.hide(true); + groupIndex++; } - me.onPlaceLabel(label, storeItem, item, i, display, animate, j, index); - - if (config.contrast && item.sprite) { - sprite = item.sprite; - colorString = sprite._to && sprite._to.fill || sprite.attr.fill; - spriteColor = Color.fromString(colorString); + if (item && field[j]) { + if (!label) { + label = me.onCreateLabel(storeItem, item, i, display, j, index); + } + me.onPlaceLabel(label, storeItem, item, i, display, animate, j, index); + groupIndex++; + - if (colorString && !spriteColor) { - colorString = colorString.match(me.colorStringRe)[1]; - for (k = 0; k < gradientsCount; k++) { - gradient = gradients[k]; - if (gradient.id == colorString) { - - colorStop = 0; colorStopTotal = 0; - for (colorStopIndex in gradient.stops) { - colorStop++; - colorStopTotal += Color.fromString(gradient.stops[colorStopIndex].color).getGrayscale(); + if (config.contrast && item.sprite) { + sprite = item.sprite; + + 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); + + if (colorString && !spriteColor) { + colorString = colorString.match(me.colorStringRe)[1]; + for (k = 0; k < gradientsCount; k++) { + gradient = gradients[k]; + if (gradient.id == colorString) { + + colorStop = 0; colorStopTotal = 0; + for (colorStopIndex in gradient.stops) { + colorStop++; + colorStopTotal += Color.fromString(gradient.stops[colorStopIndex].color).getGrayscale(); + } + spriteBrightness = (colorStopTotal / colorStop) / 255; + break; } - spriteBrightness = (colorStopTotal / colorStop) / 255; - break; } } + 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; + label.setAttributes({ + fill: String(Color.fromHSL.apply({}, labelColor)) + }, true); } - else { - spriteBrightness = spriteColor.getGrayscale() / 255; - } - labelColor = Color.fromString(label.attr.color || label.attr.fill).getHSL(); - - labelColor[2] = spriteBrightness > 0.5? 0.2 : 0.8; - label.setAttributes({ - fill: String(Color.fromHSL.apply({}, labelColor)) - }, true); + } + count++; + index++; } - count++; - index++; } } - me.hideLabels(count); + me.hideLabels(hides); }, - - //@private a method to hide labels. - - hideLabels: function(index) { - var labelsGroup = this.labelsGroup, len; - if (labelsGroup) { - len = labelsGroup.getCount(); - while (len-->index) { - labelsGroup.getAt(len).hide(true); - } - } + hideLabels: function(hides){ + var labelsGroup = this.labelsGroup, + hlen = hides.length; + while(hlen--) + labelsGroup.getAt(hides[hlen]).hide(true); } }); Ext.define('Ext.chart.MaskLayer', { @@ -42021,7 +42905,10 @@ Ext.define('Ext.chart.Tip', { constrainPosition: false }); me.tooltip = Ext.create('Ext.tip.ToolTip', me.tipConfig); - Ext.getBody().on('mousemove', me.tooltip.onMouseMove, me.tooltip); + me.chart.surface.on('mousemove', me.tooltip.onMouseMove, me.tooltip); + me.chart.surface.on('mouseleave', function() { + me.hideTip(); + }); if (me.tipConfig.surface) { surface = me.tipConfig.surface; @@ -42091,6 +42978,7 @@ Ext.define('Ext.chart.axis.Abstract', { + constructor: function(config) { config = config || {}; @@ -42144,53 +43032,58 @@ Ext.define('Ext.chart.axis.Axis', { + + + + //@private force min/max values from store forceMinMax: false, - + dashSize: 3, - + position: 'bottom', - + skipFirst: false, - + length: 0, - + width: 0, - + majorTickSteps: false, applyData: Ext.emptyFn, - - calcEnds: function() { + getRange: function () { var me = this, + store = me.chart.getChartStore(), + fields = me.fields, + ln = fields.length, math = Math, mmax = math.max, mmin = math.min, - store = me.chart.substore || me.chart.store, - series = me.chart.series.items, - fields = me.fields, - ln = fields.length, + aggregate = false, min = isNaN(me.minimum) ? Infinity : me.minimum, max = isNaN(me.maximum) ? -Infinity : me.maximum, - prevMin = me.prevMin, - prevMax = me.prevMax, - aggregate = false, - total = 0, + total = 0, i, l, value, values, rec, excludes = [], - outfrom, outto, - i, l, values, rec, out; + series = me.chart.series.items; + + + + + + for (i = 0, l = series.length; !aggregate && i < l; i++) { aggregate = aggregate || series[i].stacked; excludes = series[i].__excludes || excludes; @@ -42207,8 +43100,8 @@ Ext.define('Ext.chart.axis.Axis', { rec = record.get(fields[i]); values[+(rec > 0)] += math.abs(rec); } - max = mmax(max, -values[0], values[1]); - min = mmin(min, -values[0], values[1]); + max = mmax(max, -values[0], +values[1]); + min = mmin(min, -values[0], +values[1]); } else { for (i = 0; i < ln; i++) { @@ -42216,8 +43109,8 @@ Ext.define('Ext.chart.axis.Axis', { continue; } value = record.get(fields[i]); - max = mmax(max, value); - min = mmin(min, value); + max = mmax(max, +value); + min = mmin(min, +value); } } }); @@ -42228,9 +43121,30 @@ Ext.define('Ext.chart.axis.Axis', { min = me.prevMin || 0; } - if (min != max && (max != (max >> 0))) { - max = (max >> 0) + 1; + if (min != max && (max != Math.floor(max))) { + max = Math.floor(max) + 1; + } + + if (!isNaN(me.minimum)) { + min = me.minimum; + } + + if (!isNaN(me.maximum)) { + max = me.maximum; } + + return {min: min, max: max}; + }, + + + calcEnds: function() { + var me = this, + fields = me.fields, + range = me.getRange(), + min = range.min, + max = range.max, + outfrom, outto, out; + out = Ext.draw.Draw.snapEnds(min, max, me.majorTickSteps !== false ? (me.majorTickSteps +1) : me.steps); outfrom = out.from; outto = out.to; @@ -42252,10 +43166,10 @@ Ext.define('Ext.chart.axis.Axis', { out.from = me.minimum; } - + out.step = (out.to - out.from) / (outto - outfrom) * out.step; - + if (me.adjustMaximumByMajorUnit) { out.to += out.step; } @@ -42295,7 +43209,7 @@ Ext.define('Ext.chart.axis.Axis', { dashesX, dashesY, delta; - + @@ -42315,11 +43229,11 @@ Ext.define('Ext.chart.axis.Axis', { path = ["M", x, currentY, "l", length, 0]; trueLength = length - (gutterX * 2); } - + delta = trueLength / (steps || 1); dashesX = Math.max(subDashesX +1, 0); dashesY = Math.max(subDashesY +1, 0); - if (me.type == 'Numeric') { + if (me.type == 'Numeric' || me.type == 'Time') { calcLabels = true; me.labels = [stepCalcs.from]; } @@ -42402,7 +43316,7 @@ Ext.define('Ext.chart.axis.Axis', { drawGrid: function() { var me = this, - surface = me.chart.surface, + surface = me.chart.surface, grid = me.grid, odd = grid.odd, even = grid.even, @@ -42416,7 +43330,7 @@ Ext.define('Ext.chart.axis.Axis', { i = 1, path = [], styles, lineWidth, dlineWidth, oddPath = [], evenPath = []; - + if ((gutter[1] !== 0 && (position == 'left' || position == 'right')) || (gutter[0] !== 0 && (position == 'top' || position == 'bottom'))) { i = 0; @@ -42431,25 +43345,25 @@ Ext.define('Ext.chart.axis.Axis', { lineWidth = (styles.lineWidth || styles['stroke-width'] || 0) / 2; dlineWidth = 2 * lineWidth; if (position == 'left') { - path.push("M", prevPoint[0] + 1 + lineWidth, prevPoint[1] + 0.5 - lineWidth, + path.push("M", prevPoint[0] + 1 + lineWidth, prevPoint[1] + 0.5 - lineWidth, "L", prevPoint[0] + 1 + width - lineWidth, prevPoint[1] + 0.5 - lineWidth, "L", point[0] + 1 + width - lineWidth, point[1] + 0.5 + lineWidth, "L", point[0] + 1 + lineWidth, point[1] + 0.5 + lineWidth, "Z"); } else if (position == 'right') { - path.push("M", prevPoint[0] - lineWidth, prevPoint[1] + 0.5 - lineWidth, + path.push("M", prevPoint[0] - lineWidth, prevPoint[1] + 0.5 - lineWidth, "L", prevPoint[0] - width + lineWidth, prevPoint[1] + 0.5 - lineWidth, "L", point[0] - width + lineWidth, point[1] + 0.5 + lineWidth, "L", point[0] - lineWidth, point[1] + 0.5 + lineWidth, "Z"); } else if (position == 'top') { - path.push("M", prevPoint[0] + 0.5 + lineWidth, prevPoint[1] + 1 + lineWidth, + path.push("M", prevPoint[0] + 0.5 + lineWidth, prevPoint[1] + 1 + lineWidth, "L", prevPoint[0] + 0.5 + lineWidth, prevPoint[1] + 1 + width - lineWidth, "L", point[0] + 0.5 - lineWidth, point[1] + 1 + width - lineWidth, "L", point[0] + 0.5 - lineWidth, point[1] + 1 + lineWidth, "Z"); } else { - path.push("M", prevPoint[0] + 0.5 + lineWidth, prevPoint[1] - lineWidth, + path.push("M", prevPoint[0] + 0.5 + lineWidth, prevPoint[1] - lineWidth, "L", prevPoint[0] + 0.5 + lineWidth, prevPoint[1] - width + lineWidth, "L", point[0] + 0.5 - lineWidth, point[1] - width + lineWidth, "L", point[0] + 0.5 - lineWidth, point[1] - lineWidth, "Z"); @@ -42488,7 +43402,7 @@ Ext.define('Ext.chart.axis.Axis', { type: 'path', path: evenPath }); - } + } me.gridEven.setAttributes(Ext.apply({ path: evenPath, hidden: false @@ -42546,8 +43460,8 @@ Ext.define('Ext.chart.axis.Axis', { if (me.label.rotation) { textLabel.setAttributes({ rotation: { - degrees: 0 - } + degrees: 0 + } }, true); textLabel._ubbox = textLabel.getBBox(); textLabel.setAttributes(me.label, true); @@ -42556,7 +43470,7 @@ Ext.define('Ext.chart.axis.Axis', { } return textLabel; }, - + rect2pointArray: function(sprite) { var surface = this.chart.surface, rect = surface.getBBox(sprite, true), @@ -42572,24 +43486,24 @@ Ext.define('Ext.chart.axis.Axis', { p1[0] = matrix.x.apply(matrix, p1p); p1[1] = matrix.y.apply(matrix, p1p); - + p2[0] = matrix.x.apply(matrix, p2p); p2[1] = matrix.y.apply(matrix, p2p); - + p3[0] = matrix.x.apply(matrix, p3p); p3[1] = matrix.y.apply(matrix, p3p); - + p4[0] = matrix.x.apply(matrix, p4p); p4[1] = matrix.y.apply(matrix, p4p); return [p1, p2, p3, p4]; }, - + intersect: function(l1, l2) { var r1 = this.rect2pointArray(l1), r2 = this.rect2pointArray(l2); return !!Ext.draw.Draw.intersect(r1, r2).length; }, - + drawHorizontalLabels: function() { var me = this, labelConf = me.label, @@ -42613,8 +43527,8 @@ Ext.define('Ext.chart.axis.Axis', { point = inflections[0]; firstLabel = me.getOrCreateLabel(0, me.label.renderer(labels[0])); - ratio = Math.abs(Math.sin(labelConf.rotate && (labelConf.rotate.degrees * Math.PI / 180) || 0)) >> 0; - + ratio = Math.floor(Math.abs(Math.sin(labelConf.rotate && (labelConf.rotate.degrees * Math.PI / 180) || 0))); + for (i = 0; i < ln; i++) { point = inflections[i]; text = me.label.renderer(labels[i]); @@ -42636,7 +43550,7 @@ Ext.define('Ext.chart.axis.Axis', { else { y = point[1] + (me.dashSize * 2) + me.label.padding + (bbox.height / 2); } - + textLabel.setAttributes({ hidden: false, x: x, @@ -42649,13 +43563,13 @@ Ext.define('Ext.chart.axis.Axis', { textLabel.hide(true); continue; } - + prevLabel = textLabel; } return maxHeight; }, - + drawVerticalLabels: function() { var me = this, inflections = me.inflections, @@ -42679,7 +43593,7 @@ Ext.define('Ext.chart.axis.Axis', { text = me.label.renderer(labels[i]); textLabel = me.getOrCreateLabel(i, text); bbox = textLabel._bbox; - + maxWidth = max(maxWidth, bbox.width + me.dashSize + me.label.padding); y = point[1]; if (gutterY < bbox.height / 2) { @@ -42695,7 +43609,7 @@ Ext.define('Ext.chart.axis.Axis', { } else { x = point[0] + me.dashSize + me.label.padding + 2; - } + } textLabel.setAttributes(Ext.apply({ hidden: false, x: x, @@ -42708,7 +43622,7 @@ Ext.define('Ext.chart.axis.Axis', { } prevLabel = textLabel; } - + return maxWidth; }, @@ -42723,7 +43637,7 @@ Ext.define('Ext.chart.axis.Axis', { ln, i; if (position == 'left' || position == 'right') { - maxWidth = me.drawVerticalLabels(); + maxWidth = me.drawVerticalLabels(); } else { maxHeight = me.drawHorizontalLabels(); } @@ -42890,7 +43804,9 @@ Ext.define('Ext.chart.axis.Gauge', { extend: 'Ext.chart.axis.Abstract', + + @@ -42959,7 +43875,7 @@ Ext.define('Ext.chart.axis.Gauge', { this.drawTitle(); } }, - + drawTitle: function() { var me = this, chart = me.chart, @@ -42967,12 +43883,12 @@ Ext.define('Ext.chart.axis.Gauge', { bbox = chart.chartBBox, labelSprite = me.titleSprite, labelBBox; - + if (!labelSprite) { me.titleSprite = labelSprite = surface.add({ type: 'text', zIndex: 2 - }); + }); } labelSprite.setAttributes(Ext.apply({ text: me.title @@ -43062,29 +43978,27 @@ 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) { var val = Math.pow(10, dec || 0); - return ((v * val) >> 0) / val; + return Math.floor(v * val) / val; }, - + minimum: NaN, @@ -43365,6 +44279,8 @@ Ext.define('Ext.data.AbstractStore', { + + sortRoot: 'data', @@ -43390,6 +44306,9 @@ Ext.define('Ext.data.AbstractStore', { 'load', + + + 'write', 'beforesync', @@ -43423,6 +44342,7 @@ Ext.define('Ext.data.AbstractStore', { me.implicitModel = true; } + me.setProxy(me.proxy || me.model.getProxy()); @@ -43814,7 +44734,7 @@ Ext.define('Ext.data.AbstractStore', { isLoading: function() { - return this.loading; + return !!this.loading; } }); @@ -43839,7 +44759,7 @@ Ext.define('Ext.data.Store', { alias: 'store.store', - requires: ['Ext.ModelManager', 'Ext.data.Model', 'Ext.util.Grouper'], + requires: ['Ext.data.StoreManager', 'Ext.ModelManager', 'Ext.data.Model', 'Ext.util.Grouper'], uses: ['Ext.data.proxy.Memory'], @@ -43847,11 +44767,9 @@ Ext.define('Ext.data.Store', { remoteFilter: false, - - - remoteGroup : false, + remoteGroup : false, @@ -43877,36 +44795,53 @@ Ext.define('Ext.data.Store', { sortOnFilter: true, - + buffered: false, - + purgePageCount: 5, isStore: true, + onClassExtended: function(cls, data) { + var model = data.model; + + if (typeof model == 'string') { + var onBeforeClassCreated = data.onBeforeClassCreated; + + data.onBeforeClassCreated = function(cls, data) { + var me = this; + + Ext.require(model, function() { + onBeforeClassCreated.call(me, cls, data); + }); + }; + } + }, + constructor: function(config) { - config = config || {}; + + config = Ext.Object.merge({}, config); var me = this, groupers = config.groupers || me.groupers, groupField = config.groupField || me.groupField, proxy, data; - + if (config.buffered || me.buffered) { me.prefetchData = Ext.create('Ext.util.MixedCollection', false, function(record) { return record.index; }); me.pendingRequests = []; me.pagesRequested = []; - + me.sortOnLoad = false; me.filterOnLoad = false; } - + me.addEvents( 'beforeprefetch', @@ -43926,7 +44861,7 @@ Ext.define('Ext.data.Store', { me.inlineData = data; delete config.data; } - + if (!groupers && groupField) { groupers = [{ property : groupField, @@ -43934,14 +44869,14 @@ Ext.define('Ext.data.Store', { }]; } delete config.groupers; - + me.groupers = Ext.create('Ext.util.MixedCollection'); me.groupers.addAll(me.decodeGroupers(groupers)); this.callParent([config]); - + if (me.groupers.items.length) { me.sort(me.groupers.items, 'prepend', false); } @@ -43965,11 +44900,14 @@ Ext.define('Ext.data.Store', { } }, - + onBeforeSort: function() { - this.sort(this.groupers.items, 'prepend', false); + var groupers = this.groupers; + if (groupers.getCount() > 0) { + this.sort(groupers.items, 'prepend', false); + } }, - + decodeGroupers: function(groupers) { if (!Ext.isArray(groupers)) { @@ -43993,7 +44931,7 @@ Ext.define('Ext.data.Store', { property: config }; } - + Ext.applyIf(config, { root : 'data', direction: "ASC" @@ -44017,13 +44955,14 @@ Ext.define('Ext.data.Store', { return groupers; }, - + group: function(groupers, direction) { var me = this, + hasNew = false, grouper, newGroupers; - + if (Ext.isArray(groupers)) { newGroupers = groupers; } else if (Ext.isObject(groupers)) { @@ -44043,24 +44982,26 @@ Ext.define('Ext.data.Store', { grouper.setDirection(direction); } } - + if (newGroupers && newGroupers.length) { + hasNew = true; newGroupers = me.decodeGroupers(newGroupers); me.groupers.clear(); me.groupers.addAll(newGroupers); } - + if (me.remoteGroup) { me.load({ scope: me, callback: me.fireGroupChange }); } else { - me.sort(); - me.fireEvent('groupchange', me, me.groupers); + + me.sort(null, null, null, hasNew); + me.fireGroupChange(); } }, - + clearGrouping: function(){ var me = this; @@ -44079,15 +45020,15 @@ Ext.define('Ext.data.Store', { me.fireEvent('groupchange', me, me.groupers); } }, - + isGrouped: function() { - return this.groupers.getCount() > 0; + return this.groupers.getCount() > 0; }, - + fireGroupChange: function(){ - this.fireEvent('groupchange', this, this.groupers); + this.fireEvent('groupchange', this, this.groupers); }, @@ -44175,1651 +45116,2358 @@ Ext.define('Ext.data.Store', { return groups; }, - - getGroupData: function(sort) { - var me = this; - if (sort !== false) { - me.sort(); + + getGroupData: function(sort) { + var me = this; + if (sort !== false) { + me.sort(); + } + + return me.getGroupsForGrouperIndex(me.data.items, 0); + }, + + + getGroupString: function(instance) { + var group = this.groupers.first(); + if (group) { + return instance.get(group.property); + } + return ''; + }, + + insert: function(index, records) { + var me = this, + sync = false, + i, + record, + len; + + records = [].concat(records); + for (i = 0, len = records.length; i < len; i++) { + record = me.createModel(records[i]); + record.set(me.modelDefaults); + + records[i] = record; + + me.data.insert(index + i, record); + record.join(me); + + sync = sync || record.phantom === true; + } + + if (me.snapshot) { + me.snapshot.addAll(records); + } + + me.fireEvent('add', me, records, index); + me.fireEvent('datachanged', me); + if (me.autoSync && sync) { + me.sync(); + } + }, + + + add: function(records) { + + if (!Ext.isArray(records)) { + records = Array.prototype.slice.apply(arguments); + } + + var me = this, + i = 0, + length = records.length, + record; + + for (; i < length; i++) { + record = me.createModel(records[i]); + + records[i] = record; + } + + me.insert(me.data.length, records); + + return records; + }, + + + createModel: function(record) { + if (!record.isModel) { + record = Ext.ModelManager.create(record, this.model); + } + + return record; + }, + + + each: function(fn, scope) { + this.data.each(fn, scope); + }, + + + remove: function(records, isMove) { + if (!Ext.isArray(records)) { + records = [records]; + } + + + isMove = isMove === true; + var me = this, + sync = false, + i = 0, + length = records.length, + isPhantom, + index, + record; + + for (; i < length; i++) { + record = records[i]; + index = me.data.indexOf(record); + + if (me.snapshot) { + me.snapshot.remove(record); + } + + if (index > -1) { + isPhantom = record.phantom === true; + if (!isMove && !isPhantom) { + + me.removed.push(record); + } + + record.unjoin(me); + me.data.remove(record); + sync = sync || !isPhantom; + + me.fireEvent('remove', me, record, index); + } + } + + me.fireEvent('datachanged', me); + if (!isMove && me.autoSync && sync) { + me.sync(); + } + }, + + + removeAt: function(index) { + var record = this.getAt(index); + + if (record) { + this.remove(record); + } + }, + + + load: function(options) { + var me = this; + + options = options || {}; + + if (Ext.isFunction(options)) { + options = { + callback: options + }; + } + + Ext.applyIf(options, { + groupers: me.groupers.items, + page: me.currentPage, + start: (me.currentPage - 1) * me.pageSize, + limit: me.pageSize, + addRecords: false + }); + + return me.callParent([options]); + }, + + + onProxyLoad: function(operation) { + var me = this, + resultSet = operation.getResultSet(), + records = operation.getRecords(), + successful = operation.wasSuccessful(); + + if (resultSet) { + me.totalCount = resultSet.total; + } + + if (successful) { + me.loadRecords(records, operation); + } + + me.loading = false; + me.fireEvent('load', me, records, successful); + + + + me.fireEvent('read', me, records, operation.wasSuccessful()); + + + Ext.callback(operation.callback, operation.scope || me, [records, operation, successful]); + }, + + + onCreateRecords: function(records, operation, success) { + if (success) { + var i = 0, + data = this.data, + snapshot = this.snapshot, + length = records.length, + originalRecords = operation.records, + record, + original, + index; + + + for (; i < length; ++i) { + record = records[i]; + original = originalRecords[i]; + if (original) { + index = data.indexOf(original); + if (index > -1) { + data.removeAt(index); + data.insert(index, record); + } + if (snapshot) { + index = snapshot.indexOf(original); + if (index > -1) { + snapshot.removeAt(index); + snapshot.insert(index, record); + } + } + record.phantom = false; + record.join(this); + } + } + } + }, + + + onUpdateRecords: function(records, operation, success){ + if (success) { + var i = 0, + length = records.length, + data = this.data, + snapshot = this.snapshot, + record; + + for (; i < length; ++i) { + record = records[i]; + data.replace(record); + if (snapshot) { + snapshot.replace(record); + } + record.join(this); + } + } + }, + + + onDestroyRecords: function(records, operation, success){ + if (success) { + var me = this, + i = 0, + length = records.length, + data = me.data, + snapshot = me.snapshot, + record; + + for (; i < length; ++i) { + record = records[i]; + record.unjoin(me); + data.remove(record); + if (snapshot) { + snapshot.remove(record); + } + } + me.removed = []; + } + }, + + + getNewRecords: function() { + return this.data.filterBy(this.filterNew).items; + }, + + + getUpdatedRecords: function() { + return this.data.filterBy(this.filterUpdated).items; + }, + + + filter: function(filters, value) { + if (Ext.isString(filters)) { + filters = { + property: filters, + value: value + }; + } + + var me = this, + decoded = me.decodeFilters(filters), + i = 0, + doLocalSort = me.sortOnFilter && !me.remoteSort, + length = decoded.length; + + for (; i < length; i++) { + me.filters.replace(decoded[i]); + } + + if (me.remoteFilter) { + + me.load(); + } else { + + if (me.filters.getCount()) { + me.snapshot = me.snapshot || me.data.clone(); + me.data = me.data.filter(me.filters.items); + + if (doLocalSort) { + me.sort(); + } + + if (!doLocalSort || me.sorters.length < 1) { + me.fireEvent('datachanged', me); + } + } + } + }, + + + clearFilter: function(suppressEvent) { + var me = this; + + me.filters.clear(); + + if (me.remoteFilter) { + me.load(); + } else if (me.isFiltered()) { + me.data = me.snapshot.clone(); + delete me.snapshot; + + if (suppressEvent !== true) { + me.fireEvent('datachanged', me); + } + } + }, + + + isFiltered: function() { + var snapshot = this.snapshot; + return !! snapshot && snapshot !== this.data; + }, + + + filterBy: function(fn, scope) { + var me = this; + + me.snapshot = me.snapshot || me.data.clone(); + me.data = me.queryBy(fn, scope || me); + me.fireEvent('datachanged', me); + }, + + + queryBy: function(fn, scope) { + var me = this, + data = me.snapshot || me.data; + return data.filterBy(fn, scope || me); + }, + + + loadData: function(data, append) { + var model = this.model, + length = data.length, + newData = [], + i, + record; + + + for (i = 0; i < length; i++) { + record = data[i]; + + if (!(record instanceof Ext.data.Model)) { + record = Ext.ModelManager.create(record, model); + } + newData.push(record); + } + + this.loadRecords(newData, {addRecords: append}); + }, + + + + loadRawData : function(data, append) { + var me = this, + result = me.proxy.reader.read(data), + records = result.records; + + if (result.success) { + me.loadRecords(records, { addRecords: append }); + me.fireEvent('load', me, records, true); + } + }, + + + + loadRecords: function(records, options) { + var me = this, + i = 0, + length = records.length; + + options = options || {}; + + + if (!options.addRecords) { + delete me.snapshot; + me.clearData(); + } + + me.data.addAll(records); + + + for (; i < length; i++) { + if (options.start !== undefined) { + records[i].index = options.start + i; + + } + records[i].join(me); + } + + + me.suspendEvents(); + + if (me.filterOnLoad && !me.remoteFilter) { + me.filter(); + } + + if (me.sortOnLoad && !me.remoteSort) { + me.sort(); + } + + me.resumeEvents(); + me.fireEvent('datachanged', me, records); + }, + + + + loadPage: function(page, options) { + var me = this; + options = Ext.apply({}, options); + + me.currentPage = page; + + me.read(Ext.applyIf(options, { + page: page, + start: (page - 1) * me.pageSize, + limit: me.pageSize, + addRecords: !me.clearOnPageLoad + })); + }, + + + nextPage: function(options) { + this.loadPage(this.currentPage + 1, options); + }, + + + previousPage: function(options) { + this.loadPage(this.currentPage - 1, options); + }, + + + clearData: function() { + var me = this; + me.data.each(function(record) { + record.unjoin(me); + }); + + me.data.clear(); + }, + + + + prefetch: function(options) { + var me = this, + operation, + requestId = me.getRequestId(); + + options = options || {}; + + Ext.applyIf(options, { + action : 'read', + filters: me.filters.items, + sorters: me.sorters.items, + requestId: requestId + }); + me.pendingRequests.push(requestId); + + operation = Ext.create('Ext.data.Operation', options); + + + + + + if (me.fireEvent('beforeprefetch', me, operation) !== false) { + me.loading = true; + me.proxy.read(operation, me.onProxyPrefetch, me); + } + + return me; + }, + + + prefetchPage: function(page, options) { + var me = this, + pageSize = me.pageSize, + start = (page - 1) * me.pageSize, + end = start + pageSize; + + + if (Ext.Array.indexOf(me.pagesRequested, page) === -1 && !me.rangeSatisfied(start, end)) { + options = options || {}; + me.pagesRequested.push(page); + Ext.applyIf(options, { + page : page, + start: start, + limit: pageSize, + callback: me.onWaitForGuarantee, + scope: me + }); + + me.prefetch(options); } - return me.getGroupsForGrouperIndex(me.data.items, 0); }, - getGroupString: function(instance) { - var group = this.groupers.first(); - if (group) { - return instance.get(group.property); - } - return ''; + getRequestId: function() { + this.requestSeed = this.requestSeed || 1; + return this.requestSeed++; }, + - insert: function(index, records) { - var me = this, - sync = false, - i, - record, - len; + onProxyPrefetch: function(operation) { + var me = this, + resultSet = operation.getResultSet(), + records = operation.getRecords(), - records = [].concat(records); - for (i = 0, len = records.length; i < len; i++) { - record = me.createModel(records[i]); - record.set(me.modelDefaults); - - records[i] = record; - - me.data.insert(index + i, record); - record.join(me); + successful = operation.wasSuccessful(); - sync = sync || record.phantom === true; + if (resultSet) { + me.totalCount = resultSet.total; + me.fireEvent('totalcountchange', me.totalCount); } - if (me.snapshot) { - me.snapshot.addAll(records); + if (successful) { + me.cacheRecords(records, operation); } - - me.fireEvent('add', me, records, index); - me.fireEvent('datachanged', me); - if (me.autoSync && sync) { - me.sync(); + Ext.Array.remove(me.pendingRequests, operation.requestId); + if (operation.page) { + Ext.Array.remove(me.pagesRequested, operation.page); } - }, - - add: function(records) { + me.loading = false; + me.fireEvent('prefetch', me, records, successful, operation); + - if (!Ext.isArray(records)) { - records = Array.prototype.slice.apply(arguments); + if (operation.blocking) { + me.fireEvent('load', me, records, successful); } - var me = this, - i = 0, + + Ext.callback(operation.callback, operation.scope || me, [records, operation, successful]); + }, + + + cacheRecords: function(records, operation) { + var me = this, + i = 0, length = records.length, - record; + start = operation ? operation.start : 0; + + if (!Ext.isDefined(me.totalCount)) { + me.totalCount = records.length; + me.fireEvent('totalcountchange', me.totalCount); + } for (; i < length; i++) { - record = me.createModel(records[i]); - records[i] = record; + records[i].index = start + i; } - me.insert(me.data.length, records); + me.prefetchData.addAll(records); + if (me.purgePageCount) { + me.purgeRecords(); + } - return records; }, + - createModel: function(record) { - if (!record.isModel) { - record = Ext.ModelManager.create(record, this.model); - } + purgeRecords: function() { + var me = this, + prefetchCount = me.prefetchData.getCount(), + purgeCount = me.purgePageCount * me.pageSize, + numRecordsToPurge = prefetchCount - purgeCount - 1, + i = 0; - return record; + for (; i <= numRecordsToPurge; i++) { + me.prefetchData.removeAt(0); + } }, - each: function(fn, scope) { - this.data.each(fn, scope); + rangeSatisfied: function(start, end) { + var me = this, + i = start, + satisfied = true; + + for (; i < end; i++) { + if (!me.prefetchData.getByKey(i)) { + satisfied = false; + break; + } + } + return satisfied; }, - remove: function(records, isMove) { - if (!Ext.isArray(records)) { - records = [records]; - } + getPageFromRecordIndex: function(index) { + return Math.floor(index / this.pageSize) + 1; + }, - - isMove = isMove === true; + + onGuaranteedRange: function() { var me = this, - sync = false, - i = 0, - length = records.length, - isPhantom, - index, - record; + totalCount = me.getTotalCount(), + start = me.requestStart, + end = ((totalCount - 1) < me.requestEnd) ? totalCount - 1 : me.requestEnd, + range = [], + record, + i = start; - for (; i < length; i++) { - record = records[i]; - index = me.data.indexOf(record); - - if (me.snapshot) { - me.snapshot.remove(record); - } - - if (index > -1) { - isPhantom = record.phantom === true; - if (!isMove && !isPhantom) { - - me.removed.push(record); - } + end = Math.max(0, end); - record.unjoin(me); - me.data.remove(record); - sync = sync || !isPhantom; - me.fireEvent('remove', me, record, index); + if (start !== me.guaranteedStart && end !== me.guaranteedEnd) { + me.guaranteedStart = start; + me.guaranteedEnd = end; + + for (; i <= end; i++) { + record = me.prefetchData.getByKey(i); + if (record) { + range.push(record); + } + } + me.fireEvent('guaranteedrange', range, start, end); + if (me.cb) { + me.cb.call(me.scope || me, range); } } - me.fireEvent('datachanged', me); - if (!isMove && me.autoSync && sync) { - me.sync(); - } + me.unmask(); }, - removeAt: function(index) { - var record = this.getAt(index); + mask: function() { + this.masked = true; + this.fireEvent('beforeload'); + }, - if (record) { - this.remove(record); + + unmask: function() { + if (this.masked) { + this.fireEvent('load'); } }, - load: function(options) { - var me = this; - - options = options || {}; - - if (Ext.isFunction(options)) { - options = { - callback: options - }; - } + hasPendingRequests: function() { + return this.pendingRequests.length; + }, - Ext.applyIf(options, { - groupers: me.groupers.items, - page: me.currentPage, - start: (me.currentPage - 1) * me.pageSize, - limit: me.pageSize, - addRecords: false - }); - return me.callParent([options]); + + onWaitForGuarantee: function() { + if (!this.hasPendingRequests()) { + this.onGuaranteedRange(); + } }, - onProxyLoad: function(operation) { - var me = this, - resultSet = operation.getResultSet(), - records = operation.getRecords(), - successful = operation.wasSuccessful(); + guaranteeRange: function(start, end, cb, scope) { - if (resultSet) { - me.totalCount = resultSet.total; - } + end = (end > this.totalCount) ? this.totalCount - 1 : end; - if (successful) { - me.loadRecords(records, operation); - } + var me = this, + i = start, + prefetchData = me.prefetchData, + range = [], + startLoaded = !!prefetchData.getByKey(start), + endLoaded = !!prefetchData.getByKey(end), + startPage = me.getPageFromRecordIndex(start), + endPage = me.getPageFromRecordIndex(end); - me.loading = false; - me.fireEvent('load', me, records, successful); + me.cb = cb; + me.scope = scope; + me.requestStart = start; + me.requestEnd = end; + if (!startLoaded || !endLoaded) { + + if (startPage === endPage) { + me.mask(); + me.prefetchPage(startPage, { + + callback: me.onWaitForGuarantee, + scope: me + }); + + } else { + me.mask(); + me.prefetchPage(startPage, { + + callback: me.onWaitForGuarantee, + scope: me + }); + me.prefetchPage(endPage, { + + callback: me.onWaitForGuarantee, + scope: me + }); + } - me.fireEvent('read', me, records, operation.wasSuccessful()); - - - Ext.callback(operation.callback, operation.scope || me, [records, operation, successful]); + } else { + me.onGuaranteedRange(); + } }, + - onCreateRecords: function(records, operation, success) { - if (success) { - var i = 0, - data = this.data, - snapshot = this.snapshot, - length = records.length, - originalRecords = operation.records, - record, - original, - index; + sort: function() { + var me = this, + prefetchData = me.prefetchData, + sorters, + start, + end, + range; - - for (; i < length; ++i) { - record = records[i]; - original = originalRecords[i]; - if (original) { - index = data.indexOf(original); - if (index > -1) { - data.removeAt(index); - data.insert(index, record); - } - if (snapshot) { - index = snapshot.indexOf(original); - if (index > -1) { - snapshot.removeAt(index); - snapshot.insert(index, record); - } - } - record.phantom = false; - record.join(this); + if (me.buffered) { + if (me.remoteSort) { + prefetchData.clear(); + me.callParent(arguments); + } else { + sorters = me.getSorters(); + start = me.guaranteedStart; + end = me.guaranteedEnd; + + if (sorters.length) { + prefetchData.sort(sorters); + range = prefetchData.getRange(); + prefetchData.clear(); + me.cacheRecords(range); + delete me.guaranteedStart; + delete me.guaranteedEnd; + me.guaranteeRange(start, end); } + me.callParent(arguments); } + } else { + me.callParent(arguments); } }, - onUpdateRecords: function(records, operation, success){ - if (success) { - var i = 0, - length = records.length, - data = this.data, - snapshot = this.snapshot, - record; - - for (; i < length; ++i) { - record = records[i]; - data.replace(record); - if (snapshot) { - snapshot.replace(record); + + + doSort: function(sorterFn) { + var me = this; + if (me.remoteSort) { + + me.load(); + } else { + me.data.sortBy(sorterFn); + if (!me.buffered) { + var range = me.getRange(), + ln = range.length, + i = 0; + for (; i < ln; i++) { + range[i].index = i; } - record.join(this); } + me.fireEvent('datachanged', me); } }, - onDestroyRecords: function(records, operation, success){ - if (success) { - var me = this, - i = 0, - length = records.length, - data = me.data, - snapshot = me.snapshot, - record; + find: function(property, value, start, anyMatch, caseSensitive, exactMatch) { + var fn = this.createFilterFn(property, value, anyMatch, caseSensitive, exactMatch); + return fn ? this.data.findIndexBy(fn, null, start) : -1; + }, - for (; i < length; ++i) { - record = records[i]; - record.unjoin(me); - data.remove(record); - if (snapshot) { - snapshot.remove(record); - } - } - me.removed = []; - } + + findRecord: function() { + var me = this, + index = me.find.apply(me, arguments); + return index !== -1 ? me.getAt(index) : null; }, - getNewRecords: function() { - return this.data.filterBy(this.filterNew).items; + createFilterFn: function(property, value, anyMatch, caseSensitive, exactMatch) { + if (Ext.isEmpty(value)) { + return false; + } + value = this.data.createValueMatcher(value, anyMatch, caseSensitive, exactMatch); + return function(r) { + return value.test(r.data[property]); + }; }, - getUpdatedRecords: function() { - return this.data.filterBy(this.filterUpdated).items; + findExact: function(property, value, start) { + return this.data.findIndexBy(function(rec) { + return rec.get(property) == value; + }, + this, start); }, - filter: function(filters, value) { - if (Ext.isString(filters)) { - filters = { - property: filters, - value: value - }; - } + findBy: function(fn, scope, start) { + return this.data.findIndexBy(fn, scope, start); + }, + + collect: function(dataIndex, allowNull, bypassFilter) { var me = this, - decoded = me.decodeFilters(filters), - i = 0, - doLocalSort = me.sortOnFilter && !me.remoteSort, - length = decoded.length; + data = (bypassFilter === true && me.snapshot) ? me.snapshot: me.data; - for (; i < length; i++) { - me.filters.replace(decoded[i]); - } + return data.collect(dataIndex, 'data', allowNull); + }, - if (me.remoteFilter) { - - me.load(); - } else { - - if (me.filters.getCount()) { - me.snapshot = me.snapshot || me.data.clone(); - me.data = me.data.filter(me.filters.items); + + getCount: function() { + return this.data.length || 0; + }, - if (doLocalSort) { - me.sort(); - } - - if (!doLocalSort || me.sorters.length < 1) { - me.fireEvent('datachanged', me); - } - } - } + + getTotalCount: function() { + return this.totalCount; }, - clearFilter: function(suppressEvent) { - var me = this; + getAt: function(index) { + return this.data.getAt(index); + }, - me.filters.clear(); + + getRange: function(start, end) { + return this.data.getRange(start, end); + }, - if (me.remoteFilter) { - me.load(); - } else if (me.isFiltered()) { - me.data = me.snapshot.clone(); - delete me.snapshot; + + getById: function(id) { + return (this.snapshot || this.data).findBy(function(record) { + return record.getId() === id; + }); + }, - if (suppressEvent !== true) { - me.fireEvent('datachanged', me); - } + + indexOf: function(record) { + return this.data.indexOf(record); + }, + + + + indexOfTotal: function(record) { + var index = record.index; + if (index || index === 0) { + return index; } + return this.indexOf(record); }, - isFiltered: function() { - var snapshot = this.snapshot; - return !! snapshot && snapshot !== this.data; + indexOfId: function(id) { + return this.indexOf(this.getById(id)); + }, + + + removeAll: function(silent) { + var me = this; + + me.clearData(); + if (me.snapshot) { + me.snapshot.clear(); + } + if (silent !== true) { + me.fireEvent('clear', me); + } + }, + + + + + first: function(grouped) { + var me = this; + + if (grouped && me.isGrouped()) { + return me.aggregate(function(records) { + return records.length ? records[0] : undefined; + }, me, true); + } else { + return me.data.first(); + } }, - filterBy: function(fn, scope) { + last: function(grouped) { var me = this; - me.snapshot = me.snapshot || me.data.clone(); - me.data = me.queryBy(fn, scope || me); - me.fireEvent('datachanged', me); + if (grouped && me.isGrouped()) { + return me.aggregate(function(records) { + var len = records.length; + return len ? records[len - 1] : undefined; + }, me, true); + } else { + return me.data.last(); + } }, - queryBy: function(fn, scope) { - var me = this, - data = me.snapshot || me.data; - return data.filterBy(fn, scope || me); + sum: function(field, grouped) { + var me = this; + + if (grouped && me.isGrouped()) { + return me.aggregate(me.getSum, me, true, [field]); + } else { + return me.getSum(me.data.items, field); + } }, - loadData: function(data, append) { - var model = this.model, - length = data.length, - i, - record; - - - for (i = 0; i < length; i++) { - record = data[i]; + getSum: function(records, field) { + var total = 0, + i = 0, + len = records.length; - if (! (record instanceof Ext.data.Model)) { - data[i] = Ext.ModelManager.create(record, model); - } + for (; i < len; ++i) { + total += records[i].get(field); } - this.loadRecords(data, {addRecords: append}); + return total; }, - loadRecords: function(records, options) { - var me = this, - i = 0, - length = records.length; + count: function(grouped) { + var me = this; - options = options || {}; + if (grouped && me.isGrouped()) { + return me.aggregate(function(records) { + return records.length; + }, me, true); + } else { + return me.getCount(); + } + }, + + min: function(field, grouped) { + var me = this; - if (!options.addRecords) { - delete me.snapshot; - me.data.clear(); + if (grouped && me.isGrouped()) { + return me.aggregate(me.getMin, me, true, [field]); + } else { + return me.getMin(me.data.items, field); } + }, - me.data.addAll(records); + + getMin: function(records, field){ + var i = 1, + len = records.length, + value, min; - - for (; i < length; i++) { - if (options.start !== undefined) { - records[i].index = options.start + i; + if (len > 0) { + min = records[0].get(field); + } + for (; i < len; ++i) { + value = records[i].get(field); + if (value < min) { + min = value; } - records[i].join(me); } + return min; + }, - - me.suspendEvents(); - - if (me.filterOnLoad && !me.remoteFilter) { - me.filter(); - } + + max: function(field, grouped) { + var me = this; - if (me.sortOnLoad && !me.remoteSort) { - me.sort(); + if (grouped && me.isGrouped()) { + return me.aggregate(me.getMax, me, true, [field]); + } else { + return me.getMax(me.data.items, field); } - - me.resumeEvents(); - me.fireEvent('datachanged', me, records); }, - - loadPage: function(page) { - var me = this; + getMax: function(records, field) { + var i = 1, + len = records.length, + value, + max; - me.currentPage = page; + if (len > 0) { + max = records[0].get(field); + } - me.read({ - page: page, - start: (page - 1) * me.pageSize, - limit: me.pageSize, - addRecords: !me.clearOnPageLoad - }); + for (; i < len; ++i) { + value = records[i].get(field); + if (value > max) { + max = value; + } + } + return max; }, - nextPage: function() { - this.loadPage(this.currentPage + 1); + average: function(field, grouped) { + var me = this; + if (grouped && me.isGrouped()) { + return me.aggregate(me.getAverage, me, true, [field]); + } else { + return me.getAverage(me.data.items, field); + } }, - previousPage: function() { - this.loadPage(this.currentPage - 1); + getAverage: function(records, field) { + var i = 0, + len = records.length, + sum = 0; + + if (records.length > 0) { + for (; i < len; ++i) { + sum += records[i].get(field); + } + return sum / len; + } + return 0; }, - clearData: function() { - this.data.each(function(record) { - record.unjoin(); - }); + aggregate: function(fn, scope, grouped, args) { + args = args || []; + if (grouped && this.isGrouped()) { + var groups = this.getGroups(), + i = 0, + len = groups.length, + out = {}, + group; - this.data.clear(); - }, + for (; i < len; ++i) { + group = groups[i]; + out[group.name] = fn.apply(scope || this, [group.children].concat(args)); + } + return out; + } else { + return fn.apply(scope || this, [this.data.items].concat(args)); + } + } +}, function() { - prefetch: function(options) { - var me = this, - operation, - requestId = me.getRequestId(); + Ext.regStore('ext-empty-store', {fields: [], proxy: 'proxy'}); +}); - options = options || {}; - Ext.applyIf(options, { - action : 'read', - filters: me.filters.items, - sorters: me.sorters.items, - requestId: requestId +Ext.define('Ext.data.JsonStore', { + extend: 'Ext.data.Store', + alias: 'store.json', + + + constructor: function(config) { + config = config || {}; + + Ext.applyIf(config, { + proxy: { + type : 'ajax', + reader: 'json', + writer: 'json' + } }); - me.pendingRequests.push(requestId); - operation = Ext.create('Ext.data.Operation', options); + this.callParent([config]); + } +}); + + +Ext.define('Ext.chart.axis.Time', { - - - - - if (me.fireEvent('beforeprefetch', me, operation) !== false) { - me.loading = true; - me.proxy.read(operation, me.onProxyPrefetch, me); - } - - return me; - }, - - prefetchPage: function(page, options) { - var me = this, - pageSize = me.pageSize, - start = (page - 1) * me.pageSize, - end = start + pageSize; - - - if (Ext.Array.indexOf(me.pagesRequested, page) === -1 && !me.rangeSatisfied(start, end)) { - options = options || {}; - me.pagesRequested.push(page); - Ext.applyIf(options, { - page : page, - start: start, - limit: pageSize, - callback: me.onWaitForGuarantee, - scope: me - }); - - me.prefetch(options); - } - - }, + + extend: 'Ext.chart.axis.Numeric', + + alternateClassName: 'Ext.chart.TimeAxis', + + alias: 'axis.time', + + requires: ['Ext.data.Store', 'Ext.data.JsonStore'], + + - getRequestId: function() { - this.requestSeed = this.requestSeed || 1; - return this.requestSeed++; - }, + dateFormat: false, + + fromDate: false, + - onProxyPrefetch: function(operation) { - var me = this, - resultSet = operation.getResultSet(), - records = operation.getRecords(), - - successful = operation.wasSuccessful(); - - if (resultSet) { - me.totalCount = resultSet.total; - me.fireEvent('totalcountchange', me.totalCount); - } - - if (successful) { - me.cacheRecords(records, operation); - } - Ext.Array.remove(me.pendingRequests, operation.requestId); - if (operation.page) { - Ext.Array.remove(me.pagesRequested, operation.page); - } - - me.loading = false; - me.fireEvent('prefetch', me, records, successful, operation); - - - if (operation.blocking) { - me.fireEvent('load', me, records, successful); - } + toDate: false, - - Ext.callback(operation.callback, operation.scope || me, [records, operation, successful]); - }, + step: [Ext.Date.DAY, 1], - cacheRecords: function(records, operation) { - var me = this, - i = 0, - length = records.length, - start = operation ? operation.start : 0; - - if (!Ext.isDefined(me.totalCount)) { - me.totalCount = records.length; - me.fireEvent('totalcountchange', me.totalCount); - } - - for (; i < length; i++) { - - records[i].index = start + i; - } - - me.prefetchData.addAll(records); - if (me.purgePageCount) { - me.purgeRecords(); - } - - }, + constrain: false, + + roundToDecimal: false, - purgeRecords: function() { - var me = this, - prefetchCount = me.prefetchData.getCount(), - purgeCount = me.purgePageCount * me.pageSize, - numRecordsToPurge = prefetchCount - purgeCount - 1, - i = 0; - - for (; i <= numRecordsToPurge; i++) { - me.prefetchData.removeAt(0); + constructor: function (config) { + var me = this, label, f, df; + me.callParent([config]); + label = me.label || {}; + df = this.dateFormat; + if (df) { + if (label.renderer) { + f = label.renderer; + label.renderer = function(v) { + v = f(v); + return Ext.Date.format(new Date(f(v)), df); + }; + } else { + label.renderer = function(v) { + return Ext.Date.format(new Date(v >> 0), df); + }; + } } }, - - - rangeSatisfied: function(start, end) { - var me = this, - i = start, - satisfied = true; - for (; i < end; i++) { - if (!me.prefetchData.getByKey(i)) { - satisfied = false; - if (end - i > me.pageSize) { - Ext.Error.raise("A single page prefetch could never satisfy this request."); + doConstrain: function () { + var me = this, + store = me.chart.store, + data = [], + series = me.chart.series.items, + math = Math, + mmax = math.max, + mmin = math.min, + fields = me.fields, + ln = fields.length, + range = me.getRange(), + min = range.min, max = range.max, i, l, excludes = [], + value, values, rec, data = []; + for (i = 0, l = series.length; i < l; i++) { + excludes[i] = series[i].__excludes; + } + store.each(function(record) { + for (i = 0; i < ln; i++) { + if (excludes[i]) { + continue; } - break; + value = record.get(fields[i]); + if (+value < +min) return; + if (+value > +max) return; } - } - return satisfied; - }, - - - getPageFromRecordIndex: function(index) { - return Math.floor(index / this.pageSize) + 1; + data.push(record); + }) + me.chart.substore = Ext.create('Ext.data.JsonStore', { model: store.model, data: data }); }, + - - onGuaranteedRange: function() { - var me = this, - totalCount = me.getTotalCount(), - start = me.requestStart, - end = ((totalCount - 1) < me.requestEnd) ? totalCount - 1 : me.requestEnd, - range = [], - record, - i = start; - - if (start > end) { - Ext.Error.raise("Start (" + start + ") was greater than end (" + end + ")"); + processView: function () { + var me = this; + if (me.fromDate) { + me.minimum = +me.fromDate; } - - if (start !== me.guaranteedStart && end !== me.guaranteedEnd) { - me.guaranteedStart = start; - me.guaranteedEnd = end; - - for (; i <= end; i++) { - record = me.prefetchData.getByKey(i); - if (!record) { - Ext.Error.raise("Record was not found and store said it was guaranteed"); - } - range.push(record); + if (me.toDate) { + me.maximum = +me.toDate; + } + if (me.constrain) { + me.doConstrain(); + } + }, + + + calcEnds: function() { + var me = this, range, step = me.step; + if (step) { + range = me.getRange(); + range = Ext.draw.Draw.snapEndsByDateAndStep(new Date(range.min), new Date(range.max), Ext.isNumber(step) ? [Date.MILLI, step]: step); + if (me.minimum) { + range.from = me.minimum; } - me.fireEvent('guaranteedrange', range, start, end); - if (me.cb) { - me.cb.call(me.scope || me, range); + if (me.maximum) { + range.to = me.maximum; } + range.step = (range.to - range.from) / range.steps; + return range; + } else { + return me.callParent(arguments); } - - me.unmask(); - }, - + } + }); + + + +Ext.define('Ext.chart.series.Series', { + - mask: function() { - this.masked = true; - this.fireEvent('beforeload'); + + mixins: { + observable: 'Ext.util.Observable', + labels: 'Ext.chart.Label', + highlights: 'Ext.chart.Highlight', + tips: 'Ext.chart.Tip', + callouts: 'Ext.chart.Callout' }, + + - unmask: function() { - if (this.masked) { - this.fireEvent('load'); - } - }, + + - hasPendingRequests: function() { - return this.pendingRequests.length; - }, + type: null, + + title: null, + + showInLegend: true, + - onWaitForGuarantee: function() { - if (!this.hasPendingRequests()) { - this.onGuaranteedRange(); - } + renderer: function(sprite, record, attributes, index, store) { + return attributes; }, + + shadowAttributes: null, + + //@private triggerdrawlistener flag + + triggerAfterDraw: false, + - guaranteeRange: function(start, end, cb, scope) { - if (start && end) { - if (end - start > this.pageSize) { - Ext.Error.raise({ - start: start, - end: end, - pageSize: this.pageSize, - msg: "Requested a bigger range than the specified pageSize" - }); - } + + constructor: function(config) { + var me = this; + if (config) { + Ext.apply(me, config); } - - end = (end > this.totalCount) ? this.totalCount - 1 : end; - - var me = this, - i = start, - prefetchData = me.prefetchData, - range = [], - startLoaded = !!prefetchData.getByKey(start), - endLoaded = !!prefetchData.getByKey(end), - startPage = me.getPageFromRecordIndex(start), - endPage = me.getPageFromRecordIndex(end); - - me.cb = cb; - me.scope = scope; - me.requestStart = start; - me.requestEnd = end; - - if (!startLoaded || !endLoaded) { - - if (startPage === endPage) { - me.mask(); - me.prefetchPage(startPage, { - - callback: me.onWaitForGuarantee, - scope: me - }); + me.shadowGroups = []; + + me.mixins.labels.constructor.call(me, config); + me.mixins.highlights.constructor.call(me, config); + me.mixins.tips.constructor.call(me, config); + me.mixins.callouts.constructor.call(me, config); + + me.addEvents({ + scope: me, + itemmouseover: true, + itemmouseout: true, + itemmousedown: true, + itemmouseup: true, + mouseleave: true, + afterdraw: true, + - } else { - me.mask(); - me.prefetchPage(startPage, { - - callback: me.onWaitForGuarantee, - scope: me - }); - me.prefetchPage(endPage, { - - callback: me.onWaitForGuarantee, - scope: me - }); - } - - } else { - me.onGuaranteedRange(); - } + titlechange: true + }); + + me.mixins.observable.constructor.call(me, config); + + me.on({ + scope: me, + itemmouseover: me.onItemMouseOver, + itemmouseout: me.onItemMouseOut, + mouseleave: me.onMouseLeave + }); }, + eachRecord: function(fn, scope) { + var chart = this.chart; + (chart.substore || chart.store).each(fn, scope); + }, + - sort: function() { - var me = this, - prefetchData = me.prefetchData, - sorters, - start, - end, - range; - - if (me.buffered) { - if (me.remoteSort) { - prefetchData.clear(); - me.callParent(arguments); - } else { - sorters = me.getSorters(); - start = me.guaranteedStart; - end = me.guaranteedEnd; - - if (sorters.length) { - prefetchData.sort(sorters); - range = prefetchData.getRange(); - prefetchData.clear(); - me.cacheRecords(range); - delete me.guaranteedStart; - delete me.guaranteedEnd; - me.guaranteeRange(start, end); - } - me.callParent(arguments); - } - } else { - me.callParent(arguments); - } + getRecordCount: function() { + var chart = this.chart, + store = chart.substore || chart.store; + return store ? store.getCount() : 0; }, + isExcluded: function(index) { + var excludes = this.__excludes; + return !!(excludes && excludes[index]); + }, + + setBBox: function(noGutter) { + var me = this, + chart = me.chart, + chartBBox = chart.chartBBox, + gutterX = noGutter ? 0 : chart.maxGutter[0], + gutterY = noGutter ? 0 : chart.maxGutter[1], + clipBox, bbox; + + clipBox = { + x: chartBBox.x, + y: chartBBox.y, + width: chartBBox.width, + height: chartBBox.height + }; + me.clipBox = clipBox; + + bbox = { + x: (clipBox.x + gutterX) - (chart.zoom.x * chart.zoom.width), + y: (clipBox.y + gutterY) - (chart.zoom.y * chart.zoom.height), + width: (clipBox.width - (gutterX * 2)) * chart.zoom.width, + height: (clipBox.height - (gutterY * 2)) * chart.zoom.height + }; + me.bbox = bbox; + }, + - doSort: function(sorterFn) { + onAnimate: function(sprite, attr) { var me = this; - if (me.remoteSort) { - - me.load(); + sprite.stopAnimation(); + if (me.triggerAfterDraw) { + return sprite.animate(Ext.applyIf(attr, me.chart.animate)); } else { - me.data.sortBy(sorterFn); - if (!me.buffered) { - var range = me.getRange(), - ln = range.length, - i = 0; - for (; i < ln; i++) { - range[i].index = i; + me.triggerAfterDraw = true; + return sprite.animate(Ext.apply(Ext.applyIf(attr, me.chart.animate), { + listeners: { + 'afteranimate': function() { + me.triggerAfterDraw = false; + me.fireEvent('afterrender'); + } } - } - me.fireEvent('datachanged', me); + })); } }, - - - find: function(property, value, start, anyMatch, caseSensitive, exactMatch) { - var fn = this.createFilterFn(property, value, anyMatch, caseSensitive, exactMatch); - return fn ? this.data.findIndexBy(fn, null, start) : -1; - }, - findRecord: function() { - var me = this, - index = me.find.apply(me, arguments); - return index !== -1 ? me.getAt(index) : null; + getGutters: function() { + return [0, 0]; }, - createFilterFn: function(property, value, anyMatch, caseSensitive, exactMatch) { - if (Ext.isEmpty(value)) { - return false; + onItemMouseOver: function(item) { + var me = this; + if (item.series === me) { + if (me.highlight) { + me.highlightItem(item); + } + if (me.tooltip) { + me.showTip(item); + } } - value = this.data.createValueMatcher(value, anyMatch, caseSensitive, exactMatch); - return function(r) { - return value.test(r.data[property]); - }; }, - findExact: function(property, value, start) { - return this.data.findIndexBy(function(rec) { - return rec.get(property) === value; - }, - this, start); + onItemMouseOut: function(item) { + var me = this; + if (item.series === me) { + me.unHighlightItem(); + if (me.tooltip) { + me.hideTip(item); + } + } }, - findBy: function(fn, scope, start) { - return this.data.findIndexBy(fn, scope, start); + onMouseLeave: function() { + var me = this; + me.unHighlightItem(); + if (me.tooltip) { + me.hideTip(); + } }, - collect: function(dataIndex, allowNull, bypassFilter) { + getItemForPoint: function(x, y) { + + if (!this.items || !this.items.length || this.seriesIsHidden) { + return null; + } var me = this, - data = (bypassFilter === true && me.snapshot) ? me.snapshot: me.data; + items = me.items, + bbox = me.bbox, + item, i, ln; + + if (!Ext.draw.Draw.withinBox(x, y, bbox)) { + return null; + } + for (i = 0, ln = items.length; i < ln; i++) { + if (items[i] && this.isItemInPoint(x, y, items[i], i)) { + return items[i]; + } + } - return data.collect(dataIndex, 'data', allowNull); + return null; }, - - getCount: function() { - return this.data.length || 0; + isItemInPoint: function(x, y, item, i) { + return false; }, - getTotalCount: function() { - return this.totalCount; - }, + hideAll: function() { + var me = this, + items = me.items, + item, len, i, j, l, sprite, shadows; - - getAt: function(index) { - return this.data.getAt(index); - }, + me.seriesIsHidden = true; + me._prevShowMarkers = me.showMarkers; - - getRange: function(start, end) { - return this.data.getRange(start, end); - }, + me.showMarkers = false; + + me.hideLabels(0); + + for (i = 0, len = items.length; i < len; i++) { + item = items[i]; + sprite = item.sprite; + if (sprite) { + sprite.setAttributes({ + hidden: true + }, true); + } - - getById: function(id) { - return (this.snapshot || this.data).findBy(function(record) { - return record.getId() === id; - }); + if (sprite && sprite.shadows) { + shadows = sprite.shadows; + for (j = 0, l = shadows.length; j < l; ++j) { + shadows[j].setAttributes({ + hidden: true + }, true); + } + } + } }, - indexOf: function(record) { - return this.data.indexOf(record); + showAll: function() { + var me = this, + prevAnimate = me.chart.animate; + me.chart.animate = false; + me.seriesIsHidden = false; + me.showMarkers = me._prevShowMarkers; + me.drawSeries(); + me.chart.animate = prevAnimate; }, - - indexOfTotal: function(record) { - return record.index || this.indexOf(record); + getLegendColor: function(index) { + var me = this, fill, stroke; + if (me.seriesStyle) { + fill = me.seriesStyle.fill; + stroke = me.seriesStyle.stroke; + if (fill && fill != 'none') { + return fill; + } + return stroke; + } + return '#000'; }, - indexOfId: function(id) { - return this.data.indexOfKey(id); + visibleInLegend: function(index){ + var excludes = this.__excludes; + if (excludes) { + return !excludes[index]; + } + return !this.seriesIsHidden; }, - + - removeAll: function(silent) { - var me = this; + setTitle: function(index, title) { + var me = this, + oldTitle = me.title; - me.clearData(); - if (me.snapshot) { - me.snapshot.clear(); + if (Ext.isString(index)) { + title = index; + index = 0; } - if (silent !== true) { - me.fireEvent('clear', me); + + if (Ext.isArray(oldTitle)) { + oldTitle[index] = title; + } else { + me.title = title; } - }, + + me.fireEvent('titlechange', title, index); + } +}); + + +Ext.define('Ext.chart.series.Cartesian', { + extend: 'Ext.chart.series.Series', + + alternateClassName: ['Ext.chart.CartesianSeries', 'Ext.chart.CartesianChart'], + - first: function(grouped) { - var me = this; - if (grouped && me.isGrouped()) { - return me.aggregate(function(records) { - return records.length ? records[0] : undefined; - }, me, true); - } else { - return me.data.first(); - } - }, + + xField: null, - last: function(grouped) { - var me = this; + yField: null, - if (grouped && me.isGrouped()) { - return me.aggregate(function(records) { - var len = records.length; - return len ? records[len - 1] : undefined; - }, me, true); - } else { - return me.data.last(); + + axis: 'left', + + getLegendLabels: function() { + var me = this, + labels = [], + combinations = me.combinations; + + Ext.each([].concat(me.yField), function(yField, i) { + var title = me.title; + + labels.push((Ext.isArray(title) ? title[i] : title) || yField); + }); + + + if (combinations) { + Ext.each(combinations, function(combo) { + var label0 = labels[combo[0]], + label1 = labels[combo[1]]; + labels[combo[1]] = label0 + ' & ' + label1; + labels.splice(combo[0], 1); + }); } + + return labels; }, - sum: function(field, grouped) { - var me = this; - - if (grouped && me.isGrouped()) { - return me.aggregate(me.getSum, me, true, [field]); - } else { - return me.getSum(me.data.items, field); - } + eachYValue: function(record, fn, scope) { + Ext.each(this.getYValueAccessors(), function(accessor, i) { + fn.call(scope, accessor(record), i); + }); }, - getSum: function(records, field) { - var total = 0, - i = 0, - len = records.length; + getYValueCount: function() { + return this.getYValueAccessors().length; + }, - for (; i < len; ++i) { - total += records[i].get(field); - } + combine: function(index1, index2) { + var me = this, + accessors = me.getYValueAccessors(), + accessor1 = accessors[index1], + accessor2 = accessors[index2]; - return total; + + accessors[index2] = function(record) { + return accessor1(record) + accessor2(record); + }; + accessors.splice(index1, 1); + + me.callParent([index1, index2]); }, - - count: function(grouped) { - var me = this; + clearCombinations: function() { + + delete this.yValueAccessors; + this.callParent(); + }, - if (grouped && me.isGrouped()) { - return me.aggregate(function(records) { - return records.length; - }, me, true); - } else { - return me.getCount(); + + getYValueAccessors: function() { + var me = this, + accessors = me.yValueAccessors; + if (!accessors) { + accessors = me.yValueAccessors = []; + Ext.each([].concat(me.yField), function(yField) { + accessors.push(function(record) { + return record.get(yField); + }); + }); } + return accessors; }, - min: function(field, grouped) { - var me = this; + getMinMaxXValues: function() { + var me = this, + min, max, + xField = me.xField; - if (grouped && me.isGrouped()) { - return me.aggregate(me.getMin, me, true, [field]); + if (me.getRecordCount() > 0) { + min = Infinity; + max = -min; + me.eachRecord(function(record) { + var xValue = record.get(xField); + if (xValue > max) { + max = xValue; + } + if (xValue < min) { + min = xValue; + } + }); } else { - return me.getMin(me.data.items, field); + min = max = 0; } + return [min, max]; }, - getMin: function(records, field){ - var i = 1, - len = records.length, - value, min; + getMinMaxYValues: function() { + var me = this, + stacked = me.stacked, + min, max, + positiveTotal, negativeTotal; - if (len > 0) { - min = records[0].get(field); + function eachYValueStacked(yValue, i) { + if (!me.isExcluded(i)) { + if (yValue < 0) { + negativeTotal += yValue; + } else { + positiveTotal += yValue; + } + } } - for (; i < len; ++i) { - value = records[i].get(field); - if (value < min) { - min = value; + function eachYValue(yValue, i) { + if (!me.isExcluded(i)) { + if (yValue > max) { + max = yValue; + } + if (yValue < min) { + min = yValue; + } } } - return min; - }, - - - max: function(field, grouped) { - var me = this; - if (grouped && me.isGrouped()) { - return me.aggregate(me.getMax, me, true, [field]); + if (me.getRecordCount() > 0) { + min = Infinity; + max = -min; + me.eachRecord(function(record) { + if (stacked) { + positiveTotal = 0; + negativeTotal = 0; + me.eachYValue(record, eachYValueStacked); + if (positiveTotal > max) { + max = positiveTotal; + } + if (negativeTotal < min) { + min = negativeTotal; + } + } else { + me.eachYValue(record, eachYValue); + } + }); } else { - return me.getMax(me.data.items, field); + min = max = 0; } + return [min, max]; }, - - getMax: function(records, field) { - var i = 1, - len = records.length, - value, - max; + getAxesForXAndYFields: function() { + var me = this, + axes = me.chart.axes, + axis = [].concat(me.axis), + xAxis, yAxis; - if (len > 0) { - max = records[0].get(field); + if (Ext.Array.indexOf(axis, 'top') > -1) { + xAxis = 'top'; + } else if (Ext.Array.indexOf(axis, 'bottom') > -1) { + xAxis = 'bottom'; + } else { + if (axes.get('top')) { + xAxis = 'top'; + } else if (axes.get('bottom')) { + xAxis = 'bottom'; + } } - for (; i < len; ++i) { - value = records[i].get(field); - if (value > max) { - max = value; + if (Ext.Array.indexOf(axis, 'left') > -1) { + yAxis = 'left'; + } else if (Ext.Array.indexOf(axis, 'right') > -1) { + yAxis = 'right'; + } else { + if (axes.get('left')) { + yAxis = 'left'; + } else if (axes.get('right')) { + yAxis = 'right'; } } - return max; - }, + + return { + xAxis: xAxis, + yAxis: yAxis + }; + } + + +}); + + +Ext.define('Ext.chart.series.Area', { - average: function(field, grouped) { - var me = this; - if (grouped && me.isGrouped()) { - return me.aggregate(me.getAverage, me, true, [field]); - } else { - return me.getAverage(me.data.items, field); + + extend: 'Ext.chart.series.Cartesian', + + alias: 'series.area', + + requires: ['Ext.chart.axis.Axis', 'Ext.draw.Color', 'Ext.fx.Anim'], + + + + type: 'area', + + + stacked: true, + + + style: {}, + + constructor: function(config) { + this.callParent(arguments); + var me = this, + surface = me.chart.surface, + i, l; + Ext.apply(me, config, { + __excludes: [], + highlightCfg: { + lineWidth: 3, + stroke: '#55c', + opacity: 0.8, + color: '#f00' + } + }); + if (me.highlight) { + me.highlightSprite = surface.add({ + type: 'path', + path: ['M', 0, 0], + zIndex: 1000, + opacity: 0.3, + lineWidth: 5, + hidden: true, + stroke: '#444' + }); } + me.group = surface.getGroup(me.seriesId); }, - getAverage: function(records, field) { - var i = 0, - len = records.length, - sum = 0; - - if (records.length > 0) { - for (; i < len; ++i) { - sum += records[i].get(field); + shrink: function(xValues, yValues, size) { + var len = xValues.length, + ratio = Math.floor(len / size), + i, j, + xSum = 0, + yCompLen = this.areas.length, + ySum = [], + xRes = [], + yRes = []; + + for (j = 0; j < yCompLen; ++j) { + ySum[j] = 0; + } + for (i = 0; i < len; ++i) { + xSum += xValues[i]; + for (j = 0; j < yCompLen; ++j) { + ySum[j] += yValues[i][j]; + } + if (i % ratio == 0) { + + xRes.push(xSum/ratio); + for (j = 0; j < yCompLen; ++j) { + ySum[j] /= ratio; + } + yRes.push(ySum); + + xSum = 0; + for (j = 0, ySum = []; j < yCompLen; ++j) { + ySum[j] = 0; + } } - return sum / len; } - return 0; + return { + x: xRes, + y: yRes + }; }, - - aggregate: function(fn, scope, grouped, args) { - args = args || []; - if (grouped && this.isGrouped()) { - var groups = this.getGroups(), - i = 0, - len = groups.length, - out = {}, - group; + + getBounds: function() { + var me = this, + chart = me.chart, + store = chart.getChartStore(), + areas = [].concat(me.yField), + areasLen = areas.length, + xValues = [], + yValues = [], + infinity = Infinity, + minX = infinity, + minY = infinity, + maxX = -infinity, + maxY = -infinity, + math = Math, + mmin = math.min, + mmax = math.max, + bbox, xScale, yScale, xValue, yValue, areaIndex, acumY, ln, sumValues, clipBox, areaElem; + + me.setBBox(); + bbox = me.bbox; - for (; i < len; ++i) { - group = groups[i]; - out[group.name] = fn.apply(scope || this, [group.children].concat(args)); + + if (me.axis) { + axis = chart.axes.get(me.axis); + if (axis) { + out = axis.calcEnds(); + minY = out.from || axis.prevMin; + maxY = mmax(out.to || axis.prevMax, 0); } - return out; - } else { - return fn.apply(scope || this, [this.data.items].concat(args)); } - } -}); + if (me.yField && !Ext.isNumber(minY)) { + axis = Ext.create('Ext.chart.axis.Axis', { + chart: chart, + fields: [].concat(me.yField) + }); + out = axis.calcEnds(); + minY = out.from || axis.prevMin; + maxY = mmax(out.to || axis.prevMax, 0); + } -Ext.define('Ext.data.JsonStore', { - extend: 'Ext.data.Store', - alias: 'store.json', - - - constructor: function(config) { - config = config || {}; + if (!Ext.isNumber(minY)) { + minY = 0; + } + if (!Ext.isNumber(maxY)) { + maxY = 0; + } - Ext.applyIf(config, { - proxy: { - type : 'ajax', - reader: 'json', - writer: 'json' + store.each(function(record, i) { + xValue = record.get(me.xField); + yValue = []; + if (typeof xValue != 'number') { + xValue = i; } - }); - - this.callParent([config]); - } -}); - - -Ext.define('Ext.chart.axis.Time', { - - - - extend: 'Ext.chart.axis.Category', + xValues.push(xValue); + acumY = 0; + for (areaIndex = 0; areaIndex < areasLen; areaIndex++) { + areaElem = record.get(areas[areaIndex]); + if (typeof areaElem == 'number') { + minY = mmin(minY, areaElem); + yValue.push(areaElem); + acumY += areaElem; + } + } + minX = mmin(minX, xValue); + maxX = mmax(maxX, xValue); + maxY = mmax(maxY, acumY); + yValues.push(yValue); + }, me); - alternateClassName: 'Ext.chart.TimeAxis', + xScale = bbox.width / ((maxX - minX) || 1); + yScale = bbox.height / ((maxY - minY) || 1); - alias: 'axis.time', + ln = xValues.length; + if ((ln > bbox.width) && me.areas) { + sumValues = me.shrink(xValues, yValues, bbox.width); + xValues = sumValues.x; + yValues = sumValues.y; + } - requires: ['Ext.data.Store', 'Ext.data.JsonStore'], + return { + bbox: bbox, + minX: minX, + minY: minY, + xValues: xValues, + yValues: yValues, + xScale: xScale, + yScale: yScale, + areasLen: areasLen + }; + }, + getPaths: function() { + var me = this, + chart = me.chart, + store = chart.getChartStore(), + first = true, + bounds = me.getBounds(), + bbox = bounds.bbox, + items = me.items = [], + componentPaths = [], + componentPath, + paths = [], + i, ln, x, y, xValue, yValue, acumY, areaIndex, prevAreaIndex, areaElem, path; - - calculateByLabelSize: true, - - - dateFormat: false, - - - groupBy: 'year,month,day', - - - aggregateOp: 'sum', - - - fromDate: false, - - - toDate: false, - - - step: [Ext.Date.DAY, 1], - - - constrain: false, - - - dateMethods: { - 'year': function(date) { - return date.getFullYear(); - }, - 'month': function(date) { - return date.getMonth() + 1; - }, - 'day': function(date) { - return date.getDate(); - }, - 'hour': function(date) { - return date.getHours(); - }, - 'minute': function(date) { - return date.getMinutes(); - }, - 'second': function(date) { - return date.getSeconds(); - }, - 'millisecond': function(date) { - return date.getMilliseconds(); - } - }, - - - aggregateFn: (function() { - var etype = (function() { - var rgxp = /^\[object\s(.*)\]$/, - toString = Object.prototype.toString; - return function(e) { - return toString.call(e).match(rgxp)[1]; - }; - })(); - return { - 'sum': function(list) { - var i = 0, l = list.length, acum = 0; - if (!list.length || etype(list[0]) != 'Number') { - return list[0]; - } - for (; i < l; i++) { - acum += list[i]; - } - return acum; - }, - 'max': function(list) { - if (!list.length || etype(list[0]) != 'Number') { - return list[0]; + ln = bounds.xValues.length; + + for (i = 0; i < ln; i++) { + xValue = bounds.xValues[i]; + yValue = bounds.yValues[i]; + x = bbox.x + (xValue - bounds.minX) * bounds.xScale; + acumY = 0; + for (areaIndex = 0; areaIndex < bounds.areasLen; areaIndex++) { + + if (me.__excludes[areaIndex]) { + continue; } - return Math.max.apply(Math, list); - }, - 'min': function(list) { - if (!list.length || etype(list[0]) != 'Number') { - return list[0]; + if (!componentPaths[areaIndex]) { + componentPaths[areaIndex] = []; } - return Math.min.apply(Math, list); - }, - 'avg': function(list) { - var i = 0, l = list.length, acum = 0; - if (!list.length || etype(list[0]) != 'Number') { - return list[0]; + areaElem = yValue[areaIndex]; + acumY += areaElem; + y = bbox.y + bbox.height - (acumY - bounds.minY) * bounds.yScale; + if (!paths[areaIndex]) { + paths[areaIndex] = ['M', x, y]; + componentPaths[areaIndex].push(['L', x, y]); + } else { + paths[areaIndex].push('L', x, y); + componentPaths[areaIndex].push(['L', x, y]); } - for (; i < l; i++) { - acum += list[i]; + if (!items[areaIndex]) { + items[areaIndex] = { + pointsUp: [], + pointsDown: [], + series: me + }; } - return acum / l; + items[areaIndex].pointsUp.push([x, y]); } - }; - })(), - - - constrainDates: function() { - var fromDate = Ext.Date.clone(this.fromDate), - toDate = Ext.Date.clone(this.toDate), - step = this.step, - field = this.fields, - store = this.chart.store, - record, recObj, fieldNames = [], - newStore = Ext.create('Ext.data.Store', { - model: store.model - }); - - var getRecordByDate = (function() { - var index = 0, l = store.getCount(); - return function(date) { - var rec, recDate; - for (; index < l; index++) { - rec = store.getAt(index); - recDate = rec.get(field); - if (+recDate > +date) { - return false; - } else if (+recDate == +date) { - return rec; - } - } - return false; - }; - })(); - - if (!this.constrain) { - this.chart.filteredStore = this.chart.store; - return; } - while(+fromDate <= +toDate) { - record = getRecordByDate(fromDate); - recObj = {}; - if (record) { - newStore.add(record.data); - } else { - newStore.model.prototype.fields.each(function(f) { - recObj[f.name] = false; - }); - recObj.date = fromDate; - newStore.add(recObj); - } - fromDate = Ext.Date.add(fromDate, step[0], step[1]); - } - - this.chart.filteredStore = newStore; - }, - - - aggregate: function() { - var aggStore = {}, - aggKeys = [], key, value, - op = this.aggregateOp, - field = this.fields, i, - fields = this.groupBy.split(','), - curField, - recFields = [], - recFieldsLen = 0, - obj, - dates = [], - json = [], - l = fields.length, - dateMethods = this.dateMethods, - aggregateFn = this.aggregateFn, - store = this.chart.filteredStore || this.chart.store; - - store.each(function(rec) { - - if (!recFields.length) { - rec.fields.each(function(f) { - recFields.push(f.name); - }); - recFieldsLen = recFields.length; - } - - value = rec.get(field); + + for (areaIndex = 0; areaIndex < bounds.areasLen; areaIndex++) { - for (i = 0; i < l; i++) { - if (i == 0) { - key = String(dateMethods[fields[i]](value)); - } else { - key += '||' + dateMethods[fields[i]](value); - } + if (me.__excludes[areaIndex]) { + continue; } + path = paths[areaIndex]; - if (key in aggStore) { - obj = aggStore[key]; - } else { - obj = aggStore[key] = {}; - aggKeys.push(key); - dates.push(value); + if (areaIndex == 0 || first) { + first = false; + path.push('L', x, bbox.y + bbox.height, + 'L', bbox.x, bbox.y + bbox.height, + 'Z'); } - for (i = 0; i < recFieldsLen; i++) { - curField = recFields[i]; - if (!obj[curField]) { - obj[curField] = []; - } - if (rec.get(curField) !== undefined) { - obj[curField].push(rec.get(curField)); + else { + componentPath = componentPaths[prevAreaIndex]; + componentPath.reverse(); + path.push('L', x, componentPath[0][2]); + for (i = 0; i < ln; i++) { + path.push(componentPath[i][0], + componentPath[i][1], + componentPath[i][2]); + items[areaIndex].pointsDown[ln -i -1] = [componentPath[i][1], componentPath[i][2]]; } + path.push('L', bbox.x, path[2], 'Z'); } - }); - - for (key in aggStore) { - obj = aggStore[key]; - for (i = 0; i < recFieldsLen; i++) { - curField = recFields[i]; - obj[curField] = aggregateFn[op](obj[curField]); - } - json.push(obj); + prevAreaIndex = areaIndex; } - this.chart.substore = Ext.create('Ext.data.JsonStore', { - fields: recFields, - data: json - }); - - this.dates = dates; - }, - - - setLabels: function() { - var store = this.chart.substore, - fields = this.fields, - format = this.dateFormat, - labels, i, dates = this.dates, - formatFn = Ext.Date.format; - this.labels = labels = []; - store.each(function(record, i) { - if (!format) { - labels.push(record.get(fields)); - } else { - labels.push(formatFn(dates[i], format)); - } - }, this); - }, - - processView: function() { - - if (this.constrain) { - this.constrainDates(); - this.aggregate(); - this.chart.substore = this.chart.filteredStore; - } else { - this.aggregate(); - } - }, - - - applyData: function() { - this.setLabels(); - var count = this.chart.substore.getCount(); - return { - from: 0, - to: count, - steps: count - 1, - step: 1 - }; - } - }); - - - -Ext.define('Ext.chart.series.Series', { - - - - mixins: { - observable: 'Ext.util.Observable', - labels: 'Ext.chart.Label', - highlights: 'Ext.chart.Highlight', - tips: 'Ext.chart.Tip', - callouts: 'Ext.chart.Callout' + return { + paths: paths, + areasLen: bounds.areasLen + }; }, + drawSeries: function() { + var me = this, + chart = me.chart, + store = chart.getChartStore(), + surface = chart.surface, + animate = chart.animate, + group = me.group, + endLineStyle = Ext.apply(me.seriesStyle, me.style), + colorArrayStyle = me.colorArrayStyle, + colorArrayLength = colorArrayStyle && colorArrayStyle.length || 0, + areaIndex, areaElem, paths, path, rendererAttributes; - - - + me.unHighlightItem(); + me.cleanHighlights(); - - type: null, + if (!store || !store.getCount()) { + return; + } - - title: null, + paths = me.getPaths(); - - showInLegend: true, + if (!me.areas) { + me.areas = []; + } - - renderer: function(sprite, record, attributes, index, store) { - return attributes; + for (areaIndex = 0; areaIndex < paths.areasLen; areaIndex++) { + + if (me.__excludes[areaIndex]) { + continue; + } + if (!me.areas[areaIndex]) { + me.items[areaIndex].sprite = me.areas[areaIndex] = surface.add(Ext.apply({}, { + type: 'path', + group: group, + + path: paths.paths[areaIndex], + stroke: endLineStyle.stroke || colorArrayStyle[areaIndex % colorArrayLength], + fill: colorArrayStyle[areaIndex % colorArrayLength] + }, endLineStyle || {})); + } + areaElem = me.areas[areaIndex]; + path = paths.paths[areaIndex]; + if (animate) { + + rendererAttributes = me.renderer(areaElem, false, { + path: path, + + fill: colorArrayStyle[areaIndex % colorArrayLength], + stroke: endLineStyle.stroke || colorArrayStyle[areaIndex % colorArrayLength] + }, areaIndex, store); + + me.animation = me.onAnimate(areaElem, { + to: rendererAttributes + }); + } else { + rendererAttributes = me.renderer(areaElem, false, { + path: path, + + hidden: false, + fill: colorArrayStyle[areaIndex % colorArrayLength], + stroke: endLineStyle.stroke || colorArrayStyle[areaIndex % colorArrayLength] + }, areaIndex, store); + me.areas[areaIndex].setAttributes(rendererAttributes, true); + } + } + me.renderLabels(); + me.renderCallouts(); }, - shadowAttributes: null, - - //@private triggerdrawlistener flag - - triggerAfterDraw: false, + onAnimate: function(sprite, attr) { + sprite.show(); + return this.callParent(arguments); + }, - - constructor: function(config) { - var me = this; - if (config) { - Ext.apply(me, config); - } - - me.shadowGroups = []; - - me.mixins.labels.constructor.call(me, config); - me.mixins.highlights.constructor.call(me, config); - me.mixins.tips.constructor.call(me, config); - me.mixins.callouts.constructor.call(me, config); - - me.addEvents({ - scope: me, - itemmouseover: true, - itemmouseout: true, - itemmousedown: true, - itemmouseup: true, - mouseleave: true, - afterdraw: true, - - - titlechange: true - }); - - me.mixins.observable.constructor.call(me, config); + onCreateLabel: function(storeItem, item, i, display) { + var me = this, + group = me.labelsGroup, + config = me.label, + bbox = me.bbox, + endLabelStyle = Ext.apply(config, me.seriesLabelStyle); - me.on({ - scope: me, - itemmouseover: me.onItemMouseOver, - itemmouseout: me.onItemMouseOut, - mouseleave: me.onMouseLeave - }); + return me.chart.surface.add(Ext.apply({ + 'type': 'text', + 'text-anchor': 'middle', + 'group': group, + 'x': item.point[0], + 'y': bbox.y + bbox.height / 2 + }, endLabelStyle || {})); }, - setBBox: function(noGutter) { + onPlaceLabel: function(label, storeItem, item, i, display, animate, index) { var me = this, chart = me.chart, - chartBBox = chart.chartBBox, - gutterX = noGutter ? 0 : chart.maxGutter[0], - gutterY = noGutter ? 0 : chart.maxGutter[1], - clipBox, bbox; + resizing = chart.resizing, + config = me.label, + format = config.renderer, + field = config.field, + bbox = me.bbox, + x = item.point[0], + y = item.point[1], + bb, width, height; - clipBox = { - x: chartBBox.x, - y: chartBBox.y, - width: chartBBox.width, - height: chartBBox.height - }; - me.clipBox = clipBox; + label.setAttributes({ + text: format(storeItem.get(field[index])), + hidden: true + }, true); - bbox = { - x: (clipBox.x + gutterX) - (chart.zoom.x * chart.zoom.width), - y: (clipBox.y + gutterY) - (chart.zoom.y * chart.zoom.height), - width: (clipBox.width - (gutterX * 2)) * chart.zoom.width, - height: (clipBox.height - (gutterY * 2)) * chart.zoom.height - }; - me.bbox = bbox; - }, + bb = label.getBBox(); + width = bb.width / 2; + height = bb.height / 2; - - onAnimate: function(sprite, attr) { - var me = this; - sprite.stopAnimation(); - if (me.triggerAfterDraw) { - return sprite.animate(Ext.applyIf(attr, me.chart.animate)); + x = x - width < bbox.x? bbox.x + width : x; + x = (x + width > bbox.x + bbox.width) ? (x - (x + width - bbox.x - bbox.width)) : x; + y = y - height < bbox.y? bbox.y + height : y; + y = (y + height > bbox.y + bbox.height) ? (y - (y + height - bbox.y - bbox.height)) : y; + + if (me.chart.animate && !me.chart.resizing) { + label.show(true); + me.onAnimate(label, { + to: { + x: x, + y: y + } + }); } else { - me.triggerAfterDraw = true; - return sprite.animate(Ext.apply(Ext.applyIf(attr, me.chart.animate), { - listeners: { - 'afteranimate': function() { - me.triggerAfterDraw = false; - me.fireEvent('afterrender'); - } - } - })); + label.setAttributes({ + x: x, + y: y + }, true); + if (resizing) { + me.animation.on('afteranimate', function() { + label.show(true); + }); + } else { + label.show(true); + } } }, - - - getGutters: function() { - return [0, 0]; - }, - onItemMouseOver: function(item) { - var me = this; - if (item.series === me) { - if (me.highlight) { - me.highlightItem(item); - } - if (me.tooltip) { - me.showTip(item); - } + onPlaceCallout : function(callout, storeItem, item, i, display, animate, index) { + var me = this, + chart = me.chart, + surface = chart.surface, + resizing = chart.resizing, + config = me.callouts, + items = me.items, + prev = (i == 0) ? false : items[i -1].point, + next = (i == items.length -1) ? false : items[i +1].point, + cur = item.point, + dir, norm, normal, a, aprev, anext, + bbox = callout.label.getBBox(), + offsetFromViz = 30, + offsetToSide = 10, + offsetBox = 3, + boxx, boxy, boxw, boxh, + p, clipRect = me.clipRect, + x, y; + + + if (!prev) { + prev = cur; + } + if (!next) { + next = cur; } - }, + a = (next[1] - prev[1]) / (next[0] - prev[0]); + aprev = (cur[1] - prev[1]) / (cur[0] - prev[0]); + anext = (next[1] - cur[1]) / (next[0] - cur[0]); - - onItemMouseOut: function(item) { - var me = this; - if (item.series === me) { - me.unHighlightItem(); - if (me.tooltip) { - me.hideTip(item); - } - } - }, + norm = Math.sqrt(1 + a * a); + dir = [1 / norm, a / norm]; + normal = [-dir[1], dir[0]]; - - onMouseLeave: function() { - var me = this; - me.unHighlightItem(); - if (me.tooltip) { - me.hideTip(); + + if (aprev > 0 && anext < 0 && normal[1] < 0 || aprev < 0 && anext > 0 && normal[1] > 0) { + normal[0] *= -1; + normal[1] *= -1; + } else if (Math.abs(aprev) < Math.abs(anext) && normal[0] < 0 || Math.abs(aprev) > Math.abs(anext) && normal[0] > 0) { + normal[0] *= -1; + normal[1] *= -1; } - }, - - getItemForPoint: function(x, y) { - if (!this.items || !this.items.length || this.seriesIsHidden) { - return null; - } - var me = this, - items = me.items, - bbox = me.bbox, - item, i, ln; + x = cur[0] + normal[0] * offsetFromViz; + y = cur[1] + normal[1] * offsetFromViz; + - if (!Ext.draw.Draw.withinBox(x, y, bbox)) { - return null; + boxx = x + (normal[0] > 0? 0 : -(bbox.width + 2 * offsetBox)); + boxy = y - bbox.height /2 - offsetBox; + boxw = bbox.width + 2 * offsetBox; + boxh = bbox.height + 2 * offsetBox; + + + + if (boxx < clipRect[0] || (boxx + boxw) > (clipRect[0] + clipRect[2])) { + normal[0] *= -1; } - for (i = 0, ln = items.length; i < ln; i++) { - if (items[i] && this.isItemInPoint(x, y, items[i], i)) { - return items[i]; - } + if (boxy < clipRect[1] || (boxy + boxh) > (clipRect[1] + clipRect[3])) { + normal[1] *= -1; } - - return null; - }, - - isItemInPoint: function(x, y, item, i) { - return false; - }, - - hideAll: function() { - var me = this, - items = me.items, - item, len, i, sprite; + + x = cur[0] + normal[0] * offsetFromViz; + y = cur[1] + normal[1] * offsetFromViz; - me.seriesIsHidden = true; - me._prevShowMarkers = me.showMarkers; + + boxx = x + (normal[0] > 0? 0 : -(bbox.width + 2 * offsetBox)); + boxy = y - bbox.height /2 - offsetBox; + boxw = bbox.width + 2 * offsetBox; + boxh = bbox.height + 2 * offsetBox; - me.showMarkers = false; - me.hideLabels(0); + callout.lines.setAttributes({ + path: ["M", cur[0], cur[1], "L", x, y, "Z"] + }, true); - for (i = 0, len = items.length; i < len; i++) { - item = items[i]; - sprite = item.sprite; - if (sprite) { - sprite.setAttributes({ - hidden: true - }, true); - } + callout.box.setAttributes({ + x: boxx, + y: boxy, + width: boxw, + height: boxh + }, true); + + callout.label.setAttributes({ + x: x + (normal[0] > 0? offsetBox : -(bbox.width + offsetBox)), + y: y + }, true); + for (p in callout) { + callout[p].show(true); } }, - - showAll: function() { + isItemInPoint: function(x, y, item, i) { var me = this, - prevAnimate = me.chart.animate; - me.chart.animate = false; - me.seriesIsHidden = false; - me.showMarkers = me._prevShowMarkers; - me.drawSeries(); - me.chart.animate = prevAnimate; + pointsUp = item.pointsUp, + pointsDown = item.pointsDown, + abs = Math.abs, + dist = Infinity, p, pln, point; + + for (p = 0, pln = pointsUp.length; p < pln; p++) { + point = [pointsUp[p][0], pointsUp[p][1]]; + if (dist > abs(x - point[0])) { + dist = abs(x - point[0]); + } else { + point = pointsUp[p -1]; + if (y >= point[1] && (!pointsDown.length || y <= (pointsDown[p -1][1]))) { + item.storeIndex = p -1; + item.storeField = me.yField[i]; + item.storeItem = me.chart.store.getAt(p -1); + item._points = pointsDown.length? [point, pointsDown[p -1]] : [point]; + return true; + } else { + break; + } + } + } + return false; }, + - - getLegendColor: function(index) { - var me = this, fill, stroke; - if (me.seriesStyle) { - fill = me.seriesStyle.fill; - stroke = me.seriesStyle.stroke; - if (fill && fill != 'none') { - return fill; + highlightSeries: function() { + var area, to, fillColor; + if (this._index !== undefined) { + area = this.areas[this._index]; + if (area.__highlightAnim) { + area.__highlightAnim.paused = true; + } + area.__highlighted = true; + area.__prevOpacity = area.__prevOpacity || area.attr.opacity || 1; + area.__prevFill = area.__prevFill || area.attr.fill; + area.__prevLineWidth = area.__prevLineWidth || area.attr.lineWidth; + fillColor = Ext.draw.Color.fromString(area.__prevFill); + to = { + lineWidth: (area.__prevLineWidth || 0) + 2 + }; + if (fillColor) { + to.fill = fillColor.getLighter(0.2).toString(); + } + else { + to.opacity = Math.max(area.__prevOpacity - 0.3, 0); + } + if (this.chart.animate) { + area.__highlightAnim = Ext.create('Ext.fx.Anim', Ext.apply({ + target: area, + to: to + }, this.chart.animate)); + } + else { + area.setAttributes(to, true); } - return stroke; } - return '#000'; }, + - - visibleInLegend: function(index){ - var excludes = this.__excludes; - if (excludes) { - return !excludes[index]; + unHighlightSeries: function() { + var area; + if (this._index !== undefined) { + area = this.areas[this._index]; + if (area.__highlightAnim) { + area.__highlightAnim.paused = true; + } + if (area.__highlighted) { + area.__highlighted = false; + area.__highlightAnim = Ext.create('Ext.fx.Anim', { + target: area, + to: { + fill: area.__prevFill, + opacity: area.__prevOpacity, + lineWidth: area.__prevLineWidth + } + }); + } } - return !this.seriesIsHidden; }, - setTitle: function(index, title) { + highlightItem: function(item) { var me = this, - oldTitle = me.title; - - if (Ext.isString(index)) { - title = index; - index = 0; - } - - if (Ext.isArray(oldTitle)) { - oldTitle[index] = title; - } else { - me.title = title; + points, path; + if (!item) { + this.highlightSeries(); + return; } - - me.fireEvent('titlechange', title, index); - } -}); - - -Ext.define('Ext.chart.series.Cartesian', { + points = item._points; + path = points.length == 2? ['M', points[0][0], points[0][1], 'L', points[1][0], points[1][1]] + : ['M', points[0][0], points[0][1], 'L', points[0][0], me.bbox.y + me.bbox.height]; + me.highlightSprite.setAttributes({ + path: path, + hidden: false + }, true); + }, + unHighlightItem: function(item) { + if (!item) { + this.unHighlightSeries(); + } - extend: 'Ext.chart.series.Series', - - alternateClassName: ['Ext.chart.CartesianSeries', 'Ext.chart.CartesianChart'], - - + if (this.highlightSprite) { + this.highlightSprite.hide(true); + } + }, - xField: null, + hideAll: function() { + if (!isNaN(this._index)) { + this.__excludes[this._index] = true; + this.areas[this._index].hide(true); + this.drawSeries(); + } + }, - yField: null, + showAll: function() { + if (!isNaN(this._index)) { + this.__excludes[this._index] = false; + this.areas[this._index].show(true); + this.drawSeries(); + } + }, - axis: 'left' + getLegendColor: function(index) { + var me = this; + return me.colorArrayStyle[index % me.colorArrayStyle.length]; + } }); - Ext.define('Ext.chart.series.Area', { extend: 'Ext.chart.series.Cartesian', - + alias: 'series.area', requires: ['Ext.chart.axis.Axis', 'Ext.draw.Color', 'Ext.fx.Anim'], @@ -45905,7 +47553,7 @@ Ext.define('Ext.chart.series.Area', { getBounds: function() { var me = this, chart = me.chart, - store = chart.substore || chart.store, + store = chart.getChartStore(), areas = [].concat(me.yField), areasLen = areas.length, xValues = [], @@ -45972,8 +47620,8 @@ Ext.define('Ext.chart.series.Area', { yValues.push(yValue); }, me); - xScale = bbox.width / (maxX - minX); - yScale = bbox.height / (maxY - minY); + xScale = bbox.width / ((maxX - minX) || 1); + yScale = bbox.height / ((maxY - minY) || 1); ln = xValues.length; if ((ln > bbox.width) && me.areas) { @@ -45998,7 +47646,7 @@ Ext.define('Ext.chart.series.Area', { getPaths: function() { var me = this, chart = me.chart, - store = chart.substore || chart.store, + store = chart.getChartStore(), first = true, bounds = me.getBounds(), bbox = bounds.bbox, @@ -46043,7 +47691,7 @@ Ext.define('Ext.chart.series.Area', { items[areaIndex].pointsUp.push([x, y]); } } - + for (areaIndex = 0; areaIndex < bounds.areasLen; areaIndex++) { @@ -46083,7 +47731,7 @@ Ext.define('Ext.chart.series.Area', { drawSeries: function() { var me = this, chart = me.chart, - store = chart.substore || chart.store, + store = chart.getChartStore(), surface = chart.surface, animate = chart.animate, group = me.group, @@ -46098,7 +47746,7 @@ Ext.define('Ext.chart.series.Area', { if (!store || !store.getCount()) { return; } - + paths = me.getPaths(); if (!me.areas) { @@ -46124,7 +47772,7 @@ Ext.define('Ext.chart.series.Area', { path = paths.paths[areaIndex]; if (animate) { - rendererAttributes = me.renderer(areaElem, false, { + rendererAttributes = me.renderer(areaElem, false, { path: path, fill: colorArrayStyle[areaIndex % colorArrayLength], @@ -46135,7 +47783,7 @@ Ext.define('Ext.chart.series.Area', { to: rendererAttributes }); } else { - rendererAttributes = me.renderer(areaElem, false, { + rendererAttributes = me.renderer(areaElem, false, { path: path, hidden: false, @@ -46184,16 +47832,16 @@ Ext.define('Ext.chart.series.Area', { x = item.point[0], y = item.point[1], bb, width, height; - + label.setAttributes({ text: format(storeItem.get(field[index])), hidden: true }, true); - + bb = label.getBBox(); width = bb.width / 2; height = bb.height / 2; - + x = x - width < bbox.x? bbox.x + width : x; x = (x + width > bbox.x + bbox.width) ? (x - (x + width - bbox.x - bbox.width)) : x; y = y - height < bbox.y? bbox.y + height : y; @@ -46252,11 +47900,11 @@ Ext.define('Ext.chart.series.Area', { a = (next[1] - prev[1]) / (next[0] - prev[0]); aprev = (cur[1] - prev[1]) / (cur[0] - prev[0]); anext = (next[1] - cur[1]) / (next[0] - cur[0]); - + norm = Math.sqrt(1 + a * a); dir = [1 / norm, a / norm]; normal = [-dir[1], dir[0]]; - + if (aprev > 0 && anext < 0 && normal[1] < 0 || aprev < 0 && anext > 0 && normal[1] > 0) { normal[0] *= -1; @@ -46269,13 +47917,13 @@ Ext.define('Ext.chart.series.Area', { x = cur[0] + normal[0] * offsetFromViz; y = cur[1] + normal[1] * offsetFromViz; - + boxx = x + (normal[0] > 0? 0 : -(bbox.width + 2 * offsetBox)); boxy = y - bbox.height /2 - offsetBox; boxw = bbox.width + 2 * offsetBox; boxh = bbox.height + 2 * offsetBox; - + if (boxx < clipRect[0] || (boxx + boxw) > (clipRect[0] + clipRect[2])) { @@ -46288,13 +47936,13 @@ Ext.define('Ext.chart.series.Area', { x = cur[0] + normal[0] * offsetFromViz; y = cur[1] + normal[1] * offsetFromViz; - + boxx = x + (normal[0] > 0? 0 : -(bbox.width + 2 * offsetBox)); boxy = y - bbox.height /2 - offsetBox; boxw = bbox.width + 2 * offsetBox; boxh = bbox.height + 2 * offsetBox; - + callout.lines.setAttributes({ path: ["M", cur[0], cur[1], "L", x, y, "Z"] @@ -46315,14 +47963,14 @@ Ext.define('Ext.chart.series.Area', { callout[p].show(true); } }, - + isItemInPoint: function(x, y, item, i) { var me = this, pointsUp = item.pointsUp, pointsDown = item.pointsDown, abs = Math.abs, dist = Infinity, p, pln, point; - + for (p = 0, pln = pointsUp.length; p < pln; p++) { point = [pointsUp[p][0], pointsUp[p][1]]; if (dist > abs(x - point[0])) { @@ -46470,10 +48118,10 @@ Ext.define('Ext.chart.series.Bar', { alias: 'series.bar', column: false, - + style: {}, - + gutter: 38.2, @@ -46499,7 +48147,7 @@ Ext.define('Ext.chart.series.Bar', { opacity: 0.8, color: '#f00' }, - + shadowAttributes: [{ "stroke-width": 6, "stroke-opacity": 0.05, @@ -46537,11 +48185,11 @@ Ext.define('Ext.chart.series.Bar', { getBarGirth: function() { var me = this, - store = me.chart.store, + store = me.chart.getChartStore(), column = me.column, ln = store.getCount(), gutter = me.gutter / 100; - + return (me.chart.chartBBox[column ? 'width' : 'height'] - me[column ? 'xPadding' : 'yPadding'] * 2) / (ln * (gutter + 1) - gutter); }, @@ -46557,7 +48205,7 @@ Ext.define('Ext.chart.series.Bar', { getBounds: function() { var me = this, chart = me.chart, - store = chart.substore || chart.store, + store = chart.getChartStore(), bars = [].concat(me.yField), barsLen = bars.length, groupBarsLen = barsLen, @@ -46589,8 +48237,8 @@ Ext.define('Ext.chart.series.Bar', { axis = chart.axes.get(me.axis); if (axis) { out = axis.calcEnds(); - minY = out.from || axis.prevMin; - maxY = mmax(out.to || axis.prevMax, 0); + minY = out.from; + maxY = out.to; } } @@ -46600,8 +48248,8 @@ Ext.define('Ext.chart.series.Bar', { fields: [].concat(me.yField) }); out = axis.calcEnds(); - minY = out.from || axis.prevMin; - maxY = mmax(out.to || axis.prevMax, 0); + minY = out.from; + maxY = out.to; } if (!Ext.isNumber(minY)) { @@ -46658,7 +48306,7 @@ Ext.define('Ext.chart.series.Bar', { getPaths: function() { var me = this, chart = me.chart, - store = chart.substore || chart.store, + store = chart.getChartStore(), bounds = me.bounds = me.getBounds(), items = me.items = [], gutter = me.gutter / 100, @@ -46689,14 +48337,14 @@ Ext.define('Ext.chart.series.Bar', { top = bounds.zero; totalDim = 0; totalNegDim = 0; - hasShadow = false; + hasShadow = false; for (j = 0, counter = 0; j < barsLen; j++) { if (me.__excludes && me.__excludes[j]) { continue; } yValue = record.get(bounds.bars[j]); - height = Math.round((yValue - ((bounds.minY < 0) ? 0 : bounds.minY)) * bounds.scale); + height = Math.round((yValue - mmax(bounds.minY, 0)) * bounds.scale); barAttr = { fill: colors[(barsLen > 1 ? j : 0) % colorLength] }; @@ -46802,7 +48450,7 @@ Ext.define('Ext.chart.series.Bar', { shadowGroups = me.shadowGroups, shadowAttributes = me.shadowAttributes, shadowGroupsLn = shadowGroups.length, - store = chart.substore || chart.store, + store = chart.getChartStore(), column = me.column, items = me.items, shadows = [], @@ -46858,7 +48506,7 @@ Ext.define('Ext.chart.series.Bar', { drawSeries: function() { var me = this, chart = me.chart, - store = chart.substore || chart.store, + store = chart.getChartStore(), surface = chart.surface, animate = chart.animate, stacked = me.stacked, @@ -46870,11 +48518,11 @@ Ext.define('Ext.chart.series.Bar', { seriesStyle = me.seriesStyle, items, ln, i, j, baseAttrs, sprite, rendererAttributes, shadowIndex, shadowGroup, bounds, endSeriesStyle, barAttr, attrs, anim; - + if (!store || !store.getCount()) { return; } - + delete seriesStyle.fill; endSeriesStyle = Ext.apply(seriesStyle, this.style); @@ -46948,7 +48596,7 @@ Ext.define('Ext.chart.series.Bar', { } me.renderLabels(); }, - + onCreateLabel: function(storeItem, item, i, display) { var me = this, @@ -46962,7 +48610,7 @@ Ext.define('Ext.chart.series.Bar', { group: group }, endLabelStyle || {})); }, - + onPlaceLabel: function(label, storeItem, item, i, display, animate, j, index) { @@ -46998,6 +48646,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)) { @@ -47006,6 +48655,7 @@ Ext.define('Ext.chart.series.Bar', { } else { if (height + offsetY > attr.height) { display = outside; + label.isOutside = true; } } x = attr.x + groupBarWidth / 2; @@ -47023,6 +48673,7 @@ Ext.define('Ext.chart.series.Bar', { else { if (width + offsetX > attr.width) { display = outside; + label.isOutside = true; } } x = display == insideStart ? @@ -47111,14 +48762,14 @@ Ext.define('Ext.chart.series.Bar', { sprite.show(); return this.callParent(arguments); }, - + isItemInPoint: function(x, y, item) { var bbox = item.sprite.getBBox(); return bbox.x <= x && bbox.y <= y && (bbox.x + bbox.width) >= x && (bbox.y + bbox.height) >= y; }, - + hideAll: function() { var axes = this.chart.axes; @@ -47148,11 +48799,32 @@ Ext.define('Ext.chart.series.Bar', { }); } }, - + 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(); } }); @@ -47260,7 +48932,7 @@ Ext.define('Ext.chart.series.Gauge', { initialize: function() { var me = this, - store = me.chart.substore || me.chart.store; + store = me.chart.getChartStore(); me.yField = []; if (me.label.field) { @@ -47359,7 +49031,7 @@ Ext.define('Ext.chart.series.Gauge', { drawSeries: function() { var me = this, chart = me.chart, - store = chart.substore || chart.store, + store = chart.getChartStore(), group = me.group, animate = me.chart.animate, axis = me.chart.axes.get(0), @@ -47586,14 +49258,14 @@ Ext.define('Ext.chart.series.Line', { type: 'line', - + alias: 'series.line', - + selectionTolerance: 20, - + showMarkers: true, @@ -47602,11 +49274,14 @@ Ext.define('Ext.chart.series.Line', { style: {}, - + smooth: false, + defaultSmoothness: 3, + + fill: false, constructor: function(config) { @@ -47650,12 +49325,12 @@ Ext.define('Ext.chart.series.Line', { me.markerGroup = surface.getGroup(me.seriesId + '-markers'); } if (shadow) { - for (i = 0, l = this.shadowAttributes.length; i < l; i++) { + for (i = 0, l = me.shadowAttributes.length; i < l; i++) { me.shadowGroups.push(surface.getGroup(me.seriesId + '-shadows' + i)); } } }, - + shrink: function(xValues, yValues, size) { @@ -47666,7 +49341,7 @@ Ext.define('Ext.chart.series.Line', { ySum = 0, xRes = [xValues[0]], yRes = [yValues[0]]; - + for (; i < len; ++i) { xSum += xValues[i] || 0; ySum += yValues[i] || 0; @@ -47687,56 +49362,68 @@ Ext.define('Ext.chart.series.Line', { drawSeries: function() { var me = this, chart = me.chart, - store = chart.substore || chart.store, - surface = chart.surface, - chartBBox = chart.chartBBox, + chartAxes = chart.axes, + store = chart.getChartStore(), + storeCount = store.getCount(), + surface = me.chart.surface, bbox = {}, group = me.group, - gutterX = chart.maxGutter[0], - gutterY = chart.maxGutter[1], showMarkers = me.showMarkers, 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"], + renderPath = ["M"], + smoothPath = ["M"], markerIndex = chart.markerIndex, axes = [].concat(me.axis), - shadowGroup, shadowBarAttr, xValues = [], + xValueMap = {}, yValues = [], - numericAxis = true, - axisCount = 0, + yValueMap = {}, onbreak = false, + storeIndices = [], markerStyle = me.markerStyle, - seriesStyle = me.seriesStyle, - seriesLabelStyle = me.seriesLabelStyle, + seriesStyle = me.style, colorArrayStyle = me.colorArrayStyle, colorArrayLength = colorArrayStyle && colorArrayStyle.length || 0, - posHash = { - 'left': 'right', - 'right': 'left', - 'top': 'bottom', - 'bottom': 'top' - }, - 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, + isNumber = Ext.isNumber, + seriesIdx = me.seriesIdx, + boundAxes = me.getAxesForXAndYFields(), + boundXAxis = boundAxes.xAxis, + boundYAxis = boundAxes.yAxis, + shadows, shadow, shindex, fromPath, fill, fillPath, rendererAttributes, + x, y, prevX, prevY, firstX, 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; - - - if (!store || !store.getCount()) { + endLineStyle, type, count, items; + + if (me.fireEvent('beforedraw', me) === false) { return; } + + if (!storeCount || me.seriesIsHidden) { + items = this.items; + if (items) { + for (i = 0, ln = items.length; i < ln; ++i) { + if (items[i].sprite) { + items[i].sprite.hide(true); + } + } + } + return; + } + - endMarkerStyle = Ext.apply(markerStyle, me.markerConfig); + endMarkerStyle = Ext.apply(markerStyle || {}, me.markerConfig); type = endMarkerStyle.type; delete endMarkerStyle.type; - endLineStyle = Ext.apply(seriesStyle, me.style); + endLineStyle = seriesStyle; if (!endLineStyle['stroke-width']) { @@ -47760,129 +49447,97 @@ Ext.define('Ext.chart.series.Line', { }, true); } } - + me.unHighlightItem(); me.cleanHighlights(); me.setBBox(); bbox = me.bbox; - me.clipRect = [bbox.x, bbox.y, bbox.width, bbox.height]; - - chart.axes.each(function(axis) { - - - - - if (axis.position == me.axis || axis.position != posHash[me.axis]) { - axisCount++; - if (axis.type != 'Numeric') { - numericAxis = false; - return; + for (i = 0, ln = axes.length; i < ln; i++) { + axis = chartAxes.get(axes[i]); + if (axis) { + ends = axis.calcEnds(); + if (axis.position == 'top' || axis.position == 'bottom') { + minX = ends.from; + maxX = ends.to; } - numericAxis = (numericAxis && axis.type == 'Numeric'); - if (axis) { - ends = axis.calcEnds(); - if (axis.position == 'top' || axis.position == 'bottom') { - minX = ends.from; - maxX = ends.to; - } - else { - minY = ends.from; - maxY = ends.to; - } + else { + minY = ends.from; + maxY = ends.to; } } - }); - - - - - if (numericAxis && axisCount == 1) { - numericAxis = false; } - - if (me.xField && !Ext.isNumber(minX)) { - if (me.axis == 'bottom' || me.axis == 'top') { - axis = Ext.create('Ext.chart.axis.Axis', { - chart: chart, - fields: [].concat(me.xField) - }).calcEnds(); - minX = axis.from; - maxX = axis.to; - } else if (numericAxis) { - axis = Ext.create('Ext.chart.axis.Axis', { - chart: chart, - fields: [].concat(me.xField), - forceMinMax: true - }).calcEnds(); - minX = axis.from; - maxX = axis.to; - } + if (me.xField && !isNumber(minX) && + (boundXAxis == 'bottom' || boundXAxis == 'top') && + !chartAxes.get(boundXAxis)) { + axis = Ext.create('Ext.chart.axis.Axis', { + chart: chart, + fields: [].concat(me.xField) + }).calcEnds(); + minX = axis.from; + maxX = axis.to; } - - if (me.yField && !Ext.isNumber(minY)) { - if (me.axis == 'right' || me.axis == 'left') { - axis = Ext.create('Ext.chart.axis.Axis', { - chart: chart, - fields: [].concat(me.yField) - }).calcEnds(); - minY = axis.from; - maxY = axis.to; - } else if (numericAxis) { - axis = Ext.create('Ext.chart.axis.Axis', { - chart: chart, - fields: [].concat(me.yField), - forceMinMax: true - }).calcEnds(); - minY = axis.from; - maxY = axis.to; - } + if (me.yField && !isNumber(minY) && + (boundYAxis == 'right' || boundYAxis == 'left') && + !chartAxes.get(boundYAxis)) { + axis = Ext.create('Ext.chart.axis.Axis', { + chart: chart, + fields: [].concat(me.yField) + }).calcEnds(); + minY = axis.from; + maxY = axis.to; } - if (isNaN(minX)) { minX = 0; - xScale = bbox.width / (store.getCount() - 1); + xScale = bbox.width / ((storeCount - 1) || 1); } else { - xScale = bbox.width / (maxX - minX); + xScale = bbox.width / ((maxX - minX) || (storeCount -1) || 1); } if (isNaN(minY)) { minY = 0; - yScale = bbox.height / (store.getCount() - 1); - } + yScale = bbox.height / ((storeCount - 1) || 1); + } else { - yScale = bbox.height / (maxY - minY); + yScale = bbox.height / ((maxY - minY) || (storeCount - 1) || 1); } + - store.each(function(record, i) { + me.eachRecord(function(record, i) { xValue = record.get(me.xField); + + + if (typeof xValue == 'string' || typeof xValue == 'object' && !Ext.isDate(xValue) + + || boundXAxis && chartAxes.get(boundXAxis) && chartAxes.get(boundXAxis).type == 'Category') { + if (xValue in xValueMap) { + xValue = xValueMap[xValue]; + } else { + xValue = xValueMap[xValue] = i; + } + } + + yValue = record.get(me.yField); if (typeof yValue == 'undefined' || (typeof yValue == 'string' && !yValue)) { - if (Ext.isDefined(Ext.global.console)) { - Ext.global.console.warn("[Ext.chart.series.Line] Skipping a store element with an undefined value at ", record, xValue, yValue); - } return; } - if (typeof xValue == 'string' || typeof xValue == 'object' - - || (me.axis != 'top' && me.axis != 'bottom' && !numericAxis)) { - xValue = i; - } - if (typeof yValue == 'string' || typeof yValue == 'object' + if (typeof yValue == 'string' || typeof yValue == 'object' && !Ext.isDate(yValue) - || (me.axis != 'left' && me.axis != 'right' && !numericAxis)) { + || boundYAxis && chartAxes.get(boundYAxis) && chartAxes.get(boundYAxis).type == 'Category') { yValue = i; } + storeIndices.push(i); xValues.push(xValue); yValues.push(yValue); - }, me); + }); ln = xValues.length; if (ln > bbox.width) { @@ -47911,11 +49566,12 @@ Ext.define('Ext.chart.series.Line', { if (onbreak) { onbreak = false; path.push('M'); - } + } path = path.concat([x, y]); } if ((typeof firstY == 'undefined') && (typeof y != 'undefined')) { firstY = y; + firstX = x; } if (!me.line || chart.resizing) { @@ -47950,15 +49606,16 @@ Ext.define('Ext.chart.series.Line', { group: [group, markerGroup], x: 0, y: 0, translate: { - x: prevX || x, + x: +(prevX || x), y: prevY || (bbox.y + bbox.height / 2) }, - value: '"' + xValue + ', ' + yValue + '"' + value: '"' + xValue + ', ' + yValue + '"', + zIndex: 4000 }, endMarkerStyle)); marker._to = { translate: { - x: x, - y: y + x: +x, + y: +y } }; } else { @@ -47969,7 +49626,8 @@ Ext.define('Ext.chart.series.Line', { }, true); marker._to = { translate: { - x: x, y: y + x: +x, + y: +y } }; } @@ -47979,25 +49637,29 @@ Ext.define('Ext.chart.series.Line', { value: [xValue, yValue], point: [x, y], sprite: marker, - storeItem: store.getAt(i) + storeItem: store.getAt(storeIndices[i]) }); prevX = x; prevY = y; } - + if (path.length <= 1) { - return; + return; } - + if (me.smooth) { - path = Ext.draw.Draw.smooth(path, 6); + smoothPath = Ext.draw.Draw.smooth(path, isNumber(smooth) ? smooth : me.defaultSmoothness); } - + + renderPath = smooth ? smoothPath : path; + if (chart.markerIndex && me.previousPath) { fromPath = me.previousPath; - fromPath.splice(1, 2); + if (!smooth) { + Ext.Array.erase(fromPath, 1, 2); + } } else { fromPath = path; } @@ -48010,9 +49672,15 @@ Ext.define('Ext.chart.series.Line', { path: dummyPath, stroke: endLineStyle.stroke || endLineStyle.fill }, endLineStyle || {})); + + if (enableShadows) { + me.line.setAttributes(Ext.apply({}, me.shadowOptions), true); + } + me.line.setAttributes({ - fill: 'none' + fill: 'none', + zIndex: 3000 }); if (!endLineStyle.stroke && colorArrayLength) { me.line.setAttributes({ @@ -48021,11 +49689,11 @@ Ext.define('Ext.chart.series.Line', { } if (enableShadows) { - shadows = me.line.shadows = []; + shadows = me.line.shadows = []; for (shindex = 0; shindex < lnsh; shindex++) { shadowBarAttr = shadowAttributes[shindex]; shadowBarAttr = Ext.apply({}, shadowBarAttr, { path: dummyPath }); - shadow = chart.surface.add(Ext.apply({}, { + shadow = surface.add(Ext.apply({}, { type: 'path', group: shadowGroups[shindex] }, shadowBarAttr)); @@ -48034,17 +49702,17 @@ 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] + ["L", firstX, bbox.y + bbox.height], + ["L", firstX, firstY] ]); if (!me.fillPath) { me.fillPath = surface.add({ group: group, type: 'path', opacity: endLineStyle.opacity || 0.3, - fill: colorArrayStyle[seriesIdx % colorArrayLength] || endLineStyle.fill, + fill: endLineStyle.fill || colorArrayStyle[seriesIdx % colorArrayLength], path: dummyPath }); } @@ -48054,12 +49722,13 @@ Ext.define('Ext.chart.series.Line', { fill = me.fill; line = me.line; - 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 }); delete rendererAttributes.fill; + line.show(true); if (chart.markerIndex && me.previousPath) { me.animation = animation = me.onAnimate(line, { to: rendererAttributes, @@ -48076,24 +49745,27 @@ Ext.define('Ext.chart.series.Line', { if (enableShadows) { shadows = line.shadows; for(j = 0; j < lnsh; j++) { + shadows[j].show(true); 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 } }); } } } if (fill) { + me.fillPath.show(true); me.onAnimate(me.fillPath, { to: Ext.apply({}, { path: fillPath, - fill: colorArrayStyle[seriesIdx % colorArrayLength] || endLineStyle.fill + fill: endLineStyle.fill || colorArrayStyle[seriesIdx % colorArrayLength], + 'stroke-width': 0 }, endLineStyle || {}) }); } @@ -48108,16 +49780,21 @@ Ext.define('Ext.chart.series.Line', { me.onAnimate(item, { to: Ext.apply(rendererAttributes, endMarkerStyle || {}) }); + item.show(true); } - } + } } for(; count < markerCount; count++) { item = markerGroup.getAt(count); item.hide(true); } + + + + } } 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 }); @@ -48129,13 +49806,15 @@ Ext.define('Ext.chart.series.Line', { shadows = me.line.shadows; for(j = 0; j < lnsh; j++) { shadows[j].setAttributes({ - path: path + path: renderPath, + hidden: false }, true); } } if (me.fill) { me.fillPath.setAttributes({ - path: fillPath + path: fillPath, + hidden: false }, true); } if (showMarkers) { @@ -48146,8 +49825,9 @@ Ext.define('Ext.chart.series.Line', { if (item) { rendererAttributes = me.renderer(item, store.getAt(i), item._to, i, store); item.setAttributes(Ext.apply(endMarkerStyle || {}, rendererAttributes || {}), true); + item.show(true); } - } + } } for(; count < markerCount; count++) { item = markerGroup.getAt(count); @@ -48157,13 +49837,19 @@ 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(); me.renderCallouts(); + + me.fireEvent('draw', me); }, - + onCreateLabel: function(storeItem, item, i, display) { var me = this, @@ -48180,7 +49866,7 @@ Ext.define('Ext.chart.series.Line', { 'y': bbox.y + bbox.height / 2 }, endLabelStyle || {})); }, - + onPlaceLabel: function(label, storeItem, item, i, display, animate) { var me = this, @@ -48194,12 +49880,12 @@ Ext.define('Ext.chart.series.Line', { y = item.point[1], radius = item.sprite.attr.radius, bb, width, height; - + label.setAttributes({ text: format(storeItem.get(field)), hidden: true }, true); - + if (display == 'rotate') { label.setAttributes({ 'text-anchor': 'start', @@ -48216,7 +49902,7 @@ Ext.define('Ext.chart.series.Line', { x = x < bbox.x? bbox.x : x; x = (x + width > bbox.x + bbox.width)? (x - (x + width - bbox.x - bbox.width)) : x; y = (y - height < bbox.y)? bbox.y + height : y; - + } else if (display == 'under' || display == 'over') { bb = item.sprite.getBBox(); @@ -48232,7 +49918,7 @@ Ext.define('Ext.chart.series.Line', { y = y - height < bbox.y? bbox.y + height : y; y = (y + height > bbox.y + bbox.height) ? (y - (y + height - bbox.y - bbox.height)) : y; } - + if (me.chart.animate && !me.chart.resizing) { label.show(true); me.onAnimate(label, { @@ -48246,7 +49932,7 @@ Ext.define('Ext.chart.series.Line', { x: x, y: y }, true); - if (resizing) { + if (resizing && me.animation) { me.animation.on('afteranimate', function() { label.show(true); }); @@ -48261,20 +49947,20 @@ Ext.define('Ext.chart.series.Line', { highlightItem: function() { var me = this; me.callParent(arguments); - if (this.line && !this.highlighted) { - if (!('__strokeWidth' in this.line)) { - this.line.__strokeWidth = this.line.attr['stroke-width'] || 0; + if (me.line && !me.highlighted) { + if (!('__strokeWidth' in me.line)) { + me.line.__strokeWidth = me.line.attr['stroke-width'] || 0; } - if (this.line.__anim) { - this.line.__anim.paused = true; + if (me.line.__anim) { + me.line.__anim.paused = true; } - this.line.__anim = Ext.create('Ext.fx.Anim', { - target: this.line, + me.line.__anim = Ext.create('Ext.fx.Anim', { + target: me.line, to: { - 'stroke-width': this.line.__strokeWidth + 3 + 'stroke-width': me.line.__strokeWidth + 3 } }); - this.highlighted = true; + me.highlighted = true; } }, @@ -48283,14 +49969,14 @@ Ext.define('Ext.chart.series.Line', { unHighlightItem: function() { var me = this; me.callParent(arguments); - if (this.line && this.highlighted) { - this.line.__anim = Ext.create('Ext.fx.Anim', { - target: this.line, + if (me.line && me.highlighted) { + me.line.__anim = Ext.create('Ext.fx.Anim', { + target: me.line, to: { - 'stroke-width': this.line.__strokeWidth + 'stroke-width': me.line.__strokeWidth } }); - this.highlighted = false; + me.highlighted = false; } }, @@ -48300,7 +49986,7 @@ Ext.define('Ext.chart.series.Line', { if (!display) { return; } - + var me = this, chart = me.chart, surface = chart.surface, @@ -48332,11 +50018,11 @@ Ext.define('Ext.chart.series.Line', { a = (next[1] - prev[1]) / (next[0] - prev[0]); aprev = (cur[1] - prev[1]) / (cur[0] - prev[0]); anext = (next[1] - cur[1]) / (next[0] - cur[0]); - + norm = Math.sqrt(1 + a * a); dir = [1 / norm, a / norm]; normal = [-dir[1], dir[0]]; - + if (aprev > 0 && anext < 0 && normal[1] < 0 || aprev < 0 && anext > 0 && normal[1] > 0) { @@ -48356,7 +50042,7 @@ Ext.define('Ext.chart.series.Line', { boxy = y - bbox.height /2 - offsetBox; boxw = bbox.width + 2 * offsetBox; boxh = bbox.height + 2 * offsetBox; - + if (boxx < clipRect[0] || (boxx + boxw) > (clipRect[0] + clipRect[2])) { @@ -48369,13 +50055,13 @@ Ext.define('Ext.chart.series.Line', { x = cur[0] + normal[0] * offsetFromViz; y = cur[1] + normal[1] * offsetFromViz; - + boxx = x + (normal[0] > 0? 0 : -(bbox.width + 2 * offsetBox)); boxy = y - bbox.height /2 - offsetBox; boxw = bbox.width + 2 * offsetBox; boxh = bbox.height + 2 * offsetBox; - + if (chart.animate) { me.onAnimate(callout.lines, { @@ -48402,7 +50088,7 @@ Ext.define('Ext.chart.series.Line', { callout[p].show(true); } }, - + isItemInPoint: function(x, y, item, i) { var me = this, items = me.items, @@ -48421,10 +50107,10 @@ Ext.define('Ext.chart.series.Line', { yIntersect, dist1, dist2, dist, midx, midy, sqrt = Math.sqrt, abs = Math.abs; - + nextItem = items[i]; prevItem = i && items[i - 1]; - + if (i >= ln) { prevItem = items[ln - 1]; } @@ -48437,22 +50123,22 @@ Ext.define('Ext.chart.series.Line', { dist1 = sqrt((x - x1) * (x - x1) + (y - y1) * (y - y1)); dist2 = sqrt((x - x2) * (x - x2) + (y - y2) * (y - y2)); dist = Math.min(dist1, dist2); - + if (dist <= tolerance) { return dist == dist1? prevItem : nextItem; } return false; }, - + toggleAll: function(show) { var me = this, i, ln, shadow, shadows; if (!show) { - Ext.chart.series.Line.superclass.hideAll.call(me); + Ext.chart.series.Cartesian.prototype.hideAll.call(me); } else { - Ext.chart.series.Line.superclass.showAll.call(me); + Ext.chart.series.Cartesian.prototype.showAll.call(me); } if (me.line) { me.line.setAttributes({ @@ -48474,18 +50160,19 @@ Ext.define('Ext.chart.series.Line', { }, true); } }, - + hideAll: function() { this.toggleAll(false); }, - + showAll: function() { this.toggleAll(true); } }); + Ext.define('Ext.chart.series.Pie', { @@ -48497,7 +50184,7 @@ Ext.define('Ext.chart.series.Pie', { type: "pie", - + alias: 'series.pie', rad: Math.PI / 180, @@ -48518,10 +50205,10 @@ Ext.define('Ext.chart.series.Pie', { showInLegend: false, - + style: {}, - + constructor: function(config) { this.callParent(arguments); var me = this, @@ -48536,7 +50223,7 @@ Ext.define('Ext.chart.series.Pie', { } } }); - Ext.apply(me, config, { + Ext.apply(me, config, { shadowAttributes: [{ "stroke-width": 6, "stroke-opacity": 1, @@ -48574,13 +50261,14 @@ Ext.define('Ext.chart.series.Pie', { surface.customAttributes.segment = function(opt) { return me.getSegment(opt); }; + me.__excludes = me.__excludes || []; }, - + //@private updates some onbefore render parameters. initialize: function() { var me = this, - store = me.chart.substore || me.chart.store; + store = me.chart.getChartStore(); me.yField = []; if (me.label.field) { @@ -48596,58 +50284,81 @@ Ext.define('Ext.chart.series.Pie', { rad = me.rad, cos = Math.cos, sin = Math.sin, - abs = Math.abs, x = me.centerX, y = me.centerY, x1 = 0, x2 = 0, x3 = 0, x4 = 0, y1 = 0, y2 = 0, y3 = 0, y4 = 0, + x5 = 0, y5 = 0, x6 = 0, y6 = 0, delta = 1e-2, - r = opt.endRho - opt.startRho, startAngle = opt.startAngle, endAngle = opt.endAngle, midAngle = (startAngle + endAngle) / 2 * rad, margin = opt.margin || 0, - flag = abs(endAngle - startAngle) > 180, a1 = Math.min(startAngle, endAngle) * rad, a2 = Math.max(startAngle, endAngle) * rad, - singleSlice = false; - - x += margin * cos(midAngle); - y += margin * sin(midAngle); + c1 = cos(a1), s1 = sin(a1), + c2 = cos(a2), s2 = sin(a2), + cm = cos(midAngle), sm = sin(midAngle), + flag = 0, hsqr2 = 0.7071067811865476; - x1 = x + opt.startRho * cos(a1); - y1 = y + opt.startRho * sin(a1); + if (a2 - a1 < delta) { + return {path: ""}; + } - x2 = x + opt.endRho * cos(a1); - y2 = y + opt.endRho * sin(a1); + if (margin !== 0) { + x += margin * cm; + y += margin * sm; + } - x3 = x + opt.startRho * cos(a2); - y3 = y + opt.startRho * sin(a2); + x2 = x + opt.endRho * c1; + y2 = y + opt.endRho * s1; - x4 = x + opt.endRho * cos(a2); - y4 = y + opt.endRho * sin(a2); + x4 = x + opt.endRho * c2; + y4 = y + opt.endRho * s2; - if (abs(x1 - x3) <= delta && abs(y1 - y3) <= delta) { - singleSlice = true; + if (Math.abs(x2 - x4) + Math.abs(y2 - y4) < delta) { + cm = hsqr2; + sm = -hsqr2; + flag = 1; } + + x6 = x + opt.endRho * cm; + y6 = y + opt.endRho * sm; + - if (singleSlice) { + + + if (opt.startRho !== 0) { + x1 = x + opt.startRho * c1; + y1 = y + opt.startRho * s1; + + x3 = x + opt.startRho * c2; + y3 = y + opt.startRho * s2; + + x5 = x + opt.startRho * cm; + y5 = y + opt.startRho * sm; + return { path: [ - ["M", x1, y1], - ["L", x2, y2], - ["A", opt.endRho, opt.endRho, 0, +flag, 1, x4, y4], - ["Z"]] + ["M", x2, y2], + ["A", opt.endRho, opt.endRho, 0, 0, 1, x6, y6], ["L", x6, y6], + ["A", opt.endRho, opt.endRho, 0, flag, 1, x4, y4], ["L", x4, y4], + ["L", x3, y3], + ["A", opt.startRho, opt.startRho, 0, flag, 0, x5, y5], ["L", x5, y5], + ["A", opt.startRho, opt.startRho, 0, 0, 0, x1, y1], ["L", x1, y1], + ["Z"] + ] }; } else { return { path: [ - ["M", x1, y1], - ["L", x2, y2], - ["A", opt.endRho, opt.endRho, 0, +flag, 1, x4, y4], - ["L", x3, y3], - ["A", opt.startRho, opt.startRho, 0, +flag, 0, x1, y1], - ["Z"]] + ["M", x, y], + ["L", x2, y2], + ["A", opt.endRho, opt.endRho, 0, 0, 1, x6, y6], ["L", x6, y6], + ["A", opt.endRho, opt.endRho, 0, flag, 1, x4, y4], ["L", x4, y4], + ["L", x, y], + ["Z"] + ] }; } }, @@ -48662,11 +50373,10 @@ Ext.define('Ext.chart.series.Pie', { startAngle = slice.startAngle, endAngle = slice.endAngle, donut = +me.donut, - a1 = Math.min(startAngle, endAngle) * rad, - a2 = Math.max(startAngle, endAngle) * rad, - midAngle = -(a1 + (a2 - a1) / 2), - xm = x + (item.endRho + item.startRho) / 2 * Math.cos(midAngle), - ym = y - (item.endRho + item.startRho) / 2 * Math.sin(midAngle); + midAngle = -(startAngle + endAngle) * rad / 2, + r = (item.endRho + item.startRho) / 2, + xm = x + r * Math.cos(midAngle), + ym = y - r * Math.sin(midAngle); item.middle = { x: xm, @@ -48677,7 +50387,7 @@ Ext.define('Ext.chart.series.Pie', { drawSeries: function() { var me = this, - store = me.chart.substore || me.chart.store, + store = me.chart.getChartStore(), group = me.group, animate = me.chart.animate, field = me.angleField || me.field || me.xField, @@ -48711,6 +50421,7 @@ Ext.define('Ext.chart.series.Pie', { colorArrayLength = colorArrayStyle && colorArrayStyle.length || 0, gutterX = chart.maxGutter[0], gutterY = chart.maxGutter[1], + abs = Math.abs, rendererAttributes, shadowGroup, shadowAttr, @@ -48738,7 +50449,7 @@ Ext.define('Ext.chart.series.Pie', { path, p, spriteOptions, bbox; - + Ext.apply(seriesStyle, me.style || {}); me.setBBox(); @@ -48749,12 +50460,12 @@ Ext.define('Ext.chart.series.Pie', { colorArrayStyle = me.colorSet; colorArrayLength = colorArrayStyle.length; } - + if (!store || !store.getCount()) { return; } - + me.unHighlightItem(); me.cleanHighlights(); @@ -48779,25 +50490,26 @@ Ext.define('Ext.chart.series.Pie', { } }, this); + totalField = totalField || 1; store.each(function(record, i) { if (this.__excludes && this.__excludes[i]) { - - return; - } - value = record.get(field); - middleAngle = angle - 360 * value / totalField / 2; - - if (isNaN(middleAngle)) { - middleAngle = 360; - value = 1; - totalField = 1; + value = 0; + } else { + value = record.get(field); + if (first == 0) { + first = 1; + } } + - if (!i || first == 0) { - angle = 360 - middleAngle; - me.firstAngle = angle; - middleAngle = angle - 360 * value / totalField / 2; + if (first == 1) { + first = 2; + me.firstAngle = angle = 360 * value / totalField / 2; + for (j = 0; j < i; j++) { + slices[j].startAngle = slices[j].endAngle = me.firstAngle; + } } + endAngle = angle - 360 * value / totalField; slice = { series: me, @@ -48813,20 +50525,11 @@ Ext.define('Ext.chart.series.Pie', { slice.rho = me.radius; } slices[i] = slice; - if((slice.startAngle % 360) == (slice.endAngle % 360)) { - slice.startAngle -= 0.0001; - } angle = endAngle; - first++; }, me); - if (enableShadows) { for (i = 0, ln = slices.length; i < ln; i++) { - if (this.__excludes && this.__excludes[i]) { - - continue; - } slice = slices[i]; slice.shadowAttrs = []; for (j = 0, rhoAcum = 0, shadows = []; j < layers; j++) { @@ -48841,7 +50544,8 @@ Ext.define('Ext.chart.series.Pie', { rho: slice.rho, startRho: rhoAcum + (deltaRho * donut / 100), endRho: rhoAcum + deltaRho - } + }, + hidden: !slice.value && (slice.startAngle % 360) == (slice.endAngle % 360) }; for (shindex = 0, shadows = []; shindex < lnsh; shindex++) { @@ -48860,9 +50564,7 @@ Ext.define('Ext.chart.series.Pie', { to: shadowAttr }); } else { - shadowAttr = me.renderer(shadow, store.getAt(i), Ext.apply(shadowAttr, { - hidden: false - }), i, store); + shadowAttr = me.renderer(shadow, store.getAt(i), shadowAttr, i, store); shadow.setAttributes(shadowAttr, true); } shadows.push(shadow); @@ -48873,10 +50575,6 @@ Ext.define('Ext.chart.series.Pie', { } for (i = 0, ln = slices.length; i < ln; i++) { - if (this.__excludes && this.__excludes[i]) { - - continue; - } slice = slices[i]; for (j = 0, rhoAcum = 0; j < layers; j++) { sprite = group.getAt(i * layers + j); @@ -48890,7 +50588,8 @@ Ext.define('Ext.chart.series.Pie', { rho: slice.rho, startRho: rhoAcum + (deltaRho * donut / 100), endRho: rhoAcum + deltaRho - } + }, + hidden: (!slice.value && (slice.startAngle % 360) == (slice.endAngle % 360)) }, Ext.apply(seriesStyle, colorArrayStyle && { fill: colorArrayStyle[(layers > 1? j : i) % colorArrayLength] } || {})); item = Ext.apply({}, rendererAttributes.segment, { @@ -48941,7 +50640,7 @@ Ext.define('Ext.chart.series.Pie', { rhoAcum += deltaRho; } } - + ln = group.getCount(); for (i = 0; i < ln; i++) { @@ -48974,7 +50673,7 @@ Ext.define('Ext.chart.series.Pie', { centerY = me.centerY, middle = item.middle, endLabelStyle = Ext.apply(me.seriesLabelStyle || {}, config || {}); - + return me.chart.surface.add(Ext.apply({ 'type': 'text', 'text-anchor': 'middle', @@ -49006,9 +50705,13 @@ Ext.define('Ext.chart.series.Pie', { theta = Math.atan2(y, x || 1), dg = theta * 180 / Math.PI, prevDg; - + if (this.__excludes && this.__excludes[i]) { + opt.hidden = true; + } function fixAngle(a) { - if (a < 0) a += 360; + if (a < 0) { + a += 360; + } return a % 360; } @@ -49052,7 +50755,7 @@ Ext.define('Ext.chart.series.Pie', { } opt.translate = { - x: 0, y: 0 + x: 0, y: 0 }; if (animate && !resizing && (display != 'rotate' || prevDg != null)) { me.onAnimate(label, { @@ -49163,8 +50866,8 @@ Ext.define('Ext.chart.series.Pie', { startAngle = item.startAngle, endAngle = item.endAngle, rho = Math.sqrt(dx * dx + dy * dy), - angle = Math.atan2(y - cy, x - cx) / me.rad + 360; - + angle = Math.atan2(y - cy, x - cx) / me.rad; + if (angle > me.firstAngle) { angle -= 360; @@ -49172,7 +50875,7 @@ Ext.define('Ext.chart.series.Pie', { return (angle <= startAngle && angle > endAngle && rho >= item.startRho && rho <= item.endRho); }, - + hideAll: function() { var i, l, shadow, shadows, sh, lsh, sprite; @@ -49198,7 +50901,7 @@ Ext.define('Ext.chart.series.Pie', { this.drawSeries(); } }, - + showAll: function() { if (!isNaN(this._index)) { @@ -49212,13 +50915,13 @@ Ext.define('Ext.chart.series.Pie', { var me = this, rad = me.rad; item = item || this.items[this._index]; - + this.unHighlightItem(); - + if (!item || item.sprite && item.sprite._animating) { return; } @@ -49251,7 +50954,7 @@ Ext.define('Ext.chart.series.Pie', { if (Math.abs(y) < 1e-10) { y = 0; } - + if (animate) { label.stopAnimation(); label.animate({ @@ -49390,11 +51093,11 @@ Ext.define('Ext.chart.series.Pie', { } me.callParent(arguments); }, - + 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]; } }); @@ -49413,14 +51116,14 @@ Ext.define('Ext.chart.series.Radar', { type: "radar", alias: 'series.radar', - + rad: Math.PI / 180, showInLegend: false, style: {}, - + constructor: function(config) { this.callParent(arguments); var me = this, @@ -49434,7 +51137,7 @@ Ext.define('Ext.chart.series.Radar', { drawSeries: function() { var me = this, - store = me.chart.substore || me.chart.store, + store = me.chart.getChartStore(), group = me.group, sprite, chart = me.chart, @@ -49460,18 +51163,18 @@ Ext.define('Ext.chart.series.Radar', { first = chart.resizing || !me.radar, axis = chart.axes && chart.axes.get(0), aggregate = !(axis && axis.maximum); - + me.setBBox(); maxValue = aggregate? 0 : (axis.maximum || 0); - + Ext.apply(seriesStyle, me.style || {}); - + if (!store || !store.getCount()) { return; } - + me.unHighlightItem(); me.cleanHighlights(); @@ -49547,7 +51250,7 @@ Ext.define('Ext.chart.series.Radar', { me.renderLabels(); me.renderCallouts(); }, - + drawMarkers: function() { var me = this, @@ -49555,15 +51258,15 @@ Ext.define('Ext.chart.series.Radar', { surface = chart.surface, markerStyle = Ext.apply({}, me.markerStyle || {}), endMarkerStyle = Ext.apply(markerStyle, me.markerConfig), - items = me.items, + items = me.items, type = endMarkerStyle.type, markerGroup = me.markerGroup, centerX = me.centerX, centerY = me.centerY, item, i, l, marker; - + delete endMarkerStyle.type; - + for (i = 0, l = items.length; i < l; i++) { item = items[i]; marker = markerGroup.getAt(i); @@ -49608,7 +51311,7 @@ Ext.define('Ext.chart.series.Radar', { } } }, - + isItemInPoint: function(x, y, item) { var point, tolerance = 10, @@ -49627,7 +51330,7 @@ Ext.define('Ext.chart.series.Radar', { centerY = me.centerY, point = item.point, endLabelStyle = Ext.apply(me.seriesLabelStyle || {}, config); - + return me.chart.surface.add(Ext.apply({ 'type': 'text', 'text-anchor': 'middle', @@ -49659,14 +51362,14 @@ Ext.define('Ext.chart.series.Radar', { hidden: true }, true); - + if (resizing) { label.setAttributes({ x: centerX, y: centerY }, true); } - + if (animate) { label.show(true); me.onAnimate(label, { @@ -49703,18 +51406,18 @@ Ext.define('Ext.chart.series.Radar', { } } }, - + hideAll: function() { this.toggleAll(false); this.hideMarkers(0); }, - + showAll: function() { this.toggleAll(true); }, - + hideMarkers: function(index) { var me = this, @@ -49742,6 +51445,8 @@ Ext.define('Ext.chart.series.Scatter', { alias: 'series.scatter', + + @@ -49779,14 +51484,14 @@ Ext.define('Ext.chart.series.Scatter', { getBounds: function() { var me = this, chart = me.chart, - store = chart.substore || chart.store, + store = chart.getChartStore(), axes = [].concat(me.axis), bbox, xScale, yScale, ln, minX, minY, maxX, maxY, i, axis, ends; me.setBBox(); bbox = me.bbox; - for (i = 0, ln = axes.length; i < ln; i++) { + for (i = 0, ln = axes.length; i < ln; i++) { axis = chart.axes.get(axes[i]); if (axis) { ends = axis.calcEnds(); @@ -49831,7 +51536,7 @@ Ext.define('Ext.chart.series.Scatter', { minY = 0; maxY = store.getCount() - 1; yScale = bbox.height / (store.getCount() - 1); - } + } else { yScale = bbox.height / (maxY - minY); } @@ -49850,7 +51555,7 @@ Ext.define('Ext.chart.series.Scatter', { var me = this, chart = me.chart, enableShadows = chart.shadow, - store = chart.substore || chart.store, + store = chart.getChartStore(), group = me.group, bounds = me.bounds = me.getBounds(), bbox = me.bbox, @@ -49870,16 +51575,13 @@ Ext.define('Ext.chart.series.Scatter', { yValue = record.get(me.yField); if (typeof yValue == 'undefined' || (typeof yValue == 'string' && !yValue)) { - if (Ext.isDefined(Ext.global.console)) { - Ext.global.console.warn("[Ext.chart.series.Scatter] Skipping a store element with an undefined value at ", record, xValue, yValue); - } return; } - if (typeof xValue == 'string' || typeof xValue == 'object') { + if (typeof xValue == 'string' || typeof xValue == 'object' && !Ext.isDate(xValue)) { xValue = i; } - if (typeof yValue == 'string' || typeof yValue == 'object') { + if (typeof yValue == 'string' || typeof yValue == 'object' && !Ext.isDate(yValue)) { yValue = i; } x = boxX + (xValue - minX) * xScale; @@ -50003,7 +51705,7 @@ Ext.define('Ext.chart.series.Scatter', { drawSeries: function() { var me = this, chart = me.chart, - store = chart.substore || chart.store, + store = chart.getChartStore(), group = me.group, enableShadows = chart.shadow, shadowGroups = me.shadowGroups, @@ -50050,23 +51752,28 @@ Ext.define('Ext.chart.series.Scatter', { for (shindex = 0; shindex < lnsh; shindex++) { shadowAttribute = Ext.apply({}, shadowAttributes[shindex]); rendererAttributes = me.renderer(shadows[shindex], store.getAt(i), Ext.apply({}, { + hidden: false, translate: { x: attr.x + (shadowAttribute.translate? shadowAttribute.translate.x : 0), y: attr.y + (shadowAttribute.translate? shadowAttribute.translate.y : 0) - } + } }, shadowAttribute), i, store); me.onAnimate(shadows[shindex], { to: rendererAttributes }); } } else { - rendererAttributes = me.renderer(sprite, store.getAt(i), Ext.apply({ translate: attr }, { hidden: false }), i, store); + rendererAttributes = me.renderer(sprite, store.getAt(i), { translate: attr }, i, store); + sprite._to = rendererAttributes; sprite.setAttributes(rendererAttributes, true); for (shindex = 0; shindex < lnsh; shindex++) { - shadowAttribute = shadowAttributes[shindex]; - rendererAttributes = me.renderer(shadows[shindex], store.getAt(i), Ext.apply({ - x: attr.x, - y: attr.y + shadowAttribute = Ext.apply({}, shadowAttributes[shindex]); + rendererAttributes = me.renderer(shadows[shindex], store.getAt(i), Ext.apply({}, { + hidden: false, + translate: { + x: attr.x + (shadowAttribute.translate? shadowAttribute.translate.x : 0), + y: attr.y + (shadowAttribute.translate? shadowAttribute.translate.y : 0) + } }, shadowAttribute), i, store); shadows[shindex].setAttributes(rendererAttributes, true); } @@ -50082,7 +51789,7 @@ Ext.define('Ext.chart.series.Scatter', { me.renderLabels(); me.renderCallouts(); }, - + onCreateLabel: function(storeItem, item, i, display) { var me = this, @@ -50090,7 +51797,7 @@ Ext.define('Ext.chart.series.Scatter', { config = me.label, endLabelStyle = Ext.apply({}, config, me.seriesLabelStyle), bbox = me.bbox; - + return me.chart.surface.add(Ext.apply({ type: 'text', group: group, @@ -50098,7 +51805,7 @@ Ext.define('Ext.chart.series.Scatter', { y: bbox.y + bbox.height / 2 }, endLabelStyle)); }, - + onPlaceLabel: function(label, storeItem, item, i, display, animate) { var me = this, @@ -50112,12 +51819,12 @@ Ext.define('Ext.chart.series.Scatter', { y = item.point[1], radius = item.sprite.attr.radius, bb, width, height, anim; - + label.setAttributes({ text: format(storeItem.get(field)), hidden: true }, true); - + if (display == 'rotate') { label.setAttributes({ 'text-anchor': 'start', @@ -50134,7 +51841,7 @@ Ext.define('Ext.chart.series.Scatter', { x = x < bbox.x? bbox.x : x; x = (x + width > bbox.x + bbox.width)? (x - (x + width - bbox.x - bbox.width)) : x; y = (y - height < bbox.y)? bbox.y + height : y; - + } else if (display == 'under' || display == 'over') { bb = item.sprite.getBBox(); @@ -50168,7 +51875,7 @@ Ext.define('Ext.chart.series.Scatter', { y: y }, true); label.show(true); - }); + }); } else { label.show(true); @@ -50184,7 +51891,7 @@ Ext.define('Ext.chart.series.Scatter', { } } }, - + onPlaceCallout: function(callout, storeItem, item, i, display, animate, index) { var me = this, @@ -50202,18 +51909,18 @@ Ext.define('Ext.chart.series.Scatter', { boxx, boxy, boxw, boxh, p, clipRect = me.bbox, x, y; - + normal = [Math.cos(Math.PI /4), -Math.sin(Math.PI /4)]; x = cur[0] + normal[0] * offsetFromViz; y = cur[1] + normal[1] * offsetFromViz; - + boxx = x + (normal[0] > 0? 0 : -(bbox.width + 2 * offsetBox)); boxy = y - bbox.height /2 - offsetBox; boxw = bbox.width + 2 * offsetBox; boxh = bbox.height + 2 * offsetBox; - + if (boxx < clipRect[0] || (boxx + boxw) > (clipRect[0] + clipRect[2])) { @@ -50222,17 +51929,17 @@ Ext.define('Ext.chart.series.Scatter', { if (boxy < clipRect[1] || (boxy + boxh) > (clipRect[1] + clipRect[3])) { normal[1] *= -1; } - + x = cur[0] + normal[0] * offsetFromViz; y = cur[1] + normal[1] * offsetFromViz; - + boxx = x + (normal[0] > 0? 0 : -(bbox.width + 2 * offsetBox)); boxy = y - bbox.height /2 - offsetBox; boxw = bbox.width + 2 * offsetBox; boxh = bbox.height + 2 * offsetBox; - + if (chart.animate) { me.onAnimate(callout.lines, { @@ -50460,7 +52167,6 @@ Ext.define('Ext.data.ArrayStore', { alias: 'store.array', uses: ['Ext.data.reader.Array'], - constructor: function(config) { config = config || {}; @@ -50500,92 +52206,93 @@ Ext.define('Ext.data.Batch', { mixins: { observable: 'Ext.util.Observable' }, - + autoStart: false, - + current: -1, - + total: 0, - + isRunning: false, - + isComplete: false, - + hasException: false, - + pauseOnException: true, + - constructor: function(config) { + constructor: function(config) { var me = this; - + me.addEvents( 'complete', - + 'exception', - + 'operationcomplete' ); - + me.mixins.observable.constructor.call(me, config); - + me.operations = []; }, - + add: function(operation) { this.total++; - + operation.setBatch(this); - + this.operations.push(operation); }, - + start: function() { this.hasException = false; this.isRunning = true; - + this.runNextOperation(); }, - + runNextOperation: function() { this.runOperation(this.current + 1); }, - + pause: function() { this.isRunning = false; }, - + runOperation: function(index) { var me = this, operations = me.operations, operation = operations[index], onProxyReturn; - + if (operation === undefined) { me.isRunning = false; me.isComplete = true; me.fireEvent('complete', me, operations[operations.length - 1]); } else { me.current = index; - + onProxyReturn = function(operation) { var hasException = operation.hasException(); - + if (hasException) { me.hasException = true; me.fireEvent('exception', me, operation); @@ -50600,9 +52307,9 @@ Ext.define('Ext.data.Batch', { me.runNextOperation(); } }; - + operation.setStarted(); - + me.proxy[operation.action](operation, onProxyReturn, me); } } @@ -50618,9 +52325,8 @@ Ext.define('Ext.data.BelongsToAssociation', { - - + constructor: function(config) { this.callParent(arguments); @@ -50680,38 +52386,37 @@ Ext.define('Ext.data.BelongsToAssociation', { 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; - 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; } @@ -50736,18 +52441,17 @@ Ext.define('Ext.data.BufferStore', { } }); - Ext.define('Ext.direct.Manager', { - + singleton: true, - + mixins: { observable: 'Ext.util.Observable' }, - + requires: ['Ext.util.MixedCollection'], - + statics: { exceptions: { TRANSPORT: 'xhr', @@ -50756,12 +52460,12 @@ Ext.define('Ext.direct.Manager', { SERVER: 'exception' } }, + - - + constructor: function(){ var me = this; - + me.addEvents( 'event', @@ -50770,17 +52474,17 @@ Ext.define('Ext.direct.Manager', { ); me.transactions = Ext.create('Ext.util.MixedCollection'); me.providers = Ext.create('Ext.util.MixedCollection'); - + me.mixins.observable.constructor.call(me); }, - + addProvider : function(provider){ var me = this, args = arguments, i = 0, len; - + if (args.length > 1) { for (len = args.length; i < len; ++i) { me.addProvider(args[i]); @@ -50802,18 +52506,19 @@ Ext.define('Ext.direct.Manager', { return provider; }, - + getProvider : function(id){ return id.isProvider ? id : this.providers.get(id); }, - + removeProvider : function(provider){ var me = this, - providers = me.providers, - provider = provider.isProvider ? provider : providers.get(provider); - + providers = me.providers; + + provider = provider.isProvider ? provider : providers.get(provider); + if (provider) { provider.un('data', me.onProviderData, me); providers.remove(provider); @@ -50821,7 +52526,7 @@ Ext.define('Ext.direct.Manager', { } return null; }, - + addTransaction: function(transaction){ this.transactions.add(transaction); @@ -50839,12 +52544,12 @@ Ext.define('Ext.direct.Manager', { getTransaction: function(transaction){ return transaction.isTransaction ? transaction : this.transactions.get(transaction); }, - + onProviderData : function(provider, event){ var me = this, i = 0, len; - + if (Ext.isArray(event)) { for (len = event.length; i < len; ++i) { me.onProviderData(provider, event[i]); @@ -50853,7 +52558,7 @@ Ext.define('Ext.direct.Manager', { } if (event.name && event.name != 'event' && event.name != 'exception') { me.fireEvent(event.name, event); - } else if (event.type == 'exception') { + } else if (event.status === false) { me.fireEvent('exception', event); } me.fireEvent('event', event, provider); @@ -50866,17 +52571,17 @@ Ext.define('Ext.direct.Manager', { Ext.define('Ext.data.proxy.Direct', { - + extend: 'Ext.data.proxy.Server', alternateClassName: 'Ext.data.DirectProxy', - + alias: 'proxy.direct', - + requires: ['Ext.direct.Manager'], + + - - paramOrder: undefined, @@ -50884,24 +52589,24 @@ Ext.define('Ext.data.proxy.Direct', { directFn : undefined, + + - - - + paramOrderRe: /[\s,|]/, - + constructor: function(config){ var me = this; - + Ext.apply(me, config); if (Ext.isString(me.paramOrder)) { me.paramOrder = me.paramOrder.split(me.paramOrderRe); } me.callParent(arguments); }, - + doRequest: function(operation, callback, scope) { var me = this, writer = me.getWriter(), @@ -50913,19 +52618,16 @@ Ext.define('Ext.data.proxy.Direct', { method, i = 0, len; - - if (!fn) { - Ext.Error.raise('No direct function specified for this proxy'); - } - + + if (operation.allowWrite()) { request = writer.write(request); } - + if (operation.action == 'read') { method = fn.directCfg.method; - + if (method.ordered) { if (method.len > 0) { if (paramOrder) { @@ -50942,7 +52644,7 @@ Ext.define('Ext.data.proxy.Direct', { } else { args.push(request.jsonData); } - + Ext.apply(request, { args: args, directFn: fn @@ -50950,30 +52652,30 @@ Ext.define('Ext.data.proxy.Direct', { args.push(me.createRequestCallback(request, operation, callback, scope), me); fn.apply(window, args); }, - + applyEncoding: function(value){ return value; }, - + createRequestCallback: function(request, operation, callback, scope){ var me = this; - + return function(data, event){ me.processResponse(event.status, operation, request, event, callback, scope); }; }, - + extractResponseData: function(response){ return Ext.isDefined(response.result) ? response.result : response.data; }, - + setException: function(operation, response) { operation.setException(response.message); }, - + buildUrl: function(){ return ''; @@ -50981,7 +52683,6 @@ Ext.define('Ext.data.proxy.Direct', { }); - Ext.define('Ext.data.DirectStore', { @@ -50992,8 +52693,8 @@ Ext.define('Ext.data.DirectStore', { requires: ['Ext.data.proxy.Direct'], - - constructor : function(config){ + + constructor : function(config){ config = Ext.apply({}, config); if (!config.proxy) { var proxy = { @@ -51011,7 +52712,6 @@ Ext.define('Ext.data.DirectStore', { }); - Ext.define('Ext.util.Inflector', { @@ -51043,7 +52743,7 @@ Ext.define('Ext.util.Inflector', { [(/s$/i), "s" ], [(/$/), "s" ] ], - + singulars: [ [(/(quiz)zes$/i), "$1" ], @@ -51072,7 +52772,7 @@ Ext.define('Ext.util.Inflector', { [(/people$/i), "person" ], [(/s$/i), "" ] ], - + uncountable: [ "sheep", @@ -51089,27 +52789,27 @@ Ext.define('Ext.util.Inflector', { "deer", "means" ], - + singular: function(matcher, replacer) { this.singulars.unshift([matcher, replacer]); }, - + plural: function(matcher, replacer) { this.plurals.unshift([matcher, replacer]); }, - + clearSingulars: function() { this.singulars = []; }, - + clearPlurals: function() { this.plurals = []; }, - + isTransnumeral: function(word) { return Ext.Array.indexOf(this.uncountable, word) != -1; @@ -51124,19 +52824,19 @@ Ext.define('Ext.util.Inflector', { var plurals = this.plurals, length = plurals.length, tuple, regex, i; - + for (i = 0; i < length; i++) { tuple = plurals[i]; regex = tuple[0]; - + if (regex == word || (regex.test && regex.test(word))) { return word.replace(regex, tuple[1]); } } - + return word; }, - + singularize: function(word) { if (this.isTransnumeral(word)) { @@ -51146,30 +52846,30 @@ Ext.define('Ext.util.Inflector', { var singulars = this.singulars, length = singulars.length, tuple, regex, i; - + for (i = 0; i < length; i++) { tuple = singulars[i]; regex = tuple[0]; - + if (regex == word || (regex.test && regex.test(word))) { return word.replace(regex, tuple[1]); } } - + return word; }, - + classify: function(word) { return Ext.String.capitalize(this.singularize(word)); }, - + ordinalize: function(number) { var parsed = parseInt(number, 10), mod10 = parsed % 10, mod100 = parsed % 100; - + if (11 <= mod100 && mod100 <= 13) { return number + "th"; @@ -51218,7 +52918,7 @@ Ext.define('Ext.util.Inflector', { vita: 'vitae' }, singular; - + for (singular in irregulars) { this.plural(singular, irregulars[singular]); this.singular(irregulars[singular], singular); @@ -51336,57 +53036,55 @@ Ext.define('Ext.data.HasManyAssociation', { }); Ext.define('Ext.data.JsonP', { + - - + singleton: true, - + statics: { requestCount: 0, requests: {} }, + - - + timeout: 30000, - + disableCaching: true, - + disableCachingParam: '_dc', - + callbackKey: 'callback', - + request: function(options){ options = Ext.apply({}, options); - - if (!options.url) { - Ext.Error.raise('A url must be specified for a JSONP request.'); - } - - var me = this, - disableCaching = Ext.isDefined(options.disableCaching) ? options.disableCaching : me.disableCaching, - cacheParam = options.disableCachingParam || me.disableCachingParam, - id = ++me.statics().requestCount, - callbackName = options.callbackName || 'callback' + id, - callbackKey = options.callbackKey || me.callbackKey, - timeout = Ext.isDefined(options.timeout) ? options.timeout : me.timeout, - params = Ext.apply({}, options.params), + + + var me = this, + disableCaching = Ext.isDefined(options.disableCaching) ? options.disableCaching : me.disableCaching, + cacheParam = options.disableCachingParam || me.disableCachingParam, + id = ++me.statics().requestCount, + callbackName = options.callbackName || 'callback' + id, + callbackKey = options.callbackKey || me.callbackKey, + timeout = Ext.isDefined(options.timeout) ? options.timeout : me.timeout, + params = Ext.apply({}, options.params), url = options.url, - request, + name = Ext.isSandboxed ? Ext.getUniqueGlobalNamespace() : 'Ext', + request, script; - - params[callbackKey] = 'Ext.data.JsonP.' + callbackName; + + params[callbackKey] = name + '.data.JsonP.' + callbackName; if (disableCaching) { params[cacheParam] = new Date().getTime(); } - + script = me.createScript(url, params); - + me.statics().requests[id] = request = { url: url, params: params, @@ -51398,22 +53096,22 @@ Ext.define('Ext.data.JsonP', { callback: options.callback, callbackName: callbackName }; - + if (timeout > 0) { request.timeout = setTimeout(Ext.bind(me.handleTimeout, me, [request]), timeout); } - + me.setupErrorHandling(request); me[callbackName] = Ext.bind(me.handleResponse, me, [request], true); Ext.getHead().appendChild(script); return request; }, - + abort: function(request){ var requests = this.statics().requests, key; - + if (request) { if (!request.id) { request = requests[request]; @@ -51427,40 +53125,40 @@ Ext.define('Ext.data.JsonP', { } } }, - + setupErrorHandling: function(request){ request.script.onerror = Ext.bind(this.handleError, this, [request]); }, - + handleAbort: function(request){ request.errorType = 'abort'; this.handleResponse(null, request); }, - + handleError: function(request){ request.errorType = 'error'; this.handleResponse(null, request); }, - + cleanupErrorHandling: function(request){ request.script.onerror = null; }, - + handleTimeout: function(request){ request.errorType = 'timeout'; this.handleResponse(null, request); }, - + handleResponse: function(result, request){ - + var success = true; - + if (request.timeout) { clearTimeout(request.timeout); } @@ -51468,7 +53166,7 @@ Ext.define('Ext.data.JsonP', { delete this.statics()[request.id]; this.cleanupErrorHandling(request); Ext.fly(request.script).remove(); - + if (request.errorType) { success = false; Ext.callback(request.failure, request.scope, [request.errorType]); @@ -51477,7 +53175,7 @@ Ext.define('Ext.data.JsonP', { } Ext.callback(request.callback, request.scope, [success, result, request.errorType]); }, - + createScript: function(url, params) { var script = document.createElement('script'); @@ -51505,7 +53203,66 @@ Ext.define('Ext.data.JsonPStore', { Ext.define('Ext.data.NodeInterface', { requires: ['Ext.data.Field'], + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + statics: { decorate: function(record) { @@ -51516,51 +53273,46 @@ 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; 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: 'icon', 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; + len = newFields.length; - 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; - } + for (i = 0; i < len; ++i) { + newField = newFields[i]; + if (record.get(newField.name) === undefined) { + record.data[newField.name] = newField.defaultValue; } } } - + Ext.applyIf(record, { firstChild: null, lastChild: null, @@ -51571,7 +53323,7 @@ Ext.define('Ext.data.NodeInterface', { }); record.commit(true); - + record.enableBubble([ "append", @@ -51596,26 +53348,26 @@ Ext.define('Ext.data.NodeInterface', { "beforeinsert", - + "expand", - + "collapse", - + "beforeexpand", - + "beforecollapse", - + "sort" ]); - + return record; }, - + applyFields: function(modelClass, addFields) { var modelPrototype = modelClass.prototype, fields = modelPrototype.fields, @@ -51623,20 +53375,20 @@ Ext.define('Ext.data.NodeInterface', { ln = addFields.length, addField, i, name, newFields = []; - + for (i = 0; i < ln; i++) { addField = addFields[i]; if (!Ext.Array.contains(keys, addField.name)) { addField = Ext.create('data.field', addField); - + newFields.push(addField); fields.add(addField); } } - + return newFields; }, - + getPrototypeBody: function() { return { isNode: true, @@ -51649,7 +53401,7 @@ Ext.define('Ext.data.NodeInterface', { return Ext.data.NodeInterface.decorate(node); }, - + isLeaf : function() { return this.get('leaf') === true; @@ -51681,8 +53433,8 @@ Ext.define('Ext.data.NodeInterface', { while (parent.parentNode) { ++depth; parent = parent.parentNode; - } - + } + me.beginEdit(); me.set({ isFirst: isFirst, @@ -51695,7 +53447,7 @@ Ext.define('Ext.data.NodeInterface', { if (silent) { me.commit(); } - + for (i = 0; i < len; i++) { children[i].updateInfo(silent); } @@ -51718,7 +53470,12 @@ Ext.define('Ext.data.NodeInterface', { isExpandable : function() { - return this.get('expandable') || this.hasChildNodes(); + var me = this; + + if (me.get('expandable')) { + return !(me.isLeaf() || (me.isLoaded() && !me.hasChildNodes())); + } + return false; }, @@ -51737,9 +53494,9 @@ Ext.define('Ext.data.NodeInterface', { } else { node = me.createNode(node); - + if (suppressEvents !== true && me.fireEvent("beforeappend", me, node) === false) { - return false; + return false; } index = me.childNodes.length; @@ -51763,7 +53520,7 @@ Ext.define('Ext.data.NodeInterface', { node.nextSibling = null; me.setLastChild(node); - + ps = me.childNodes[index - 1]; if (ps) { node.previousSibling = ps; @@ -51774,28 +53531,28 @@ Ext.define('Ext.data.NodeInterface', { } node.updateInfo(suppressNodeUpdate); - + if (!me.isLoaded()) { - me.set('loaded', true); + me.set('loaded', true); } else if (me.childNodes.length === 1) { me.set('loaded', me.isLoaded()); } - + if (suppressEvents !== true) { me.fireEvent("append", me, node, index); if (oldParent) { node.fireEvent("move", node, oldParent, me, index); - } + } } return node; } }, - + getBubbleTarget: function() { return this.parentNode; @@ -51805,13 +53562,13 @@ Ext.define('Ext.data.NodeInterface', { removeChild : function(node, destroy, suppressEvents, suppressNodeUpdate) { var me = this, index = me.indexOf(node); - + if (index == -1 || (suppressEvents !== true && me.fireEvent("beforeremove", me, node) === false)) { return false; } - me.childNodes.splice(index, 1); + Ext.Array.erase(me.childNodes, index, 1); if (me.firstChild == node) { @@ -51820,7 +53577,7 @@ Ext.define('Ext.data.NodeInterface', { if (me.lastChild == node) { me.setLastChild(node.previousSibling); } - + if (node.previousSibling) { node.previousSibling.nextSibling = node.nextSibling; @@ -51834,13 +53591,13 @@ Ext.define('Ext.data.NodeInterface', { if (suppressEvents !== true) { me.fireEvent("remove", me, node); } - - + + if (!me.childNodes.length) { me.set('loaded', me.isLoaded()); } - + if (destroy) { node.destroy(true); } else { @@ -51869,7 +53626,7 @@ Ext.define('Ext.data.NodeInterface', { clear : function(destroy) { var me = this; - + me.parentNode = me.previousSibling = me.nextSibling = null; if (destroy) { @@ -51882,7 +53639,7 @@ Ext.define('Ext.data.NodeInterface', { var me = this, options = me.destroyOptions; - + if (silent === true) { me.clear(true); Ext.each(me.childNodes, function(n) { @@ -51905,11 +53662,11 @@ Ext.define('Ext.data.NodeInterface', { oldParent = node.parentNode, refIndex = index, ps; - + if (!refNode) { return me.appendChild(node); } - + if (node == refNode) { return false; @@ -51917,11 +53674,11 @@ Ext.define('Ext.data.NodeInterface', { node = me.createNode(node); - + if (suppressEvents !== true && me.fireEvent("beforeinsert", me, node, refNode) === false) { return false; } - + if (oldParent == me && me.indexOf(node) < index) { refIndex--; @@ -51939,12 +53696,12 @@ 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; refNode.previousSibling = node; - + ps = me.childNodes[refIndex - 1]; if (ps) { node.previousSibling = ps; @@ -51953,12 +53710,12 @@ Ext.define('Ext.data.NodeInterface', { } else { node.previousSibling = null; } - + node.updateInfo(); - + if (!me.isLoaded()) { - me.set('loaded', true); - } + me.set('loaded', true); + } else if (me.childNodes.length === 1) { me.set('loaded', me.isLoaded()); @@ -51969,13 +53726,13 @@ Ext.define('Ext.data.NodeInterface', { if (oldParent) { node.fireEvent("move", node, oldParent, me, refIndex, refNode); - } + } } return node; }, + - insertChild: function(index, node) { var sibling = this.childNodes[index]; if (sibling) { @@ -52015,7 +53772,7 @@ Ext.define('Ext.data.NodeInterface', { replaceChild : function(newChild, oldChild, suppressEvents) { var s = oldChild ? oldChild.nextSibling : null; - + this.removeChild(oldChild, suppressEvents); this.insertBefore(newChild, s, suppressEvents); return oldChild; @@ -52027,6 +53784,21 @@ Ext.define('Ext.data.NodeInterface', { }, + getPath: function(field, separator) { + field = field || this.idProperty; + separator = separator || '/'; + + var path = [this.get(field)], + parent = this.parentNode; + + while (parent) { + path.unshift(parent.get(field)); + parent = parent.parentNode; + } + return separator + path.join(separator); + }, + + getDepth : function() { return this.get('depth'); }, @@ -52126,14 +53898,14 @@ Ext.define('Ext.data.NodeInterface', { var cs = this.childNodes, ln = cs.length, i, n; - + if (ln > 0) { Ext.Array.sort(cs, sortFn); for (i = 0; i < ln; i++) { n = cs[i]; n.previousSibling = cs[i-1]; n.nextSibling = cs[i+1]; - + if (i === 0) { this.setFirstChild(n); n.updateInfo(); @@ -52146,34 +53918,34 @@ Ext.define('Ext.data.NodeInterface', { n.sort(sortFn, true, true); } } - + if (suppressEvent !== true) { this.fireEvent('sort', this, cs); } } }, - - + + isExpanded: function() { return this.get('expanded'); }, + - isLoaded: function() { return this.get('loaded'); }, - + isLoading: function() { return this.get('loading'); }, - - + + isRoot: function() { return !this.parentNode; }, + - isVisible: function() { var parent = this.parentNode; while (parent) { @@ -52184,7 +53956,7 @@ Ext.define('Ext.data.NodeInterface', { } return true; }, - + expand: function(recursive, callback, scope) { var me = this; @@ -52195,42 +53967,41 @@ Ext.define('Ext.data.NodeInterface', { if (!me.isLeaf()) { - if (!me.isLoading() && !me.isExpanded()) { - - - + if (me.isLoading()) { + me.on('expand', function(){ + me.expand(recursive, callback, scope); + }, me, {single: true}); + } else { - me.fireEvent('beforeexpand', me, function(records) { - me.set('expanded', true); - me.fireEvent('expand', me, me.childNodes, false); + if (!me.isExpanded()) { - if (recursive) { - me.expandChildren(true, callback, scope); - } - else { - Ext.callback(callback, scope || me, [me.childNodes]); - } - }, me); - } - - else if (recursive) { - me.expandChildren(true, callback, scope); - } - else { - Ext.callback(callback, scope || me, [me.childNodes]); - } + + + me.fireEvent('beforeexpand', me, function(){ + me.set('expanded', true); + me.fireEvent('expand', me, me.childNodes, false); + + if (recursive) { + me.expandChildren(true, callback, scope); + } else { + Ext.callback(callback, scope || me, [me.childNodes]); + } + }, me); + } else if (recursive) { + + me.expandChildren(true, callback, scope); + } else { + Ext.callback(callback, scope || me, [me.childNodes]); + } + } + } else { - - - } - - else { Ext.callback(callback, scope || me); } }, - + expandChildren: function(recursive, callback, scope) { var me = this, @@ -52247,15 +54018,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]); } }, @@ -52266,18 +54036,18 @@ Ext.define('Ext.data.NodeInterface', { if (!me.isLeaf()) { if (!me.collapsing && me.isExpanded()) { - me.fireEvent('beforecollapse', me, function(records) { - me.set('expanded', false); + me.fireEvent('beforecollapse', me, function() { + me.set('expanded', false); me.fireEvent('collapse', me, me.childNodes, false); - + if (recursive) { me.collapseChildren(true, callback, scope); } else { - Ext.callback(callback, scope || me, [me.childNodes]); + Ext.callback(callback, scope || me, [me.childNodes]); } - }, me); + }, me); } else if (recursive) { @@ -52286,10 +54056,10 @@ Ext.define('Ext.data.NodeInterface', { } else { - Ext.callback(callback, scope || me, me.childNodes); + Ext.callback(callback, scope || me, [me.childNodes]); } }, - + collapseChildren: function(recursive, callback, scope) { var me = this, @@ -52306,14 +54076,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]); } } }; @@ -52342,10 +54112,6 @@ Ext.define('Ext.data.NodeStore', { config = config || {}; Ext.apply(me, config); - if (Ext.isDefined(me.proxy)) { - Ext.Error.raise("A NodeStore cannot be bound to a proxy. Instead bind it to a record " + - "decorated with the NodeInterface by setting the node config."); - } config.proxy = {type: 'proxy'}; me.callParent([config]); @@ -52561,28 +54327,59 @@ Ext.define('Ext.data.Request', { url: undefined, + constructor: function(config) { Ext.apply(this, config); } }); +Ext.define('Ext.data.SequentialIdGenerator', { + extend: 'Ext.data.IdGenerator', + alias: 'idgen.sequential', + + constructor: function() { + var me = this; + + me.callParent(arguments); + + me.parts = [ me.prefix, '']; + }, + + + prefix: '', + + + seed: 1, + + + generate: function () { + var me = this, + parts = me.parts; + + parts[1] = me.seed++; + return parts.join(''); + } +}); + + Ext.define('Ext.data.Tree', { alias: 'data.tree', - + mixins: { observable: "Ext.util.Observable" }, root: null, - + + constructor: function(root) { var me = this; + - me.nodeHash = {}; me.mixins.observable.constructor.call(me); - + if (root) { me.setRootNode(root); } @@ -52596,14 +54393,14 @@ Ext.define('Ext.data.Tree', { setRootNode : function(node) { var me = this; - + me.root = node; Ext.data.NodeInterface.decorate(node); - + if (me.fireEvent('beforeappend', null, node) !== false) { node.set('root', true); node.updateInfo(); - + me.relayEvents(node, [ "append", @@ -52644,7 +54441,7 @@ Ext.define('Ext.data.Tree', { "rootchange" ]); - + node.on({ scope: me, insert: me.onNodeInsert, @@ -52652,20 +54449,21 @@ Ext.define('Ext.data.Tree', { remove: me.onNodeRemove }); - me.registerNode(node); + me.nodeHash = {}; + me.registerNode(node); me.fireEvent('append', null, node); me.fireEvent('rootchange', node); } - + return node; }, - + flatten: function(){ var nodes = [], hash = this.nodeHash, key; - + for (key in hash) { if (hash.hasOwnProperty(key)) { nodes.push(hash[key]); @@ -52673,20 +54471,20 @@ Ext.define('Ext.data.Tree', { } return nodes; }, - + onNodeInsert: function(parent, node) { - this.registerNode(node); + this.registerNode(node, true); }, - + onNodeAppend: function(parent, node) { - this.registerNode(node); + this.registerNode(node, true); }, - + onNodeRemove: function(parent, node) { - this.unregisterNode(node); + this.unregisterNode(node, true); }, @@ -52695,20 +54493,30 @@ Ext.define('Ext.data.Tree', { }, - registerNode : function(node) { + registerNode : function(node, includeChildren) { this.nodeHash[node.getId() || node.internalId] = node; + if (includeChildren === true) { + node.eachChild(function(child){ + this.registerNode(child, true); + }, this); + } }, - unregisterNode : function(node) { + unregisterNode : function(node, includeChildren) { delete this.nodeHash[node.getId() || node.internalId]; + if (includeChildren === true) { + node.eachChild(function(child){ + this.unregisterNode(child, true); + }, this); + } }, - + sort: function(sorterFn, recursive) { this.getRootNode().sort(sorterFn, recursive); }, - + filter: function(filters, recursive) { this.getRootNode().filter(filters, recursive); @@ -52721,6 +54529,8 @@ Ext.define('Ext.data.TreeStore', { requires: ['Ext.data.Tree', 'Ext.data.NodeInterface', 'Ext.data.NodeStore'], + + clearOnLoad : true, @@ -52728,21 +54538,20 @@ Ext.define('Ext.data.TreeStore', { defaultRootId: 'root', - + defaultRootProperty: 'children', folderSort: false, - + constructor: function(config) { - var me = this, + var me = this, root, fields; - - + config = Ext.apply({}, config); - + fields = config.fields || me.fields; if (!fields) { @@ -52750,76 +54559,75 @@ Ext.define('Ext.data.TreeStore', { } me.callParent([config]); - + 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, [ "append", - + "remove", - + "move", - + "insert", - + "beforeappend", - + "beforeremove", - + "beforemove", - + "beforeinsert", - + "expand", - + "collapse", - + "beforeexpand", - + "beforecollapse", - - "sort", - "rootchange" ]); - + + 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.addEvents( - 'rootchange' + 'sort' ); - + if (Ext.isDefined(me.nodeParameter)) { if (Ext.isDefined(Ext.global.console)) { Ext.global.console.warn('Ext.data.TreeStore: nodeParameter has been deprecated. Please use nodeParam instead.'); @@ -52828,12 +54636,12 @@ Ext.define('Ext.data.TreeStore', { delete me.nodeParameter; } }, - + setProxy: function(proxy) { var reader, needsRoot; - + if (proxy instanceof Ext.data.proxy.Proxy) { needsRoot = Ext.isEmpty(proxy.getReader().root); @@ -52853,17 +54661,17 @@ Ext.define('Ext.data.TreeStore', { reader.buildExtractors(true); } }, - + onBeforeSort: function() { if (this.folderSort) { this.sort({ property: 'leaf', direction: 'ASC' - }, 'prepend', false); + }, 'prepend', false); } }, - + onBeforeNodeExpand: function(node, callback, scope) { if (node.isLoaded()) { @@ -52880,10 +54688,10 @@ Ext.define('Ext.data.TreeStore', { callback: function() { Ext.callback(callback, scope || node, [node.childNodes]); } - }); + }); } }, - + getNewRecords: function() { return Ext.Array.filter(this.tree.flatten(), this.filterNew); @@ -52893,28 +54701,28 @@ Ext.define('Ext.data.TreeStore', { getUpdatedRecords: function() { return Ext.Array.filter(this.tree.flatten(), this.filterUpdated); }, - + onBeforeNodeCollapse: function(node, callback, scope) { callback.call(scope || node, node.childNodes); }, - + onNodeRemove: function(parent, node) { var removed = this.removed; - + if (!node.isReplace && Ext.Array.indexOf(removed, node) == -1) { removed.push(node); } }, - + onNodeAdded: function(parent, node) { var proxy = this.getProxy(), reader = proxy.getReader(), data = node.raw || node.data, dataRoot, children; - - Ext.Array.remove(this.removed, node); - + + Ext.Array.remove(this.removed, node); + if (!node.isLeaf() && !node.isLoaded()) { dataRoot = reader.getRoot(data); if (dataRoot) { @@ -52923,12 +54731,12 @@ Ext.define('Ext.data.TreeStore', { } } }, - + setRootNode: function(root) { var me = this; - root = root || {}; + root = root || {}; if (!root.isNode) { Ext.applyIf(root, { @@ -52943,20 +54751,20 @@ Ext.define('Ext.data.TreeStore', { me.getProxy().getReader().buildExtractors(true); - + me.tree.setRootNode(root); + - - if (!root.isLoaded() && root.isExpanded()) { + if (!root.isLoaded() && (me.autoLoad === true || root.isExpanded())) { me.load({ node: root }); } - + return root; }, - + getRootNode: function() { return this.tree.getRootNode(); @@ -52971,11 +54779,11 @@ Ext.define('Ext.data.TreeStore', { load: function(options) { options = options || {}; options.params = options.params || {}; - + var me = this, node = options.node || me.tree.getRootNode(), root; - + if (!node) { @@ -52983,23 +54791,23 @@ Ext.define('Ext.data.TreeStore', { expanded: true }); } - + if (me.clearOnLoad) { - node.removeAll(); + node.removeAll(true); } - + Ext.applyIf(options, { node: node }); options.params[me.nodeParam] = node ? node.getId() : 'root'; - + if (node) { node.set('loading', true); } - + return me.callParent([options]); }, - + fillNode: function(node, records) { @@ -53013,12 +54821,12 @@ Ext.define('Ext.data.TreeStore', { sortCollection.sort(me.sorters.items); records = sortCollection.items; } - + node.set('loaded', true); for (; i < ln; i++) { node.appendChild(records[i], undefined, true); } - + return records; }, @@ -53029,17 +54837,21 @@ Ext.define('Ext.data.TreeStore', { records = operation.getRecords(), node = operation.node; + me.loading = false; node.set('loading', false); if (successful) { records = me.fillNode(node, records); } + + + me.fireEvent('read', me, operation.node, records, successful); me.fireEvent('load', me, operation.node, records, successful); Ext.callback(operation.callback, operation.scope || me, [records, operation, successful]); }, - + onCreateRecords: function(records, operation, success) { if (success) { @@ -53116,11 +54928,139 @@ Ext.define('Ext.data.TreeStore', { } else { me.tree.sort(sorterFn, true); me.fireEvent('datachanged', me); - } + } me.fireEvent('sort', me); } }); + +Ext.define('Ext.data.UuidGenerator', function () { + var twoPow14 = Math.pow(2, 14), + twoPow16 = Math.pow(2, 16), + twoPow28 = Math.pow(2, 28), + twoPow32 = Math.pow(2, 32); + + function toHex (value, length) { + var ret = value.toString(16); + if (ret.length > length) { + ret = ret.substring(ret.length - length); + } else if (ret.length < length) { + ret = Ext.String.leftPad(ret, length, '0'); + } + return ret; + } + + function rand (lo, hi) { + var v = Math.random() * (hi - lo + 1); + return Math.floor(v) + lo; + } + + function split (bignum) { + if (typeof(bignum) == 'number') { + var hi = Math.floor(bignum / twoPow32); + return { + lo: Math.floor(bignum - hi * twoPow32), + hi: hi + }; + } + return bignum; + } + + return { + extend: 'Ext.data.IdGenerator', + + alias: 'idgen.uuid', + + id: 'uuid', + + + + + + + version: 4, + + constructor: function() { + var me = this; + + me.callParent(arguments); + + me.parts = []; + me.init(); + }, + + generate: function () { + var me = this, + parts = me.parts, + ts = me.timestamp; + + + parts[0] = toHex(ts.lo, 8); + parts[1] = toHex(ts.hi & 0xFFFF, 4); + parts[2] = toHex(((ts.hi >>> 16) & 0xFFF) | (me.version << 12), 4); + parts[3] = toHex(0x80 | ((me.clockSeq >>> 8) & 0x3F), 2) + + toHex(me.clockSeq & 0xFF, 2); + parts[4] = toHex(me.salt.hi, 4) + toHex(me.salt.lo, 8); + + if (me.version == 4) { + me.init(); + } else { + + ++ts.lo; + if (ts.lo >= twoPow32) { + ts.lo = 0; + ++ts.hi; + } + } + + return parts.join('-').toLowerCase(); + }, + + getRecId: function (rec) { + return rec.getId(); + }, + + + init: function () { + var me = this, + salt, time; + + if (me.version == 4) { + + + + + me.clockSeq = rand(0, twoPow14-1); + + + salt = me.salt || (me.salt = {}); + time = me.timestamp || (me.timestamp = {}); + + + salt.lo = rand(0, twoPow32-1); + salt.hi = rand(0, twoPow16-1); + time.lo = rand(0, twoPow32-1); + time.hi = rand(0, twoPow28-1); + } else { + + me.salt = split(me.salt); + me.timestamp = split(me.timestamp); + + + + me.salt.hi |= 0x100; + } + }, + + + reconfigure: function (config) { + Ext.apply(this, config); + this.init(); + } + }; +}()); + + Ext.define('Ext.data.XmlStore', { extend: 'Ext.data.Store', alternateClassName: 'Ext.data.XmlStore', @@ -53147,10 +55087,9 @@ Ext.define('Ext.data.XmlStore', { Ext.define('Ext.data.proxy.Client', { extend: 'Ext.data.proxy.Proxy', alternateClassName: 'Ext.data.ClientProxy', - + clear: function() { - Ext.Error.raise("The Ext.data.proxy.Client subclass that you are using has not defined a 'clear' function. See src/data/ClientProxy.js for details."); } }); @@ -53199,12 +55138,12 @@ Ext.define('Ext.data.proxy.JsonP', { disableCaching: false, callback: me.createRequestCallback(request, operation, callback, scope) }); - + if (me.autoAppendParams) { request.params = {}; } - + request.jsonp = Ext.data.JsonP.request(request); request.params = params; @@ -53223,7 +55162,7 @@ Ext.define('Ext.data.proxy.JsonP', { me.processResponse(success, operation, request, response, callback, scope); }; }, - + setException: function(operation, response) { operation.setException(operation.request.jsonp.errorType); @@ -53240,7 +55179,7 @@ Ext.define('Ext.data.proxy.JsonP', { filter, i; delete params.filters; - + if (me.autoAppendParams) { url = Ext.urlAppend(url, Ext.Object.toQueryString(params)); } @@ -53297,27 +55236,21 @@ Ext.define('Ext.data.proxy.JsonP', { Ext.define('Ext.data.proxy.WebStorage', { extend: 'Ext.data.proxy.Client', alternateClassName: 'Ext.data.WebStorageProxy', - + id: undefined, constructor: function(config) { this.callParent(arguments); - + this.cache = {}; - if (this.getStorageObject() === undefined) { - Ext.Error.raise("Local Storage is not supported in this browser, please use another type of data proxy"); - } this.id = this.id || (this.store ? this.store.storeId : undefined); - if (this.id === undefined) { - Ext.Error.raise("No unique id was provided to the local storage proxy. See Ext.data.proxy.LocalStorage documentation for details"); - } this.initialize(); }, @@ -53328,7 +55261,7 @@ Ext.define('Ext.data.proxy.WebStorage', { length = records.length, ids = this.getIds(), id, record, i; - + operation.setStarted(); for (i = 0; i < length; i++) { @@ -53363,11 +55296,11 @@ Ext.define('Ext.data.proxy.WebStorage', { ids = this.getIds(), length = ids.length, i, recordData, record; - + if (operation.id) { record = this.getRecord(operation.id); - + if (record) { records.push(record); operation.setSuccessful(); @@ -53378,7 +55311,7 @@ Ext.define('Ext.data.proxy.WebStorage', { } operation.setSuccessful(); } - + operation.setCompleted(); operation.resultSet = Ext.create('Ext.data.ResultSet', { @@ -53404,7 +55337,7 @@ Ext.define('Ext.data.proxy.WebStorage', { for (i = 0; i < length; i++) { record = records[i]; this.setRecord(record); - + id = record.getId(); @@ -53438,7 +55371,7 @@ Ext.define('Ext.data.proxy.WebStorage', { } this.setIds(newIds); - + operation.setCompleted(); operation.setSuccessful(); @@ -53473,7 +55406,7 @@ Ext.define('Ext.data.proxy.WebStorage', { this.cache[id] = record; } - + return this.cache[id]; }, @@ -53507,10 +55440,10 @@ Ext.define('Ext.data.proxy.WebStorage', { obj = me.getStorageObject(); key = me.getRecordKey(id); - + me.cache[id] = record; - + obj.removeItem(key); obj.setItem(key, Ext.encode(data)); @@ -53520,7 +55453,7 @@ Ext.define('Ext.data.proxy.WebStorage', { removeRecord: function(id, updateIds) { var me = this, ids; - + if (id.isModel) { id = id.getId(); } @@ -53569,9 +55502,9 @@ Ext.define('Ext.data.proxy.WebStorage', { setIds: function(ids) { var obj = this.getStorageObject(), str = ids.join(","); - + obj.removeItem(this.id); - + if (!Ext.isEmpty(str)) { obj.setItem(this.id, str); } @@ -53583,15 +55516,15 @@ Ext.define('Ext.data.proxy.WebStorage', { key = this.getRecordCounterKey(), last = obj.getItem(key), ids, id; - + if (last === null) { ids = this.getIds(); last = ids[ids.length - 1] || 0; } - + id = parseInt(last, 10) + 1; obj.setItem(key, id); - + return id; }, @@ -53620,7 +55553,6 @@ Ext.define('Ext.data.proxy.WebStorage', { getStorageObject: function() { - Ext.Error.raise("The getStorageObject function has not been defined in your Ext.data.proxy.WebStorage subclass"); } }); @@ -53746,16 +55678,18 @@ Ext.define('Ext.data.reader.Array', { this.callParent(arguments); var fields = this.model.prototype.fields.items, + i = 0, length = fields.length, extractorFunctions = [], - i; + map; - for (i = 0; i < length; i++) { + for (; i < length; i++) { + map = fields[i].mapping; extractorFunctions.push(function(index) { return function(data) { return data[index]; }; - }(fields[i].mapping || i)); + }(map !== null ? map : i)); } this.extractorFunctions = extractorFunctions; @@ -53767,47 +55701,37 @@ Ext.define('Ext.data.reader.Xml', { extend: 'Ext.data.reader.Reader', alternateClassName: 'Ext.data.XmlReader', alias : 'reader.xml', - + createAccessor: function(expr) { var me = this; - + if (Ext.isEmpty(expr)) { return Ext.emptyFn; } - + if (Ext.isFunction(expr)) { return expr; } - + 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; }, getResponseData: function(response) { var xml = response.responseXML; - if (!xml) { - Ext.Error.raise({ - response: response, - msg: 'XML data not found in the response' - }); - } return xml; }, @@ -53821,7 +55745,7 @@ Ext.define('Ext.data.reader.Xml', { getRoot: function(data) { var nodeName = data.nodeName, root = this.root; - + if (!root || (nodeName && nodeName == root)) { return data; } else if (Ext.DomQuery.isXml(data)) { @@ -53835,11 +55759,8 @@ Ext.define('Ext.data.reader.Xml', { extractData: function(root) { var recordName = this.record; - - if (!recordName) { - Ext.Error.raise('Record is a required parameter'); - } - + + if (recordName != root.nodeName) { root = Ext.DomQuery.select(recordName, root); } else { @@ -53847,7 +55768,7 @@ Ext.define('Ext.data.reader.Xml', { } return this.callParent([root]); }, - + getAssociatedDataRoot: function(data, associationName) { return Ext.DomQuery.select(associationName, data)[0]; @@ -53859,14 +55780,13 @@ Ext.define('Ext.data.reader.Xml', { if (Ext.isArray(doc)) { doc = doc[0]; } - + this.xmlData = doc; return this.callParent([doc]); } }); - Ext.define('Ext.data.writer.Xml', { @@ -53935,21 +55855,22 @@ Ext.define('Ext.data.writer.Xml', { Ext.define('Ext.direct.Event', { + - - + alias: 'direct.event', - + requires: ['Ext.direct.Manager'], + - - + status: true, + constructor: function(config) { Ext.apply(this, config); }, - + getData: function(){ return this.data; @@ -53989,36 +55910,36 @@ Ext.define('Ext.direct.ExceptionEvent', { Ext.define('Ext.direct.Provider', { + - - + alias: 'direct.provider', - + mixins: { - observable: 'Ext.util.Observable' + observable: 'Ext.util.Observable' }, - + + - - + constructor : function(config){ var me = this; - + Ext.apply(me, config); me.addEvents( - + 'connect', - + 'disconnect', - + 'data', - + 'exception' ); me.mixins.observable.constructor.call(me, config); }, - + isConnected: function(){ return false; @@ -54026,7 +55947,7 @@ Ext.define('Ext.direct.Provider', { connect: Ext.emptyFn, - + disconnect: Ext.emptyFn }); @@ -54034,17 +55955,17 @@ Ext.define('Ext.direct.Provider', { Ext.define('Ext.direct.JsonProvider', { + - - + extend: 'Ext.direct.Provider', - + alias: 'direct.jsonprovider', - + uses: ['Ext.direct.ExceptionEvent'], + - - + parseResponse: function(response){ if (!Ext.isEmpty(response.responseText)) { @@ -54063,7 +55984,7 @@ Ext.define('Ext.direct.JsonProvider', { event, i = 0, len; - + try{ data = this.parseResponse(response); } catch(e) { @@ -54075,7 +55996,7 @@ Ext.define('Ext.direct.JsonProvider', { }); return [event]; } - + if (Ext.isArray(data)) { for (len = data.length; i < len; ++i) { events.push(this.createEvent(data[i])); @@ -54085,7 +56006,7 @@ Ext.define('Ext.direct.JsonProvider', { } return events; }, - + createEvent: function(response){ return Ext.create('direct.' + response.type, response); @@ -54154,7 +56075,6 @@ Ext.define('Ext.direct.PollingProvider', { }); me.fireEvent('connect', me); } else if (!url) { - Ext.Error.raise('Error initializing PollingProvider, no url configured.'); } }, @@ -54193,12 +56113,12 @@ Ext.define('Ext.direct.PollingProvider', { }); Ext.define('Ext.direct.RemotingMethod', { - + constructor: function(config){ var me = this, params = Ext.isDefined(config.params) ? config.params : config.len, name; - + me.name = config.name; me.formHandler = config.formHandler; if (Ext.isNumber(params)) { @@ -54214,7 +56134,7 @@ Ext.define('Ext.direct.RemotingMethod', { }); } }, - + getCallData: function(args){ var me = this, @@ -54224,7 +56144,7 @@ Ext.define('Ext.direct.RemotingMethod', { callback, scope, name; - + if (me.ordered) { callback = args[len]; scope = args[len + 1]; @@ -54235,7 +56155,7 @@ Ext.define('Ext.direct.RemotingMethod', { data = Ext.apply({}, args[0]); callback = args[1]; scope = args[2]; - + for (name in data) { if (data.hasOwnProperty(name)) { @@ -54245,11 +56165,11 @@ Ext.define('Ext.direct.RemotingMethod', { } } } - + return { data: data, callback: callback, - scope: scope + scope: scope }; } }); @@ -54267,7 +56187,8 @@ Ext.define('Ext.direct.Transaction', { }, - + + constructor: function(config){ var me = this; @@ -54399,7 +56320,6 @@ Ext.define('Ext.direct.RemotingProvider', { me.connected = true; me.fireEvent('connect', me); } else if(!me.url) { - Ext.Error.raise('Error initializing RemotingProvider, no url configured.'); } }, @@ -54770,14 +56690,14 @@ Ext.define('Ext.draw.Matrix', { toFilter: function() { var me = this; - return "progid:DXImageTransform.Microsoft.Matrix(M11=" + me.get(0, 0) + + return "progid:DXImageTransform.Microsoft.Matrix(sizingMethod='auto expand',FilterType=bilinear,M11=" + me.get(0, 0) + ", M12=" + me.get(0, 1) + ", M21=" + me.get(1, 0) + ", M22=" + me.get(1, 1) + ", Dx=" + me.get(0, 2) + ", Dy=" + me.get(1, 2) + ")"; }, offset: function() { var matrix = this.matrix; - return [matrix[0][2].toFixed(4), matrix[1][2].toFixed(4)]; + return [(matrix[0][2] || 0).toFixed(4), (matrix[1][2] || 0).toFixed(4)]; }, @@ -54798,7 +56718,7 @@ Ext.define('Ext.draw.Matrix', { row; - row = [[matrix[0][0], matrix[0][1]], [matrix[1][1], matrix[1][1]]]; + row = [[matrix[0][0], matrix[0][1]], [matrix[1][0], matrix[1][1]]]; out.scaleX = Math.sqrt(norm(row[0])); normalize(row[0]); @@ -54818,6 +56738,7 @@ Ext.define('Ext.draw.Matrix', { } }); + Ext.define('Ext.draw.SpriteDD', { extend: 'Ext.dd.DragSource', @@ -54847,7 +56768,7 @@ Ext.define('Ext.draw.SpriteDD', { bbox = sprite.getBBox(); try { - pos = Ext.core.Element.getXY(el); + pos = Ext.Element.getXY(el); } catch (e) { } if (!pos) { @@ -54866,38 +56787,35 @@ Ext.define('Ext.draw.SpriteDD', { startDrag: function(x, y) { var me = this, - attr = me.sprite.attr, - trans = attr.translation; - if (me.sprite.vml) { - me.prevX = x + attr.x; - me.prevY = y + attr.y; - } else { - me.prevX = x - trans.x; - me.prevY = y - trans.y; - } + attr = me.sprite.attr; + me.prev = me.sprite.surface.transformToViewBox(x, y); }, onDrag: function(e) { var xy = e.getXY(), me = this, sprite = me.sprite, - attr = sprite.attr; - me.translateX = xy[0] - me.prevX; - me.translateY = xy[1] - me.prevY; + attr = sprite.attr, dx, dy; + xy = me.sprite.surface.transformToViewBox(xy[0], xy[1]); + dx = xy[0] - me.prev[0]; + dy = xy[1] - me.prev[1]; sprite.setAttributes({ translate: { - x: me.translateX, - y: me.translateY + x: attr.translation.x + dx, + y: attr.translation.y + dy } }, true); - if (sprite.vml) { - me.prevX = xy[0] + attr.x || 0; - me.prevY = xy[1] + attr.y || 0; - } + me.prev = xy; + }, + + setDragElPos: function () { + + return false; } }); Ext.define('Ext.draw.Sprite', { + mixins: { @@ -54909,6 +56827,38 @@ Ext.define('Ext.draw.Sprite', { + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + dirty: false, dirtyHidden: false, dirtyTransform: false, @@ -54987,6 +56937,7 @@ Ext.define('Ext.draw.Sprite', { }, + initDraggable: function() { var me = this; me.draggable = true; @@ -55059,7 +57010,7 @@ Ext.define('Ext.draw.Sprite', { rotate = attrs.rotate; rotation = spriteAttrs.rotation; if (rotate) { - if ((rotate.x && rotate.x !== rotation.x) || + if ((rotate.x && rotate.x !== rotation.x) || (rotate.y && rotate.y !== rotation.y) || (rotate.degrees && rotate.degrees !== rotation.degrees)) { Ext.apply(rotation, rotate); @@ -55071,7 +57022,7 @@ Ext.define('Ext.draw.Sprite', { scale = attrs.scale; scaling = spriteAttrs.scaling; if (scale) { - if ((scale.x && scale.x !== scaling.x) || + if ((scale.x && scale.x !== scaling.x) || (scale.y && scale.y !== scaling.y) || (scale.cx && scale.cx !== scaling.cx) || (scale.cy && scale.cy !== scaling.cy)) { @@ -55094,7 +57045,7 @@ Ext.define('Ext.draw.Sprite', { getBBox: function() { return this.surface.getBBox(this); }, - + setText: function(text) { return this.surface.setText(this, text); }, @@ -55171,7 +57122,7 @@ Ext.define('Ext.draw.engine.Svg', { extend: 'Ext.draw.Surface', - requires: ['Ext.draw.Draw', 'Ext.draw.Sprite', 'Ext.draw.Matrix', 'Ext.core.Element'], + requires: ['Ext.draw.Draw', 'Ext.draw.Sprite', 'Ext.draw.Matrix', 'Ext.Element'], @@ -55191,6 +57142,8 @@ Ext.define('Ext.draw.engine.Svg', { strokeOpacity: "stroke-opacity", strokeLinejoin: "stroke-linejoin" }, + + parsers: {}, minDefaults: { circle: { @@ -55594,6 +57547,12 @@ Ext.define('Ext.draw.engine.Svg', { el = sprite.el, group = sprite.group, sattr = sprite.attr, + parsers = me.parsers, + + + + gradientsMap = me.gradientsMap || {}, + safariFix = Ext.isSafari && !Ext.isStrict, groups, i, ln, attrs, font, key, style, name, rect; if (group) { @@ -55619,7 +57578,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; @@ -55646,9 +57604,22 @@ Ext.define('Ext.draw.engine.Svg', { } for (key in attrs) { if (attrs.hasOwnProperty(key) && attrs[key] != null) { - el.dom.setAttribute(key, attrs[key]); + + + + + + 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); } @@ -55700,17 +57671,19 @@ Ext.define('Ext.draw.engine.Svg', { applyZIndex: function(sprite) { - var idx = this.normalizeSpriteCollection(sprite), + var me = this, + items = me.items, + idx = items.indexOf(sprite), el = sprite.el, prevEl; - if (this.el.dom.childNodes[idx + 2] !== el.dom) { + if (me.el.dom.childNodes[idx + 2] !== el.dom) { if (idx > 0) { do { - prevEl = this.items.getAt(--idx).el; + prevEl = items.getAt(--idx).el; } while (!prevEl && idx > 0); } - el.insertAfter(prevEl || this.bgRect); + el.insertAfter(prevEl || me.bgRect); } sprite.zIndexDirty = false; }, @@ -55723,40 +57696,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); + + + + 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; }, @@ -55806,7 +57788,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); } } } @@ -55832,7 +57814,7 @@ Ext.define('Ext.draw.engine.Vml', { extend: 'Ext.draw.Surface', - requires: ['Ext.draw.Draw', 'Ext.draw.Color', 'Ext.draw.Sprite', 'Ext.draw.Matrix', 'Ext.core.Element'], + requires: ['Ext.draw.Draw', 'Ext.draw.Color', 'Ext.draw.Sprite', 'Ext.draw.Matrix', 'Ext.Element'], @@ -55854,8 +57836,11 @@ Ext.define('Ext.draw.engine.Vml', { coordsize: 1000, coordorigin: '0 0', - // @private - // Convert an SVG standard path into a VML path + // VML uses CSS z-index and therefore doesn't need sprites to be kept in zIndex order + orderSpritesByZIndex: false, + + + path2vml: function (path) { var me = this, nonVML = me.NonVmlPathRe, @@ -55899,7 +57884,7 @@ Ext.define('Ext.draw.engine.Vml', { return res.join(" "); }, - // @private - set of attributes which need to be translated from the sprite API to the native browser API + translateAttrs: { radius: "r", radiusX: "rx", @@ -55910,7 +57895,7 @@ Ext.define('Ext.draw.engine.Vml', { strokeLinejoin: "stroke-linejoin" }, - // @private - Minimun set of defaults for different types of sprites. + minDefaults: { circle: { fill: "none", @@ -55977,17 +57962,17 @@ Ext.define('Ext.draw.engine.Vml', { } }, - // private + onMouseEnter: function(e) { this.fireEvent("mouseenter", e); }, - // private + onMouseLeave: function(e) { this.fireEvent("mouseleave", e); }, - // @private - Normalize a delegated single event from the main container to each sprite and sprite group + processEvent: function(name, e) { var target = e.getTarget(), surface = this.surface, @@ -55999,7 +57984,7 @@ Ext.define('Ext.draw.engine.Vml', { } }, - // Create the VML element/elements and append them to the DOM + createSpriteElement: function(sprite) { var me = this, attr = sprite.attr, @@ -56007,7 +57992,7 @@ Ext.define('Ext.draw.engine.Vml', { zoom = me.zoom, vml = sprite.vml || (sprite.vml = {}), round = Math.round, - el = (type === 'image') ? me.createNode('image') : me.createNode('shape'), + el = me.createNode('shape'), path, skew, textPath; el.coordsize = zoom + ' ' + zoom; @@ -56039,7 +58024,7 @@ Ext.define('Ext.draw.engine.Vml', { return sprite.el; }, - // @private - Get bounding box for the sprite. The Sprite itself has the public method. + getBBox: function (sprite, isWithoutTransform) { var realPath = this["getPath" + sprite.type](sprite); if (isWithoutTransform) { @@ -56084,24 +58069,9 @@ Ext.define('Ext.draw.engine.Vml', { me.setZIndex(sprite); } - // Apply minimum default attributes + Ext.applyIf(scrubbedAttrs, me.minDefaults[sprite.type]); - if (sprite.type == 'image') { - Ext.apply(sprite.attr, { - x: scrubbedAttrs.x, - y: scrubbedAttrs.y, - width: scrubbedAttrs.width, - height: scrubbedAttrs.height - }); - bbox = sprite.getBBox(); - el.setStyle({ - width: bbox.width + 'px', - height: bbox.height + 'px' - }); - dom.src = scrubbedAttrs.src; - } - if (dom.href) { dom.href = scrubbedAttrs.href; } @@ -56115,13 +58085,13 @@ Ext.define('Ext.draw.engine.Vml', { dom.cursor = scrubbedAttrs.cursor; } - // Change visibility + if (sprite.dirtyHidden) { (scrubbedAttrs.hidden) ? me.hidePrim(sprite) : me.showPrim(sprite); sprite.dirtyHidden = false; } - // Update path + if (sprite.dirtyPath) { if (sprite.type == "circle" || sprite.type == "ellipse") { var cx = scrubbedAttrs.x, @@ -56136,34 +58106,34 @@ Ext.define('Ext.draw.engine.Vml', { Math.round(cx * me.zoom)); sprite.dirtyPath = false; } - else if (sprite.type !== "text" && sprite.type !== 'image') { + else if (sprite.type !== "text") { sprite.attr.path = scrubbedAttrs.path = me.setPaths(sprite, scrubbedAttrs) || scrubbedAttrs.path; dom.path = me.path2vml(scrubbedAttrs.path); sprite.dirtyPath = false; } } - // Apply clipping + if ("clip-rect" in scrubbedAttrs) { me.setClip(sprite, scrubbedAttrs); } - // Handle text (special handling required) + if (sprite.type == "text") { me.setTextAttributes(sprite, scrubbedAttrs); } - // Handle fill and opacity - if (scrubbedAttrs.opacity || scrubbedAttrs['stroke-opacity'] || scrubbedAttrs.fill) { + + if (sprite.type == 'image' || scrubbedAttrs.opacity || scrubbedAttrs['fill-opacity'] || scrubbedAttrs.fill) { me.setFill(sprite, scrubbedAttrs); } - // Handle stroke (all fills require a stroke element) + if (scrubbedAttrs.stroke || scrubbedAttrs['stroke-opacity'] || scrubbedAttrs.fill) { me.setStroke(sprite, scrubbedAttrs); } - //set styles + style = spriteAttr.style; if (style) { el.setStyle(style); @@ -56181,10 +58151,10 @@ Ext.define('Ext.draw.engine.Vml', { } }, - // Normalize all virtualized types into paths. + setPaths: function(sprite, params) { var spriteAttr = sprite.attr; - // Clear bbox cache + sprite.bbox.plain = null; sprite.bbox.transform = null; if (sprite.type == 'circle') { @@ -56196,7 +58166,7 @@ Ext.define('Ext.draw.engine.Vml', { spriteAttr.ry = params.ry; return Ext.draw.Draw.ellipsePath(sprite); } - else if (sprite.type == 'rect') { + else if (sprite.type == 'rect' || sprite.type == 'image') { spriteAttr.rx = spriteAttr.ry = params.r; return Ext.draw.Draw.rectPath(sprite); } @@ -56208,23 +58178,27 @@ Ext.define('Ext.draw.engine.Vml', { setFill: function(sprite, params) { var me = this, - el = sprite.el.dom, - fillEl = el.fill, - newfill = false, + el = sprite.el, + dom = el.dom, + fillEl = dom.getElementsByTagName('fill')[0], opacity, gradient, fillUrl, rotation, angle; - if (!fillEl) { - // NOT an expando (but it sure looks like one)... - fillEl = el.fill = me.createNode("fill"); - newfill = true; + if (fillEl) { + dom.removeChild(fillEl); + } else { + fillEl = me.createNode('fill'); } if (Ext.isArray(params.fill)) { params.fill = params.fill[0]; } - if (params.fill == "none") { + if (sprite.type == 'image') { + fillEl.on = true; + fillEl.src = params.src; + fillEl.type = "tile"; + fillEl.rotate = true; + } else if (params.fill == "none") { fillEl.on = false; - } - else { + } else { if (typeof params.opacity == "number") { fillEl.opacity = params.opacity; } @@ -56236,39 +58210,38 @@ Ext.define('Ext.draw.engine.Vml', { fillUrl = params.fill.match(me.fillUrlRe); if (fillUrl) { fillUrl = fillUrl[1]; - // If the URL matches one of the registered gradients, render that gradient + if (fillUrl.charAt(0) == "#") { gradient = me.gradientsColl.getByKey(fillUrl.substring(1)); } if (gradient) { - // VML angle is offset and inverted from standard, and must be adjusted to match rotation transform + rotation = params.rotation; angle = -(gradient.angle + 270 + (rotation ? rotation.degrees : 0)) % 360; - // IE will flip the angle at 0 degrees... + if (angle === 0) { angle = 180; } fillEl.angle = angle; fillEl.type = "gradient"; fillEl.method = "sigma"; - fillEl.colors.value = gradient.colors; + fillEl.colors = gradient.colors; } - // Otherwise treat it as an image + else { fillEl.src = fillUrl; fillEl.type = "tile"; + fillEl.rotate = true; } } else { - fillEl.color = Ext.draw.Color.toHex(params.fill); + fillEl.color = Ext.draw.Color.toHex(params.fill) || params.fill; fillEl.src = ""; fillEl.type = "solid"; } } } - if (newfill) { - el.appendChild(fillEl); - } + dom.appendChild(fillEl); }, setStroke: function(sprite, params) { @@ -56291,7 +58264,7 @@ Ext.define('Ext.draw.engine.Vml', { else { strokeEl.on = true; if (params.stroke && !params.stroke.match(me.fillUrlRe)) { - // VML does NOT support a gradient stroke :( + strokeEl.color = Ext.draw.Color.toHex(params.stroke); } strokeEl.joinstyle = params["stroke-linejoin"]; @@ -56299,7 +58272,7 @@ Ext.define('Ext.draw.engine.Vml', { strokeEl.miterlimit = params["stroke-miterlimit"] || 8; width = parseFloat(params["stroke-width"] || 1) * 0.75; opacity = params["stroke-opacity"] || 1; - // VML Does not support stroke widths under 1, so we're going to fiddle with stroke-opacity instead. + if (Ext.isNumber(width) && width < 1) { strokeEl.weight = 1; strokeEl.opacity = opacity * width; @@ -56415,64 +58388,74 @@ 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) { + + if (width != undefined) { + me.el.setWidth(width); + } + if (height != undefined) { + me.el.setHeight(height); + } - - if (width != undefined) { - me.el.setWidth(width); - } - if (height != undefined) { - me.el.setHeight(height); + + 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(); + }, + + + applyViewBox: function() { + var me = this, + viewBox = me.viewBox, + width = me.width, + height = me.height, + viewBoxX, viewBoxY, viewBoxWidth, viewBoxHeight, + relativeHeight, relativeWidth, size; - 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); - + 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) { @@ -56490,24 +58473,26 @@ Ext.define('Ext.draw.engine.Vml', { this.callParent(arguments); }, + + createNode : (function () { + try { + var doc = Ext.getDoc().dom; + if (!doc.namespaces.rvml) { + doc.namespaces.add("rvml", "urn:schemas-microsoft-com:vml"); + } + return function (tagName) { + return doc.createElement("'); + }; + } catch (e) { + return function (tagName) { + return doc.createElement("<" + tagName + ' xmlns="urn:schemas-microsoft.com:vml" class="rvml">'); + }; + } + })(), + render: function (container) { var me = this, doc = Ext.getDoc().dom; - - if (!me.createNode) { - try { - if (!doc.namespaces.rvml) { - doc.namespaces.add("rvml", "urn:schemas-microsoft-com:vml"); - } - me.createNode = function (tagName) { - return doc.createElement("'); - }; - } catch (e) { - me.createNode = function (tagName) { - return doc.createElement("<" + tagName + ' xmlns="urn:schemas-microsoft.com:vml" class="rvml">'); - }; - } - } if (!me.el) { var el = doc.createElement("div"); @@ -56572,92 +58557,130 @@ Ext.define('Ext.draw.engine.Vml', { }; }, - transform: function(sprite) { + extractTransform: function (sprite) { var me = this, - matrix = Ext.create('Ext.draw.Matrix'), - transforms = sprite.transformations, - transformsLength = transforms.length, - i = 0, - deltaDegrees = 0, - deltaScaleX = 1, - deltaScaleY = 1, - flip = "", - el = sprite.el, - dom = el.dom, - domStyle = dom.style, - zoom = me.zoom, - skew = sprite.skew, - deltaX, deltaY, transform, type, compensate, y, fill, newAngle,zoomScaleX, zoomScaleY, newOrigin; + matrix = Ext.create('Ext.draw.Matrix'), scale, + transformstions, tranformationsLength, + transform, i = 0, + shift = me.viewBoxShift; - for (; i < transformsLength; i++) { - transform = transforms[i]; - type = transform.type; - if (type == "translate") { - matrix.translate(transform.x, transform.y); - } - else if (type == "rotate") { - matrix.rotate(transform.degrees, transform.x, transform.y); - deltaDegrees += transform.degrees; - } - else if (type == "scale") { - matrix.scale(transform.x, transform.y, transform.centerX, transform.centerY); - deltaScaleX *= transform.x; - deltaScaleY *= transform.y; + for(transformstions = sprite.transformations, tranformationsLength = transformstions.length; + i < tranformationsLength; i ++) { + transform = transformstions[i]; + switch (transform.type) { + case 'translate' : + matrix.translate(transform.x, transform.y); + break; + case 'rotate': + matrix.rotate(transform.degrees, transform.x, transform.y); + break; + case 'scale': + matrix.scale(transform.x || transform.scale, transform.y || transform.scale, transform.centerX, transform.centerY); + break; } } - if (me.viewBoxShift) { - matrix.scale(me.viewBoxShift.scale, me.viewBoxShift.scale, -1, -1); - matrix.add(1, 0, 0, 1, me.viewBoxShift.dx, me.viewBoxShift.dy); + if (shift) { + matrix.add(1, 0, 0, 1, shift.dx, shift.dy); + matrix.prepend(shift.scale, 0, 0, shift.scale, 0, 0); } + + return sprite.matrix = matrix; + }, - sprite.matrix = matrix; + setSimpleCoords: function(sprite, sx, sy, dx, dy, rotate) { + var me = this, + matrix = sprite.matrix, + dom = sprite.el.dom, + style = dom.style, + yFlipper = 1, + flip = "", + fill = dom.getElementsByTagName('fill')[0], + kx = me.zoom / sx, + ky = me.zoom / sy, + rotationCompensation; + if (!sx || !sy) { + return; + } + dom.coordsize = Math.abs(kx) + ' ' + Math.abs(ky); + style.rotation = rotate * (sx * sy < 0 ? -1 : 1); + if (rotate) { + rotationCompensation = me.rotationCompensation(rotate, dx, dy); + dx = rotationCompensation.x; + dy = rotationCompensation.y; + } + if (sx < 0) { + flip += "x" + } + if (sy < 0) { + flip += " y"; + yFlipper = -1; + } + style.flip = flip; + dom.coordorigin = (dx * -kx) + ' ' + (dy * -ky); + if (fill) { + dom.removeChild(fill); + rotationCompensation = me.rotationCompensation(rotate, matrix.x(sprite.x, sprite.y), matrix.y(sprite.x, sprite.y)); + fill.position = rotationCompensation.x * yFlipper + ' ' + rotationCompensation.y * yFlipper; + fill.size = sprite.width * Math.abs(sx) + ' ' + sprite.height * Math.abs(sy); + dom.appendChild(fill); + } + }, + + transform : function (sprite) { + var me = this, + el = sprite.el, + skew = sprite.skew, + dom = el.dom, + domStyle = dom.style, + matrix = me.extractTransform(sprite).clone(), + split, zoom = me.zoom, + fill = dom.getElementsByTagName('fill')[0], + isPatt = !String(sprite.fill).indexOf("url("), + offset, c; - if (sprite.type != "image" && skew) { + if (sprite.type != "image" && skew && !isPatt) { skew.matrix = matrix.toString(); - skew.offset = matrix.offset(); - } - else { - deltaX = matrix.matrix[0][2]; - deltaY = matrix.matrix[1][2]; - zoomScaleX = zoom / deltaScaleX; - zoomScaleY = zoom / deltaScaleY; - - dom.coordsize = Math.abs(zoomScaleX) + " " + Math.abs(zoomScaleY); - - newAngle = deltaDegrees * (deltaScaleX * ((deltaScaleY < 0) ? -1 : 1)); - if (newAngle != domStyle.rotation && !(newAngle === 0 && !domStyle.rotation)) { - domStyle.rotation = newAngle; - } - if (deltaDegrees) { - - compensate = me.rotationCompensation(deltaDegrees, deltaX, deltaY); - deltaX = compensate.x; - deltaY = compensate.y; - } - - if (deltaScaleX < 0) { - flip += "x"; - } - if (deltaScaleY < 0) { - flip += " y"; - y = -1; + offset = matrix.offset(); + if (offset[0] > 32767) { + offset[0] = 32767; + } else if (offset[0] < -32768) { + offset[0] = -32768 } - if (flip != "" && !dom.style.flip) { - domStyle.flip = flip; + if (offset[1] > 32767) { + offset[1] = 32767; + } else if (offset[1] < -32768) { + offset[1] = -32768 } - - - newOrigin = (deltaX * -zoomScaleX) + " " + (deltaY * -zoomScaleY); - if (newOrigin != dom.coordorigin) { - dom.coordorigin = (deltaX * -zoomScaleX) + " " + (deltaY * -zoomScaleY); + skew.offset = offset; + } else { + if (skew) { + skew.matrix = "1 0 0 1"; + skew.offset = "0 0"; + } + split = matrix.split(); + if (split.isSimple) { + domStyle.filter = ''; + me.setSimpleCoords(sprite, split.scaleX, split.scaleY, split.translateX, split.translateY, split.rotate / Math.PI * 180); + } else { + domStyle.filter = matrix.toFilter(); + var bb = me.getBBox(sprite), + dx = bb.x - sprite.x, + dy = bb.y - sprite.y; + dom.coordorigin = (dx * -zoom) + ' ' + (dy * -zoom); + if (fill) { + dom.removeChild(fill); + fill.position = dx + ' ' + dy; + fill.size = sprite.width * sprite.scale.x + ' ' + sprite.height * 1.1; + dom.appendChild(fill); + } } } }, @@ -56822,16 +58845,39 @@ Ext.define('Ext.layout.container.Fit', { extend: 'Ext.layout.container.AbstractFit', alias: 'layout.fit', alternateClassName: 'Ext.layout.FitLayout', + requires: ['Ext.layout.container.Box'], - + + + defaultMargins: { + top: 0, + right: 0, + bottom: 0, + left: 0 + }, + onLayout : function() { - var me = this; + var me = this, + size, + item, + margins; me.callParent(); if (me.owner.items.length) { - me.setItemBox(me.owner.items.get(0), me.getLayoutTargetSize()); + item = me.owner.items.get(0); + margins = item.margins || me.defaultMargins; + size = me.getLayoutTargetSize(); + size.width -= margins.width; + size.height -= margins.height; + me.setItemBox(item, size); + + + + if (margins.left || margins.top) { + item.setPosition(margins.left, margins.top); + } } }, @@ -56842,18 +58888,31 @@ 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) { + + + + item.layoutManagedHeight = 0; + item.layoutManagedWidth = 0; + + this.callParent(arguments); } +}, function() { + + + this.prototype.renderItem = Ext.layout.container.Box.prototype.renderItem; }); - Ext.define('Ext.layout.container.AbstractCard', { @@ -56873,7 +58932,7 @@ Ext.define('Ext.layout.container.AbstractCard', { beforeLayout: function() { var me = this; - me.activeItem = me.getActiveItem(); + me.getActiveItem(); if (me.activeItem && me.deferredRender) { me.renderItems([me.activeItem], me.getRenderTarget()); return true; @@ -56883,6 +58942,13 @@ Ext.define('Ext.layout.container.AbstractCard', { } }, + renderChildren: function () { + if (!this.deferredRender) { + this.getActiveItem(); + this.callParent(); + } + }, + onLayout: function() { var me = this, activeItem = me.activeItem, @@ -56968,38 +59034,38 @@ Ext.define('Ext.layout.container.AbstractCard', { }, - getNext: function(wrap) { - + getNext: function() { + var wrap = arguments[0]; var items = this.getLayoutItems(), index = Ext.Array.indexOf(items, this.activeItem); return items[index + 1] || (wrap ? items[0] : false); }, - next: function(anim, wrap) { - + next: function() { + var anim = arguments[0], wrap = arguments[1]; return this.setActiveItem(this.getNext(wrap), anim); }, - getPrev: function(wrap) { - + getPrev: function() { + 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); }, - prev: function(anim, wrap) { - + prev: function() { + var anim = arguments[0], wrap = arguments[1]; return this.setActiveItem(this.getPrev(wrap), anim); } }); @@ -57007,31 +59073,30 @@ 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'], - + allowDeselect: false, selected: null, - - + pruneRemoved: true, constructor: function(cfg) { var me = this; - + cfg = cfg || {}; Ext.apply(me, cfg); - + me.addEvents( - 'selectionchange' + 'selectionchange' ); me.modes = { @@ -57045,17 +59110,17 @@ Ext.define('Ext.selection.Model', { me.selected = Ext.create('Ext.util.MixedCollection'); - + me.callParent(arguments); }, bind : function(store, initial){ var me = this; - + if(!initial && me.store){ if(store !== me.store && me.store.autoDestroy){ - me.store.destroy(); + me.store.destroyStore(); }else{ me.store.un("add", me.onStoreAdd, me); me.store.un("clear", me.onStoreClear, me); @@ -57086,7 +59151,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); @@ -57103,7 +59168,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); @@ -57116,9 +59181,9 @@ Ext.define('Ext.selection.Model', { - selectWithEvent: function(record, e) { + selectWithEvent: function(record, e, keepExisting) { var me = this; - + switch (me.selectionMode) { case 'MULTI': if (e.ctrlKey && me.isSelected(record)) { @@ -57128,7 +59193,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); } @@ -57161,22 +59226,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); } - + if (startRow > endRow){ tmp = endRow; @@ -57195,7 +59260,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) { @@ -57207,21 +59272,24 @@ Ext.define('Ext.selection.Model', { } me.doMultiSelect(records, true); }, - + select: function(records, keepExisting, suppressEvent) { - this.doSelect(records, keepExisting, suppressEvent); + + if (Ext.isDefined(records)) { + this.doSelect(records, keepExisting, suppressEvent); + } }, deselect: function(records, suppressEvent) { this.doDeselect(records, suppressEvent); }, - + doSelect: function(records, keepExisting, suppressEvent) { var me = this, record; - + if (me.locked) { return; } @@ -57242,17 +59310,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; + } + + } + + function commit () { + selected.add(record); change = true; - me.doDeselect(me.getSelection(), suppressEvent); } for (; i < len; i++) { @@ -57260,11 +59335,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); @@ -57275,38 +59348,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); } } + - 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; } @@ -57315,16 +59399,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); }, @@ -57334,7 +59430,7 @@ Ext.define('Ext.selection.Model', { me.lastFocused = record; me.onLastFocusChanged(recordBeforeLast, record, supressFocus); }, - + isFocused: function(record) { return record === this.getLastFocused(); @@ -57354,7 +59450,7 @@ Ext.define('Ext.selection.Model', { getLastSelected: function() { return this.lastSelected; }, - + getLastFocused: function() { return this.lastFocused; }, @@ -57392,7 +59488,7 @@ Ext.define('Ext.selection.Model', { record = Ext.isNumber(record) ? this.store.getAt(record) : record; return this.selected.indexOf(record) !== -1; }, - + hasSelection: function() { return this.selected.getCount() > 0; @@ -57425,7 +59521,7 @@ Ext.define('Ext.selection.Model', { } me.clearSelections(); - + if (me.store.indexOf(lastFocused) !== -1) { this.setLastFocused(lastFocused, true); @@ -57435,17 +59531,16 @@ Ext.define('Ext.selection.Model', { me.doSelect(toBeSelected, false, true); } - + me.maybeFireSelectionChange(change); }, clearSelections: function() { - var me = this; - me.selected.clear(); - me.lastSelected = null; - me.setLastFocused(null); + this.selected.clear(); + this.lastSelected = null; + this.setLastFocused(null); }, @@ -57456,14 +59551,9 @@ Ext.define('Ext.selection.Model', { 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); } }, @@ -57473,7 +59563,7 @@ Ext.define('Ext.selection.Model', { onStoreRemove: function(store, record) { var me = this, selected = me.selected; - + if (me.locked || !me.pruneRemoved) { return; } @@ -57489,6 +59579,7 @@ Ext.define('Ext.selection.Model', { } }, + getCount: function() { return this.selected.getCount(); }, @@ -57526,25 +59617,31 @@ Ext.define('Ext.selection.Model', { Ext.define('Ext.selection.DataViewModel', { extend: 'Ext.selection.Model', - + requires: ['Ext.util.KeyNav'], deselectOnContainerClick: true, - + enableKeyNav: true, - + constructor: function(cfg){ this.addEvents( - 'deselect', + 'beforedeselect', + + 'beforeselect', + + + 'deselect', + 'select' ); this.callParent(arguments); }, - + bindComponent: function(view) { var me = this, eventListeners = { @@ -57574,15 +59671,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 }); @@ -57594,7 +59691,7 @@ Ext.define('Ext.selection.DataViewModel', { scope: me }); }, - + onNavKey: function(step) { step = step || 1; var me = this, @@ -57602,44 +59699,46 @@ 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); }, - 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); } } + }, + + destroy: function(){ + Ext.destroy(this.keyNav); + this.callParent(); } }); @@ -57647,6 +59746,15 @@ Ext.define('Ext.selection.DataViewModel', { Ext.define('Ext.state.CookieProvider', { extend: 'Ext.state.Provider', + + + + + + + + + constructor : function(config){ var me = this; me.path = "/"; @@ -57656,11 +59764,11 @@ Ext.define('Ext.state.CookieProvider', { me.callParent(arguments); me.state = me.readCookies(); }, - + set : function(name, value){ var me = this; - + if(typeof value == "undefined" || value === null){ me.clear(name); return; @@ -57685,7 +59793,7 @@ Ext.define('Ext.state.CookieProvider', { matches, name, value; - + while((matches = re.exec(c)) != null){ name = matches[1]; value = matches[2]; @@ -57699,7 +59807,7 @@ Ext.define('Ext.state.CookieProvider', { setCookie : function(name, value){ var me = this; - + document.cookie = me.prefix + name + "=" + me.encodeValue(value) + ((me.expires == null) ? "" : ("; expires=" + me.expires.toGMTString())) + ((me.path == null) ? "" : ("; path=" + me.path)) + @@ -57710,7 +59818,7 @@ Ext.define('Ext.state.CookieProvider', { clearCookie : function(name){ var me = this; - + document.cookie = me.prefix + name + "=null; expires=Thu, 01-Jan-70 00:00:01 GMT" + ((me.path == null) ? "" : ("; path=" + me.path)) + ((me.domain == null) ? "" : ("; domain=" + me.domain)) + @@ -57718,6 +59826,8 @@ Ext.define('Ext.state.CookieProvider', { } }); + + Ext.define('Ext.state.LocalStorageProvider', { @@ -57778,12 +59888,10 @@ Ext.define('Ext.state.LocalStorageProvider', { } catch (e) { return false; } - Ext.Error.raise('LocalStorage is not supported by the current browser'); } }); - Ext.define('Ext.util.Point', { @@ -57800,6 +59908,7 @@ Ext.define('Ext.util.Point', { + constructor: function(x, y) { this.callParent([y, x, y, x]); }, @@ -57837,6 +59946,196 @@ Ext.define('Ext.util.Point', { }); + +Ext.define('Ext.LoadMask', { + + extend: 'Ext.Component', + + alias: 'widget.loadmask', + + + + mixins: { + floating: 'Ext.util.Floating' + }, + + uses: ['Ext.data.StoreManager'], + + + + + + + msg : 'Loading...', + + msgCls : Ext.baseCSSPrefix + 'mask-loading', + + + useMsg: true, + + + disabled: false, + + baseCls: Ext.baseCSSPrefix + 'mask-msg', + + renderTpl: '
', + + + modal: true, + + + floating: { + shadow: 'frame' + }, + + + focusOnToFront: false, + + + constructor : function(el, config) { + var me = this; + + + if (el.isComponent) { + me.ownerCt = el; + me.bindComponent(el); + } + + else { + me.ownerCt = new Ext.Component({ + el: Ext.get(el), + rendered: true, + componentLayoutCounter: 1 + }); + me.container = el; + } + me.callParent([config]); + + if (me.store) { + me.bindStore(me.store, true); + } + me.renderData = { + msgCls: me.msgCls + }; + me.renderSelectors = { + msgEl: 'div' + }; + }, + + bindComponent: function(comp) { + this.mon(comp, { + resize: this.onComponentResize, + scope: this + }); + }, + + afterRender: function() { + this.callParent(arguments); + this.container = this.floatParent.getContentTarget(); + }, + + + onComponentResize: function() { + var me = this; + if (me.rendered && me.isVisible()) { + me.toFront(); + me.center(); + } + }, + + + bindStore : function(store, initial) { + var me = this; + + if (!initial && me.store) { + me.mun(me.store, { + scope: me, + beforeload: me.onBeforeLoad, + load: me.onLoad, + exception: me.onLoad + }); + if (!store) { + me.store = null; + } + } + if (store) { + store = Ext.data.StoreManager.lookup(store); + me.mon(store, { + scope: me, + beforeload: me.onBeforeLoad, + load: me.onLoad, + exception: me.onLoad + }); + + } + me.store = store; + if (store && store.isLoading()) { + me.onBeforeLoad(); + } + }, + + onDisable : function() { + this.callParent(arguments); + if (this.loading) { + this.onLoad(); + } + }, + + + onBeforeLoad : function() { + var me = this, + owner = me.ownerCt || me.floatParent, + origin; + if (!this.disabled) { + + + if (owner.componentLayoutCounter) { + Ext.Component.prototype.show.call(me); + } else { + + origin = owner.afterComponentLayout; + owner.afterComponentLayout = function() { + owner.afterComponentLayout = origin; + origin.apply(owner, arguments); + if(me.loading) { + Ext.Component.prototype.show.call(me); + } + }; + } + } + }, + + onHide: function(){ + var me = this; + me.callParent(arguments); + me.showOnParentShow = true; + }, + + onShow: function() { + var me = this, + msgEl = me.msgEl; + + me.callParent(arguments); + me.loading = true; + if (me.useMsg) { + msgEl.show().update(me.msg); + } else { + msgEl.parent().hide(); + } + }, + + afterShow: function() { + this.callParent(arguments); + this.center(); + }, + + + onLoad : function() { + this.loading = false; + Ext.Component.prototype.hide.call(this); + } +}); + Ext.define('Ext.view.AbstractView', { extend: 'Ext.Component', alternateClassName: 'Ext.view.AbstractView', @@ -57847,37 +60146,43 @@ 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); } }, - + + deferInitialRefresh: true, + + itemCls: Ext.baseCSSPrefix + 'dataview-item', - + loadingText: 'Loading...', + + loadMask: true, + - + loadingUseMsg: true, - + @@ -57901,12 +60206,12 @@ Ext.define('Ext.view.AbstractView', { last: false, - + triggerEvent: 'itemclick', triggerCtEvent: 'containerclick', - + addCmpEvents: function() { - + }, @@ -57915,7 +60220,7 @@ Ext.define('Ext.view.AbstractView', { isDef = Ext.isDefined, itemTpl = me.itemTpl, memberFn = {}; - + if (itemTpl) { if (Ext.isArray(itemTpl)) { @@ -57925,59 +60230,30 @@ 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('
{1}
', me.itemCls, itemTpl); me.tpl = Ext.create('Ext.XTemplate', itemTpl, memberFn); } - if (!isDef(me.tpl) || !isDef(me.itemSelector)) { - Ext.Error.raise({ - sourceClass: 'Ext.view.View', - tpl: me.tpl, - itemSelector: me.itemSelector, - msg: "DataView requires both tpl and itemSelector configurations to be defined." - }); - } me.callParent(); if(Ext.isString(me.tpl) || Ext.isArray(me.tpl)){ me.tpl = Ext.create('Ext.XTemplate', me.tpl); } - - - if (isDef(me.overCls) || isDef(me.overClass)) { - if (Ext.isDefined(Ext.global.console)) { - Ext.global.console.warn('Ext.view.View: Using the deprecated overCls or overClass configuration. Use overItemCls instead.'); - } - me.overItemCls = me.overCls || me.overClass; - delete me.overCls; - delete me.overClass; - } - if (me.overItemCls) { - me.trackOver = true; - } - - if (isDef(me.selectedCls) || isDef(me.selectedClass)) { - if (Ext.isDefined(Ext.global.console)) { - Ext.global.console.warn('Ext.view.View: Using the deprecated selectedCls or selectedClass configuration. Use selectedItemCls instead.'); - } - me.selectedItemCls = me.selectedCls || me.selectedClass; - delete me.selectedCls; - delete me.selectedClass; - } - me.addEvents( 'beforerefresh', 'refresh', + 'viewready', + 'itemupdate', 'itemadd', @@ -57987,49 +60263,67 @@ Ext.define('Ext.view.AbstractView', { me.addCmpEvents(); - if (me.store) { - me.store = Ext.data.StoreManager.lookup(me.store); - } + + me.store = Ext.data.StoreManager.lookup(me.store || 'ext-empty-store'); me.all = new Ext.CompositeElementLite(); - me.getSelectionModel().bindComponent(me); }, onRender: function() { var me = this, - loadingText = me.loadingText, - loadingHeight = me.loadingHeight, - undef; + mask = me.loadMask, + cfg = { + msg: me.loadingText, + msgCls: me.loadingCls, + useMsg: me.loadingUseMsg + }; me.callParent(arguments); - if (loadingText) { + + if (mask) { + if (Ext.isObject(mask)) { + cfg = Ext.apply(cfg, mask); + } - me.loadMask = Ext.create('Ext.LoadMask', me.floating ? me : me.ownerCt || me, { - msg: loadingText, - msgCls: me.loadingCls, - useMsg: me.loadingUseMsg, - listeners: { - beforeshow: function() { - me.getTargetEl().update(''); - me.getSelectionModel().deselectAll(); - me.all.clear(); - if (loadingHeight) { - me.setCalculatedSize(undef, loadingHeight); - } - }, - hide: function() { - if (loadingHeight) { - me.setHeight(me.height); - } - } - } + me.loadMask = Ext.create('Ext.LoadMask', me, cfg); + me.loadMask.on({ + scope: me, + beforeshow: me.onMaskBeforeShow, + hide: me.onMaskHide }); } }, + onMaskBeforeShow: function(){ + var loadingHeight = this.loadingHeight; + + this.getSelectionModel().deselectAll(); + if (loadingHeight) { + this.setCalculatedSize(undefined, loadingHeight); + } + }, + + onMaskHide: function(){ + var me = this; + + if (!me.destroying && me.loadingHeight) { + me.setHeight(me.height); + } + }, + + afterRender: function() { + this.callParent(arguments); + + + + + this.getSelectionModel().bindComponent(this); + }, + + getSelectionModel: function(){ var me = this, mode = 'SINGLE'; @@ -58054,7 +60348,9 @@ Ext.define('Ext.view.AbstractView', { } if (!me.selModel.hasRelaySetup) { - me.relayEvents(me.selModel, ['selectionchange', 'beforeselect', 'select', 'deselect']); + me.relayEvents(me.selModel, [ + 'selectionchange', 'beforeselect', 'beforedeselect', 'select', 'deselect' + ]); me.selModel.hasRelaySetup = true; } @@ -58072,11 +60368,11 @@ Ext.define('Ext.view.AbstractView', { var me = this, el, records; - - if (!me.rendered) { + + if (!me.rendered || me.isDestroyed) { return; } - + me.fireEvent('beforerefresh', me); el = me.getTargetEl(); records = me.store.getRange(); @@ -58092,30 +60388,40 @@ Ext.define('Ext.view.AbstractView', { me.all.fill(Ext.query(me.getItemSelector(), el.dom)); me.updateIndexes(0); } - + me.selModel.refresh(); me.hasSkippedEmptyText = true; me.fireEvent('refresh', me); + + + + if (!me.viewReady) { + + + me.viewReady = true; + me.fireEvent('viewready', me); + } }, prepareData: function(data, index, record) { - if (record) { - Ext.apply(data, record.getAssociatedData()); + if (record) { + Ext.apply(data, record.getAssociatedData()); } return data; }, - + 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; }, @@ -58130,20 +60436,19 @@ 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); - me.updateIndexes(index, index); - - - me.selModel.refresh(); - me.fireEvent('itemupdate', record, index, node); + if (me.getNode(record)) { + me.all.replaceElement(index, node, true); + me.updateIndexes(index, index); + + + me.selModel.refresh(); + me.fireEvent('itemupdate', record, index, node); + } } }, @@ -58152,12 +60457,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); @@ -58167,21 +60472,21 @@ 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)); - } - else { - n = this.all.last().insertSibling(nodes, 'after', true); - a.push.apply(a, nodes); - } + var all = this.all; + + if (index < all.getCount()) { + all.item(index).insertSibling(nodes, 'before', true); + } else { + all.last().insertSibling(nodes, 'after', true); + } + + Ext.Array.insert(all.elements, index, nodes); }, - + onRemove : function(ds, record, index) { var me = this; - + me.doRemove(record, index); me.updateIndexes(index); if (me.store.getCount() === 0){ @@ -58189,7 +60494,7 @@ Ext.define('Ext.view.AbstractView', { } me.fireEvent('itemremove', record, index); }, - + doRemove: function(record, index) { this.all.removeElement(index, true); }, @@ -58202,10 +60507,12 @@ Ext.define('Ext.view.AbstractView', { updateIndexes : function(startIndex, endIndex) { var ns = this.all.elements, - records = this.store.getRange(); + records = this.store.getRange(), + i; + startIndex = startIndex || 0; endIndex = endIndex || ((endIndex === 0) ? 0 : (ns.length - 1)); - for(var i = startIndex; i <= endIndex; i++){ + for(i = startIndex; i <= endIndex; i++){ ns[i].viewIndex = i; ns[i].viewRecordId = records[i].internalId; if (!ns[i].boundView) { @@ -58221,12 +60528,13 @@ Ext.define('Ext.view.AbstractView', { bindStore : function(store, initial) { - var me = this; - + var me = this, + maskStore; + if (!initial && me.store) { if (store !== me.store && me.store.autoDestroy) { - me.store.destroy(); - } + me.store.destroyStore(); + } else { me.mun(me.store, { scope: me, @@ -58238,7 +60546,8 @@ Ext.define('Ext.view.AbstractView', { }); } if (!store) { - if (me.loadMask) { + + if (me.loadMask && me.loadMask.bindStore) { me.loadMask.bindStore(null); } me.store = null; @@ -58254,17 +60563,37 @@ Ext.define('Ext.view.AbstractView', { update: me.onUpdate, clear: me.refresh }); - if (me.loadMask) { - me.loadMask.bindStore(store); + + if (me.loadMask && me.loadMask.bindStore) { + + if (Ext.Array.contains(store.alias, 'store.node')) { + maskStore = this.ownerCt.store; + } else { + maskStore = store; + } + me.loadMask.bindStore(maskStore); } } + + + me.viewReady = false; + me.store = store; me.getSelectionModel().bind(store); + if (store) { - me.refresh(true); + if (initial && me.deferInitialRefresh) { + Ext.Function.defer(function () { + if (!me.isDestroyed) { + me.refresh(true); + } + }, 1); + } else { + me.refresh(true); + } } }, @@ -58279,7 +60608,7 @@ Ext.define('Ext.view.AbstractView', { findItemByChild: function(node){ return Ext.fly(node).findParent(this.getItemSelector(), this.getTargetEl()); }, - + findTargetByEvent: function(e) { return e.getTarget(this.getItemSelector(), this.getTargetEl()); @@ -58318,7 +60647,7 @@ Ext.define('Ext.view.AbstractView', { getRecord: function(node){ return this.store.data.getByKey(Ext.getDom(node).viewRecordId); }, - + isSelected : function(node) { @@ -58326,7 +60655,7 @@ Ext.define('Ext.view.AbstractView', { var r = this.getRecord(node); return this.selModel.isSelected(r); }, - + select: function(records, keepExisting, suppressEvent) { this.selModel.select(records, keepExisting, suppressEvent); @@ -58339,31 +60668,36 @@ Ext.define('Ext.view.AbstractView', { getNode : function(nodeInfo) { + if (!this.rendered) { + return null; + } if (Ext.isString(nodeInfo)) { return document.getElementById(nodeInfo); - } else if (Ext.isNumber(nodeInfo)) { + } + if (Ext.isNumber(nodeInfo)) { return this.all.elements[nodeInfo]; - } else if (nodeInfo instanceof Ext.data.Model) { + } + if (nodeInfo instanceof Ext.data.Model) { return this.getNodeByRecord(nodeInfo); } - return nodeInfo; + return nodeInfo; }, - + getNodeByRecord: function(record) { 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; }, - + getNodes: function(start, end) { var ns = this.all.elements, @@ -58395,7 +60729,7 @@ Ext.define('Ext.view.AbstractView', { onDestroy : function() { var me = this; - + me.all.clear(); me.callParent(); me.bindStore(null); @@ -58405,15 +60739,21 @@ Ext.define('Ext.view.AbstractView', { onItemSelect: function(record) { var node = this.getNode(record); - Ext.fly(node).addCls(this.selectedItemCls); + + if (node) { + Ext.fly(node).addCls(this.selectedItemCls); + } }, onItemDeselect: function(record) { var node = this.getNode(record); - Ext.fly(node).removeCls(this.selectedItemCls); + + if (node) { + Ext.fly(node).removeCls(this.selectedItemCls); + } }, - + getItemSelector: function() { return this.itemSelector; } @@ -58427,7 +60767,7 @@ Ext.define('Ext.view.AbstractView', { - + getSelectionCount : function(){ if (Ext.global.console) { @@ -58435,7 +60775,7 @@ Ext.define('Ext.view.AbstractView', { } return this.selModel.getSelection().length; }, - + getSelectedRecords : function(){ if (Ext.global.console) { @@ -58443,7 +60783,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()"); @@ -58451,7 +60791,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()"); @@ -58459,7 +60799,7 @@ Ext.define('Ext.view.AbstractView', { var sm = this.getSelectionModel(); return sm.deselectAll(); } - }); + }); }); }); @@ -58478,6 +60818,7 @@ Ext.define('Ext.Action', { + constructor : function(config){ this.initialConfig = config; this.itemId = config.itemId = (config.itemId || config.id || Ext.id()); @@ -58568,7 +60909,7 @@ Ext.define('Ext.Action', { var items = this.items, i = 0, len = items.length; - + for(; i < len; i++){ items[i][fnName].apply(items[i], args); } @@ -58726,8 +61067,10 @@ Ext.define('Ext.Editor', { me.addEvents( 'beforestartedit', + 'startedit', + 'beforecomplete', @@ -58747,19 +61090,22 @@ Ext.define('Ext.Editor', { onRender : function(ct, position) { var me = this, - field = me.field; + field = me.field, + inputEl = field.inputEl; me.callParent(arguments); field.render(me.el); - field.inputEl.dom.name = ''; - if (me.swallowKeys) { - field.inputEl.swallowEvent([ - 'keypress', - 'keydown' - ]); + if (inputEl) { + inputEl.dom.name = ''; + if (me.swallowKeys) { + inputEl.swallowEvent([ + 'keypress', + 'keydown' + ]); + } } }, @@ -58986,12 +61332,13 @@ Ext.define('Ext.Layer', { shims: [] }, - extend: 'Ext.core.Element', + extend: 'Ext.Element', + constructor: function(config, existingEl) { config = config || {}; var me = this, - dh = Ext.core.DomHelper, + dh = Ext.DomHelper, cp = config.parentEl, pel = cp ? Ext.getDom(cp) : document.body, hm = config.hideMode; @@ -59020,14 +61367,14 @@ Ext.define('Ext.Layer', { if (hm) { - me.setVisibilityMode(Ext.core.Element[hm.toUpperCase()]); - if (me.visibilityMode == Ext.core.Element.ASCLASS) { + me.setVisibilityMode(Ext.Element[hm.toUpperCase()]); + if (me.visibilityMode == Ext.Element.ASCLASS) { me.visibilityCls = config.visibilityCls; } } else if (config.useDisplay) { - me.setVisibilityMode(Ext.core.Element.DISPLAY); + me.setVisibilityMode(Ext.Element.DISPLAY); } else { - me.setVisibilityMode(Ext.core.Element.VISIBILITY); + me.setVisibilityMode(Ext.Element.VISIBILITY); } if (config.id) { @@ -59050,7 +61397,7 @@ Ext.define('Ext.Layer', { if (config.hidden === true) { me.hide(); } else { - this.show(); + me.show(); } }, @@ -59082,29 +61429,35 @@ Ext.define('Ext.Layer', { }, hideShim: function() { - if (this.shim) { - this.shim.setDisplayed(false); - this.self.shims.push(this.shim); - delete this.shim; + var me = this; + + if (me.shim) { + me.shim.setDisplayed(false); + me.self.shims.push(me.shim); + delete me.shim; } }, disableShadow: function() { - if (this.shadow) { - this.shadowDisabled = true; - this.shadow.hide(); - this.lastShadowOffset = this.shadowOffset; - this.shadowOffset = 0; + var me = this; + + if (me.shadow && !me.shadowDisabled) { + me.shadowDisabled = true; + me.shadow.hide(); + me.lastShadowOffset = me.shadowOffset; + me.shadowOffset = 0; } }, enableShadow: function(show) { - if (this.shadow) { - this.shadowDisabled = false; - this.shadowOffset = this.lastShadowOffset; - delete this.lastShadowOffset; + var me = this; + + if (me.shadow && me.shadowDisabled) { + me.shadowDisabled = false; + me.shadowOffset = me.lastShadowOffset; + delete me.lastShadowOffset; if (show) { - this.sync(true); + me.sync(true); } } }, @@ -59115,17 +61468,17 @@ Ext.define('Ext.Layer', { shadow = me.shadow, shadowPos, shimStyle, shadowSize; - if (!this.updating && this.isVisible() && (shadow || this.useShim)) { - var shim = this.getShim(), - l = this.getLeft(true), - t = this.getTop(true), - w = this.getWidth(), - h = this.getHeight(), + if (!me.updating && me.isVisible() && (shadow || me.useShim)) { + var shim = me.getShim(), + l = me.getLeft(true), + t = me.getTop(true), + w = me.dom.offsetWidth, + h = me.dom.offsetHeight, shimIndex; - if (shadow && !this.shadowDisabled) { + if (shadow && !me.shadowDisabled) { if (doShow && !shadow.isVisible()) { - shadow.show(this); + shadow.show(me); } else { shadow.realign(l, t, w, h); } @@ -59141,6 +61494,12 @@ Ext.define('Ext.Layer', { shadowPos = shadow.el.getXY(); shimStyle = shim.dom.style; shadowSize = shadow.el.getSize(); + if (Ext.supports.CSS3BoxShadow) { + shadowSize.height += 6; + shadowSize.width += 4; + shadowPos[0] -= 2; + shadowPos[1] -= 4; + } shimStyle.left = (shadowPos[0]) + 'px'; shimStyle.top = (shadowPos[1]) + 'px'; shimStyle.width = (shadowSize.width) + 'px'; @@ -59161,7 +61520,7 @@ Ext.define('Ext.Layer', { shim.setLeftTop(l, t); } } - return this; + return me; }, remove: function() { @@ -59191,8 +61550,8 @@ Ext.define('Ext.Layer', { constrainXY: function() { if (this.constrain) { - var vw = Ext.core.Element.getViewWidth(), - vh = Ext.core.Element.getViewHeight(), + var vw = Ext.Element.getViewWidth(), + vh = Ext.Element.getViewHeight(), s = Ext.getDoc().getScroll(), xy = this.getXY(), x = xy[0], @@ -59248,13 +61607,13 @@ Ext.define('Ext.Layer', { if (!visible) { - this.hideUnders(true); + me.hideUnders(true); } - this.callParent([visible, animate, duration, callback, easing]); + me.callParent([visible, animate, duration, callback, easing]); if (!animate) { cb(); } - return this; + return me; }, @@ -59293,17 +61652,18 @@ Ext.define('Ext.Layer', { }, setXY: function(xy, animate, duration, callback, easing) { - + var me = this; + - callback = this.createCB(callback); + callback = me.createCB(callback); - this.fixDisplay(); - this.beforeAction(); - this.callParent([xy, animate, duration, callback, easing]); + me.fixDisplay(); + me.beforeAction(); + me.callParent([xy, animate, duration, callback, easing]); if (!animate) { callback(); } - return this; + return me; }, @@ -59334,70 +61694,86 @@ Ext.define('Ext.Layer', { setSize: function(w, h, animate, duration, callback, easing) { + var me = this; - callback = this.createCB(callback); + + callback = me.createCB(callback); - this.beforeAction(); - this.callParent([w, h, animate, duration, callback, easing]); + me.beforeAction(); + me.callParent([w, h, animate, duration, callback, easing]); if (!animate) { callback(); } - return this; + return me; }, setWidth: function(w, animate, duration, callback, easing) { + var me = this; - callback = this.createCB(callback); + + callback = me.createCB(callback); - this.beforeAction(); - this.callParent([w, animate, duration, callback, easing]); + me.beforeAction(); + me.callParent([w, animate, duration, callback, easing]); if (!animate) { callback(); } - return this; + return me; }, setHeight: function(h, animate, duration, callback, easing) { + var me = this; + - callback = this.createCB(callback); + callback = me.createCB(callback); - this.beforeAction(); - this.callParent([h, animate, duration, callback, easing]); + me.beforeAction(); + me.callParent([h, animate, duration, callback, easing]); if (!animate) { callback(); } - return this; + return me; }, setBounds: function(x, y, width, height, animate, duration, callback, easing) { + var me = this; + - callback = this.createCB(callback); + callback = me.createCB(callback); - this.beforeAction(); + me.beforeAction(); if (!animate) { - Ext.Layer.superclass.setXY.call(this, [x, y]); - Ext.Layer.superclass.setSize.call(this, width, height); + Ext.Layer.superclass.setXY.call(me, [x, y]); + Ext.Layer.superclass.setSize.call(me, width, height); callback(); } else { - this.callParent([x, y, width, height, animate, duration, callback, easing]); + me.callParent([x, y, width, height, animate, duration, callback, easing]); } - return this; + return me; }, setZIndex: function(zindex) { - this.zindex = zindex; - if (this.getShim()) { - this.shim.setStyle('z-index', zindex++); + var me = this; + + me.zindex = zindex; + if (me.getShim()) { + me.shim.setStyle('z-index', zindex++); + } + if (me.shadow) { + me.shadow.setZIndex(zindex++); } + return me.setStyle('z-index', zindex); + }, + + setOpacity: function(opacity){ if (this.shadow) { - this.shadow.setZIndex(zindex++); + this.shadow.setOpacity(opacity); } - this.setStyle('z-index', zindex); - return this; + return this.callParent(arguments); } }); @@ -59441,6 +61817,15 @@ Ext.define('Ext.ProgressBar', { ], uses: ['Ext.fx.Anim'], + + + + + + + + + baseCls: Ext.baseCSSPrefix + 'progress', @@ -59459,7 +61844,7 @@ Ext.define('Ext.ProgressBar', { '
', '
 
', '
', - '
', + '
', '
', '
 
', '
', @@ -59472,11 +61857,7 @@ Ext.define('Ext.ProgressBar', { initComponent: function() { this.callParent(); - this.renderSelectors = Ext.apply(this.renderSelectors || {}, { - textTopEl: '.' + this.baseCls + '-text', - textBackEl: '.' + this.baseCls + '-text-back', - bar: '.' + this.baseCls + '-bar' - }); + this.addChildEls('bar'); this.addEvents( @@ -59487,9 +61868,11 @@ Ext.define('Ext.ProgressBar', { afterRender : function() { var me = this; + + me.textEl = me.textEl ? Ext.get(me.textEl) : me.el.select('.' + me.baseCls + '-text'); - this.callParent(arguments); + me.callParent(arguments); if (me.value) { me.updateProgress(me.value, me.text); @@ -59501,38 +61884,47 @@ Ext.define('Ext.ProgressBar', { updateProgress: function(value, text, animate) { - var newWidth; - this.value = value || 0; + var me = this, + newWidth; + + me.value = value || 0; if (text) { - this.updateText(text); + me.updateText(text); } - if (this.rendered && !this.isDestroyed) { - newWidth = Math.floor(this.value * this.el.getWidth(true)); - if (Ext.isForcedBorderBox) { - newWidth += this.bar.getBorderWidth("lr"); - } - if (animate === true || (animate !== false && this.animate)) { - this.bar.stopAnimation(); - this.bar.animate(Ext.apply({ - to: { - width: newWidth + 'px' - } - }, this.animate)); + if (me.rendered && !me.isDestroyed) { + if (me.isVisible(true)) { + newWidth = Math.floor(me.value * me.el.getWidth(true)); + if (Ext.isForcedBorderBox) { + newWidth += me.bar.getBorderWidth("lr"); + } + if (animate === true || (animate !== false && me.animate)) { + me.bar.stopAnimation(); + me.bar.animate(Ext.apply({ + to: { + width: newWidth + 'px' + } + }, me.animate)); + } else { + me.bar.setWidth(newWidth); + } } else { - this.bar.setWidth(newWidth); + + me.doComponentLayout(); } } - this.fireEvent('update', this, this.value, text); - return this; + me.fireEvent('update', me, me.value, text); + return me; }, updateText: function(text) { - this.text = text; - if (this.rendered) { - this.textEl.update(this.text); + var me = this; + + me.text = text; + if (me.rendered) { + me.textEl.update(me.text); } - return this; + return me; }, applyText : function(text) { @@ -59541,28 +61933,30 @@ Ext.define('Ext.ProgressBar', { wait: function(o) { - if (!this.waitTimer) { - var scope = this; + var me = this; + + if (!me.waitTimer) { + scope = me; o = o || {}; - this.updateText(o.text); - this.waitTimer = Ext.TaskManager.start({ + me.updateText(o.text); + me.waitTimer = Ext.TaskManager.start({ run: function(i){ var inc = o.increment || 10; i -= 1; - this.updateProgress(((((i+inc)%inc)+1)*(100/inc))*0.01, null, o.animate); + me.updateProgress(((((i+inc)%inc)+1)*(100/inc))*0.01, null, o.animate); }, interval: o.interval || 1000, duration: o.duration, onStop: function(){ if (o.fn) { - o.fn.apply(o.scope || this); + o.fn.apply(o.scope || me); } - this.reset(); + me.reset(); }, scope: scope }); } - return this; + return me; }, @@ -59572,39 +61966,45 @@ Ext.define('Ext.ProgressBar', { reset: function(hide){ - this.updateProgress(0); - this.clearTimer(); + var me = this; + + me.updateProgress(0); + me.clearTimer(); if (hide === true) { - this.hide(); + me.hide(); } - return this; + return me; }, clearTimer: function(){ - if (this.waitTimer) { - this.waitTimer.onStop = null; - Ext.TaskManager.stop(this.waitTimer); - this.waitTimer = null; + var me = this; + + if (me.waitTimer) { + me.waitTimer.onStop = null; + Ext.TaskManager.stop(me.waitTimer); + me.waitTimer = null; } }, onDestroy: function(){ - this.clearTimer(); - if (this.rendered) { - if (this.textEl.isComposite) { - this.textEl.clear(); + var me = this; + + me.clearTimer(); + if (me.rendered) { + if (me.textEl.isComposite) { + me.textEl.clear(); } - Ext.destroyMembers(this, 'textEl', 'progressBar', 'textTopEl'); + Ext.destroyMembers(me, 'textEl', 'progressBar'); } - this.callParent(); + me.callParent(); } }); Ext.define('Ext.ShadowPool', { singleton: true, - requires: ['Ext.core.DomHelper'], + requires: ['Ext.DomHelper'], markup: function() { if (Ext.supports.CSS3BoxShadow) { @@ -59637,7 +62037,7 @@ Ext.define('Ext.ShadowPool', { pull: function() { var sh = this.shadows.shift(); if (!sh) { - sh = Ext.get(Ext.core.DomHelper.insertHtml("beforeBegin", document.body.firstChild, this.markup)); + sh = Ext.get(Ext.DomHelper.insertHtml("beforeBegin", document.body.firstChild, this.markup)); sh.autoBoxAdjust = false; } return sh; @@ -59658,18 +62058,23 @@ Ext.define('Ext.ShadowPool', { Ext.define('Ext.Shadow', { requires: ['Ext.ShadowPool'], + constructor: function(config) { - Ext.apply(this, config); - if (typeof this.mode != "string") { - this.mode = this.defaultMode; - } - var offset = this.offset, + var me = this, adjusts = { h: 0 }, - rad = Math.floor(this.offset / 2); - - switch (this.mode.toLowerCase()) { + offset, + rad; + + Ext.apply(me, config); + if (!Ext.isString(me.mode)) { + me.mode = me.defaultMode; + } + offset = me.offset; + rad = Math.floor(offset / 2); + me.opacity = 50; + switch (me.mode.toLowerCase()) { case "drop": if (Ext.supports.CSS3BoxShadow) { @@ -59726,7 +62131,7 @@ Ext.define('Ext.Shadow', { break; } } - this.adjusts = adjusts; + me.adjusts = adjusts; }, @@ -59738,24 +62143,28 @@ Ext.define('Ext.Shadow', { show: function(target) { + var me = this, + index; + target = Ext.get(target); - if (!this.el) { - this.el = Ext.ShadowPool.pull(); - if (this.el.dom.nextSibling != target.dom) { - this.el.insertBefore(target); + if (!me.el) { + me.el = Ext.ShadowPool.pull(); + if (me.el.dom.nextSibling != target.dom) { + me.el.insertBefore(target); } } - this.el.setStyle("z-index", this.zIndex || parseInt(target.getStyle("z-index"), 10) - 1); + index = (parseInt(target.getStyle("z-index"), 10) - 1) || 0; + me.el.setStyle("z-index", me.zIndex || index); if (Ext.isIE && !Ext.supports.CSS3BoxShadow) { - this.el.dom.style.filter = "progid:DXImageTransform.Microsoft.alpha(opacity=50) progid:DXImageTransform.Microsoft.Blur(pixelradius=" + (this.offset) + ")"; + me.el.dom.style.filter = "progid:DXImageTransform.Microsoft.alpha(opacity=" + me.opacity + ") progid:DXImageTransform.Microsoft.Blur(pixelradius=" + (me.offset) + ")"; } - this.realign( + me.realign( target.getLeft(true), target.getTop(true), - target.getWidth(), - target.getHeight() + target.dom.offsetWidth, + target.dom.offsetHeight ); - this.el.dom.style.display = "block"; + me.el.dom.style.display = "block"; }, @@ -59806,10 +62215,12 @@ Ext.define('Ext.Shadow', { hide: function() { - if (this.el) { - this.el.dom.style.display = "none"; - Ext.ShadowPool.push(this.el); - delete this.el; + var me = this; + + if (me.el) { + me.el.dom.style.display = "none"; + Ext.ShadowPool.push(me.el); + delete me.el; } }, @@ -59819,18 +62230,31 @@ Ext.define('Ext.Shadow', { if (this.el) { this.el.setStyle("z-index", z); } + }, + + + setOpacity: function(opacity){ + if (this.el) { + if (Ext.isIE && !Ext.supports.CSS3BoxShadow) { + opacity = Math.floor(opacity * 100 / 2) / 100; + } + this.opacity = opacity; + this.el.setOpacity(opacity); + } } }); - Ext.define('Ext.button.Split', { - alias: 'widget.splitbutton', extend: 'Ext.button.Button', alternateClassName: 'Ext.SplitButton', + + + + arrowCls : 'split', @@ -59843,7 +62267,7 @@ Ext.define('Ext.button.Split', { this.addEvents("arrowclick"); }, - + setArrowHandler : function(handler, scope){ this.arrowHandler = handler; this.scope = scope; @@ -59856,28 +62280,19 @@ Ext.define('Ext.button.Split', { e.preventDefault(); if (!me.disabled) { if (me.overMenuTrigger) { - if (me.menu && !me.menu.isVisible() && !me.ignoreNextClick) { - me.showMenu(); - } + me.maybeShowMenu(); me.fireEvent("arrowclick", me, e); if (me.arrowHandler) { me.arrowHandler.call(me.scope || me, me, e); } } else { - if (me.enableToggle) { - me.toggle(); - } - me.fireEvent("click", me, e); - if (me.handler) { - me.handler.call(me.scope || me, me, e); - } - me.onBlur(); + me.doToggle(); + me.fireHandler(); } } } }); - Ext.define('Ext.button.Cycle', { @@ -60030,9 +62445,9 @@ Ext.define('Ext.container.ButtonGroup', { frame: true, - + frameHeader: false, - + internalDefaults: {removeMode: 'container', hideParent: true}, initComponent : function(){ @@ -60053,7 +62468,7 @@ Ext.define('Ext.container.ButtonGroup', { afterLayout: function() { var me = this; - + me.callParent(arguments); @@ -60062,24 +62477,39 @@ Ext.define('Ext.container.ButtonGroup', { var t = me.getTargetEl(); t.setWidth(me.layout.table.offsetWidth + t.getPadding('lr')); } + + + if (Ext.isIE7) { + me.el.repaint(); + } }, afterRender: function() { var me = this; - + if (me.header) { + + delete me.header.items.items[0].flex; + + + me.suspendLayout = true; + me.header.insert(1, { + xtype: 'component', + ui : me.ui, + flex : 1 + }); me.header.insert(0, { xtype: 'component', ui : me.ui, - html : ' ', flex : 1 }); + me.suspendLayout = false; } - + me.callParent(arguments); }, - + onBeforeAdd: function(component) { if (component.is('button')) { @@ -60120,19 +62550,33 @@ Ext.define('Ext.container.Viewport', { + + + + + + + + + + + + + isViewport: true, ariaRole: 'application', + initComponent : function() { var me = this, html = Ext.fly(document.body.parentNode), @@ -60148,16 +62592,15 @@ Ext.define('Ext.container.Viewport', { el.setSize = Ext.emptyFn; el.dom.scroll = 'no'; me.allowDomMove = false; - - Ext.EventManager.onWindowResize(me.fireResize, me); me.renderTo = me.el; + me.width = Ext.Element.getViewportWidth(); + me.height = Ext.Element.getViewportHeight(); }, fireResize : function(w, h){ this.setSize(w, h); - } }); @@ -60167,6 +62610,8 @@ Ext.define('Ext.container.Viewport', { Ext.define('Ext.dd.DDTarget', { extend: 'Ext.dd.DragDrop', + + constructor: function(id, sGroup, config) { if (id) { this.initTarget(id, sGroup, config); @@ -60461,9 +62906,6 @@ Ext.define('Ext.dd.DragTracker', { this.mouseIsDown = false; - delete e.dragTracked; - - if (this.mouseIsOut) { this.mouseIsOut = false; this.onMouseOut(e); @@ -60489,6 +62931,9 @@ Ext.define('Ext.dd.DragTracker', { } delete this._constrainRegion; + + + delete Ext.EventObject.dragTracked; }, triggerStart: function(e) { @@ -60630,6 +63075,7 @@ Ext.define('Ext.dd.DragZone', { extend: 'Ext.dd.DragSource', + constructor : function(el, config){ this.callParent([el, config]); if (this.containerScroll) { @@ -60664,7 +63110,7 @@ Ext.define('Ext.dd.DragZone', { getRepairXY : function(e){ - return Ext.core.Element.fly(this.dragData.ddel).getXY(); + return Ext.Element.fly(this.dragData.ddel).getXY(); }, destroy : function(){ @@ -60852,6 +63298,7 @@ Ext.define('Ext.dd.DropTarget', { extend: 'Ext.dd.DDTarget', requires: ['Ext.dd.ScrollManager'], + constructor : function(el, config){ this.el = Ext.get(el); @@ -61122,12 +63569,6 @@ Ext.define('Ext.flash.Component', { renderTpl: ['
'], initComponent: function() { - if (!('swfobject' in window)) { - Ext.Error.raise('The SWFObject library is not loaded. Ext.flash.Component requires SWFObject version 2.2 or later: http://code.google.com/p/swfobject/'); - } - if (!this.url) { - Ext.Error.raise('The "url" config is required for Ext.flash.Component'); - } this.callParent(); this.addEvents( @@ -61244,7 +63685,7 @@ Ext.define('Ext.form.action.Action', { - + submitEmptyText : true, @@ -61253,8 +63694,7 @@ Ext.define('Ext.form.action.Action', { - - + constructor: function(config) { if (config) { Ext.apply(this, config); @@ -61441,7 +63881,7 @@ Ext.define('Ext.form.action.Submit', { } - formEl = Ext.core.DomHelper.append(Ext.getBody(), formSpec); + formEl = Ext.DomHelper.append(Ext.getBody(), formSpec); @@ -61511,6 +63951,7 @@ Ext.define('Ext.util.ComponentDragger', { autoStart: 500, + constructor: function(comp, config) { this.comp = comp; this.initialConstrainTo = config.constrainTo; @@ -61594,12 +64035,13 @@ Ext.define("Ext.form.Labelable", { labelableRenderTpl: [ '', - ' for="{inputId}" class="{labelCls}" style="{labelStyle}">', + '', '', - '
id="{baseBodyCls}-{inputId}" role="presentation">{subTplMarkup}
', - '', + '', + '', '', { compiled: true, @@ -61624,6 +64066,8 @@ Ext.define("Ext.form.Labelable", { labelCls: Ext.baseCSSPrefix + 'form-item-label', + + errorMsgCls: Ext.baseCSSPrefix + 'form-error-msg', @@ -61692,6 +64136,8 @@ Ext.define("Ext.form.Labelable", { getLabelableRenderData: function() { var me = this, labelAlign = me.labelAlign, + labelCls = me.labelCls, + labelClsExtra = me.labelClsExtra, labelPad = me.labelPad, labelStyle; @@ -61711,27 +64157,27 @@ Ext.define("Ext.form.Labelable", { { inputId: me.getInputId(), fieldLabel: me.getFieldLabel(), + labelCls: labelClsExtra ? labelCls + ' ' + labelClsExtra : labelCls, labelStyle: labelStyle + (me.labelStyle || ''), subTplMarkup: me.getSubTplMarkup() }, me, - 'hideLabel,hideEmptyLabel,labelCls,fieldBodyCls,baseBodyCls,errorMsgCls,clearCls,labelSeparator', + 'hideLabel,hideEmptyLabel,fieldBodyCls,baseBodyCls,errorMsgCls,clearCls,labelSeparator', true ); }, - - getLabelableSelectors: function() { - return { + onLabelableRender: function () { + this.addChildEls( - labelEl: 'label.' + this.labelCls, + 'labelEl', - bodyEl: '.' + this.baseBodyCls, + 'bodyEl', - errorEl: '.' + this.errorMsgCls - }; + 'errorEl' + ); }, @@ -61822,12 +64268,11 @@ Ext.define("Ext.form.Labelable", { Ext.define('Ext.form.field.Field', { - isFormField : true, - + @@ -61878,7 +64323,7 @@ Ext.define('Ext.form.field.Field', { getValue: function() { return this.value; }, - + setValue: function(value) { var me = this; @@ -61891,6 +64336,11 @@ Ext.define('Ext.form.field.Field', { isEqual: function(value1, value2) { return String(value1) === String(value2); }, + + + isEqualAsString: function(value1, value2){ + return String(Ext.value(value1, '')) === String(Ext.value(value2, '')); + }, getSubmitData: function() { @@ -61917,7 +64367,7 @@ Ext.define('Ext.form.field.Field', { reset : function(){ var me = this; - + me.setValue(me.originalValue); me.clearInvalid(); @@ -61996,9 +64446,14 @@ Ext.define('Ext.form.field.Field', { batchChanges: function(fn) { - this.suspendCheckChange++; - fn(); - this.suspendCheckChange--; + try { + this.suspendCheckChange++; + fn(); + } catch(e){ + throw e; + } finally { + this.suspendCheckChange--; + } this.checkChange(); }, @@ -62116,6 +64571,10 @@ Ext.define('Ext.layout.component.field.Field', { me.activeError = owner.getActiveError(); }, + + onFocus: function(){ + this.getErrorStrategy().onFocus(this.owner); + }, @@ -62245,6 +64704,18 @@ Ext.define('Ext.layout.component.field.Field', { el.setStyle(name, value); } } + + function showTip(owner) { + var tip = Ext.layout.component.field.Field.tip, + target; + + if (tip && tip.isVisible()) { + target = tip.activeTarget; + if (target && target.el === owner.getActionEl().dom) { + tip.toFront(true); + } + } + } var applyIf = Ext.applyIf, emptyFn = Ext.emptyFn, @@ -62255,7 +64726,8 @@ Ext.define('Ext.layout.component.field.Field', { adjustHorizInsets: emptyFn, adjustVertInsets: emptyFn, layoutHoriz: emptyFn, - layoutVert: emptyFn + layoutVert: emptyFn, + onFocus: emptyFn }; return { @@ -62284,7 +64756,8 @@ Ext.define('Ext.layout.component.field.Field', { if (owner.hasActiveError()) { setStyle(owner.errorEl, 'top', info.insets.top + 'px'); } - } + }, + onFocus: showTip }, base), @@ -62317,7 +64790,8 @@ Ext.define('Ext.layout.component.field.Field', { setDisplayed(owner.errorEl, false); Ext.layout.component.field.Field.initTip(); owner.getActionEl().dom.setAttribute('data-errorqtip', owner.getActiveError() || ''); - } + }, + onFocus: showTip }, base), @@ -62512,7 +64986,6 @@ Ext.define('Ext.layout.component.field.TextArea', { }); - Ext.define('Ext.layout.container.Anchor', { @@ -62524,7 +64997,6 @@ Ext.define('Ext.layout.container.Anchor', { - type: 'anchor', @@ -62546,8 +65018,8 @@ Ext.define('Ext.layout.container.Anchor', { 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; @@ -62564,47 +65036,27 @@ Ext.define('Ext.layout.container.Anchor', { } - 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 (!Ext.supports.RightMargin) { - cleaner = Ext.core.Element.getRightMarginFixCleaner(target); + cleaner = Ext.Element.getRightMarginFixCleaner(target); target.addCls(Ext.baseCSSPrefix + 'inline-children'); } 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; - - 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, @@ -62681,6 +65133,60 @@ Ext.define('Ext.layout.container.Anchor', { 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; + } + + + 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) { + + 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); } }); @@ -62748,12 +65254,19 @@ Ext.define('Ext.window.Window', { alias: 'widget.window', + + + + + + + @@ -62808,11 +65321,11 @@ Ext.define('Ext.window.Window', { floating: true, ariaRole: 'alertdialog', - + itemCls: 'x-window-item', overlapHeader: true, - + ignoreHeaderBorderManagement: true, @@ -62821,13 +65334,18 @@ Ext.define('Ext.window.Window', { me.callParent(); me.addEvents( + + 'resize', + 'maximize', + 'minimize', + 'restore' ); @@ -62889,9 +65407,14 @@ Ext.define('Ext.window.Window', { }, - onMouseDown: function () { + onMouseDown: function (e) { + var preventFocus; + if (this.floating) { - this.toFront(); + if (Ext.fly(e.getTarget()).focusable()) { + preventFocus = true; + } + this.toFront(preventFocus); } }, @@ -62929,6 +65452,11 @@ Ext.define('Ext.window.Window', { me.mon(me.el, 'mousedown', me.onMouseDown, me); + + + me.el.set({ + tabIndex: -1 + }); if (me.maximized) { @@ -62959,7 +65487,7 @@ Ext.define('Ext.window.Window', { if (!me.header) { me.updateHeader(true); } - + if (me.header) { ddConfig = Ext.applyIf({ @@ -63057,7 +65585,12 @@ Ext.define('Ext.window.Window', { afterShow: function(animateTarget) { - var me = this; + var me = this, + animating = animateTarget || me.animateTarget; + + + + @@ -63068,7 +65601,9 @@ Ext.define('Ext.window.Window', { } me.syncMonitorWindowResize(); - me.doConstrain(); + if (!animating) { + me.doConstrain(); + } if (me.keyMap) { me.keyMap.enable(); @@ -63082,10 +65617,12 @@ Ext.define('Ext.window.Window', { if (me.hidden) { me.fireEvent('close', me); - me[me.closeAction](); + if (me.closeAction == 'destroy') { + this.destroy(); + } } else { - me.hide(me.animTarget, me.doClose, me); + me.hide(me.animateTarget, me.doClose, me); } }, @@ -63257,6 +65794,7 @@ Ext.define('Ext.window.Window', { }); + Ext.define('Ext.form.field.Base', { extend: 'Ext.Component', mixins: { @@ -63267,7 +65805,8 @@ Ext.define('Ext.form.field.Base', { alternateClassName: ['Ext.form.Field', 'Ext.form.BaseField'], requires: ['Ext.util.DelayedTask', 'Ext.XTemplate', 'Ext.layout.component.field.Field'], - fieldSubTpl: [ + + fieldSubTpl: [ 'name="{name}" ', 'size="{size}" ', @@ -63323,9 +65862,9 @@ Ext.define('Ext.form.field.Base', { hasFocus : false, - + baseCls: Ext.baseCSSPrefix + 'field', - + maskOnDisable: false, @@ -63368,6 +65907,7 @@ Ext.define('Ext.form.field.Base', { return Ext.applyIf(me.subTplData, { id: inputId, + cmpId: me.id, name: me.name || inputId, type: type, size: me.size || 20, @@ -63378,6 +65918,14 @@ Ext.define('Ext.form.field.Base', { }); }, + afterRender: function() { + this.callParent(); + + if (this.inputEl) { + this.inputEl.selectable(); + } + }, + getSubTplMarkup: function() { return this.getTpl('fieldSubTpl').apply(this.getSubTplData()); @@ -63408,15 +65956,12 @@ Ext.define('Ext.form.field.Base', { onRender : function() { var me = this, - fieldStyle = me.fieldStyle, - renderSelectors = me.renderSelectors; + fieldStyle = me.fieldStyle; - Ext.applyIf(renderSelectors, me.getLabelableSelectors()); + me.onLabelableRender(); - Ext.applyIf(renderSelectors, { - - inputEl: '.' + me.fieldCls - }); + + me.addChildEls({ name: 'inputEl', id: me.getInputId() }); me.callParent(arguments); @@ -63637,6 +66182,7 @@ Ext.define('Ext.form.field.Base', { } if (!me.hasFocus) { me.hasFocus = true; + me.componentLayout.onFocus(); me.fireEvent('focus', me); } }, @@ -63649,6 +66195,11 @@ Ext.define('Ext.form.field.Base', { var me = this, focusCls = me.focusCls, inputEl = me.inputEl; + + if (me.destroying) { + return; + } + me.beforeBlur(); if (focusCls && inputEl) { inputEl.removeCls(focusCls); @@ -63742,7 +66293,7 @@ Ext.define('Ext.form.field.Text', { alternateClassName: ['Ext.form.TextField', 'Ext.form.Text'], - + @@ -63752,13 +66303,13 @@ Ext.define('Ext.form.field.Text', { growMin : 30, - + growMax : 800, growAppend: 'W', - + @@ -63767,33 +66318,33 @@ Ext.define('Ext.form.field.Text', { allowBlank : true, - + minLength : 0, - + maxLength : Number.MAX_VALUE, - + minLengthText : 'The minimum length for this field is {0}', - + maxLengthText : 'The maximum length for this field is {0}', + - - + blankText : 'This field is required', - + regexText : '', - + @@ -63824,7 +66375,7 @@ Ext.define('Ext.form.field.Text', { initEvents : function(){ var me = this, el = me.inputEl; - + me.callParent(); if(me.selectOnFocus || me.emptyText){ me.mon(el, 'mousedown', me.onMouseDown, me); @@ -63845,7 +66396,7 @@ Ext.define('Ext.form.field.Text', { isEqual: function(value1, value2) { - return String(Ext.value(value1, '')) === String(Ext.value(value2, '')); + return this.isEqualAsString(value1, value2); }, @@ -63853,7 +66404,7 @@ Ext.define('Ext.form.field.Text', { this.callParent(); this.autoSize(); }, - + afterRender: function(){ var me = this; if (me.enforceMaxLength) { @@ -63876,7 +66427,7 @@ Ext.define('Ext.form.field.Text', { var me = this, stripRe = me.stripCharsRe, newValue; - + if (stripRe) { newValue = value.replace(stripRe, ''); if (newValue !== value) { @@ -63928,13 +66479,13 @@ Ext.define('Ext.form.field.Text', { if (me.rendered && emptyText) { isEmpty = me.getRawValue().length < 1 && !me.hasFocus; - + if (Ext.supports.Placeholder) { me.inputEl.dom.placeholder = emptyText; } else if (isEmpty) { me.setRawValue(emptyText); } - + if (isEmpty) { @@ -63979,16 +66530,17 @@ Ext.define('Ext.form.field.Text', { filterKeys : function(e){ - if(e.ctrlKey){ + + if (e.ctrlKey && !e.altKey) { return; } var key = e.getKey(), charCode = String.fromCharCode(e.getCharCode()); - + if(Ext.isGecko && (e.isNavKeyPress() || key === e.BACKSPACE || (key === e.DELETE && e.button === -1))){ return; } - + if(!Ext.isGecko && e.isSpecialKey() && !charCode){ return; } @@ -64011,11 +66563,11 @@ Ext.define('Ext.form.field.Text', { setValue: function(value) { var me = this, inputEl = me.inputEl; - + if (inputEl && me.emptyText && !Ext.isEmpty(value)) { inputEl.removeCls(me.emptyCls); } - + me.callParent(arguments); me.applyEmptyText(); @@ -64081,7 +66633,7 @@ Ext.define('Ext.form.field.Text', { el = me.inputEl.dom, undef, range; - + if (v.length > 0) { start = start === undef ? 0 : start; end = end === undef ? v.length : end; @@ -64248,8 +66800,6 @@ Ext.define('Ext.window.MessageBox', { 'Ext.ProgressBar' ], - alternateClassName: 'Ext.MessageBox', - alias: 'widget.messagebox', @@ -64490,18 +67040,13 @@ Ext.define('Ext.window.MessageBox', { me.width = initialWidth; me.render(Ext.getBody()); } else { - me.hidden = false; me.setSize(initialWidth, me.maxHeight); } me.setPosition(-10000, -10000); me.closable = cfg.closable && !cfg.wait; - if (cfg.closable === false) { - me.tools.close.hide(); - } else { - me.tools.close.show(); - } + me.header.child('[type=close]').setVisible(cfg.closable !== false); if (!cfg.title && !me.closable) { @@ -64579,7 +67124,6 @@ Ext.define('Ext.window.MessageBox', { } else { me.bottomTb.show(); } - me.hidden = true; }, @@ -64589,7 +67133,7 @@ Ext.define('Ext.window.MessageBox', { me.reconfigure(cfg); me.addCls(cfg.cls); if (cfg.animateTarget) { - me.doAutoSize(false); + me.doAutoSize(true); me.callParent(); } else { me.callParent(); @@ -64750,24 +67294,24 @@ Ext.define('Ext.window.MessageBox', { cfg = { title: cfg, msg: msg, + progress: true, progressText: progressText }; } return this.show(cfg); } }, function() { + Ext.MessageBox = Ext.Msg = new this(); }); - - - Ext.define('Ext.form.Basic', { extend: 'Ext.util.Observable', alternateClassName: 'Ext.form.BasicForm', requires: ['Ext.util.MixedCollection', 'Ext.form.action.Load', 'Ext.form.action.Submit', 'Ext.window.MessageBox', 'Ext.data.Errors', 'Ext.util.DelayedTask'], + constructor: function(owner, config) { var me = this, onItemAddOrRemove = me.onItemAddOrRemove; @@ -64813,7 +67357,9 @@ Ext.define('Ext.form.Basic', { }, + + @@ -64871,10 +67417,15 @@ Ext.define('Ext.form.Basic', { if (child.isFormField) { handleField(child); - } - else if (isContainer) { + } else if (isContainer) { - Ext.Array.forEach(child.query('[isFormField]'), handleField); + if (child.isDestroyed) { + + + delete me._fields; + } else { + Ext.Array.forEach(child.query('[isFormField]'), handleField); + } } @@ -64897,12 +67448,15 @@ Ext.define('Ext.form.Basic', { return fields; }, + getBoundItems: function() { var boundItems = this._boundItems; - if (!boundItems) { + + if (!boundItems || boundItems.getCount() === 0) { boundItems = this._boundItems = Ext.create('Ext.util.MixedCollection'); boundItems.addAll(this.owner.query('[formBind]')); } + return boundItems; }, @@ -65024,7 +67578,7 @@ Ext.define('Ext.form.Basic', { this._record = record; return this.setValues(record.data); }, - + getRecord: function() { return this._record; @@ -65504,7 +68058,7 @@ Ext.define('Ext.form.FieldContainer', { combineErrors: false, - + maskOnDisable: false, initComponent: function() { @@ -65533,11 +68087,9 @@ Ext.define('Ext.form.FieldContainer', { }, onRender: function() { - var me = this, - renderSelectors = me.renderSelectors, - applyIf = Ext.applyIf; + var me = this; - applyIf(renderSelectors, me.getLabelableSelectors()); + me.onLabelableRender(); me.callParent(arguments); }, @@ -65894,8 +68446,8 @@ Ext.define('Ext.form.FieldSet', { ariaRole: '', - renderTpl: ['
'], - + renderTpl: ['
'], + maskOnDisable: false, getElConfig: function(){ @@ -65912,9 +68464,7 @@ Ext.define('Ext.form.FieldSet', { me.initLegend(); - Ext.applyIf(me.renderSelectors, { - body: '.' + baseCls + '-body' - }); + me.addChildEls('body'); if (me.collapsed) { me.addCls(baseCls + '-collapsed'); @@ -65954,8 +68504,23 @@ Ext.define('Ext.form.FieldSet', { legend = me.legend = Ext.create('Ext.container.Container', { baseCls: me.baseCls + '-header', ariaRole: '', + ownerCt: this, getElConfig: function(){ - return {tag: 'legend', cls: this.baseCls}; + var result = { + tag: 'legend', + cls: this.baseCls + }; + + + + + + if (!Ext.isGecko3) { + result.children = [{ + cls: Ext.baseCSSPrefix + 'clear' + }]; + } + return result; }, items: legendItems }); @@ -65972,10 +68537,16 @@ Ext.define('Ext.form.FieldSet', { var me = this; me.titleCmp = Ext.create('Ext.Component', { html: me.title, + getElConfig: function() { + return { + tag: Ext.isGecko3 ? 'span' : 'div', + cls: me.titleCmp.cls, + id: me.titleCmp.id + }; + }, cls: me.baseCls + '-header-text' }); return me.titleCmp; - }, @@ -65984,8 +68555,15 @@ Ext.define('Ext.form.FieldSet', { createCheckboxCmp: function() { var me = this, suffix = '-checkbox'; - + me.checkboxCmp = Ext.create('Ext.form.field.Checkbox', { + getElConfig: function() { + return { + tag: Ext.isGecko3 ? 'span' : 'div', + id: me.checkboxCmp.id, + cls: me.checkboxCmp.cls + }; + }, name: me.checkboxName || me.id + suffix, cls: me.baseCls + '-header' + suffix, checked: !me.collapsed, @@ -66003,13 +68581,20 @@ Ext.define('Ext.form.FieldSet', { createToggleCmp: function() { var me = this; me.toggleCmp = Ext.create('Ext.panel.Tool', { + getElConfig: function() { + return { + tag: Ext.isGecko3 ? 'span' : 'div', + id: me.toggleCmp.id, + cls: me.toggleCmp.cls + }; + }, type: 'toggle', handler: me.toggle, scope: me }); return me.toggleCmp; }, - + setTitle: function(title) { var me = this; @@ -66018,15 +68603,15 @@ Ext.define('Ext.form.FieldSet', { me.titleCmp.update(title); return me; }, - + getTargetEl : function() { return this.body || this.frameBody || this.el; }, - + getContentTarget: function() { return this.body; }, - + getRefItems: function(deep) { var refItems = this.callParent(arguments), @@ -66046,7 +68631,7 @@ Ext.define('Ext.form.FieldSet', { expand : function(){ return this.setExpanded(true); }, - + collapse : function() { return this.setExpanded(false); @@ -66058,11 +68643,11 @@ Ext.define('Ext.form.FieldSet', { checkboxCmp = me.checkboxCmp; expanded = !!expanded; - + if (checkboxCmp) { checkboxCmp.setValue(expanded); } - + if (expanded) { me.removeCls(me.baseCls + '-collapsed'); } else { @@ -66159,11 +68744,11 @@ Ext.define('Ext.form.Panel', { initComponent: function() { var me = this; - + if (me.frame) { me.border = false; } - + me.initFieldAncestor(); me.callParent(); @@ -66184,7 +68769,7 @@ Ext.define('Ext.form.Panel', { initItems: function() { var me = this; - + me.form = me.createForm(); me.callParent(); me.form.initialize(); @@ -66199,17 +68784,17 @@ Ext.define('Ext.form.Panel', { getForm: function() { return this.form; }, - + loadRecord: function(record) { return this.getForm().loadRecord(record); }, - + getRecord: function() { return this.getForm().getRecord(); }, - + getValues: function() { return this.getForm().getValues(); @@ -66286,17 +68871,30 @@ Ext.define('Ext.form.RadioGroup', { allowBlank : true, blankText : 'You must select one item in this group', - + defaultType : 'radiofield', - + groupCls : Ext.baseCSSPrefix + 'form-radio-group', getBoxes: function() { return this.query('[isRadio]'); - } + }, + + setValue: function(value) { + var me = this; + if (Ext.isObject(value)) { + Ext.Object.each(value, function(name, cbValue) { + var radios = Ext.form.RadioManager.getWithValue(name, cbValue); + radios.each(function(cb) { + cb.setValue(true); + }); + }); + } + return me; + } }); @@ -66434,9 +69032,10 @@ Ext.define('Ext.form.field.Checkbox', { alternateClassName: 'Ext.form.Checkbox', requires: ['Ext.XTemplate', 'Ext.form.CheckboxManager'], + fieldSubTpl: [ '', - '', + '', '', @@ -66445,7 +69044,7 @@ Ext.define('Ext.form.field.Checkbox', { 'tabIndex="{tabIdx}" ', 'class="{fieldCls} {typeCls}" autocomplete="off" hidefocus="true" />', '', - '', + '', '', { disableFormats: true, @@ -66513,10 +69112,10 @@ Ext.define('Ext.form.field.Checkbox', { onRender : function(ct, position) { var me = this; - Ext.applyIf(me.renderSelectors, { - - boxLabelEl: 'label.' + me.boxLabelCls - }); + + + me.addChildEls('boxLabelEl'); + Ext.applyIf(me.subTplData, { boxLabel: me.boxLabel, boxLabelCls: me.boxLabelCls, @@ -66562,8 +69161,8 @@ Ext.define('Ext.form.field.Checkbox', { var me = this, inputEl = me.inputEl, inputValue = me.inputValue, - checked = (value === true || value === 'true' || value === '1' || - ((Ext.isString(value) && inputValue) ? value == inputValue : me.onRe.test(value))); + checked = (value === true || value === 'true' || value === '1' || value === 1 || + (((Ext.isString(value) || Ext.isNumber(value)) && inputValue) ? value == inputValue : me.onRe.test(value))); if (inputEl) { inputEl.dom.setAttribute('aria-checked', checked); @@ -66610,6 +69209,12 @@ Ext.define('Ext.form.field.Checkbox', { }, + beforeDestroy: function(){ + this.callParent(); + this.getManager().removeAtKey(this.id); + }, + + getManager: function() { return Ext.form.CheckboxManager; }, @@ -66635,6 +69240,7 @@ Ext.define('Ext.form.field.Checkbox', { }, + getBodyNaturalWidth: function() { var me = this, bodyEl = me.bodyEl, @@ -66684,7 +69290,7 @@ Ext.define('Ext.layout.component.field.Trigger', { Ext.define('Ext.view.View', { extend: 'Ext.view.AbstractView', - alternateClassName: 'Ext.view.View', + alternateClassName: 'Ext.DataView', alias: 'widget.dataview', inheritableStatics: { @@ -66698,7 +69304,8 @@ Ext.define('Ext.view.View', { mouseout: 'MouseOut', mouseenter: 'MouseEnter', mouseleave: 'MouseLeave', - keydown: 'KeyDown' + keydown: 'KeyDown', + focus: 'Focus' } }, @@ -66782,6 +69389,8 @@ Ext.define('Ext.view.View', { listeners = { scope: me, + + freezeEvent: true, click: me.handleEvent, mousedown: me.handleEvent, mouseup: me.handleEvent, @@ -66935,12 +69544,14 @@ Ext.define('Ext.view.View', { onItemMouseDown: Ext.emptyFn, onItemMouseUp: Ext.emptyFn, + onItemFocus: Ext.emptyFn, onItemClick: Ext.emptyFn, onItemDblClick: Ext.emptyFn, onItemContextMenu: Ext.emptyFn, onItemKeyDown: Ext.emptyFn, onBeforeItemMouseDown: Ext.emptyFn, onBeforeItemMouseUp: Ext.emptyFn, + onBeforeItemFocus: Ext.emptyFn, onBeforeItemMouseEnter: Ext.emptyFn, onBeforeItemMouseLeave: Ext.emptyFn, onBeforeItemClick: Ext.emptyFn, @@ -66986,8 +69597,12 @@ Ext.define('Ext.view.View', { }, refresh: function() { - this.clearHighlight(); - this.callParent(arguments); + var me = this; + me.clearHighlight(); + me.callParent(arguments); + if (!me.isFixedHeight()) { + me.doComponentLayout(); + } } }); @@ -67096,14 +69711,14 @@ Ext.define('Ext.toolbar.TextItem', { requires: ['Ext.XTemplate'], alias: 'widget.tbtext', alternateClassName: 'Ext.Toolbar.TextItem', - + text: '', - + renderTpl: '{text}', baseCls: Ext.baseCSSPrefix + 'toolbar-text', - + onRender : function() { Ext.apply(this.renderData, { text: this.text @@ -67125,16 +69740,17 @@ Ext.define('Ext.toolbar.TextItem', { Ext.define('Ext.form.field.Trigger', { extend:'Ext.form.field.Text', alias: ['widget.triggerfield', 'widget.trigger'], - requires: ['Ext.core.DomHelper', 'Ext.util.ClickRepeater', 'Ext.layout.component.field.Trigger'], + requires: ['Ext.DomHelper', 'Ext.util.ClickRepeater', 'Ext.layout.component.field.Trigger'], alternateClassName: ['Ext.form.TriggerField', 'Ext.form.TwinTriggerField', 'Ext.form.Trigger'], + fieldSubTpl: [ 'name="{name}" ', 'size="{size}" ', 'tabIndex="{tabIdx}" ', 'class="{fieldCls} {typeCls}" autocomplete="off" />', - '