X-Git-Url: http://git.ithinksw.org/extjs.git/blobdiff_plain/7a654f8d43fdb43d78b63d90528bed6e86b608cc..f562e4c6e5fac7bcb445985b99acbea4d706e6f0:/ext-all-debug.js diff --git a/ext-all-debug.js b/ext-all-debug.js index 674494ad..8fc6dc00 100644 --- a/ext-all-debug.js +++ b/ext-all-debug.js @@ -1,9 +1,23 @@ +/* + +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; @@ -122,13 +136,6 @@ }; } - 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() {}, @@ -222,11 +229,6 @@ 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.' - }); }, @@ -247,7 +249,8 @@ 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]'; @@ -292,7 +295,7 @@ isElement: function(value) { - return value ? value.nodeType !== undefined : false; + return value ? value.nodeType === 1 : false; }, @@ -372,7 +375,7 @@ var i = 0; do { - uniqueGlobalNamespace = 'ExtSandbox' + (++i); + uniqueGlobalNamespace = 'ExtBox' + (++i); } while (Ext.global[uniqueGlobalNamespace] !== undefined); Ext.global[uniqueGlobalNamespace] = Ext; @@ -404,7 +407,7 @@ (function() { -var version = '4.0.0', Version; +var version = '4.0.7', Version; Ext.Version = Version = Ext.extend(Object, { @@ -589,9 +592,10 @@ 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 */ htmlEncode: (function() { var entities = { @@ -614,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 = { '&': '&', @@ -705,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 || ''); } }; @@ -729,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; @@ -760,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, @@ -772,6 +837,7 @@ Ext.num = function() { }(), supportsSliceOnNodeList = true, ExtArray; + try { if (typeof document !== 'undefined') { @@ -781,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) { @@ -915,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); } @@ -936,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); } @@ -1032,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; @@ -1081,8 +1234,8 @@ Ext.num = function() { } } - minArray = Ext.Array.unique(minArray); - arrays.splice(x, 1); + minArray = ExtArray.unique(minArray); + erase(arrays, x, 1); @@ -1116,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--; } @@ -1127,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) { @@ -1249,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 = { @@ -1325,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); @@ -1426,7 +1617,7 @@ Ext.Function = { return function() { var me = this; if (timerId) { - clearInterval(timerId); + clearTimeout(timerId); timerId = null; } timerId = setTimeout(function(){ @@ -1454,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); + }; } }; @@ -1577,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 = []; @@ -2638,6 +2842,7 @@ var Base = Ext.Base = function() {}; }, + initConfig: function(config) { if (!this.$configInited) { this.config = Ext.Object.merge({}, this.config || {}, config || {}); @@ -2667,6 +2872,7 @@ var Base = Ext.Base = function() {}; return this; }), + callParent: function(args) { @@ -2674,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; } @@ -2688,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 || []); }, @@ -2717,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 || []); }, @@ -2748,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() { @@ -2769,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; @@ -2792,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]; @@ -2803,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]; @@ -2847,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]; @@ -2867,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; } @@ -2888,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() { @@ -2930,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); + } }) }); @@ -2952,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() { @@ -2968,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]; @@ -2980,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) { @@ -2997,7 +3226,7 @@ var Base = Ext.Base = function() {}; } } - classData.onClassCreated = onClassCreated; + classData.onClassCreated = onClassCreated || Ext.emptyFn; classData.onBeforeClassCreated = function(cls, data) { onClassCreated = data.onClassCreated; @@ -3007,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) { @@ -3072,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); @@ -3090,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, @@ -3132,6 +3360,7 @@ var Base = Ext.Base = function() {}; delete data.extend; + parentStatics = parentPrototype.$inheritableStatics; if (parentStatics) { @@ -3143,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); } @@ -3160,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; @@ -3224,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; } @@ -3242,10 +3455,55 @@ var Base = Ext.Base = function() {}; Ext.Object.merge(prototype.config, data.config); delete data.config; }); + - Class.setDefaultPreprocessors(['extend', 'statics', 'inheritableStatics', 'mixins', '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' + + + ,'config' + + + ,'mixins' + + ]); + + + Ext.extend = function(subclass, superclass, members) { if (arguments.length === 2 && Ext.isObject(superclass)) { members = superclass; @@ -3260,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); @@ -3279,6 +3551,7 @@ var Base = Ext.Base = function() {}; return cls; }; + })(); @@ -3317,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; @@ -3362,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; @@ -3415,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') { @@ -3516,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; } @@ -3569,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; @@ -3584,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; @@ -3641,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); } @@ -3670,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); } @@ -3708,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); }, @@ -3814,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; @@ -3826,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, '(.*?)'); @@ -3878,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; @@ -3929,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); } @@ -3999,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'), @@ -4028,6 +4267,7 @@ var Base = Ext.Base = function() {}; namespace: alias(Manager, 'createNamespaces') }); + Ext.createWidget = Ext.widget; @@ -4036,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) { @@ -4203,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++; @@ -4211,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; @@ -4459,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("', '") + "'" - }); - } }, @@ -4508,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 - }); }, @@ -4612,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 = [], @@ -4638,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]; @@ -4657,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++) { @@ -4708,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]; @@ -4730,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 = [], @@ -4757,6 +4968,9 @@ Ext.Error = Ext.extend(Error, { ignore: false, + + + raise: function(err){ err = err || {}; if (Ext.isString(err)) { @@ -4775,28 +4989,15 @@ Ext.Error = Ext.extend(Error, { } if (Ext.Error.handle(err) !== true) { - var global = Ext.global, - con = global.console, - msg = Ext.Error.prototype.toString.call(err), - noConsoleMsg = 'An uncaught error was raised: "' + msg + - '". Use Firebug or Webkit console for additional details.'; - - if (con) { - if (con.dir) { - con.warn('An uncaught error was raised with the following data:'); - con.dir(err); - } - else { - con.warn(noConsoleMsg); - } - if (con.error) { - con.error(msg); - } - } - else if (global.alert){ - global.alert(noConsoleMsg); - } - + var msg = Ext.Error.prototype.toString.call(err); + + Ext.log({ + msg: msg, + level: 'error', + dump: err, + stack: true + }); + throw new Ext.Error(err); } }, @@ -4808,11 +5009,20 @@ Ext.Error = Ext.extend(Error, { }, + name: 'Ext.Error', + + constructor: function(config){ if (Ext.isString(config)) { config = { msg: config }; } - Ext.apply(this, config); + + var me = this; + + Ext.apply(me, config); + + me.message = me.message || me.msg; + }, @@ -4829,6 +5039,9 @@ Ext.Error = Ext.extend(Error, { + + + Ext.JSON = new(function() { var useHasOwn = !! {}.hasOwnProperty, isNative = function() { @@ -4914,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()) + ":" @@ -4952,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 }); } }; @@ -4970,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', @@ -4986,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; }, @@ -5091,10 +5310,17 @@ Ext.ns = Ext.namespace; 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/), @@ -5104,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), @@ -5112,23 +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; + 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.0'); + + 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', @@ -5187,6 +5423,10 @@ window.undefined = window.undefined; } }, + isStrict: isStrict, + + isIEQuirks: isIE && !isStrict, + isOpera : isOpera, @@ -5209,6 +5449,9 @@ window.undefined = window.undefined; isSafari4 : isSafari4, + isSafari5 : isSafari5, + + isSafari2 : isSafari2, @@ -5236,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, @@ -5254,7 +5506,28 @@ window.undefined = window.undefined; isMac : isMac, - BLANK_IMAGE_URL : (isIE6 || isIE7) ? 'http:/' + '/www.sencha.com/s.gif' : 'data:image/gif;base64,R0lGODlhAQABAID/AMDAwAAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==', + chromeVersion: chromeVersion, + + + firefoxVersion: firefoxVersion, + + + ieVersion: ieVersion, + + + operaVersion: operaVersion, + + + safariVersion: safariVersion, + + + webKitVersion: webKitVersion, + + + isSecure: isSecure, + + + BLANK_IMAGE_URL : (isIE6 || isIE7) ? '/' + '/www.sencha.com/s.gif' : 'data:image/gif;base64,R0lGODlhAQABAID/AMDAwAAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==', value : function(v, defaultValue, allowBlank){ @@ -5291,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; }, @@ -5328,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]]; @@ -5336,6 +5619,10 @@ window.undefined = window.undefined; }, + log : + Ext.emptyFn, + + partition : function(arr, truth){ var ret = [[],[]]; Ext.each(arr, function(v, i, a) { @@ -5485,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 { @@ -5555,8 +5842,7 @@ Ext.application = function(config) { }, - number: - function(v, formatString) { + number: function(v, formatString) { if (!formatString) { return v; } @@ -5593,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); } @@ -5634,6 +5913,11 @@ Ext.application = function(config) { } } + if (neg) { + + neg = fnum.replace(/[^1-9]/g, '') !== ''; + } + return (neg ? '-' : '') + formatString.replace(/[\d,?\.?]+/, fnum); }, @@ -5982,12 +6266,33 @@ Ext.supports = { { identity: 'RightMargin', - fn: function(doc, div, view) { - view = doc.defaultView; + fn: function(doc, div) { + var view = doc.defaultView; return !(view && view.getComputedStyle(div.firstChild.firstChild, null).marginRight != '0px'); } }, + + + { + identity: 'DisplayChangeInputSelectionBug', + fn: function() { + var webKitVersion = Ext.webKitVersion; + + return 0 < webKitVersion && webKitVersion < 533; + } + }, + + { + identity: 'DisplayChangeTextAreaSelectionBug', + fn: function() { + var webKitVersion = Ext.webKitVersion; + + + return 0 < webKitVersion && webKitVersion < 534.24; + } + }, + { identity: 'TransparentColor', @@ -6189,8 +6494,16 @@ Ext.supports = { return range && !!range.createContextualFragment; } - } + }, + + { + identity: 'WindowOnError', + fn: function () { + + return Ext.isIE || Ext.isGecko || Ext.webKitVersion >= 534.16; + } + } ] }; @@ -6199,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, @@ -6231,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, @@ -6268,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); @@ -6383,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; @@ -6401,7 +6714,7 @@ Ext.core.DomHelper = function(){ return fragment; } - + pub = { markup : function(o){ @@ -6416,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); @@ -6438,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']; @@ -6456,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; @@ -6479,7 +6792,7 @@ Ext.core.DomHelper = function(){ } else { frag = createContextualFragment(html); } - + if(where == afterbegin){ el.insertBefore(frag, el.firstChild); }else{ @@ -6491,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 + '"' - }); }, @@ -6528,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); } }; @@ -6559,6 +6865,7 @@ Ext.core.DomQuery = Ext.DomQuery = function(){ tagTokenRe = /^(#)?([\w-\*]+)/, nthRe = /(\d*)n\+?(\d*)/, nthRe2 = /\D/, + startIdRe = /^\s*\#/, @@ -6976,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]){ @@ -7014,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); @@ -7039,15 +7336,26 @@ Ext.core.DomQuery = Ext.DomQuery = function(){ var docEl = (el ? el.ownerDocument || el : 0).documentElement; return docEl ? docEl.nodeName !== "HTML" : false; }, + 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) { @@ -7366,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 = { @@ -7514,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; @@ -7554,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); }, @@ -7681,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; @@ -7812,7 +8142,7 @@ Ext.query = Ext.DomQuery.select; })(); -Ext.core.Element.addMethods({ +Ext.Element.addMethods({ findParent : function(simpleSelector, maxDepth, returnEl) { var p = this.dom, @@ -7834,7 +8164,7 @@ Ext.core.Element.addMethods({ } return null; }, - + findParentNode : function(simpleSelector, maxDepth, returnEl) { var p = Ext.fly(this.dom.parentNode, '_internal'); @@ -7848,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); }, @@ -7904,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))) { @@ -7917,7 +8247,7 @@ Ext.core.Element.addMethods({ }); -Ext.core.Element.addMethods({ +Ext.Element.addMethods({ appendChild : function(el) { return Ext.get(el).appendTo(this); @@ -7982,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; @@ -8006,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; }, @@ -8020,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); @@ -8038,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, @@ -8074,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")); } @@ -8094,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")); } @@ -8108,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) { @@ -8142,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) { @@ -8156,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); } } } @@ -8219,56 +8559,83 @@ Ext.core.Element.addMethods({ }, - getStyle : function(){ + getStyle : function() { return view && view.getComputedStyle ? function(prop){ var el = this.dom, - v, cs, out, display; + v, cs, out, display, cleaner; 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 = 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; + } }(), @@ -8300,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; @@ -8313,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; } } } @@ -8375,7 +8741,7 @@ Ext.core.Element.addMethods({ } return this; }, - + adjustDirect2DDimension: function(dimension) { var me = this, @@ -8385,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'; } @@ -8395,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, @@ -8448,7 +8814,7 @@ Ext.core.Element.addMethods({ } return height; }, - + getWidth: function(contentWidth, preciseWidth) { var me = this, @@ -8463,7 +8829,7 @@ Ext.core.Element.addMethods({ overflow = style.overflow; me.setStyle({overflow: 'hidden'}); } - + if (Ext.isOpera10_5) { if (dom.parentNode.currentStyle.position === 'relative') { @@ -8473,7 +8839,7 @@ Ext.core.Element.addMethods({ dom.parentNode.style.position = parentPosition; } width = Math.max(width || 0, dom.offsetWidth); - + @@ -8499,11 +8865,11 @@ Ext.core.Element.addMethods({ width++; } } - + if (contentWidth) { width -= (me.getBorderWidth("lr") + me.getPadding("lr")); } - + if (Ext.isIEQuirks) { me.setStyle({ overflow: overflow}); } @@ -8592,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; @@ -8623,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; }, @@ -8635,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); @@ -8646,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; }, @@ -8654,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({ @@ -8695,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()){ @@ -8763,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() }; @@ -8801,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() }; } @@ -8839,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; }, @@ -8870,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", @@ -9088,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; @@ -9166,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; @@ -9184,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); @@ -9354,7 +9740,7 @@ Ext.applyIf(Ext.core.Element.prototype, { if (obj.useDisplay) { me.setDisplayed(false); } else { - me.hide(); + me.hide(); } } else { @@ -9362,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); @@ -9392,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; @@ -9431,7 +9816,7 @@ Ext.applyIf(Ext.core.Element.prototype, { } else { me.hide(); } - me.clearOpacity(); + me.clearOpacity(); me.setPositioning(position); me.setStyle({fontSize: fontSize}); } @@ -9454,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, @@ -9494,7 +9879,7 @@ Ext.applyIf(Ext.core.Element.prototype, { me.setDisplayed(false); } else { me.hide(); - } + } me.clearOpacity(); me.setPositioning(position); me.setSize(size); @@ -9512,7 +9897,7 @@ Ext.applyIf(Ext.core.Element.prototype, { return me; }, - + frame : function(color, count, obj){ var me = this, beforeAnim; @@ -9638,7 +10023,7 @@ Ext.applyIf(Ext.core.Element.prototype, { return me; }, - + highlight: function(color, o) { var me = this, dom = me.dom, @@ -9649,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', ''); @@ -9657,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; @@ -9675,7 +10060,7 @@ Ext.applyIf(Ext.core.Element.prototype, { if (dom) { dom.style[attr] = restore; } - + event = lns.afteranimate; if (event) { fn = event.fn || event; @@ -9702,7 +10087,7 @@ Ext.applyIf(Ext.core.Element.prototype, { return me; }, - + fadeIn: function(o) { this.animate(Ext.apply({}, o, { opacity: 1 @@ -9710,7 +10095,7 @@ Ext.applyIf(Ext.core.Element.prototype, { return this; }, - + fadeOut: function(o) { this.animate(Ext.apply({}, o, { opacity: 0 @@ -9718,7 +10103,7 @@ Ext.applyIf(Ext.core.Element.prototype, { return this; }, - + scale: function(w, h, o) { this.animate(Ext.apply({}, o, { width: w, @@ -9727,7 +10112,7 @@ Ext.applyIf(Ext.core.Element.prototype, { return this; }, - + shift: function(config) { this.animate(config); return this; @@ -9735,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, @@ -9747,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) { @@ -9878,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 = { @@ -9910,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)){ @@ -9933,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; @@ -10005,7 +10390,7 @@ Ext.CompositeElementLite.prototype = { els[els.length] = me.transformElement(el); } }); - + me.elements = els; return me; }, @@ -10026,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; }, @@ -10042,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) { @@ -10060,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) { @@ -10153,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); @@ -10251,7 +10622,7 @@ Ext.require('Ext.util.DelayedTask', function() { } - me.listeners.splice(index, 1); + Ext.Array.erase(me.listeners, index, 1); return true; } @@ -10322,6 +10693,7 @@ Ext.EventManager = { if(window.attachEvent){ + if (window != top) { return false; } @@ -10426,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; } @@ -10439,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; } @@ -10519,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; } @@ -10528,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 || {}; @@ -10575,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; } @@ -10619,7 +10973,7 @@ Ext.EventManager = { } - cache.splice(i, 1); + Ext.Array.erase(cache, i, 1); } } }, @@ -10662,83 +11016,94 @@ Ext.EventManager = { createListenerWrap : function(dom, ename, fn, scope, options) { - options = !Ext.isObject(options) ? {} : options; + options = options || {}; - var f = ['if(!Ext) {return;}'], - gen; + var f, gen; - if(options.buffer || options.delay || options.freezeEvent) { - f.push('e = new Ext.EventObjectImpl(e, ' + (options.freezeEvent ? 'true' : 'false' ) + ');'); - } else { - f.push('e = Ext.EventObject.setEvent(e);'); - } + return function wrap(e, args) { + + if (!gen) { + f = ['if(!Ext) {return;}']; - if (options.delegate) { - f.push('var t = e.getTarget("' + options.delegate + '", this);'); - f.push('if(!t) {return;}'); - } else { - f.push('var t = e.target;'); - } + if(options.buffer || options.delay || options.freezeEvent) { + f.push('e = new Ext.EventObjectImpl(e, ' + (options.freezeEvent ? 'true' : 'false' ) + ');'); + } else { + f.push('e = Ext.EventObject.setEvent(e);'); + } - if (options.target) { - f.push('if(e.target !== options.target) {return;}'); - } + if (options.delegate) { + f.push('var t = e.getTarget("' + options.delegate + '", this);'); + f.push('if(!t) {return;}'); + } else { + f.push('var t = e.target;'); + } - if(options.stopEvent) { - f.push('e.stopEvent();'); - } else { - if(options.preventDefault) { - f.push('e.preventDefault();'); - } - if(options.stopPropagation) { - f.push('e.stopPropagation();'); - } - } + if (options.target) { + f.push('if(e.target !== options.target) {return;}'); + } - if(options.normalized === false) { - f.push('e = e.browserEvent;'); - } + if(options.stopEvent) { + f.push('e.stopEvent();'); + } else { + if(options.preventDefault) { + f.push('e.preventDefault();'); + } + if(options.stopPropagation) { + f.push('e.stopPropagation();'); + } + } - if(options.buffer) { - f.push('(wrap.task && clearTimeout(wrap.task));'); - f.push('wrap.task = setTimeout(function(){'); - } + if(options.normalized === false) { + f.push('e = e.browserEvent;'); + } - if(options.delay) { - f.push('wrap.tasks = wrap.tasks || [];'); - f.push('wrap.tasks.push(setTimeout(function(){'); - } + if(options.buffer) { + f.push('(wrap.task && clearTimeout(wrap.task));'); + f.push('wrap.task = setTimeout(function(){'); + } - - f.push('fn.call(scope || dom, e, t, options);'); + if(options.delay) { + f.push('wrap.tasks = wrap.tasks || [];'); + f.push('wrap.tasks.push(setTimeout(function(){'); + } - if(options.single) { - f.push('Ext.EventManager.removeListener(dom, ename, fn, scope);'); - } + + f.push('fn.call(scope || dom, e, t, options);'); - if(options.delay) { - f.push('}, ' + options.delay + '));'); - } + if(options.single) { + f.push('Ext.EventManager.removeListener(dom, ename, fn, scope);'); + } - if(options.buffer) { - f.push('}, ' + options.buffer + ');'); - } + if(options.delay) { + f.push('}, ' + options.delay + '));'); + } - gen = Ext.functionFactory('e', 'options', 'fn', 'scope', 'ename', 'dom', 'wrap', 'args', f.join('\n')); + if(options.buffer) { + f.push('}, ' + options.buffer + ');'); + } + + gen = Ext.functionFactory('e', 'options', 'fn', 'scope', 'ename', 'dom', 'wrap', 'args', f.join('\n')); + } - return function wrap(e, args) { gen.call(dom, e, options, fn, scope, ename, dom, wrap, args); }; }, 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 = {}); }, @@ -10864,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){ @@ -10953,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; @@ -10963,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'); } @@ -11037,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); } @@ -11229,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/, @@ -11357,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) { @@ -11394,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 (!ret && delta) { + ret = (delta < 0) ? -1 : 1; + } + + 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 (event.wheelDelta) { - delta = event.wheelDelta / 120; - } else if (event.detail){ - delta = -event.detail / 3; + + + if (Ext.isDefined(event.axis) && event.axis === event.HORIZONTAL_AXIS) { + dx = dy; + dy = 0; + } } - return delta; + + return { + x: me.correctWheelDelta(dx), + y: me.correctWheelDelta(dy) + }; + }, + + + getWheelDelta : function(){ + var deltas = this.getWheelDeltas(); + + return deltas.y; }, @@ -11524,7 +12007,7 @@ Ext.define('Ext.EventObjectImpl', { return target; } - } + }; } else if (document.createEventObject) { var crazyIEButtons = { 0: 1, 1: 4, 2: 2 }; @@ -11652,7 +12135,6 @@ Ext.define('Ext.EventObjectImpl', { } function cannotInject (target, srcEvent) { - } return function (target) { @@ -11675,16 +12157,37 @@ Ext.EventObject = new Ext.EventObjectImpl(); (function(){ 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; }, _fly; + + + + if (!('activeElement' in doc) && doc.addEventListener) { + doc.addEventListener('focus', + function (ev) { + if (ev && ev.target) { + activeElement = (ev.target == doc) ? null : ev.target; + } + }, true); + } + + + function makeSelectionRestoreFn (activeEl, start, end) { + return function () { + activeEl.selectionStart = start; + activeEl.selectionEnd = end; + }; + } + Ext.apply(ELEMENT, { isAncestor : function(p, c) { var ret = false; @@ -11705,6 +12208,43 @@ Ext.EventObject = new Ext.EventObjectImpl(); return ret; }, + + getActiveElement: function () { + return doc.activeElement || activeElement; + }, + + + getRightMarginFixCleaner: function (target) { + var supports = Ext.supports, + hasInputBug = supports.DisplayChangeInputSelectionBug, + hasTextAreaBug = supports.DisplayChangeTextAreaSelectionBug; + + if (hasInputBug || hasTextAreaBug) { + var activeEl = doc.activeElement || activeElement, + tag = activeEl && activeEl.tagName, + start, + end; + + if ((hasTextAreaBug && tag == 'TEXTAREA') || + (hasInputBug && tag == 'INPUT' && activeEl.type == 'text')) { + if (ELEMENT.isAncestor(target, activeEl)) { + start = activeEl.selectionStart; + end = activeEl.selectionEnd; + + if (Ext.isNumber(start) && Ext.isNumber(end)) { + + + + + return makeSelectionRestoreFn(activeEl, start, end); + } + } + } + } + + return Ext.emptyFn; + }, + getViewWidth : function(full) { return full ? ELEMENT.getDocumentWidth() : ELEMENT.getViewportWidth(); }, @@ -11740,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, @@ -11752,7 +12303,7 @@ Ext.EventObject = new Ext.EventObjectImpl(); scroll, hasAbsolute, bd = (doc.body || doc.documentElement), - ret = [0,0]; + ret; el = Ext.getDom(el); @@ -11760,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; @@ -11782,7 +12337,6 @@ Ext.EventObject = new Ext.EventObjectImpl(); y += bt; } } - p = p.offsetParent; } if (Ext.isSafari && hasAbsolute) { @@ -11807,7 +12361,7 @@ Ext.EventObject = new Ext.EventObjectImpl(); ret = [x,y]; } } - return ret; + return ret || [0,0]; }, setXY : function(el, xy) { @@ -11851,7 +12405,7 @@ Ext.EventObject = new Ext.EventObjectImpl(); Ext.each(element.options, function(opt){ if (opt.selected) { hasValue = opt.hasAttribute ? opt.hasAttribute('value') : opt.getAttributeNode('value').specified; - data += String.format("{0}={1}&", encoder(name), encoder(hasValue ? opt.value : opt.text)); + data += Ext.String.format("{0}={1}&", encoder(name), encoder(hasValue ? opt.value : opt.text)); } }); } else if (!(/file|undefined|reset|button/i.test(type))) { @@ -11869,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){ @@ -12079,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(), @@ -12148,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; @@ -12169,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(); @@ -12184,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]; @@ -12204,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, @@ -12223,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]; @@ -12350,7 +12911,7 @@ Ext.core.Element.addMethods({ (function(){ -var ELEMENT = Ext.core.Element, +var ELEMENT = Ext.Element, LEFT = "left", RIGHT = "right", TOP = "top", @@ -12361,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); @@ -12658,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(); @@ -12683,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, @@ -12736,7 +13297,7 @@ Ext.override(Ext.core.Element, { })(); -Ext.override(Ext.core.Element, { +Ext.override(Ext.Element, { isScrollable : function(){ var dom = this.dom; @@ -12870,7 +13431,7 @@ Ext.override(Ext.core.Element, { } }); -Ext.core.Element.addMethods( +Ext.Element.addMethods( function() { var VISIBILITY = "visibility", DISPLAY = "display", @@ -12878,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 { @@ -12906,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); @@ -12920,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; @@ -13026,7 +13587,7 @@ Ext.core.Element.addMethods( }() ); -Ext.core.Element.addMethods({ +Ext.Element.addMethods({ addKeyListener : function(key, fn, scope){ var config; @@ -13066,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) { @@ -13104,7 +13665,7 @@ Ext.apply(Ext.CompositeElementLite.prototype, { Ext.removeNode(el); } } - els.splice(val, 1); + Ext.Array.erase(els, val, 1); } }); return this; @@ -13113,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; @@ -13218,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) { @@ -13226,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)) { @@ -13251,16 +13797,15 @@ Ext.define('Ext.util.Observable', { }, - removeManagedListener : function(item, ename, fn, scope) { + removeManagedListener : function(item, ename, fn, scope) { var me = this, options, config, managedListeners, - managedListener, length, i; - if (Ext.isObject(ename)) { + if (typeof ename !== 'string') { options = ename; for (ename in options) { if (options.hasOwnProperty(ename)) { @@ -13273,56 +13818,64 @@ Ext.define('Ext.util.Observable', { } managedListeners = me.managedListeners ? me.managedListeners.slice() : []; - length = managedListeners.length; - for (i = 0; i < length; i++) { - managedListener = managedListeners[i]; - if (managedListener.item === item && managedListener.ename === ename && (!fn || managedListener.fn === fn) && (!scope || managedListener.scope === scope)) { - Ext.Array.remove(me.managedListeners, managedListener); - item.un(managedListener.ename, managedListener.fn, managedListener.scope); - } + for (i = 0, length = managedListeners.length; i < length; i++) { + me.removeManagedListenerItem(false, managedListeners[i], item, ename, fn, scope); } }, - 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)) { @@ -13351,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)) { @@ -13364,7 +13917,7 @@ Ext.define('Ext.util.Observable', { } else { ename = ename.toLowerCase(); event = me.events[ename]; - if (event.isEvent) { + if (event && event.isEvent) { event.removeListener(fn, scope); } } @@ -13388,43 +13941,43 @@ Ext.define('Ext.util.Observable', { this.clearManagedListeners(); }, - purgeListeners : function() { - console.warn('Observable: purgeListeners has been deprecated. Please use clearListeners.'); - return this.clearListeners.apply(this, arguments); - }, clearManagedListeners : function() { var managedListeners = this.managedListeners || [], i = 0, - len = managedListeners.length, - managedListener; + len = managedListeners.length; for (; i < len; i++) { - managedListener = managedListeners[i]; - managedListener.item.un(managedListener.ename, managedListener.fn, managedListener.scope); + this.removeManagedListenerItem(true, managedListeners[i]); } this.managedListeners = []; }, - purgeManagedListeners : function() { - console.warn('Observable: purgeManagedListeners has been deprecated. Please use clearManagedListeners.'); - return this.clearManagedListeners.apply(this, arguments); + + 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); + } + } }, + addEvents: function(o) { var me = this, 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; } @@ -13450,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); + }); + } }, @@ -13504,14 +14058,15 @@ Ext.define('Ext.util.Observable', { } } }, function() { - - - this.createAlias({ + on: 'addListener', + un: 'removeListener', + mon: 'addManagedListener', + mun: 'removeManagedListener' }); @@ -13611,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; } } @@ -13675,6 +14230,7 @@ Ext.define('Ext.util.Animate', { stopAnimation: function() { Ext.fx.Manager.stopAnimation(this.id); + return this; }, @@ -13682,6 +14238,7 @@ Ext.define('Ext.util.Animate', { Ext.fx.Manager.setFxDefaults(this.id, { concurrent: true }); + return this; }, @@ -13689,6 +14246,7 @@ Ext.define('Ext.util.Animate', { Ext.fx.Manager.setFxDefaults(this.id, { concurrent: false }); + return this; }, @@ -13698,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' @@ -13835,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'] @@ -14340,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,', @@ -14358,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)); }, @@ -14394,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(); @@ -14414,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 = [], @@ -14430,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, @@ -14445,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, @@ -14460,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, @@ -14523,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]); } @@ -14553,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; } @@ -14586,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, @@ -14606,22 +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 - * @method query - */ + query: function(selector, root) { var selectors = selector.split(','), length = selectors.length, @@ -14640,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++) { @@ -14656,14 +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 - * @method query - */ + is: function(component, selector) { if (!selector) { return true; @@ -14685,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, @@ -14721,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] }); @@ -14771,3254 +14807,2295 @@ 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', - this.filterFn = this.filter; + 'remove', + + '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(); } - }, - - /** - * Initializes any state events for this object. - * @private - */ - initStateEvents: function() { - this.addStateEvents(this.stateEvents); - }, - - /** - * 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]; + + if (me.autoShow) { + me.show(); } + + }, + + initComponent: function () { - var me = this, - i = 0, - len = events.length; - - for (; i < len; ++i) { - me.on(events[i], me.onStateChange, me); - } + + this.constructPlugins(); }, + - /** - * This method is called when any of the {@link #stateEvents} are fired. - * @private - */ - onStateChange: function(){ + getState: function() { var me = this, - delay = me.saveDelay; + layout = me.ownerCt ? (me.shadowOwnerCt || me.ownerCt).getLayout() : null, + state = { + collapsed: me.collapsed + }, + width = me.width, + height = me.height, + cm = me.collapseMemento, + anchors; + - if (delay > 0) { - if (!me.stateTask) { - me.stateTask = Ext.create('Ext.util.DelayedTask', me.saveState, me); + + if (me.collapsed && cm) { + if (Ext.isDefined(cm.data.width)) { + width = cm.width; + } + if (Ext.isDefined(cm.data.height)) { + height = cm.height; } - me.stateTask.delay(me.saveDelay); - } else { - me.saveState(); } - }, - - /** - * Saves the state of the object to the persistence store. - * @private - */ - 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); - } + if (layout && me.flex) { + state.flex = me.flex; + if (layout.perpendicularPrefix) { + state[layout.perpendicularPrefix] = me['get' + layout.perpendicularPrefixCap](); + } else { } } - }, - - /** - * 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; - }, - - /** - * 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); - } - }, - - /** - * 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; - } - return id; - }, - - /** - * Initializes the state of the object upon construction. - * @private - */ - initState: 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); - } + else if (layout && me.anchor) { + state.anchor = me.anchor; + anchors = me.anchor.split(' ').concat(null); + if (!anchors[0]) { + if (me.width) { + state.width = width; + } + } + if (!anchors[1]) { + if (me.height) { + state.height = height; } } } - }, - - /** - * Destroys this stateful object. - */ - destroy: function(){ - var task = this.stateTask; - if (task) { - task.cancel(); - } - this.clearListeners(); - } - -}); - -/** - * @class Ext.AbstractManager - * @extends Object - * @ignore - * Base Manager class - */ + else { + if (me.width) { + state.width = width; + } + if (me.height) { + state.height = height; + } + } -Ext.define('Ext.AbstractManager', { + + if (state.width == me.initialConfig.width) { + delete state.width; + } + if (state.height == me.initialConfig.height) { + delete state.height; + } - /* Begin Definitions */ + + if (layout && layout.align && (layout.align.indexOf('stretch') !== -1)) { + delete state[layout.perpendicularPrefix]; + } + return state; + }, - requires: ['Ext.util.HashMap'], + show: Ext.emptyFn, - /* End Definitions */ + animate: function(animObj) { + var me = this, + to; - typeName: 'type', + animObj = animObj || {}; + to = animObj.to || {}; - constructor: function(config) { - Ext.apply(this, config || {}); + if (Ext.fx.Manager.hasFxBlock(me.id)) { + return me; + } + + if (!animObj.dynamic && (to.height || to.width)) { + var curWidth = me.getWidth(), + w = curWidth, + curHeight = me.getHeight(), + h = curHeight, + needsResize = false; - /** - * Contains all of the items currently managed - * @property all - * @type Ext.util.MixedCollection - */ - this.all = Ext.create('Ext.util.HashMap'); + if (to.height && to.height > curHeight) { + h = to.height; + needsResize = true; + } + if (to.width && to.width > curWidth) { + w = to.width; + needsResize = true; + } - this.types = {}; - }, + + + + if (needsResize) { + var clearWidth = !Ext.isNumber(me.width), + clearHeight = !Ext.isNumber(me.height); - /** - * 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); - }, - - /** - * Registers an item to be managed - * @param {Mixed} item The item to register - */ - register: function(item) { - this.all.add(item); - }, - - /** - * Unregisters an item by removing it from this manager - * @param {Mixed} item The item to unregister - */ - unregister: function(item) { - this.all.remove(item); - }, - - /** - *

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; + 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); }, - /** - * 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; + + findLayoutController: function() { + return this.findParentBy(function(c) { + + + return !c.ownerCt || (c.layout.layoutBusy && !c.ownerCt.layout.layoutBusy); + }); }, - /** - * 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 (Constructor == undefined) { - Ext.Error.raise("The '" + type + "' type has not been registered with this manager"); + onShow : function() { + + var needsLayout = this.needsLayout; + if (Ext.isObject(needsLayout)) { + this.doComponentLayout(needsLayout.width, needsLayout.height, needsLayout.isSetSize, needsLayout.ownerCt); } - - return new Constructor(config); }, - /** - * 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); - } + 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 }); } + return plugin; }, + - /** - * 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); + constructPlugins: function() { + var me = this, + plugins = me.plugins, + i, len; + + if (plugins) { + for (i = 0, len = plugins.length; i < len; i++) { + + plugins[i] = me.constructPlugin(plugins[i]); + } + } }, - - /** - * 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', + + initPlugin : function(plugin) { + plugin.init(this); - /** - * 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); - // } - //}, + return plugin; + }, - create : function(config, defaultType){ - if (config.init) { - return config; + + doAutoRender: function() { + var me = this; + if (me.floating) { + me.render(document.body); } else { - return Ext.createByAlias('plugin.' + (config.ptype || defaultType), config); + me.render(Ext.isBoolean(me.autoRender) ? Ext.getBody() : me.autoRender); } - - // Prior system supported Singleton plugins. - //var PluginCls = this.types[config.ptype || defaultType]; - //if (PluginCls.init) { - // return PluginCls; - //} else { - // return new PluginCls(config); - //} }, - /** - * 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; - - for (var name in types) { - if (!types.hasOwnProperty(name)) { - continue; - } - var item = types[name]; - - if (item.type == type && (!defaultsOnly || (defaultsOnly === true && item.isDefault))) { - matches.push(item); - } - } + + render : function(container, position) { + var me = this; - 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); - }; -}); + if (!me.rendered && me.fireEvent('beforerender', me) !== false) { -/** - * @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 { - var type = component.xtype || defaultType, - config = component; - return Ext.createByAlias('widget.' + type, config); - } - }, - - 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.rendering = true; -Ext.define('Ext.XTemplate', { + + + if (me.el) { + me.el = Ext.get(me.el); + } - /* Begin Definitions */ + + if (me.floating) { + me.onFloatRender(); + } - extend: 'Ext.Template', + container = me.initContainer(container); - 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.onRender(container, position); - + + + me.el.setVisibilityMode(Ext.Element[me.hideMode.toUpperCase()]); - argsRe: /]*>((?:(?=([^<]+))\2|<(?!tpl\b[^>]*>))*?)<\/tpl>/, - nameRe: /^]*?for="(.*?)"/, - ifRe: /^]*?if="(.*?)"/, - execRe: /^]*?exec="(.*?)"/, - constructor: function() { - this.callParent(arguments); + if (me.overCls) { + me.el.hover(me.addOverCls, me.removeOverCls, me); + } - 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; + me.fireEvent('render', me); - html = ['', html, ''].join(''); + me.initContent(); - 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); + me.afterRender(container); + me.fireEvent('afterrender', me); - 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.initEvents(); - exp = matchExec ? matchExec[1] : null; - if (exp) { - exec = Ext.functionFactory(VALUES, PARENT, XINDEX, XCOUNT, WITHVALUES + Ext.String.htmlDecode(exp) + ';}'); + if (me.hidden) { + + + + me.el.hide(); } - 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.disabled) { + + me.disable(true); } - tpls.push({ - id: id, - target: name, - exec: exec, - test: fn, - body: m[1] || '' - }); - - html = html.replace(m[0], '{xtpl' + id + '}'); - id = id + 1; - } - - for (i = tpls.length - 1; i >= 0; --i) { - me.compileTpl(tpls[i]); + + delete me.rendering; } - 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); + return me; }, - - codeRe: /\{\[((?:\\\]|.|\n)*?)\]\}/g, - - re: /\{([\w-\.\#]+)(?:\:([\w\.]*)(?:\((.*?)?\))?)?(\s?[\+\-\*\/]\s?[\d\.\+\-\*\/\(\)]+)?\}/g, - compileTpl: function(tpl) { - var fm = Ext.util.Format, - me = this, - useFormat = me.disableFormats !== true, - body, bodyReturn, evaluatedFn; + onRender : function(container, position) { + var me = this, + el = me.el, + styles = me.initStyles(), + renderTpl, renderData, i; - function fn(m, name, format, args, math) { - var v; - - - if (name.substr(0, 4) == 'xtpl') { - return "',this.applySubTemplate(" + name.substr(4) + ", values, parent, xindex, xcount),'"; - } - - if (name == '.') { - - v = 'Ext.Array.indexOf(["string", "number", "boolean"], typeof values) > -1 || Ext.isDate(values) ? values : ""'; - } + position = me.getInsertPosition(position); - - else if (name == '#') { - v = 'xindex'; + if (!el) { + if (position) { + el = Ext.DomHelper.insertBefore(position, me.getElConfig(), true); } - else if (name.substr(0, 7) == "parent.") { - v = name; + else { + el = Ext.DomHelper.append(container, me.getElConfig(), true); } - - else if (name.indexOf('.') != -1) { - v = "values." + name; + } + else if (me.allowDomMove !== false) { + if (position) { + container.dom.insertBefore(el.dom, position); + } else { + container.dom.appendChild(el.dom); } + } + if (Ext.scopeResetCSS && !me.ownerCt) { - 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) + '('; - } + if (el.dom == Ext.getBody().dom) { + el.parent().addCls(Ext.baseCSSPrefix + 'reset'); } else { - args = ''; - format = "(" + v + " === undefined ? '' : "; + + me.resetEl = el.wrap({ + cls: Ext.baseCSSPrefix + 'reset' + }); } - return "'," + format + v + args + "),'"; - } - - function codeFn(m, code) { - - return "',(" + code.replace(me.compileARe, "'") + "),'"; } - 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); + me.setUI(me.ui); - tpl.compiled = function(values, parent, xindex, xcount) { - var vs, - length, - buffer, - i; + el.addCls(me.initCls()); + el.setStyle(styles); - if (tpl.test && !tpl.test.call(me, values, parent, xindex, xcount)) { - return ''; - } + + + + + + + + + + - vs = tpl.target ? tpl.target.call(me, values, parent) : values; - if (!vs) { - return ''; - } + me.el = el; - 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(''); - } + me.initFrame(); - if (tpl.exec) { - tpl.exec.call(me, vs, parent, xindex, xcount); - } - return evaluatedFn.call(me, vs, parent, xindex, xcount); - }; + renderTpl = me.initRenderTpl(); + if (renderTpl) { + renderData = me.initRenderData(); + renderTpl.append(me.getTargetEl(), renderData); + } - return this; - }, + me.applyRenderSelectors(); - - applyTemplate: function(values) { - return this.master.compiled.call(this, values, {}, 1, 1); + me.rendered = true; }, - compile: function() { - return this; - } -}, function() { - - this.createAlias('apply', 'applyTemplate'); -}); - - -Ext.define('Ext.util.AbstractMixedCollection', { - requires: ['Ext.util.Filter'], - - mixins: { - observable: 'Ext.util.Observable' - }, - - constructor: function(allowFunctions, keyFn) { - var me = this; + afterRender : function() { + var me = this, + pos, + xy; - me.items = []; - me.map = {}; - me.keys = []; - me.length = 0; + me.getComponentLayout(); - me.addEvents( + + + + if (me.collapsed || (!me.ownerCt || (me.height || me.width))) { + me.setSize(me.width, me.height); + } else { - 'clear', - - 'add', - - 'replace', - - 'remove' - ); - - me.allowFunctions = allowFunctions === true; - - if (keyFn) { - me.getKey = keyFn; + me.renderChildren(); } - me.mixins.observable.constructor.call(me); - }, - - - allowFunctions : false, - - - add : function(key, obj){ - var me = this, - myObj = obj, - myKey = key, - old; + + + 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; + } - if (arguments.length == 1) { - myObj = myKey; - myKey = me.getKey(myObj); + if (Ext.isDefined(me.x) || Ext.isDefined(me.y)) { + me.setPosition(me.x, me.y); } - if (typeof myKey != 'undefined' && myKey !== null) { - old = me.map[myKey]; - if (typeof old != 'undefined') { - return me.replace(myKey, myObj); - } - me.map[myKey] = myObj; + + if (me.styleHtmlContent) { + me.getTargetEl().addCls(me.styleHtmlCls); } - me.length++; - me.items.push(myObj); - me.keys.push(myKey); - me.fireEvent('add', me.length - 1, myObj, myKey); - return myObj; }, - getKey : function(o){ - return o.id; + registerFloatingItem: function(cmp) { + var me = this; + if (!me.floatingItems) { + me.floatingItems = Ext.create('Ext.ZIndexManager', me); + } + me.floatingItems.register(cmp); }, - - replace : function(key, o){ + renderChildren: function () { var me = this, - old, - index; + layout = me.getComponentLayout(); - if (arguments.length == 1) { - o = arguments[0]; - key = me.getKey(o); - } - 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; + me.suspendLayout = true; + layout.renderChildren(); + delete me.suspendLayout; }, - - addAll : function(objs){ - var me = this, - i = 0, - args, - len, - key; + frameCls: Ext.baseCSSPrefix + 'frame', - 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]); - } - } - } - } + frameIdRegex: /[-]frame\d+[TMB][LCR]$/, + + frameElementCls: { + tl: [], + tc: [], + tr: [], + ml: [], + mc: [], + mr: [], + bl: [], + bc: [], + br: [] }, - - each : function(fn, scope){ - var items = [].concat(this.items), - i = 0, - len = items.length, - item; + 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">
', + '
', + '
', + '
' + ], - for (; i < len; i++) { - item = items[i]; - if (fn.call(scope || item, item, i, len) === false) { - break; - } - } - }, + 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">
' + ], - 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); + initFrame : function() { + if (Ext.supports.CSS3BorderRadius) { + return false; } - }, - - findBy : function(fn, scope) { - var keys = this.keys, - items = this.items, - i = 0, - len = items.length; + var me = this, + frameInfo = me.getFrameInfo(), + frameWidth = frameInfo.width, + frameTpl = me.getFrameTpl(frameInfo.table), + frameGenId; - for (; i < len; i++) { - if (fn.call(scope || window, items[i], keys[i])) { - return items[i]; - } + if (me.frame) { + + + me.frameGenId = frameGenId = (me.frameGenId || 0) + 1; + frameGenId = me.id + '-frame' + frameGenId; + + + 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))); + + + me.frameBody = me.el.down('.' + me.frameCls + '-mc'); + + + me.removeChildEls(function (c) { + return c.id && me.frameIdRegex.test(c.id); + }); + + + Ext.each(['TL','TC','TR','ML','MC','MR','BL','BC','BR'], function (suffix) { + me.childEls.push({ name: 'frame' + suffix, id: frameGenId + suffix }); + }); } - return null; }, - find : function() { - if (Ext.isDefined(Ext.global.console)) { - Ext.global.console.warn('Ext.util.MixedCollection: find has been deprecated. Use findBy instead.'); + updateFrame: function() { + if (Ext.supports.CSS3BorderRadius) { + return false; } - return this.findBy.apply(this, arguments); - }, - - insert : function(index, key, obj){ var me = this, - myKey = key, - myObj = obj; + wasTable = this.frameSize && this.frameSize.table, + oldFrameTL = this.frameTL, + oldFrameBL = this.frameBL, + oldFrameML = this.frameML, + oldFrameMC = this.frameMC, + newMCClassName; - if (arguments.length == 2) { - myObj = myKey; - myKey = me.getKey(myObj); + 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 { + + + } } - if (me.containsKey(myKey)) { - me.suspendEvents(); - me.removeAtKey(myKey); - me.resumeEvents(); + else if (me.frame) { + this.applyRenderSelectors(); } - if (index >= me.length) { - return me.add(myKey, myObj); + }, + + getFrameInfo: function() { + if (Ext.supports.CSS3BorderRadius) { + return false; } - me.length++; - me.items.splice(index, 0, myObj); - if (typeof myKey != 'undefined' && myKey !== null) { - me.map[myKey] = myObj; + + var me = this, + left = me.el.getStyle('background-position-x'), + top = me.el.getStyle('background-position-y'), + info, frameInfo = false, max; + + + + if (!left && !top) { + info = me.el.getStyle('background-position').split(' '); + left = info[0]; + top = info[1]; } - me.keys.splice(index, 0, myKey); - me.fireEvent('add', index, myObj, myKey); - return myObj; - }, - - remove : function(o){ - return this.removeAt(this.indexOf(o)); - }, + + + + if (parseInt(left, 10) >= 1000000 && parseInt(top, 10) >= 1000000) { + max = Math.max; - - removeAll : function(items){ - Ext.each(items || [], function(item) { - this.remove(item); - }, this); + frameInfo = { + + table: left.substr(0, 3) == '110', - return this; - }, + + vertical: top.substr(0, 3) == '110', - - removeAt : function(index){ - var me = this, - o, - key; + + 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)) + }; - 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]; - } - me.keys.splice(index, 1); - me.fireEvent('remove', o, key); - return o; - } - return false; - }, + frameInfo.width = max(frameInfo.top, frameInfo.right, frameInfo.bottom, frameInfo.left); - - removeAtKey : function(key){ - return this.removeAt(this.indexOfKey(key)); - }, + + me.el.setStyle('background-image', 'none'); + } - - getCount : function(){ - return this.length; - }, + + + if (me.frame === true && !frameInfo) { + } - - indexOf : function(o){ - return Ext.Array.indexOf(this.items, o); - }, + me.frame = me.frame || !!frameInfo; + me.frameSize = frameInfo || false; - - indexOfKey : function(key){ - return Ext.Array.indexOf(this.keys, key); + return frameInfo; }, - - get : function(key) { + getFramePositions: function(frameInfo) { 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; - }, + frameWidth = frameInfo.width, + dock = me.dock, + positions, tc, bc, ml, mr; - - getAt : function(index) { - return this.items[index]; - }, + if (frameInfo.vertical) { + tc = '0 -' + (frameWidth * 0) + 'px'; + bc = '0 -' + (frameWidth * 1) + 'px'; - - getByKey : function(key) { - return this.map[key]; - }, + if (dock && dock == "right") { + tc = 'right -' + (frameWidth * 0) + 'px'; + bc = 'right -' + (frameWidth * 1) + 'px'; + } - - contains : function(o){ - return Ext.Array.contains(this.items, o); - }, + positions = { + tl: '0 -' + (frameWidth * 0) + 'px', + tr: '0 -' + (frameWidth * 1) + 'px', + bl: '0 -' + (frameWidth * 2) + 'px', + br: '0 -' + (frameWidth * 3) + 'px', - - containsKey : function(key){ - return typeof this.map[key] != 'undefined'; - }, + ml: '-' + (frameWidth * 1) + 'px 0', + mr: 'right 0', - - clear : function(){ - var me = this; + tc: tc, + bc: bc + }; + } else { + ml = '-' + (frameWidth * 0) + 'px 0'; + mr = 'right 0'; - me.length = 0; - me.items = []; - me.keys = []; - me.map = {}; - me.fireEvent('clear'); - }, + if (dock && dock == "bottom") { + ml = 'left bottom'; + mr = 'right bottom'; + } - - first : function() { - return this.items[0]; + 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' + }; + } + + return positions; }, - last : function() { - return this.items[this.length - 1]; + getFrameTpl : function(table) { + return table ? this.getTpl('frameTableTpl') : this.getTpl('frameTpl'); }, - sum: function(property, root, start, end) { - var values = this.extractValues(property, root), - length = values.length, - sum = 0, - i; + initCls: function() { + var me = this, + cls = []; - start = start || 0; - end = (end || end === 0) ? end : length - 1; + cls.push(me.baseCls); - for (i = start; i <= end; i++) { - sum += values[i]; + 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; } - return sum; + if (me.componentCls) { + cls.push(me.componentCls); + } else { + me.componentCls = me.baseCls; + } + if (me.cls) { + cls.push(me.cls); + delete me.cls; + } + + return cls.concat(me.additionalCls); }, - collect: function(property, root, allowNull) { - var values = this.extractValues(property, root), - length = values.length, - hits = {}, - unique = [], - value, strValue, i; + setUI: function(ui) { + var me = this, + oldUICls = Ext.Array.clone(me.uiCls), + newUICls = [], + classes = [], + cls, + i; - for (i = 0; i < length; i++) { - value = values[i]; - strValue = String(value); + + for (i = 0; i < oldUICls.length; i++) { + cls = oldUICls[i]; - if ((allowNull || !Ext.isEmpty(value)) && !hits[strValue]) { - hits[strValue] = true; - unique.push(value); - } + classes = classes.concat(me.removeClsWithUI(cls, true)); + newUICls.push(cls); } - return unique; - }, + if (classes.length) { + me.removeCls(classes); + } - - extractValues: function(property, root) { - var values = this.items; + + me.removeUIFromElement(); - if (root) { - values = Ext.Array.pluck(values, root); + + me.ui = ui; + + + me.addUIToElement(); + + + classes = []; + for (i = 0; i < newUICls.length; i++) { + cls = newUICls[i]; + classes = classes.concat(me.addClsWithUI(cls, true)); } - return Ext.Array.pluck(values, property); + if (classes.length) { + me.addCls(classes); + } }, - getRange : function(start, end){ + addClsWithUI: function(cls, skip) { var me = this, - items = me.items, - range = [], + classes = [], i; - if (items.length < 1) { - return range; + if (!Ext.isArray(cls)) { + cls = [cls]; } - 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]; + 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]); + + classes = classes.concat(me.addUIClsToElement(cls[i])); } } - return range; + + if (skip !== true) { + me.addCls(classes); + } + + return classes; }, - filter : function(property, value, anyMatch, caseSensitive) { - var filters = [], - filterFn; + removeClsWithUI: function(cls, skip) { + var me = this, + classes = [], + i; - - 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 (!Ext.isArray(cls)) { + cls = [cls]; } - - - 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; + for (i = 0; i < cls.length; i++) { + if (cls[i] && me.hasUICls(cls[i])) { + me.uiCls = Ext.Array.remove(me.uiCls, cls[i]); - isMatch = isMatch && fn.call(scope, record); + classes = classes.concat(me.removeUIClsFromElement(cls[i])); } + } - return isMatch; - }; + if (skip !== true) { + me.removeCls(classes); + } - return this.filterBy(filterFn); + return classes; }, - filterBy : function(fn, scope) { + hasUICls: function(cls) { var me = this, - newMC = new this.self(), - keys = me.keys, - items = me.items, - length = items.length, - i; + uiCls = me.uiCls || []; - newMC.getKey = me.getKey; + return Ext.Array.contains(uiCls, cls); + }, - for (i = 0; i < length; i++) { - if (fn.call(scope || me, items[i], keys[i])) { - newMC.add(keys[i], items[i]); + + addUIClsToElement: function(cls, force) { + var me = this, + result = [], + frameElementCls = me.frameElementCls; + + 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]); + } + } + } } } - return newMC; - }, + me.frameElementCls = frameElementCls; - - 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); + return result; }, - findIndexBy : function(fn, scope, start){ + removeUIClsFromElement: function(cls, force) { var me = this, - keys = me.keys, - items = me.items, - i = start || 0, - len = items.length; + result = [], + frameElementCls = me.frameElementCls; - for (; i < len; i++) { - if (fn.call(scope || me, items[i], keys[i])) { - return i; + 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); + } } } - return -1; + + me.frameElementCls = frameElementCls; + + return result; }, - createValueMatcher : function(value, anyMatch, caseSensitive, exactMatch) { - if (!value.exec) { - var er = Ext.String.escapeRegex; - value = String(value); + addUIToElement: function(force) { + var me = this, + frameElementCls = me.frameElementCls; - if (anyMatch === true) { - value = er(value); - } else { - value = '^' + er(value); - if (exactMatch === true) { - value += '$'; + me.addCls(me.baseCls + '-' + me.ui); + + if (me.frame && !Ext.supports.CSS3BorderRadius) { + + var els = ['tl', 'tc', 'tr', 'ml', 'mc', 'mr', 'bl', 'bc', 'br'], + i, el, cls; + + + 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); + } } } - value = new RegExp(value, caseSensitive ? '' : 'i'); } - return value; }, - clone : function() { + removeUIFromElement: function() { var me = this, - copy = new this.self(), - keys = me.keys, - items = me.items, - i = 0, - len = items.length; + frameElementCls = me.frameElementCls; - for(; i < len; i++){ - copy.add(keys[i], items[i]); - } - copy.getKey = me.getKey; - return copy; - } -}); + me.removeCls(me.baseCls + '-' + me.ui); + if (me.frame && !Ext.supports.CSS3BorderRadius) { + + var els = ['tl', 'tc', 'tr', 'ml', 'mc', 'mr', 'bl', 'bc', 'br'], + i, j, el, cls; -Ext.define("Ext.util.Sortable", { - - isSortable: true, - - - defaultSortDirection: "ASC", - - requires: [ - 'Ext.util.Sorter' - ], + + for (i = 0; i < els.length; i++) { + el = me['frame' + els[i].toUpperCase()]; + cls = me.baseCls + '-' + me.ui + '-' + els[i]; - - 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 (el) { + el.removeCls(cls); + } else { + Ext.Array.remove(frameElementCls[els[i]], cls); + } + } } }, - - 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]; + getElConfig : function() { + if (Ext.isString(this.autoEl)) { + this.autoEl = { + tag: this.autoEl + }; } - 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); - } - } + var result = this.autoEl || {tag: 'div'}; + result.id = this.id; + return result; + }, + + + getInsertPosition: function(position) { - 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); - } + if (position !== undefined) { + if (Ext.isNumber(position)) { + position = this.container.dom.childNodes[position]; } else { - me.sorters.clear(); - me.sorters.addAll(newSorters); - } - - if (doSort !== false) { - me.onBeforeSort(newSorters); + position = Ext.getDom(position); } } - - 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; - - for (i = 1; i < length; i++) { - result = result || sorters[i].sort.call(this, r1, r2); - } + return position; + }, - return result; - }; + + initContainer: function(container) { + var me = this; - me.doSort(sorterFn); - } - } - return sorters; - }, - - onBeforeSort: Ext.emptyFn, - - decodeSorters: function(sorters) { - if (!Ext.isArray(sorters)) { - if (sorters === undefined) { - sorters = []; - } else { - sorters = [sorters]; - } + + if (!container && me.el) { + container = me.el.dom.parentNode; + me.allowDomMove = false; } - var length = sorters.length, - Sorter = Ext.util.Sorter, - fields = this.model ? this.model.prototype.fields : null, - field, - config, i; + me.container = Ext.get(container); - for (i = 0; i < length; i++) { - config = sorters[i]; + if (me.ctCls) { + me.container.addCls(me.ctCls); + } - if (!(config instanceof Sorter)) { - if (Ext.isString(config)) { - config = { - property: config - }; - } - - Ext.applyIf(config, { - root : this.sortRoot, - direction: "ASC" - }); + return me.container; + }, - - if (config.fn) { - config.sorterFn = config.fn; - } + + initRenderData: function() { + var me = this; - - if (typeof config == 'function') { - config = { - sorterFn: config - }; - } + return Ext.applyIf(me.renderData, { + id: me.id, + ui: me.ui, + uiCls: me.uiCls, + baseCls: me.baseCls, + componentCls: me.componentCls, + frame: me.frame + }); + }, - - if (fields && !config.transform) { - field = fields.get(config.property); - config.transform = field ? field.sortType : undefined; - } - sorters[i] = Ext.create('Ext.util.Sorter', config); + + getTpl: function(name) { + var me = this, + prototype = me.self.prototype, + ownerPrototype, + tpl; + + if (me.hasOwnProperty(name)) { + tpl = me[name]; + if (tpl && !(tpl instanceof Ext.XTemplate)) { + me[name] = Ext.ClassManager.dynInstantiate('Ext.XTemplate', tpl); } + + return me[name]; } - return sorters; - }, - - getSorters: function() { - return this.sorters.items; - }, - - - getSortState : function() { - return this.sortInfo; - } -}); + if (!(prototype[name] instanceof Ext.XTemplate)) { + ownerPrototype = prototype; -Ext.define('Ext.util.MixedCollection', { - extend: 'Ext.util.AbstractMixedCollection', - mixins: { - sortable: 'Ext.util.Sortable' - }, + do { + if (ownerPrototype.hasOwnProperty(name)) { + tpl = ownerPrototype[name]; + if (tpl && !(tpl instanceof Ext.XTemplate)) { + ownerPrototype[name] = Ext.ClassManager.dynInstantiate('Ext.XTemplate', tpl); + break; + } + } - constructor: function() { - var me = this; - me.callParent(arguments); - me.addEvents('sort'); - me.mixins.sortable.initSortable.call(me); + ownerPrototype = ownerPrototype.superclass; + } while (ownerPrototype); + } + + return prototype[name]; }, - doSort: function(sorterFn) { - this.sortBy(sorterFn); + + initRenderTpl: function() { + return this.getTpl('renderTpl'); }, - _sort : function(property, dir, fn){ - var me = this, - i, len, - dsc = String(dir).toUpperCase() == 'DESC' ? -1 : 1, + initStyles: function() { + var style = {}, + me = this, + Element = Ext.Element; - - c = [], - keys = me.keys, - items = me.items; + if (Ext.isString(me.style)) { + style = Element.parseStyles(me.style); + } else { + style = Ext.apply({}, me.style); + } - 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 - }; + if (me.padding !== undefined) { + style.padding = Element.unitizeBox((me.padding === true) ? 5 : me.padding); } - - 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; + if (me.margin !== undefined) { + style.margin = Element.unitizeBox((me.margin === true) ? 5 : me.margin); } - me.fireEvent('sort', me); + delete me.style; + return style; }, - sortBy: function(sorterFn) { - var me = this, - items = me.items, - keys = me.keys, - length = items.length, - temp = [], - i; + initContent: function() { + var me = this, + target = me.getTargetEl(), + contentEl, + pre; - - for (i = 0; i < length; i++) { - temp[i] = { - key : keys[i], - value: items[i], - index: i - }; + if (me.html) { + target.update(Ext.DomHelper.markup(me.html)); + delete me.html; } - 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.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); + } + + if (me.tpl) { + + if (!me.tpl.isTemplate) { + me.tpl = Ext.create('Ext.XTemplate', me.tpl); } - return v; - }); + if (me.data) { + me.tpl[me.tplWriteMode](target, me.data); + delete me.data; + } + } + }, - - for (i = 0; i < length; i++) { - items[i] = temp[i].value; - keys[i] = temp[i].key; + + 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); + } + } + } } - - me.fireEvent('sort', me, items, keys); }, - reorder: function(mapping) { + addChildEls: function () { var me = this, - items = me.items, - index = 0, - length = items.length, - order = [], - remaining = [], - oldIndex; + childEls = me.childEls || (me.childEls = []); - me.suspendEvents(); + childEls.push.apply(childEls, arguments); + }, - - for (oldIndex in mapping) { - order[mapping[oldIndex]] = items[oldIndex]; - } + + removeChildEls: function (testFn) { + var me = this, + old = me.childEls, + keepers = (me.childEls = []), + n, i, cel; - for (index = 0; index < length; index++) { - if (mapping[index] == undefined) { - remaining.push(items[index]); + for (i = 0, n = old.length; i < n; ++i) { + cel = old[i]; + if (!testFn(cel)) { + keepers.push(cel); } } + }, - for (index = 0; index < length; index++) { - if (order[index] == undefined) { - order[index] = remaining.shift(); + + applyRenderSelectors: function() { + var me = this, + 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; + } + + + + me[childName] = el.getById(childId); } } - me.clear(); - me.addAll(order); - - me.resumeEvents(); - me.fireEvent('sort', me); + + + + if (selectors) { + for (selector in selectors) { + if (selectors.hasOwnProperty(selector) && selectors[selector]) { + me[selector] = Ext.get(Ext.DomQuery.selectNode(selectors[selector], dom)); + } + } + } }, - 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.StoreManager', { - extend: 'Ext.util.MixedCollection', - alternateClassName: ['Ext.StoreMgr', 'Ext.data.StoreMgr', 'Ext.StoreManager'], - singleton: true, - uses: ['Ext.data.ArrayStore'], - - + is: function(selector) { + return Ext.ComponentQuery.is(this, selector); + }, - register : function() { - for (var i = 0, s; (s = arguments[i]); i++) { - this.add(s); + up: function(selector) { + var result = this.ownerCt; + if (selector) { + for (; result; result = result.ownerCt) { + if (Ext.ComponentQuery.is(result, selector)) { + return result; + } + } } + return result; }, - unregister : function() { - for (var i = 0, s; (s = arguments[i]); i++) { - this.remove(this.lookup(s)); + 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; }, - 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); + 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 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); } + return null; }, - getKey : function(o) { - return o.storeId; - } -}, function() { - - Ext.regStore = function(name, config) { - var store; + previousNode: function(selector, includeSelf) { + var node = this, + result, + it, len, i; - if (Ext.isObject(name)) { - config = name; - } else { - config.storeId = name; + + if (includeSelf && node.is(selector)) { + return node; } - if (config instanceof Ext.data.Store) { - store = config; - } else { - store = Ext.create('Ext.data.Store', config); + result = this.prev(selector); + if (result) { + return result; } - return Ext.data.StoreManager.register(store); - }; + 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; + } + } + } + return node.ownerCt.previousNode(selector, true); + } + }, - Ext.getStore = function(name) { - return Ext.data.StoreManager.lookup(name); - }; -}); + nextNode: function(selector, includeSelf) { + var node = this, + result, + it, len, i; + + if (includeSelf && node.is(selector)) { + return node; + } + result = this.next(selector); + if (result) { + return result; + } -Ext.define('Ext.LoadMask', { + 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; + } + } + } + return node.ownerCt.nextNode(selector); + } + }, - - mixins: { - observable: 'Ext.util.Observable' + getId : function() { + return this.id || (this.id = 'ext-comp-' + (this.getAutoId())); }, - requires: ['Ext.data.StoreManager'], + getItemId : function() { + return this.itemId || this.id; + }, + getEl : function() { + return this.el; + }, + getTargetEl: function() { + return this.frameBody || this.el; + }, - msg : 'Loading...', - - msgCls : Ext.baseCSSPrefix + 'mask-loading', - - - useMsg: true, + isXType: function(xtype, shallow) { + + if (Ext.isFunction(xtype)) { + xtype = xtype.xtype; + + } else if (Ext.isObject(xtype)) { + xtype = xtype.statics().xtype; + + } + + return !shallow ? ('/' + this.getXTypes() + '/').indexOf('/' + xtype + '/') != -1: this.self.xtype == xtype; + }, - disabled: false, + getXTypes: function() { + var self = this.self, + xtypes, parentPrototype, parentXtypes; - constructor : function(el, config) { - var me = this; + if (!self.xtypes) { + xtypes = []; + parentPrototype = this; - if (el.isComponent) { - me.bindComponent(el); - } else { - me.el = Ext.get(el); - } - Ext.apply(me, config); + while (parentPrototype) { + parentXtypes = parentPrototype.xtypes; - me.addEvents('beforeshow', 'show', 'hide'); - if (me.store) { - me.bindStore(me.store, true); + if (parentXtypes !== undefined) { + xtypes.unshift.apply(xtypes, parentXtypes); + } + + parentPrototype = parentPrototype.superclass; + } + + self.xtypeChain = xtypes; + self.xtypes = xtypes.join('/'); } - me.mixins.observable.constructor.call(me, config); + + return self.xtypes; }, - bindComponent: function(comp) { - var me = this, - listeners = { - resize: me.onComponentResize, - scope: me - }; + + update : function(htmlOrData, loadScripts, cb) { + var me = this; - if (comp.el) { - me.onComponentRender(comp); + if (me.tpl && !Ext.isString(htmlOrData)) { + me.data = htmlOrData; + if (me.rendered) { + me.tpl[me.tplWriteMode](me.getTargetEl(), htmlOrData || {}); + } } else { - listeners.render = { - fn: me.onComponentRender, - scope: me, - single: true - }; + me.html = Ext.isObject(htmlOrData) ? Ext.DomHelper.markup(htmlOrData) : htmlOrData; + if (me.rendered) { + me.getTargetEl().update(me.html, loadScripts, cb); + } + } + + if (me.rendered) { + me.doComponentLayout(); } - me.mon(comp, listeners); }, - onComponentRender: function(comp) { - this.el = comp.getContentTarget(); + setVisible : function(visible) { + return this[visible ? 'show': 'hide'](); }, - onComponentResize: function(comp, w, h) { - this.el.isMasked(); + isVisible: function(deep) { + var me = this, + child = me, + visible = !me.hidden, + ancestor = me.ownerCt; + + + me.hiddenAncestor = false; + if (me.destroyed) { + return false; + } + + 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; }, - bindStore : function(store, initial) { + enable: function(silent) { 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 (me.rendered) { + me.el.removeCls(me.disabledCls); + me.el.dom.disabled = false; + me.onEnable(); } - if (store) { - store = Ext.data.StoreManager.lookup(store); - me.mon(store, { - scope: me, - beforeload: me.onBeforeLoad, - load: me.onLoad, - exception: me.onLoad - }); + me.disabled = false; + + if (silent !== true) { + me.fireEvent('enable', me); } - me.store = store; - if (store && store.isLoading()) { - me.onBeforeLoad(); - } + + return me; }, - disable : function() { + disable: function(silent) { var me = this; - me.disabled = true; - if (me.loading) { - me.onLoad(); - } + if (me.rendered) { + me.el.addCls(me.disabledCls); + me.el.dom.disabled = true; + me.onDisable(); + } + + me.disabled = true; + + if (silent !== true) { + me.fireEvent('disable', me); + } + + return me; }, - enable : function() { - this.disabled = false; + onEnable: function() { + if (this.maskOnDisable) { + this.el.unmask(); + } + }, + + + onDisable : function() { + if (this.maskOnDisable) { + this.el.mask(); + } }, @@ -18027,6897 +17104,7994 @@ Ext.define('Ext.LoadMask', { }, - onLoad : function() { - var me = this; + setDisabled : function(disabled) { + return this[disabled ? 'disable': 'enable'](); + }, - me.loading = false; - me.el.unmask(); - me.fireEvent('hide', me, me.el, me.store); + + isHidden : function() { + return this.hidden; }, - onBeforeLoad : function() { + addCls : function(className) { 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 (!className) { + return me; + } + 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; }, - show: function() { - this.onBeforeLoad(); + addClass : function() { + return this.addCls.apply(this, arguments); }, - hide: function() { - this.onLoad(); + 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; }, - - destroy : function() { - this.hide(); - this.clearListeners(); - } -}); + addOverCls: function() { + var me = this; + if (!me.disabled) { + me.el.addCls(me.overCls); + } + }, -Ext.define('Ext.ComponentLoader', { + removeOverCls: function() { + this.el.removeCls(this.overCls); + }, - - - extend: 'Ext.ElementLoader', + addListener : function(element, listeners, scope, options) { + var me = this, + fn, + option; - statics: { - Renderer: { - Data: function(loader, response, active){ - var success = true; - try { - loader.getTarget().update(Ext.decode(response.responseText)); - } catch (e) { - success = false; - } - return success; - }, + if (Ext.isString(element) && (Ext.isObject(listeners) || options && options.element)) { + if (options.element) { + fn = listeners; - Component: function(loader, response, active){ - var success = true, - target = loader.getTarget(), - items = []; + listeners = {}; + listeners[element] = fn; + element = options.element; + if (scope) { + listeners.scope = scope; + } - if (!target.isContainer) { - Ext.Error.raise({ - target: target, - msg: 'Components can only be loaded into a container' - }); + for (option in options) { + if (options.hasOwnProperty(option)) { + if (me.eventOptionsRe.test(option)) { + listeners[option] = options[option]; + } + } } + } - try { - items = Ext.decode(response.responseText); - } catch (e) { - success = false; + + + 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); + } + } - if (success) { - if (active.removeAll) { - target.removeAll(); + 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); } - target.add(items); } - return success; } + } else { + return me.mixins.observable.removeManagedListenerItem.apply(me, arguments); } }, + getBubbleTarget : function() { + return this.ownerCt; + }, - target: null, + isFloating : function() { + return this.floating; + }, - loadMask: false, - - + isDraggable : function() { + return !!this.draggable; + }, - 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; + isDroppable : function() { + return !!this.droppable; }, + - - removeMask: function(){ - this.target.setLoading(false); + onAdded : function(container, pos) { + this.ownerCt = container; + this.fireEvent('added', this, container, pos); }, + - - addMask: function(mask){ - this.target.setLoading(mask); + onRemoved : function() { + var me = this; + + me.fireEvent('removed', me, me.ownerCt); + delete me.ownerCt; }, + beforeDestroy : Ext.emptyFn, - setOptions: function(active, options){ - active.removeAll = Ext.isDefined(options.removeAll) ? options.removeAll : this.removeAll; - }, + + onResize : Ext.emptyFn, - getRenderer: function(renderer){ - if (Ext.isFunction(renderer)) { - return renderer; + setSize : function(width, height) { + var me = this, + layoutCollection; + + + if (Ext.isObject(width)) { + height = width.height; + width = width.width; } - var renderers = this.statics().Renderer; - switch (renderer) { - case 'component': - return renderers.Component; - case 'data': - return renderers.Data; - default: - return Ext.ElementLoader.Renderer.Html; + + 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; + }, -Ext.define('Ext.layout.component.Auto', { + isFixedWidth: function() { + var me = this, + layoutManagedWidth = me.layoutManagedWidth; - + if (Ext.isDefined(me.width) || layoutManagedWidth == 1) { + return true; + } + if (layoutManagedWidth == 2) { + return false; + } + return (me.ownerCt && me.ownerCt.isFixedWidth()); + }, - alias: 'layout.autocomponent', + isFixedHeight: function() { + var me = this, + layoutManagedHeight = me.layoutManagedHeight; - extend: 'Ext.layout.component.Component', + if (Ext.isDefined(me.height) || layoutManagedHeight == 1) { + return true; + } + if (layoutManagedHeight == 2) { + return false; + } + return (me.ownerCt && me.ownerCt.isFixedHeight()); + }, - + setCalculatedSize : function(width, height, callingContainer) { + var me = this, + layoutCollection; - type: 'autocomponent', + + if (Ext.isObject(width)) { + callingContainer = width.ownerCt; + height = width.height; + width = width.width; + } - onLayout : function(width, height) { - this.setTargetSize(width, height); - } -}); + + 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: false, + ownerCt: callingContainer + }; + return me; + } + me.doComponentLayout(width, height, false, callingContainer); -Ext.define('Ext.AbstractComponent', { + return me; + }, + doComponentLayout : function(width, height, isSetSize, callingContainer) { + var me = this, + componentLayout = me.getComponentLayout(), + lastComponentSize = componentLayout.lastComponentSize || { + width: undefined, + height: undefined + }; - mixins: { - observable: 'Ext.util.Observable', - animate: 'Ext.util.Animate', - state: 'Ext.state.Stateful' - }, + + + + 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; + } + } - 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' - ], + if (isSetSize) { + me.width = width; + me.height = height; + } - - - uses: [ - 'Ext.ZIndexManager' - ], + componentLayout.layout(width, height, isSetSize, callingContainer); + } - statics: { - AUTO_ID: 1000 + return me; }, + forceComponentLayout: function () { + this.doComponentLayout(); + }, - isComponent: true, + + setComponentLayout : function(layout) { + var currentLayout = this.componentLayout; + if (currentLayout && currentLayout.isLayout && currentLayout != layout) { + currentLayout.setOwner(null); + } + this.componentLayout = layout; + layout.setOwner(this); + }, - getAutoId: function() { - return ++Ext.AbstractComponent.AUTO_ID; + getComponentLayout : function() { + var me = this; + + if (!me.componentLayout || !me.componentLayout.isLayout) { + me.setComponentLayout(Ext.layout.Layout.create(me.componentLayout, 'autocomponent')); + } + return me.componentLayout; }, + 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); + } + }, + beforeComponentLayout: function(width, height, isSetSize, callingContainer) { + this.preLayoutSize = this.componentLayout.lastComponentSize; + return true; + }, + setPosition : function(x, y) { + var me = this; - - renderTpl: null, + if (Ext.isObject(x)) { + y = x.y; + x = x.x; + } - + if (!me.rendered) { + return me; + } - + 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, + setWidth : function(width) { + return this.setSize(width); + }, + setHeight : function(height) { + return this.setSize(undefined, height); + }, + getSize : function() { + return this.el.getSize(); + }, + getWidth : function() { + return this.el.getWidth(); + }, - tplWriteMode: 'overwrite', + getHeight : function() { + return this.el.getHeight(); + }, - baseCls: Ext.baseCSSPrefix + 'component', + getLoader: function(){ + 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; - + } + return null; + }, + setLoading : function(load, targetEl) { + var me = this, + config; - - disabledCls: Ext.baseCSSPrefix + 'item-disabled', + 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; + } + } - - ui: 'default', - - - uiCls: [], - - + return me.loadMask; + }, + 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; - - hidden: false, + 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]; + } + } - - disabled: false, + 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; - - draggable: false, + if (!me.isDestroyed) { + if (me.fireEvent('beforedestroy', me) !== false) { + me.destroying = true; + me.beforeDestroy(); - - floating: false, + 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); + } - - hideMode: 'display', + me.onDestroy(); - + + Ext.destroy(me.plugins); - + if (me.rendered) { + me.el.remove(); + } - - styleHtmlContent: false, + me.fireEvent('destroy', me); + Ext.ComponentManager.unregister(me); + + me.mixins.state.destroy.call(me); + + me.clearListeners(); + + me.cleanElementRefs(); + me.destroying = false; + me.isDestroyed = true; + } + } + }, - styleHtmlCls: Ext.baseCSSPrefix + 'html', + 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, + + constructor: function(config) { + Ext.apply(this, config); + }, + + getCmp: function() { + return this.cmp; + }, + + init: Ext.emptyFn, + + destroy: Ext.emptyFn, + + enable: function() { + this.disabled = false; + }, + disable: function() { + this.disabled = true; + } +}); - - allowDomMove: true, +Ext.define('Ext.data.Connection', { + mixins: { + observable: 'Ext.util.Observable' + }, - - autoShow: false, + statics: { + requestId: 0 + }, - - autoRender: false, + url: null, + async: true, + method: null, + username: '', + password: '', - needsLayout: false, + + disableCaching: true, + withCredentials: false, - rendered: false, + cors: false, - weight: 0, + + disableCachingParam: '_dc', - trimRe: /^\s+|\s+$/g, - spacesRe: /\s+/, + timeout : 30000, + - - maskOnDisable: true, - constructor : function(config) { - var me = this, - i, len; + useDefaultHeader : true, + defaultPostHeader : 'application/x-www-form-urlencoded; charset=UTF-8', + useDefaultXhrHeader : true, + defaultXhrHeader : 'XMLHttpRequest', + constructor : function(config) { 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]); - } - } - - me.initComponent(); + requestOptions = me.setOptions(options, scope); - - Ext.ComponentManager.register(me); + if (this.isFormUpload(options) === true) { + this.upload(options.form, requestOptions.url, requestOptions.data, options); + return null; + } - - me.mixins.observable.constructor.call(me); - me.mixins.state.constructor.call(me, config); + + if (options.autoAbort === true || me.autoAbort) { + me.abort(); + } - - 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 (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.'); + 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]); + } + + + 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, + + upload: function(form, url, params, options) { + form = Ext.getDom(form); + options = options || {}; - show: Ext.emptyFn, + 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; - animate: function(animObj) { - var me = this, - to; + + Ext.fly(frame).set({ + id: id, + name: id, + cls: Ext.baseCSSPrefix + 'hide-display', + src: Ext.SSL_SECURE_URL + }); - animObj = animObj || {}; - to = animObj.to || {}; + document.body.appendChild(frame); - if (Ext.fx.Manager.hasFxBlock(me.id)) { - return me; + + 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); + + me.fireEvent('requestcomplete', me, response, options); + + Ext.callback(options.success, options.scope, [response, options]); + Ext.callback(options.callback, options.scope, [options, true, response]); + + setTimeout(function(){ + Ext.removeNode(frame); + }, 100); }, - findLayoutController: function() { - return this.findParentBy(function(c) { - - - return !c.ownerCt || (c.layout.layoutBusy && !c.ownerCt.layout.layoutBusy); - }); + isFormUpload: function(options){ + var form = this.getForm(options); + if (form) { + return (options.isUpload || (/multipart\/form-data/i).test(form.getAttribute('enctype'))); + } + return false; }, - onShow : function() { - - var needsLayout = this.needsLayout; - if (Ext.isObject(needsLayout)) { - this.doComponentLayout(needsLayout.width, needsLayout.height, needsLayout.isSetSize, needsLayout.ownerCt); - } + + getForm: function(options){ + return Ext.getDom(options.form) || null; }, - constructPlugin: function(plugin) { - if (plugin.ptype && typeof plugin.init != 'function') { - plugin.cmp = this; - plugin = Ext.PluginManager.create(plugin); + + 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); } - else if (typeof plugin == 'string') { - plugin = Ext.PluginManager.create({ - ptype: plugin, - cmp: this - }); + + + if (Ext.isFunction(url)) { + url = url.call(scope, options); } - return plugin; - }, + url = this.setupUrl(options, url); - - initPlugin : function(plugin) { - plugin.init(this); - return plugin; - }, + + data = options.rawData || options.xmlData || jsonData || null; + if (jsonData && !Ext.isPrimitive(jsonData)) { + data = Ext.encode(data); + } - - doAutoRender: function() { - var me = this; - if (me.floating) { - me.render(document.body); - } else { - me.render(Ext.isBoolean(me.autoRender) ? Ext.getBody() : me.autoRender); + + if (Ext.isObject(params)) { + params = Ext.Object.toQueryString(params); } - }, - - render : function(container, position) { - var me = this; + if (Ext.isObject(extraParams)) { + extraParams = Ext.Object.toQueryString(extraParams); + } - if (!me.rendered && me.fireEvent('beforerender', me) !== false) { - - - if (me.el) { - me.el = Ext.get(me.el); - } + params = params + ((extraParams) ? ((params) ? '&' : '') + extraParams : ''); - - if (me.floating) { - me.onFloatRender(); - } + urlParams = Ext.isObject(urlParams) ? Ext.Object.toQueryString(urlParams) : urlParams; - container = me.initContainer(container); + params = this.setupParams(options, params); - me.onRender(container, position); + + method = (options.method || me.method || ((params || data) ? 'POST' : 'GET')).toUpperCase(); + this.setupMethod(options, method); - - - me.el.setVisibilityMode(Ext.core.Element[me.hideMode.toUpperCase()]); - if (me.overCls) { - me.el.hover(me.addOverCls, me.removeOverCls, me); - } + disableCache = options.disableCaching !== false ? (options.disableCaching || me.disableCaching) : false; + + if (method === 'GET' && disableCache) { + url = Ext.urlAppend(url, (options.disableCachingParam || me.disableCachingParam) + '=' + (new Date().getTime())); + } - me.fireEvent('render', me); + + if ((method == 'GET' || data) && params) { + url = Ext.urlAppend(url, params); + params = null; + } - me.initContent(); + + if (urlParams) { + url = Ext.urlAppend(url, urlParams); + } - me.afterRender(container); - me.fireEvent('afterrender', me); + return { + url: url, + method: method, + data: data || params || null + }; + }, - me.initEvents(); + + setupUrl: function(options, url){ + var form = this.getForm(options); + if (form) { + url = url || form.action; + } + return url; + }, - if (me.hidden) { - - - - me.el.hide(); - } - if (me.disabled) { - - me.disable(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; } - return me; + return params; }, - onRender : function(container, position) { - var me = this, - el = me.el, - cls = me.initCls(), - styles = me.initStyles(), - renderTpl, renderData, i; + setupMethod: function(options, method){ + if (this.isFormUpload(options)) { + return 'POST'; + } + return method; + }, - position = me.getInsertPosition(position); + + 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 (!el) { - if (position) { - el = Ext.core.DomHelper.insertBefore(position, me.getElConfig(), true); - } - else { - el = Ext.core.DomHelper.append(container, me.getElConfig(), true); + 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; } - else if (me.allowDomMove !== false) { - if (position) { - container.dom.insertBefore(el.dom, position); - } else { - container.dom.appendChild(el.dom); - } + + 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); + } - 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' - }); } + } catch(e) { + me.fireEvent('exception', key, header); } + return headers; + }, - el.addCls(cls); - el.setStyle(styles); - - - - - - - - - - - + + 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; - me.el = el; - - me.rendered = true; - me.addUIToElement(true); - - for (i = 0; i < me.uiCls.length; i++) { - me.addUIClsToElement(me.uiCls[i], true); + for(; i < len; ++i) { + try{ + xhr = options[i]; + xhr(); + break; + }catch(e){} } - me.rendered = false; - me.initFrame(); + return xhr; + })(), - renderTpl = me.initRenderTpl(); - if (renderTpl) { - renderData = me.initRenderData(); - renderTpl.append(me.getTargetEl(), renderData); + + isLoading : function(request) { + if (!request) { + request = this.getLatest(); + } + if (!(request && request.xhr)) { + return false; } - - me.applyRenderSelectors(); - - me.rendered = true; - 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', + + clearTimeout: function(request){ + clearTimeout(request.timeout); + delete request.timeout; + }, - 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">
', - '
', - '
', - '
' - ], + + cleanup: function(request){ + request.xhr = null; + delete request.xhr; + }, + + + onComplete : function(request) { + var me = this, + options = request.options, + result, + success, + response; + + try { + result = me.parseStatus(request.xhr.status); + } catch (e) { + + result = { + success : false, + isException : false + }; + } + 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]); + } + Ext.callback(options.callback, options.scope, [options, success, response]); + delete me.requests[request.id]; + return response; + }, - 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">
' - ], + 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 + }; + }, + - initFrame : function() { - if (Ext.supports.CSS3BorderRadius) { - return false; + 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); + } } + + 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; + }, + + + 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 + }; + } +}); + + +Ext.define('Ext.Ajax', { + extend: 'Ext.data.Connection', + singleton: true, + + + + + + + + + + + + + + + + + + + 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; + } + } + }, + + + + + url: null, + + + params: null, + + + baseParams: null, + + + autoLoad: false, + + + target: null, + + + loadMask: false, + + + ajaxOptions: null, + + + scripts: false, + + + + + + + + + + + + isLoader: true, + + constructor: function(config) { 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))); + autoLoad; + config = config || {}; + Ext.apply(me, config); + me.setTarget(me.target); + me.addEvents( - me.frameBody = me.el.down('.' + me.frameCls + '-mc'); + 'beforeload', + + 'exception', + - 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' - }); + 'load' + ); + + + me.mixins.observable.constructor.call(me); + + if (me.autoLoad) { + autoLoad = me.autoLoad; + if (autoLoad === true) { + autoLoad = {}; + } + me.load(autoLoad); } }, + - updateFrame: function() { - if (Ext.supports.CSS3BorderRadius) { - return false; + setTarget: function(target){ + var me = this; + target = Ext.get(target); + if (me.target && me.target != target) { + me.abort(); } - + me.target = target; + }, + + + getTarget: function(){ + return this.target || null; + }, + + + abort: function(){ + var active = this.active; + if (active !== undefined) { + Ext.Ajax.abort(active.request); + if (active.mask) { + this.removeMask(); + } + delete this.active; + } + }, + + + removeMask: function(){ + this.target.unmask(); + }, + + + addMask: function(mask){ + this.target.mask(mask === true ? null : mask); + }, + + + load: function(options) { + + options = Ext.apply({}, options); + 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(); + 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; + + Ext.applyIf(ajaxOptions, me.ajaxOptions); + Ext.applyIf(options, ajaxOptions); + + Ext.applyIf(params, me.params); + Ext.apply(params, me.baseParams); + + Ext.applyIf(options, { + url: me.url + }); + + + 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); + }, + + + setOptions: Ext.emptyFn, + + + onComplete: function(options, success, response) { + var me = this, + active = me.active, + scope = active.scope, + renderer = me.getRenderer(active.renderer); + + + if (success) { + success = renderer.call(me, me, response, active); + } + + 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]); + + if (active.mask) { + me.removeMask(); + } + + delete me.active; + }, + + + getRenderer: function(renderer){ + if (Ext.isFunction(renderer)) { + return renderer; + } + return this.statics().Renderer.Html; + }, + + + startAutoRefresh: function(interval, options){ + var me = this; + me.stopAutoRefresh(); + me.autoRefresh = setInterval(function(){ + me.load(options); + }, interval); + }, + + + stopAutoRefresh: function(){ + clearInterval(this.autoRefresh); + delete this.autoRefresh; + }, + + + isAutoRefreshing: function(){ + return Ext.isDefined(this.autoRefresh); + }, + + + destroy: function(){ + var me = this; + me.stopAutoRefresh(); + delete me.target; + me.abort(); + me.clearListeners(); + } +}); + + +Ext.define('Ext.ComponentLoader', { + + + + 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 = []; + + + try { + items = Ext.decode(response.responseText); + } catch (e) { + success = false; + } + + if (success) { + if (active.removeAll) { + target.removeAll(); } - oldFrameML.remove(); + target.add(items); } - } - else { - - + return success; } } - else if (me.frame) { - this.applyRenderSelectors(); + }, + + + + + 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; }, + - getFrameInfo: function() { - if (Ext.supports.CSS3BorderRadius) { - return false; + removeMask: function(){ + this.target.setLoading(false); + }, + + + addMask: function(mask){ + this.target.setLoading(mask); + }, + + + + setOptions: function(active, options){ + active.removeAll = Ext.isDefined(options.removeAll) ? options.removeAll : this.removeAll; + }, + + + getRenderer: function(renderer){ + if (Ext.isFunction(renderer)) { + return renderer; } - - var me = this, - left = me.el.getStyle('background-position-x'), - top = me.el.getStyle('background-position-y'), - info, frameInfo = false, max; - - - if (!left && !top) { - info = me.el.getStyle('background-position').split(' '); - left = info[0]; - top = info[1]; + var renderers = this.statics().Renderer; + switch (renderer) { + case 'component': + return renderers.Component; + case 'data': + return renderers.Data; + default: + return Ext.ElementLoader.Renderer.Html; } - - - - - 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); + } +}); - - 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."); + +Ext.define('Ext.data.Association', { + + + + + + primaryKey: 'id', + + + + + + 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: + } + } + 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; + + + this.ownerModel = ownerModel; + this.associatedModel = associatedModel; + - me.frame = me.frame || !!frameInfo; - me.frameSize = frameInfo || false; + - return frameInfo; + + Ext.applyIf(this, { + ownerName : ownerName, + associatedName: associatedName + }); }, + - getFramePositions: function(frameInfo) { + getReader: function(){ 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'; + reader = me.reader, + model = me.associatedModel; + + if (reader) { + if (Ext.isString(reader)) { + reader = { + type: reader + }; } - - positions = { - tl: '0 -' + (frameWidth * 0) + 'px', - tr: '0 -' + (frameWidth * 1) + 'px', - bl: '0 -' + (frameWidth * 2) + 'px', - br: '0 -' + (frameWidth * 3) + 'px', + 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; + } +}); - ml: '-' + (frameWidth * 1) + 'px 0', - mr: 'right 0', - tc: tc, - bc: bc - }; +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 { - ml = '-' + (frameWidth * 0) + 'px 0'; - mr = 'right 0'; - if (dock && dock == "bottom") { - ml = 'left bottom'; - mr = 'right bottom'; + if (!config.extend) { + config.extend = 'Ext.data.Model'; } - - positions = { - tl: '0 -' + (frameWidth * 2) + 'px', - tr: 'right -' + (frameWidth * 3) + 'px', - bl: '0 -' + (frameWidth * 4) + 'px', - br: 'right -' + (frameWidth * 5) + 'px', + model = Ext.define(name, config); + } + this.types[name] = model; + return model; + }, - ml: ml, - mr: mr, + + onModelDefined: function(model) { + var stack = this.associationStack, + length = stack.length, + create = [], + association, i, created; - tc: '0 -' + (frameWidth * 0) + 'px', - bc: '0 -' + (frameWidth * 1) + 'px' - }; + for (i = 0; i < length; i++) { + association = stack[i]; + + if (association.associatedModel == model.modelName) { + create.push(association); + } } - - return positions; + + 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; }, + + + create: function(config, name, id) { + var con = typeof name == 'function' ? name : this.types[name || config.name]; + + return new con(config, id); + } +}, function() { + + + Ext.regModel = function() { + return this.ModelManager.registerType.apply(this.ModelManager, arguments); + }; +}); + + +Ext.define('Ext.PluginManager', { + extend: 'Ext.AbstractManager', + alternateClassName: 'Ext.PluginMgr', + singleton: true, + typeName: 'ptype', + + + + + + + + + + + + + + + + - getFrameTpl : function(table) { - return table ? this.getTpl('frameTableTpl') : this.getTpl('frameTpl'); - }, - - initCls: function() { - var me = this, - cls = []; - - 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; - } - if (me.componentCls) { - cls.push(me.componentCls); + create : function(config, defaultType){ + if (config.init) { + return config; } else { - me.componentCls = me.baseCls; - } - if (me.cls) { - cls.push(me.cls); - delete me.cls; + return Ext.createByAlias('plugin.' + (config.ptype || defaultType), config); } - 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]); + findByType: function(type, defaultsOnly) { + var matches = [], + types = this.types; + + for (var name in types) { + if (!types.hasOwnProperty(name)) { + continue; + } + var item = types[name]; + + if (item.type == type && (!defaultsOnly || (defaultsOnly === true && item.isDefault))) { + matches.push(item); } } - }, + + return matches; + } +}, function() { + Ext.preg = function() { + return Ext.PluginManager.registerType.apply(Ext.PluginManager, arguments); + }; +}); + + +Ext.define('Ext.Template', { + - removeClsWithUI: function(cls) { - var me = this, - i; - - if (!Ext.isArray(cls)) { - cls = [cls]; - } + + requires: ['Ext.DomHelper', 'Ext.util.Format'], + + inheritableStatics: { - 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]); - } + from: function(el, config) { + el = Ext.getDom(el); + return new this(el.value || el.innerHTML, config || ''); } }, + + - hasUICls: function(cls) { + constructor: function(html) { 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]); + 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); } } - } - }, - - - 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]); - } + html = buffer.join(''); + } else { + if (Ext.isArray(html)) { + buffer.push(html.join('')); + } else { + buffer.push(html); } } - }, - - - 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]); - } - } + me.html = buffer.join(''); + + if (me.compiled) { + me.compile(); } }, + + isTemplate: 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]); + 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); }, + - getElConfig : function() { - var result = this.autoEl || {tag: 'div'}; - result.id = this.id; - return result; + set: function(html, compile) { + var me = this; + me.html = html; + me.compiled = null; + return compile ? me.compile() : me; }, - - getInsertPosition: function(position) { - - if (position !== undefined) { - if (Ext.isNumber(position)) { - position = this.container.dom.childNodes[position]; + 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 { - position = Ext.getDom(position); + args = ''; + format = "(values['" + name + "'] == undefined ? '' : "; } + return "'," + format + "values['" + name + "']" + args + ") ,'"; } - return position; + 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; }, - - initContainer: function(container) { - 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 (!container && me.el) { - container = me.el.dom.parentNode; - me.allowDomMove = false; - } + /** + * 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); + }, - me.container = Ext.get(container); + /** + * 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.ctCls) { - me.container.addCls(me.ctCls); - } + /** + * 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); + }, - return me.container; + 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; }, - - initRenderData: function() { - var me = this; + /** + * 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() { - return Ext.applyIf(me.renderData, { - ui: me.ui, - uiCls: me.uiCls, - baseCls: me.baseCls, - componentCls: me.componentCls, - frame: me.frame - }); - }, + /** + * @method apply + * @member Ext.Template + * Alias for {@link #applyTemplate}. + * @alias Ext.Template#applyTemplate + */ + this.createAlias('apply', 'applyTemplate'); +}); - - getTpl: function(name) { - var prototype = this.self.prototype, - ownerPrototype; +/** + * 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', { - if (this.hasOwnProperty(name)) { - if (!(this[name] instanceof Ext.XTemplate)) { - this[name] = Ext.ClassManager.dynInstantiate('Ext.XTemplate', this[name]); - } + /* Begin Definitions */ - return this[name]; - } + extend: 'Ext.Template', - if (!(prototype[name] instanceof Ext.XTemplate)) { - ownerPrototype = prototype; + /* End Definitions */ - do { - if (ownerPrototype.hasOwnProperty(name)) { - ownerPrototype[name] = Ext.ClassManager.dynInstantiate('Ext.XTemplate', ownerPrototype[name]); - break; - } + argsRe: /]*>((?:(?=([^<]+))\2|<(?!tpl\b[^>]*>))*?)<\/tpl>/, + nameRe: /^]*?for="(.*?)"/, + ifRe: /^]*?if="(.*?)"/, + execRe: /^]*?exec="(.*?)"/, + constructor: function() { + this.callParent(arguments); - ownerPrototype = ownerPrototype.superclass; - } while (ownerPrototype); - } + 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; - return prototype[name]; - }, + html = ['', html, ''].join(''); - - initRenderTpl: function() { - return this.getTpl('renderTpl'); - }, + 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); - - initStyles: function() { - var style = {}, - me = this, - Element = Ext.core.Element; + exp = matchIf ? matchIf[1] : null; + if (exp) { + fn = Ext.functionFactory(VALUES, PARENT, XINDEX, XCOUNT, WITHVALUES + 'try{' + RETURN + Ext.String.htmlDecode(exp) + ';}catch(e){return;}}'); + } - if (Ext.isString(me.style)) { - style = Element.parseStyles(me.style); - } else { - style = Ext.apply({}, me.style); - } + exp = matchExec ? matchExec[1] : null; + if (exp) { + exec = Ext.functionFactory(VALUES, PARENT, XINDEX, XCOUNT, WITHVALUES + Ext.String.htmlDecode(exp) + ';}'); + } - - - if (me.padding !== undefined) { - style.padding = Element.unitizeBox((me.padding === true) ? 5 : me.padding); + 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; } - if (me.margin !== undefined) { - style.margin = Element.unitizeBox((me.margin === true) ? 5 : me.margin); + for (i = tpls.length - 1; i >= 0; --i) { + me.compileTpl(tpls[i]); } + me.master = tpls[tpls.length - 1]; + me.tpls = tpls; + }, - delete me.style; - return style; + // @private + applySubTemplate: function(id, values, parent, xindex, xcount) { + var me = this, t = me.tpls[id]; + return t.compiled.call(me, values, parent, xindex, xcount); }, - - initContent: function() { - var me = this, - target = me.getTargetEl(), - contentEl, - pre; + /** + * @cfg {RegExp} codeRe + * The regular expression used to match code variables. Default: matches {[expression]}. + */ + codeRe: /\{\[((?:\\\]|.|\n)*?)\]\}/g, - if (me.html) { - target.update(Ext.core.DomHelper.markup(me.html)); - delete me.html; - } + /** + * @cfg {Boolean} compiled + * Only applies to {@link Ext.Template}, XTemplates are compiled automatically. + */ - 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); - } + re: /\{([\w-\.\#]+)(?:\:([\w\.]*)(?:\((.*?)?\))?)?(\s?[\+\-\*\/]\s?[\d\.\+\-\*\/\(\)]+)?\}/g, - if (me.tpl) { - - if (!me.tpl.isTemplate) { - me.tpl = Ext.create('Ext.XTemplate', me.tpl); + // @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 : ""'; } - if (me.data) { - me.tpl[me.tplWriteMode](target, me.data); - delete me.data; + // 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; } - } - }, - - initEvents : function() { - 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); - } + // 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 + "),'"; } - }, - - - applyRenderSelectors: function() { - var selectors = this.renderSelectors || {}, - el = this.el.dom, - selector; - for (selector in selectors) { - if (selectors.hasOwnProperty(selector) && selectors[selector]) { - this[selector] = Ext.get(Ext.DomQuery.selectNode(selectors[selector], el)); - } + 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, "'") + "),'"; } - }, - - is: function(selector) { - return Ext.ComponentQuery.is(this, selector); - }, + 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); - - up: function(selector) { - var result = this.ownerCt; - if (selector) { - for (; result; result = result.ownerCt) { - if (Ext.ComponentQuery.is(result, selector)) { - return result; - } + tpl.compiled = function(values, parent, xindex, xcount) { + var vs, + length, + buffer, + i; + + if (tpl.test && !tpl.test.call(me, values, parent, xindex, xcount)) { + return ''; } - } - 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); - } - } + vs = tpl.target ? tpl.target.call(me, values, parent) : values; + if (!vs) { + return ''; } - } - return null; - }, - - 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; - } + 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 { - if (idx) { - return it.getAt(--idx); + for (i = 0; i < length; i++) { + buffer[buffer.length] = evaluatedFn.call(me, vs[i], parent, i + 1, length); } } + return buffer.join(''); } - } - return null; - }, - - - previousNode: function(selector, includeSelf) { - var node = this, - result, - it, len, i; - - if (includeSelf && node.is(selector)) { - return node; - } + if (tpl.exec) { + tpl.exec.call(me, vs, parent, xindex, xcount); + } + return evaluatedFn.call(me, vs, parent, xindex, xcount); + }; - result = this.prev(selector); - if (result) { - return result; - } + return this; + }, - 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; - } - } - } - return node.ownerCt.previousNode(selector, true); - } + // inherit docs from Ext.Template + applyTemplate: function(values) { + return this.master.compiled.call(this, values, {}, 1, 1); }, - - nextNode: function(selector, includeSelf) { - var node = this, - result, - it, len, i; + /** + * 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'); +}); - - if (includeSelf && node.is(selector)) { - return node; - } - result = this.next(selector); - if (result) { - return result; - } +Ext.define('Ext.app.Controller', { - 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; - } - } - } - return node.ownerCt.nextNode(selector); - } + mixins: { + observable: 'Ext.util.Observable' }, - getId : function() { - return this.id || (this.id = 'ext-comp-' + (this.getAutoId())); - }, - - getItemId : function() { - return this.itemId || this.id; - }, - - getEl : function() { - return this.el; - }, - - 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; - - } - - return !shallow ? ('/' + this.getXTypes() + '/').indexOf('/' + xtype + '/') != -1: this.self.xtype == xtype; - }, - 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); - } - - parentPrototype = parentPrototype.superclass; - } - - self.xtypeChain = xtypes; - self.xtypes = xtypes.join('/'); - } - return self.xtypes; - }, + onClassExtended: function(cls, data) { + var className = Ext.getClassName(cls), + match = className.match(/^(.*)\.controller\./); - - update : function(htmlOrData, loadScripts, cb) { - var me = this; + if (match !== null) { + var namespace = Ext.Loader.getPrefix(className) || match[1], + onBeforeClassCreated = data.onBeforeClassCreated, + requires = [], + modules = ['model', 'view', 'store'], + prefix; - 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); - } - } + data.onBeforeClassCreated = function(cls, data) { + var i, ln, module, + items, j, subLn, item; - if (me.rendered) { - me.doComponentLayout(); - } - }, + for (i = 0,ln = modules.length; i < ln; i++) { + module = modules[i]; - - setVisible : function(visible) { - return this[visible ? 'show': 'hide'](); - }, + items = Ext.Array.from(data[module + 's']); - - isVisible: function(deep) { - var me = this, - child = me, - visible = !me.hidden, - ancestor = me.ownerCt; + for (j = 0,subLn = items.length; j < subLn; j++) { + item = items[j]; - - me.hiddenAncestor = false; - if (me.destroyed) { - return false; - } + prefix = Ext.Loader.getPrefix(item); - 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; + if (prefix === '' || prefix === item) { + requires.push(namespace + '.' + module + '.' + item); + } + else { + requires.push(item); + } + } } - child = ancestor; - ancestor = ancestor.ownerCt; - } - } - return visible; - }, - - enable: function(silent) { - var me = this; - - if (me.rendered) { - me.el.removeCls(me.disabledCls); - me.el.dom.disabled = false; - me.onEnable(); - } - - me.disabled = false; - - if (silent !== true) { - me.fireEvent('enable', me); + Ext.require(requires, Ext.Function.pass(onBeforeClassCreated, arguments, this)); + }; } - - return me; }, - disable: function(silent) { - var me = this; - - if (me.rendered) { - me.el.addCls(me.disabledCls); - me.el.dom.disabled = true; - me.onDisable(); - } - - me.disabled = true; + constructor: function(config) { + this.mixins.observable.constructor.call(this, config); - if (silent !== true) { - me.fireEvent('disable', me); - } + Ext.apply(this, config || {}); - return me; - }, - - - onEnable: function() { - if (this.maskOnDisable) { - this.el.unmask(); - } - }, + this.createGetters('model', this.models); + this.createGetters('store', this.stores); + this.createGetters('view', this.views); - - onDisable : function() { - if (this.maskOnDisable) { - this.el.mask(); + if (this.refs) { + this.ref(this.refs); } }, - - - 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.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; - }, + init: function(application) {}, - addClass : function() { - return this.addCls.apply(this, arguments); - }, + onLaunch: function(application) {}, - - removeCls : function(className) { - var me = this; + createGetters: function(type, refs) { + type = Ext.String.capitalize(type); + Ext.Array.each(refs, function(ref) { + var fn = 'get', + parts = ref.split('.'); - 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); + + Ext.Array.each(parts, function(part) { + fn += Ext.String.capitalize(part); }); - } - return me; - }, + fn += type; - 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); + if (!this[fn]) { + this[fn] = Ext.Function.pass(this['get' + type], [ref], this); + } + + this[fn](ref); + }, + this); }, - addOverCls: function() { + ref: function(refs) { var me = this; - if (!me.disabled) { - me.el.addCls(me.overCls); - } - }, - - removeOverCls: function() { - this.el.removeCls(this.overCls); + 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); + } + }); }, - addListener : function(element, listeners, scope, options) { - var me = this, - fn, - option; + getRef: function(ref, info, config) { + this.refCache = this.refCache || {}; + info = info || {}; + config = config || {}; - if (Ext.isString(element) && (Ext.isObject(listeners) || options && options.element)) { - if (options.element) { - fn = listeners; + Ext.apply(info, config); - listeners = {}; - listeners[element] = fn; - element = options.element; - if (scope) { - listeners.scope = scope; - } + if (info.forceCreate) { + return Ext.ComponentManager.create(info, 'component'); + } - for (option in options) { - if (options.hasOwnProperty(option)) { - if (me.eventOptionsRe.test(option)) { - listeners[option] = options[option]; - } - } - } - } + var me = this, + selector = info.selector, + cached = me.refCache[ref]; - - - if (me[element] && me[element].on) { - me.mon(me[element], listeners); - } else { - me.afterRenderEvents = me.afterRenderEvents || {}; - me.afterRenderEvents[element] = listeners; + 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 me.mixins.observable.addListener.apply(me, arguments); + return cached; }, - - - getBubbleTarget : function() { - return this.ownerCt; + control: function(selectors, listeners) { + this.application.control(selectors, listeners, this); }, - isFloating : function() { - return this.floating; + getController: function(name) { + return this.application.getController(name); }, - isDraggable : function() { - return !!this.draggable; + getStore: function(name) { + return this.application.getStore(name); }, - isDroppable : function() { - return !!this.droppable; + getModel: function(model) { + return this.application.getModel(model); }, - onAdded : function(container, pos) { - this.ownerCt = container; - this.fireEvent('added', this, container, pos); - }, + getView: function(view) { + return this.application.getView(view); + } +}); - - onRemoved : function() { - var me = this; - me.fireEvent('removed', me, me.ownerCt); - delete me.ownerCt; - }, +Ext.define('Ext.data.IdGenerator', { - - beforeDestroy : Ext.emptyFn, - - - onResize : Ext.emptyFn, + isGenerator: true, - setSize : function(width, height) { - var me = this, - layoutCollection; + constructor: function(config) { + var me = this; - - if (Ext.isObject(width)) { - height = width.height; - width = width.width; - } + Ext.apply(me, 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.id) { + Ext.data.IdGenerator.all[me.id] = me; } + }, - 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; + getRecId: function (rec) { + return rec.modelName + '-' + rec.internalId; }, - setCalculatedSize : function(width, height, ownerCt) { - var me = this, - layoutCollection; + + statics: { - if (Ext.isObject(width)) { - ownerCt = width.ownerCt; - height = width.height; - width = width.width; - } + all: {}, - 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); - } + get: function (config) { + var generator, + id, + type; - if (!me.rendered || !me.isVisible()) { - - if (me.hiddenAncestor) { - layoutCollection = me.hiddenAncestor.layoutOnShow; - layoutCollection.remove(me); - layoutCollection.add(me); + 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.needsLayout = { - width: width, - height: height, - isSetSize: false, - ownerCt: ownerCt - }; - return me; - } - me.doComponentLayout(width, height, false, ownerCt); - - return me; - }, - - doComponentLayout : function(width, height, isSetSize, ownerCt) { - var me = this, - componentLayout = me.getComponentLayout(); - - - - - if (me.rendered && componentLayout) { - width = (width !== undefined) ? width : me.width; - height = (height !== undefined) ? height : me.height; - if (isSetSize) { - me.width = width; - me.height = height; + generator = this.all[id]; + if (!generator) { + generator = Ext.create('idgen.' + type, config); } - componentLayout.layout(width, height, isSetSize, ownerCt); + return generator; } - return me; - }, + } +}); + +Ext.define('Ext.data.SortTypes', { - setComponentLayout : function(layout) { - var currentLayout = this.componentLayout; - if (currentLayout && currentLayout.isLayout && currentLayout != layout) { - currentLayout.setOwner(null); - } - this.componentLayout = layout; - layout.setOwner(this); + singleton: true, + + + none : function(s) { + return s; }, - getComponentLayout : function() { - var me = this; + + stripTagsRE : /<\/?[^>]+>/gi, - if (!me.componentLayout || !me.componentLayout.isLayout) { - me.setComponentLayout(Ext.layout.Layout.create(me.componentLayout, 'autocomponent')); - } - return me.componentLayout; + + asText : function(s) { + return String(s).replace(this.stripTagsRE, ""); }, - afterComponentLayout: function(width, height, isSetSize, layoutOwner) { - this.fireEvent('resize', this, width, height); + asUCText : function(s) { + return String(s).toUpperCase().replace(this.stripTagsRE, ""); }, - beforeComponentLayout: function(width, height, isSetSize, layoutOwner) { - return true; + asUCString : function(s) { + return String(s).toUpperCase(); }, - setPosition : function(x, y) { - var me = this; - - if (Ext.isObject(x)) { - y = x.y; - x = x.x; - } - - if (!me.rendered) { - return me; + asDate : function(s) { + if(!s){ + return 0; } - - if (x !== undefined || y !== undefined) { - me.el.setBox(x, y); - me.onPosition(x, y); - me.fireEvent('move', me, x, y); + if(Ext.isDate(s)){ + return s.getTime(); } - return me; + return Date.parse(String(s)); }, - onPosition: Ext.emptyFn, - - - setWidth : function(width) { - return this.setSize(width); + asFloat : function(s) { + var val = parseFloat(String(s).replace(/,/g, "")); + return isNaN(val) ? 0 : val; }, - setHeight : function(height) { - return this.setSize(undefined, height); - }, + asInt : function(s) { + var val = parseInt(String(s).replace(/,/g, ""), 10); + return isNaN(val) ? 0 : val; + } +}); - - getSize : function() { - return this.el.getSize(); - }, +Ext.define('Ext.util.Filter', { - getWidth : function() { - return this.el.getWidth(); - }, - 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; + + + + + anyMatch: false, + + + exactMatch: false, + + + caseSensitive: false, + + - if (loader) { - if (!loader.isLoader) { - me.loader = Ext.create('Ext.ComponentLoader', Ext.apply({ - target: me, - autoLoad: autoLoad - }, loader)); + + 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 { - loader.setTarget(me); + me.filter = me.createFilterFn(); } - return me.loader; - + + me.filterFn = me.filter; } - return null; }, - - setLoading : function(load, targetEl) { - var me = this, - config; + + 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); + }; + }, + + + 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); - if (me.rendered) { - if (load !== false && !me.collapsed) { - if (Ext.isObject(load)) { - config = load; - } - else if (Ext.isString(load)) { - config = {msg: load}; - } - else { - config = {}; + if (anyMatch === true) { + value = escapeRe(value); + } else { + value = '^' + escapeRe(value); + if (exactMatch === true) { + value += '$'; } - 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; } - } + value = new RegExp(value, caseSensitive ? '' : 'i'); + } + + return value; + } +}); - return me.loadMask; - }, +Ext.define('Ext.util.Sorter', { - setDocked : function(dock, layoutParent) { + + + + + + + + + direction: "ASC", + + constructor: function(config) { var me = this; - - me.dock = dock; - if (layoutParent && me.ownerCt && me.rendered) { - me.ownerCt.doComponentLayout(); - } - return me; + + Ext.apply(me, config); + + + me.updateSortFunction(); }, - - onDestroy : function() { - var me = this; - - if (me.monitorResize && Ext.EventManager.resizeEvent) { - Ext.EventManager.resizeEvent.removeListener(me.setSize, me); - } - Ext.destroy(me.componentLayout, me.loadMask); + + + createSortFunction: function(sorterFn) { + var me = this, + property = me.property, + direction = me.direction || "ASC", + modifier = direction.toUpperCase() == "DESC" ? -1 : 1; + + + + return function(o1, o2) { + return modifier * sorterFn.call(me, o1, o2); + }; }, + + + 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); + } + return v1 > v2 ? 1 : (v1 < v2 ? -1 : 0); + }, - destroy : function() { + + getRoot: function(item) { + return this.root === undefined ? item : item[this.root]; + }, + + + setDirection: function(direction) { var me = this; - - if (!me.isDestroyed) { - if (me.fireEvent('beforedestroy', me) !== false) { - me.destroying = true; - me.beforeDestroy(); - - 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); - } - - if (me.rendered) { - me.el.remove(); - } - - me.onDestroy(); - - - Ext.destroy(me.plugins); - - Ext.ComponentManager.unregister(me); - me.fireEvent('destroy', me); - - me.mixins.state.destroy.call(me); - - me.clearListeners(); - me.destroying = false; - me.isDestroyed = true; - } - } + me.direction = direction; + me.updateSortFunction(); }, - - getPlugin: function(pluginId) { - var i = 0, - plugins = this.plugins, - ln = plugins.length; - for (; i < ln; i++) { - if (plugins[i].pluginId === pluginId) { - return plugins[i]; - } - } + + toggle: function() { + var me = this; + me.direction = Ext.String.toggle(me.direction, "ASC", "DESC"); + me.updateSortFunction(); }, - isDescendantOf: function(container) { - return !!this.findParentBy(function(p){ - return p === container; - }); + updateSortFunction: function(fn) { + var me = this; + fn = fn || me.sorterFn || me.defaultSorterFn; + me.sort = me.createSortFunction(fn); } -}, function() { - this.createAlias({ - on: 'addListener', - prev: 'previousSibling', - next: 'nextSibling' - }); }); +Ext.define('Ext.data.Operation', { + + synchronous: true, -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); - }, + action: undefined, + - getCmp: function() { - return this.cmp; - }, + filters: undefined, - init: Ext.emptyFn, + sorters: undefined, - destroy: Ext.emptyFn, + group: undefined, - enable: function() { - this.disabled = false; - }, + start: undefined, - disable: function() { - this.disabled = true; - } -}); + limit: undefined, + + batch: undefined, -Ext.define('Ext.data.Connection', { - mixins: { - observable: 'Ext.util.Observable' - }, + + callback: undefined, - statics: { - requestId: 0 - }, + + scope: undefined, - url: null, - async: true, - method: null, - username: '', - password: '', + + started: false, + + + running: false, - disableCaching: true, + complete: false, - disableCachingParam: '_dc', + success: undefined, - timeout : 30000, + exception: false, + error: undefined, - useDefaultHeader : true, - defaultPostHeader : 'application/x-www-form-urlencoded; charset=UTF-8', - useDefaultXhrHeader : true, - defaultXhrHeader : 'XMLHttpRequest', + + actionCommitRecordsRe: /^(?:create|update)$/i, - constructor : function(config) { - config = config || {}; - Ext.apply(this, config); + + actionSkipSyncRe: /^destroy$/i, - this.addEvents( - - 'beforerequest', - - 'requestcomplete', - - 'requestexception' - ); - this.requests = {}; - this.mixins.observable.constructor.call(this); + + constructor: function(config) { + Ext.apply(this, config || {}); }, - request : function(options) { - options = options || {}; + commitRecords: function (serverRecords) { var me = this, - scope = options.scope || window, - username = options.username || me.username, - password = options.password || me.password || '', - async, - requestOptions, - request, - headers, - xhr; - - if (me.fireEvent('beforerequest', me, options) !== false) { - - requestOptions = me.setOptions(options, scope); - - if (this.isFormUpload(options) === true) { - this.upload(options.form, requestOptions.url, requestOptions.data, options); - return null; - } + mc, index, clientRecords, serverRec, clientRec; - - if (options.autoAbort === true || me.autoAbort) { - me.abort(); - } - - - xhr = this.getXhrInstance(); - - async = options.async !== false ? (options.async || me.async) : false; + if (!me.actionSkipSyncRe.test(me.action)) { + clientRecords = me.records; - - if (username) { - xhr.open(requestOptions.method, requestOptions.url, async, username, password); - } else { - xhr.open(requestOptions.method, requestOptions.url, async); - } - - headers = me.setupHeaders(xhr, options, requestOptions.data, requestOptions.params); + if (clientRecords && clientRecords.length) { + mc = Ext.create('Ext.util.MixedCollection', true, function(r) {return r.getId();}); + mc.addAll(clientRecords); - - 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; + for (index = serverRecords ? serverRecords.length : 0; index--; ) { + serverRec = serverRecords[index]; + clientRec = mc.get(serverRec.getId()); - - if (async) { - xhr.onreadystatechange = Ext.Function.bind(me.onStateChange, me, [request]); - } + if (clientRec) { + clientRec.beginEdit(); + clientRec.set(serverRec.data); + clientRec.endEdit(true); + } + } - - xhr.send(requestOptions.data); - if (!async) { - return this.onComplete(request); + if (me.actionCommitRecordsRe.test(me.action)) { + for (index = clientRecords.length; index--; ) { + clientRecords[index].commit(); + } + } } - return request; - } else { - Ext.callback(options.callback, options.scope, [options, undefined, undefined]); - return null; } }, - 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); + setStarted: function() { + this.started = true; + this.running = true; + }, - - if (document.frames) { - document.frames[id].name = id; - } + + setCompleted: function() { + this.complete = true; + this.running = false; + }, - Ext.fly(form).set({ - target: id, - method: 'POST', - enctype: encoding, - encoding: encoding, - action: url || buf.action - }); + + setSuccessful: function() { + this.success = true; + }, - - 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); - }); - } + + setException: function(error) { + this.exception = true; + this.success = false; + this.running = false; + this.error = error; + }, - Ext.fly(frame).on('load', Ext.Function.bind(this.onUploadComplete, this, [frame, options]), null, {single: true}); - form.submit(); + + hasException: function() { + return this.exception === true; + }, - Ext.fly(form).set(buf); - Ext.each(hiddens, function(h) { - Ext.removeNode(h); - }); + + getError: function() { + return this.error; }, - onUploadComplete: function(frame, options){ - var me = this, - - response = { - responseText: '', - responseXML: null - }, doc, firstChild; + + getRecords: function() { + var resultSet = this.getResultSet(); - 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; - } - } - - response.responseXML = doc.XMLDocument || doc; - } - } catch (e) { - } + return (resultSet === undefined ? this.records : resultSet.records); + }, - me.fireEvent('requestcomplete', me, response, options); + + getResultSet: function() { + return this.resultSet; + }, - Ext.callback(options.success, options.scope, [response, options]); - Ext.callback(options.callback, options.scope, [options, true, response]); + + isStarted: function() { + return this.started === true; + }, - setTimeout(function(){ - Ext.removeNode(frame); - }, 100); + + isRunning: function() { + return this.running === true; }, - isFormUpload: function(options){ - var form = this.getForm(options); - if (form) { - return (options.isUpload || (/multipart\/form-data/i).test(form.getAttribute('enctype'))); - } - return false; + isComplete: function() { + return this.complete === true; }, - getForm: function(options){ - return Ext.getDom(options.form) || null; + wasSuccessful: function() { + return this.isComplete() && this.success === true; }, - 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; + setBatch: function(batch) { + this.batch = batch; + }, + + allowWrite: function() { + return this.action != 'read'; + } +}); - - if (Ext.isFunction(params)) { - params = params.call(scope, options); +Ext.define('Ext.data.validations', { + singleton: true, + + + presenceMessage: 'must be present', + + + lengthMessage: 'is the wrong length', + + + formatMessage: 'is the wrong format', + + + inclusionMessage: 'is not included in the list of acceptable values', + + + 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; } - - if (Ext.isFunction(url)) { - url = url.call(scope, options); - } - - url = this.setupUrl(options, url); - - if (!url) { - Ext.Error.raise({ - options: options, - msg: 'No URL specified' - }); - } - - data = options.rawData || options.xmlData || jsonData || null; - if (jsonData && !Ext.isPrimitive(jsonData)) { - data = Ext.encode(data); + return !!value || value === 0; + }, + + + length: function(config, value) { + if (value === undefined || value === null) { + return false; } - - if (Ext.isObject(params)) { - params = Ext.Object.toQueryString(params); + var length = value.length, + min = config.min, + max = config.max; + + if ((min && length < min) || (max && length > max)) { + return false; + } else { + return true; } + }, + + + email: function(config, email) { + return Ext.data.validations.emailRe.test(email); + }, + + + format: function(config, value) { + return !!(config.matcher && config.matcher.test(value)); + }, + + + inclusion: function(config, value) { + return config.list && Ext.Array.indexOf(config.list,value) != -1; + }, + + + exclusion: function(config, value) { + return config.list && Ext.Array.indexOf(config.list,value) == -1; + } +}); - if (Ext.isObject(extraParams)) { - extraParams = Ext.Object.toQueryString(extraParams); - } +Ext.define('Ext.data.ResultSet', { + + loaded: true, - params = params + ((extraParams) ? ((params) ? '&' : '') + extraParams : ''); + + count: 0, - urlParams = Ext.isObject(urlParams) ? Ext.Object.toQueryString(urlParams) : urlParams; + + total: 0, - params = this.setupParams(options, params); + + success: false, - - method = (options.method || me.method || ((params || data) ? 'POST' : 'GET')).toUpperCase(); - this.setupMethod(options, method); + + + constructor: function(config) { + Ext.apply(this, 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())); - } + this.totalRecords = this.total; - - if ((method == 'GET' || data) && params) { - url = Ext.urlAppend(url, params); - params = null; + if (config.count === undefined) { + this.count = this.records.length; } + } +}); - - if (urlParams) { - url = Ext.urlAppend(url, urlParams); - } +Ext.define('Ext.data.writer.Writer', { + alias: 'writer.base', + alternateClassName: ['Ext.data.DataWriter', 'Ext.data.Writer'], + + + writeAllFields: true, + + + nameProperty: 'name', - return { - url: url, - method: method, - data: data || params || null - }; + + constructor: function(config) { + Ext.apply(this, config); }, - setupUrl: function(options, url){ - var form = this.getForm(options); - if (form) { - url = url || form.action; + write: function(request) { + var operation = request.operation, + records = operation.records || [], + len = records.length, + i = 0, + data = []; + + for (; i < len; i++) { + data.push(this.getRecordData(records[i])); } - return url; + return this.writeRecords(request, data); }, - - 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; + getRecordData: function(record) { + var isPhantom = record.phantom === true, + writeAll = this.writeAllFields || isPhantom, + nameProperty = this.nameProperty, + fields = record.fields, + data = {}, + changes, + name, + field, + key; + + if (writeAll) { + fields.each(function(field){ + if (field.persist) { + name = field[nameProperty] || field.name; + data[name] = record.get(field.name); + } + }); + } else { + + changes = record.getChanges(); + for (key in changes) { + if (changes.hasOwnProperty(key)) { + field = fields.get(key); + name = field[nameProperty] || field.name; + data[name] = changes[key]; + } + } + if (!isPhantom) { + + data[record.idProperty] = record.getId(); + } } - return params; - }, + return data; + } +}); + + +Ext.define('Ext.util.Floating', { + + uses: ['Ext.Layer', 'Ext.window.Window'], - setupMethod: function(options, method){ - if (this.isFormUpload(options)) { - return 'POST'; + focusOnToFront: true, + + + shadow: 'sides', + + constructor: function(config) { + 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: me.shim === false ? false : undefined + }), me.el); + }, + + onFloatRender: function() { + var me = this; + me.zIndexParent = me.getZIndexParent(); + me.setFloatParent(me.ownerCt); + delete me.ownerCt; + + if (me.zIndexParent) { + me.zIndexParent.registerFloatingItem(me); + } else { + Ext.WindowManager.register(me); } - return method; }, - - 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; + setFloatParent: function(floatParent) { + var me = this; - 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.floatParent) { + me.mun(me.floatParent, { + hide: me.onFloatParentHide, + show: me.onFloatParentShow, + scope: me + }); + } + + me.floatParent = floatParent; + + + if (floatParent) { + me.mon(me.floatParent, { + hide: me.onFloatParentHide, + show: me.onFloatParentShow, + scope: me + }); } - 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); - } - - } - } catch(e) { - me.fireEvent('exception', key, header); + + if ((me.constrain || me.constrainHeader) && !me.constrainTo) { + me.constrainTo = floatParent ? floatParent.getTargetEl() : me.container; } - return headers; }, - - 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){} + onFloatParentHide: function() { + var me = this; + + if (me.hideOnParentHide !== false) { + me.showOnParentShow = me.isVisible(); + me.hide(); } - return xhr; - })(), + }, - - isLoading : function(request) { - if (!(request && request.xhr)) { - return false; + onFloatParentShow: function() { + if (this.showOnParentShow) { + delete this.showOnParentShow; + this.show(); } - - var state = request.xhr.readyState; - return !(state === 0 || state == 4); }, - abort : function(request) { - var me = this, - requests = me.requests, - id; + getZIndexParent: function() { + var p = this.ownerCt, + c; - if (request && me.isLoading(request)) { - - request.xhr.onreadystatechange = null; - request.xhr.abort(); - me.clearTimeout(request); - if (!request.timedout) { - request.aborted = true; + if (p) { + while (p) { + c = p; + p = p.ownerCt; } - me.onComplete(request); - me.cleanup(request); - } else if (!request) { - for(id in requests) { - if (requests.hasOwnProperty(id)) { - me.abort(requests[id]); - } + if (c.floating) { + return c; } } }, - onStateChange : function(request) { - if (request.xhr.readyState == 4) { - this.clearTimeout(request); - this.onComplete(request); - this.cleanup(request); + + + + + setZIndex: function(index) { + var me = this; + me.el.setZIndex(index); + + + index += 10; + + + + if (me.floatingItems) { + index = Math.floor(me.floatingItems.setBase(index) / 100) * 100 + 10000; } + return index; }, - clearTimeout: function(request){ - clearTimeout(request.timeout); - delete request.timeout; - }, + doConstrain: function(constrainTo) { + var me = this, + vector = me.getConstrainVector(constrainTo || me.el.getScopeParent()), + xy; - - cleanup: function(request){ - request.xhr = null; - delete request.xhr; + if (vector) { + xy = me.getPosition(); + xy[0] += vector[0]; + xy[1] += vector[1]; + me.setPosition(xy); + } }, + - onComplete : function(request) { + getConstrainVector: function(constrainTo){ var me = this, - options = request.options, - result = me.parseStatus(request.xhr.status), - success = result.success, - response; + el; - 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]); + if (me.constrain || me.constrainHeader) { + el = me.constrainHeader ? me.header.el : me.el; + constrainTo = constrainTo || (me.floatParent && me.floatParent.getTargetEl()) || me.container; + return el.getConstrainVector(constrainTo); } - Ext.callback(options.callback, options.scope, [options, success, response]); - delete me.requests[request.id]; - return response; }, - 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; - } + alignTo: function(element, position, offsets) { + if (element.isComponent) { + element = element.getEl(); } - return { - success: success, - isException: isException - }; + var xy = this.el.getAlignToXY(element, position, offsets); + this.setPagePosition(xy); + return this; }, - 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; + toFront: function(preventFocus) { + var me = this; - 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); + + + if (me.zIndexParent) { + me.zIndexParent.toFront(true); + } + if (me.zIndexManager.bringToFront(me)) { + if (!Ext.isDefined(preventFocus)) { + preventFocus = !me.focusOnToFront; + } + if (!preventFocus) { + + + + me.focus(false, true); } } + return me; + }, - 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 - }; - - + + setActive: function(active, newActive) { + var me = this; - xhr = null; - return response; + if (active) { + if (me.el.shadow && !me.maximized) { + me.el.enableShadow(true); + } + me.fireEvent('activate', me); + } else { + + + if ((me instanceof Ext.window.Window) && (newActive instanceof Ext.window.Window)) { + me.el.disableShadow(); + } + me.fireEvent('deactivate', me); + } }, - 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 - }; - } -}); - - -Ext.define('Ext.Ajax', { - extend: 'Ext.data.Connection', - singleton: true, + toBack: function() { + this.zIndexManager.sendToBack(this); + return this; + }, - - - - - + center: function() { + var me = this, + xy = me.el.getAlignToXY(me.container, 'c-c'); + me.setPagePosition(xy); + return me; + }, + syncShadow : function(){ + if (this.floating) { + this.el.sync(true); + } + }, - - - - - + fitContainer: function() { + var parent = this.floatParent, + container = parent ? parent.getTargetEl() : this.container, + size = container.getViewSize(false); - - autoAbort : false + this.setSize(size); + } }); -Ext.define('Ext.data.Association', { - - - +Ext.define('Ext.layout.Layout', { - primaryKey: 'id', - - - defaultReaderType: 'json', + isLayout: true, + initialized: false, statics: { - create: function(association){ - if (!association.isAssociation) { - if (Ext.isString(association)) { - association = { - type: association - }; + 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 = {}; } - - 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 + '"'); + else { + type = layout.type || defaultType; } + return Ext.createByAlias('layout.' + type, layout || {}); } - return association; } }, - constructor: function(config) { + constructor : function(config) { + this.id = Ext.id(null, this.type + '-'); Ext.apply(this, config); + }, - var types = Ext.ModelManager.types, - ownerName = config.ownerModel, - associatedName = config.associatedModel, - ownerModel = types[ownerName], - associatedModel = types[associatedName], - ownerProto; + + layout : function() { + var me = this; + me.layoutBusy = true; + me.initLayout(); - if (ownerModel === undefined) { - Ext.Error.raise("The configured ownerModel was not valid (you tried " + ownerName + ")"); + 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); } - if (associatedModel === undefined) { - Ext.Error.raise("The configured associatedModel was not valid (you tried " + associatedName + ")"); + else { + me.layoutCancelled = true; } + me.layoutBusy = false; + me.doOwnerCtLayouts(); + }, - this.ownerModel = ownerModel; - this.associatedModel = associatedModel; - - - - + beforeLayout : function() { + this.renderChildren(); + return true; + }, - Ext.applyIf(this, { - ownerName : ownerName, - associatedName: associatedName - }); + renderChildren: function () { + this.renderItems(this.getLayoutItems(), this.getRenderTarget()); }, - getReader: function(){ + renderItems : function(items, target) { var me = this, - reader = me.reader, - model = me.associatedModel; + ln = items.length, + i = 0, + item; - if (reader) { - if (Ext.isString(reader)) { - reader = { - type: reader - }; - } - if (reader.isReader) { - reader.setModel(model); + 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 { - Ext.applyIf(reader, { - model: model, - type : me.defaultReaderType - }); + + me.configureItem(item); } - 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'; + 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; } - model = Ext.define(name, config); + return (dom.parentNode == (target.dom || target)); } - this.types[name] = model; - return model; + return false; }, + - - onModelDefined: function(model) { - var stack = this.associationStack, - length = stack.length, - create = [], - association, i, created; - - for (i = 0; i < length; i++) { - association = stack[i]; - - if (association.associatedModel == model.modelName) { - create.push(association); + 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; } + }, + + + moveItem : function(item, target, position) { - 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); + 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; }, + - - registerDeferredAssociation: function(association){ - this.associationStack.push(association); + initLayout : function() { + var me = this, + targetCls = me.targetCls; + + if (!me.initialized && !Ext.isEmpty(targetCls)) { + me.getTarget().addCls(targetCls); + } + me.initialized = true; }, + - - getModel: function(id) { - var model = id; - if (typeof model == 'string') { - model = this.types[model]; - } - return model; + setOwner : function(owner) { + this.owner = owner; }, + + getLayoutItems : function() { + return []; + }, + - create: function(config, name, id) { - var con = typeof name == 'function' ? name : this.types[name || config.name]; - - return new con(config, id); - } -}, function() { + configureItem: Ext.emptyFn, - 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); - }; -}); + onLayout : Ext.emptyFn, + afterLayout : Ext.emptyFn, + onRemove : Ext.emptyFn, + onDestroy : Ext.emptyFn, + doOwnerCtLayouts : Ext.emptyFn, - -Ext.define('Ext.app.Controller', { + 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); + } + } - mixins: { - observable: 'Ext.util.Observable' + + + + delete item.layoutManagedWidth; + delete item.layoutManagedHeight; }, - 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; + + destroy : function() { + var targetCls = this.targetCls, + target; + + if (!Ext.isEmpty(targetCls)) { + target = this.getTarget(); + if (target) { + target.removeCls(targetCls); + } + } + this.onDestroy(); + } +}); - data.onBeforeClassCreated = function(cls, data) { - var i, ln, module, - items, j, subLn, item; +Ext.define('Ext.ZIndexManager', { - for (i = 0,ln = modules.length; i < ln; i++) { - module = modules[i]; + alternateClassName: 'Ext.WindowGroup', - items = Ext.Array.from(data[module + 's']); + statics: { + zBase : 9000 + }, - for (j = 0,subLn = items.length; j < subLn; j++) { - item = items[j]; + constructor: function(container) { + var me = this; - prefix = Ext.Loader.getPrefix(item); + me.list = {}; + me.zIndexStack = []; + me.front = null; - if (prefix === '' || prefix === item) { - requires.push(namespace + '.' + module + '.' + item); - } - else { - requires.push(item); - } - } - } + if (container) { - Ext.require(requires, Ext.Function.pass(onBeforeClassCreated, arguments, this)); - }; + + if (container.isContainer) { + container.on('resize', me._onContainerResize, me); + me.zseed = Ext.Number.from(container.getEl().getStyle('zIndex'), me.getNextZSeed()); + + me.targetEl = container.getTargetEl(); + me.container = container; + } + + else { + Ext.EventManager.onWindowResize(me._onContainerResize, me); + me.zseed = me.getNextZSeed(); + me.targetEl = Ext.get(container); + } + } + + + else { + Ext.EventManager.onWindowResize(me._onContainerResize, me); + me.zseed = me.getNextZSeed(); + Ext.onDocumentReady(function() { + me.targetEl = Ext.getBody(); + }); } }, - 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); + getNextZSeed: function() { + return (Ext.ZIndexManager.zBase += 10000); + }, - if (this.refs) { - this.ref(this.refs); - } + setBase: function(baseZIndex) { + this.zseed = baseZIndex; + return this.assignZIndices(); }, - 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('.'); + assignZIndices: function() { + var a = this.zIndexStack, + len = a.length, + i = 0, + zIndex = this.zseed, + comp; - - Ext.Array.each(parts, function(part) { - fn += Ext.String.capitalize(part); - }); - fn += type; + for (; i < len; i++) { + comp = a[i]; + if (comp && !comp.hidden) { - if (!this[fn]) { - this[fn] = Ext.Function.pass(this['get' + type], [ref], this); + + + + + + + + zIndex = comp.setZIndex(zIndex); } - - this[fn](ref); - }, - this); + } + this._activateLast(); + return zIndex; }, - 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); + + _setActiveChild: function(comp) { + if (comp !== this.front) { + + if (this.front) { + this.front.setActive(false, comp); } - }); + this.front = comp; + if (comp) { + comp.setActive(true); + if (comp.modal) { + this._showModalMask(comp); + } + } + } }, - getRef: function(ref, info, config) { - this.refCache = this.refCache || {}; - info = info || {}; - config = config || {}; + + _activateLast: function(justHidden) { + var comp, + lastActivated = false, + i; - Ext.apply(info, config); + + + + for (i = this.zIndexStack.length-1; i >= 0; --i) { + comp = this.zIndexStack[i]; + if (!comp.hidden) { + if (!lastActivated) { + this._setActiveChild(comp); + lastActivated = true; + } - if (info.forceCreate) { - return Ext.ComponentManager.create(info, 'component'); + + if (comp.modal) { + this._showModalMask(comp); + return; + } + } } - var me = this, - selector = info.selector, - cached = me.refCache[ref]; + + + this._hideModalMask(); + if (!lastActivated) { + this._setActiveChild(null); + } + }, - 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; - }); - } + _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(); - return cached; + if (!this.mask) { + this.mask = Ext.getBody().createChild({ + cls: Ext.baseCSSPrefix + 'mask' + }); + this.mask.setVisibilityMode(Ext.Element.DISPLAY); + this.mask.on('click', this._onMaskClick, this); + } + 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(); }, - control: function(selectors, listeners) { - this.application.control(selectors, listeners, this); + _hideModalMask: function() { + if (this.mask && this.mask.dom.parentNode) { + Ext.get(this.mask.dom.parentNode).removeCls(Ext.baseCSSPrefix + 'body-masked'); + this.mask.hide(); + } }, - getController: function(name) { - return this.application.getController(name); + _onMaskClick: function() { + if (this.front) { + this.front.focus(); + } }, - getStore: function(name) { - return this.application.getStore(name); + _onContainerResize: function() { + if (this.mask && this.mask.isVisible()) { + this.mask.setSize(Ext.get(this.mask.dom.parentNode).getViewSize(true)); + } }, - getModel: function(model) { - return this.application.getModel(model); + + register : function(comp) { + if (comp.zIndexManager) { + comp.zIndexManager.unregister(comp); + } + comp.zIndexManager = this; + + this.list[comp.id] = comp; + this.zIndexStack.push(comp); + comp.on('hide', this._activateLast, this); }, - getView: function(view) { - return this.application.getView(view); - } -}); + + unregister : function(comp) { + delete comp.zIndexManager; + if (this.list && this.list[comp.id]) { + delete this.list[comp.id]; + comp.un('hide', this._activateLast); + Ext.Array.remove(this.zIndexStack, comp); + + this._activateLast(comp); + } + }, -Ext.define('Ext.data.SortTypes', { - - singleton: true, - - none : function(s) { - return s; + get : function(id) { + return typeof id == "object" ? id : this.list[id]; }, - - stripTagsRE : /<\/?[^>]+>/gi, + + bringToFront : function(comp) { + comp = this.get(comp); + if (comp !== this.front) { + Ext.Array.remove(this.zIndexStack, comp); + this.zIndexStack.push(comp); + this.assignZIndices(); + return true; + } + if (comp.modal) { + this._showModalMask(comp); + } + return false; + }, - asText : function(s) { - return String(s).replace(this.stripTagsRE, ""); + sendToBack : function(comp) { + comp = this.get(comp); + Ext.Array.remove(this.zIndexStack, comp); + this.zIndexStack.unshift(comp); + this.assignZIndices(); + return comp; }, - asUCText : function(s) { - return String(s).toUpperCase().replace(this.stripTagsRE, ""); + hideAll : function() { + for (var id in this.list) { + if (this.list[id].isComponent && this.list[id].isVisible()) { + this.list[id].hide(); + } + } }, - asUCString : function(s) { - return String(s).toUpperCase(); + hide: function() { + var i = 0, + ln = this.zIndexStack.length, + comp; + + this.tempHidden = []; + for (; i < ln; i++) { + comp = this.zIndexStack[i]; + if (comp.isVisible()) { + this.tempHidden.push(comp); + comp.hide(); + } + } }, - asDate : function(s) { - if(!s){ - return 0; - } - if(Ext.isDate(s)){ - return s.getTime(); + show: function() { + var i = 0, + ln = this.tempHidden.length, + comp, + x, + y; + + for (; i < ln; i++) { + comp = this.tempHidden[i]; + x = comp.x; + y = comp.y; + comp.show(); + comp.setPosition(x, y); } - return Date.parse(String(s)); + delete this.tempHidden; }, - asFloat : function(s) { - var val = parseFloat(String(s).replace(/,/g, "")); - return isNaN(val) ? 0 : val; + getActive : function() { + return this.front; }, - asInt : function(s) { - var val = parseInt(String(s).replace(/,/g, ""), 10); - return isNaN(val) ? 0 : val; - } -}); + getBy : function(fn, scope) { + var r = [], + i = 0, + len = this.zIndexStack.length, + comp; + + for (; i < len; i++) { + comp = this.zIndexStack[i]; + if (fn.call(scope||comp, comp) !== false) { + r.push(comp); + } + } + return r; + }, -Ext.define('Ext.data.Errors', { - extend: 'Ext.util.MixedCollection', - - isValid: function() { - return this.length === 0; + each : function(fn, scope) { + var comp; + for (var id in this.list) { + comp = this.list[id]; + if (comp.isComponent && fn.call(scope || comp, comp) === false) { + return; + } + } }, + + eachBottomUp: function (fn, scope) { + var comp, + stack = this.zIndexStack, + i, n; + + for (i = 0, n = stack.length ; i < n; i++) { + comp = stack[i]; + if (comp.isComponent && fn.call(scope || comp, comp) === false) { + return; + } + } + }, + - 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); + eachTopDown: function (fn, scope) { + var comp, + stack = this.zIndexStack, + i; + + for (i = stack.length ; i-- > 0; ) { + comp = stack[i]; + if (comp.isComponent && fn.call(scope || comp, comp) === false) { + return; } } - - return errors; + }, + + destroy: function() { + this.each(function(c) { + c.destroy(); + }); + delete this.zIndexStack; + delete this.list; + delete this.container; + delete this.targetEl; } +}, function() { + + Ext.WindowManager = Ext.WindowMgr = new this(); }); -Ext.define('Ext.data.Operation', { - - synchronous: true, - - - action: undefined, - - - filters: undefined, - - - sorters: undefined, - - - group: undefined, - - - start: undefined, - - - limit: undefined, - - - batch: undefined, - - - started: false, - - - running: false, - - - complete: false, - - - success: undefined, - - - exception: false, - +Ext.define('Ext.layout.container.boxOverflow.None', { - error: undefined, + alternateClassName: 'Ext.layout.boxOverflow.None', - constructor: function(config) { + constructor: function(layout, config) { + this.layout = layout; Ext.apply(this, config || {}); }, + + handleOverflow: Ext.emptyFn, + + clearOverflow: Ext.emptyFn, + onRemove: Ext.emptyFn, + - setStarted: function() { - this.started = true; - this.running = true; - }, - - - setCompleted: function() { - this.complete = true; - this.running = false; + getItem: function(item) { + return this.layout.owner.getComponent(item); }, + onRemove: Ext.emptyFn +}); + +Ext.define('Ext.util.KeyMap', { + alternateClassName: 'Ext.KeyMap', + - setSuccessful: function() { - this.success = true; + constructor: function(el, binding, eventName){ + var me = this; + + Ext.apply(me, { + el: Ext.get(el), + eventName: eventName || me.eventName, + bindings: [] + }); + if (binding) { + me.addBinding(binding); + } + me.enable(); }, + + eventName: 'keydown', + - - setException: function(error) { - this.exception = true; - this.success = false; - this.running = false; - this.error = error; + addBinding : function(binding){ + if (Ext.isArray(binding)) { + Ext.each(binding, this.addBinding, this); + return; + } + + var keyCode = binding.key, + processed = false, + key, + keys, + keyString, + i, + len; + + if (Ext.isString(keyCode)) { + keys = []; + 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.toUpperCase().charCodeAt(0); + } + } + } + + this.bindings.push(Ext.apply({ + keyCode: keyCode + }, binding)); }, + - - hasException: function() { - return this.exception === true; + 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); + } + } }, + - - getError: function() { - return this.error; + processEvent: function(event){ + return event; }, + - - getRecords: function() { - var resultSet = this.getResultSet(); - - return (resultSet === undefined ? this.records : resultSet.records); + processBinding: function(binding, event){ + if (this.checkModifiers(binding, event)) { + var key = event.getKey(), + handler = binding.fn || binding.handler, + scope = binding.scope || this, + keyCode = binding.keyCode, + defaultEventAction = binding.defaultEventAction, + 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) { + keydownEvent[defaultEventAction](); + } + break; + } + } + } }, + - - getResultSet: function() { - return this.resultSet; + 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]; + if (!(val === undefined || (val === e[key + 'Key']))) { + return false; + } + } + return true; }, + - - isStarted: function() { - return this.started === true; + on: function(key, fn, scope) { + var keyCode, shift, ctrl, alt; + if (Ext.isObject(key) && !Ext.isArray(key)) { + keyCode = key.key; + shift = key.shift; + ctrl = key.ctrl; + alt = key.alt; + } else { + keyCode = key; + } + this.addBinding({ + key: keyCode, + shift: shift, + ctrl: ctrl, + alt: alt, + fn: fn, + scope: scope + }); }, + - - isRunning: function() { - return this.running === true; + isEnabled : function(){ + return this.enabled; }, + - - isComplete: function() { - return this.complete === true; + enable: function(){ + var me = this; + + if (!me.enabled) { + me.el.on(me.eventName, me.handleKeyDown, me); + me.enabled = true; + } }, + - - wasSuccessful: function() { - return this.isComplete() && this.success === true; + disable: function(){ + var me = this; + + if (me.enabled) { + me.el.removeListener(me.eventName, me.handleKeyDown, me); + me.enabled = false; + } }, + - - setBatch: function(batch) { - this.batch = batch; + setDisabled : function(disabled){ + if (disabled) { + this.disable(); + } else { + this.enable(); + } }, + - - allowWrite: function() { - return this.action != 'read'; + destroy: function(removeEl){ + var me = this; + + me.bindings = []; + me.disable(); + if (removeEl === true) { + me.el.remove(); + } + delete me.el; } }); -Ext.define('Ext.data.validations', { - singleton: true, - - - presenceMessage: 'must be present', - +Ext.define('Ext.util.ClickRepeater', { + extend: 'Ext.util.Observable', + - lengthMessage: 'is the wrong length', + constructor : function(el, config){ + this.el = Ext.get(el); + this.el.unselectable(); + + Ext.apply(this, config); + + this.addEvents( + + "mousedown", + + "click", + + "mouseup" + ); + + if(!this.disabled){ + this.disabled = true; + this.enable(); + } + + + if(this.handler){ + this.on("click", this.handler, this.scope || this); + } + + this.callParent(); + }, + + - formatMessage: 'is the wrong format', + + - inclusionMessage: 'is not included in the list of acceptable values', + interval : 20, + + delay: 250, + - exclusionMessage: 'is not an acceptable value', + preventDefault : true, + stopDefault : false, + + timer : 0, + - presence: function(config, value) { - if (value === undefined) { - value = config; + enable: function(){ + if(this.disabled){ + this.el.on('mousedown', this.handleMouseDown, this); + if (Ext.isIE){ + this.el.on('dblclick', this.handleDblClick, this); + } + if(this.preventDefault || this.stopDefault){ + this.el.on('click', this.eventOptions, this); + } } - - return !!value; + this.disabled = false; }, + + disable: function( force){ + if(force || !this.disabled){ + clearTimeout(this.timer); + if(this.pressedCls){ + this.el.removeCls(this.pressedCls); + } + Ext.getDoc().un('mouseup', this.handleMouseUp, this); + this.el.removeAllListeners(); + } + this.disabled = true; + }, + - length: function(config, value) { - if (value === undefined) { - return false; + setDisabled: function(disabled){ + this[disabled ? 'disable' : 'enable'](); + }, + + eventOptions: function(e){ + if(this.preventDefault){ + e.preventDefault(); } - - var length = value.length, - min = config.min, - max = config.max; - - if ((min && length < min) || (max && length > max)) { - return false; - } else { - return true; + if(this.stopDefault){ + e.stopEvent(); } }, + - - format: function(config, value) { - return !!(config.matcher && config.matcher.test(value)); + destroy : function() { + this.disable(true); + Ext.destroy(this.el); + this.clearListeners(); }, - - - inclusion: function(config, value) { - return config.list && Ext.Array.indexOf(config.list,value) != -1; + + handleDblClick : function(e){ + clearTimeout(this.timer); + this.el.blur(); + + this.fireEvent("mousedown", this, e); + this.fireEvent("click", this, e); }, - - - exclusion: function(config, value) { - return config.list && Ext.Array.indexOf(config.list,value) == -1; - } -}); -Ext.define('Ext.data.ResultSet', { - - loaded: true, - - - count: 0, - - - total: 0, - - - success: false, - + handleMouseDown : function(e){ + clearTimeout(this.timer); + this.el.blur(); + if(this.pressedCls){ + this.el.addCls(this.pressedCls); + } + this.mousedownTime = new Date(); + + Ext.getDoc().on("mouseup", this.handleMouseUp, this); + this.el.on("mouseout", this.handleMouseOut, this); + + this.fireEvent("mousedown", this, e); + this.fireEvent("click", this, e); - constructor: function(config) { - Ext.apply(this, config); + if (this.accelerate) { + this.delay = 400; + } + - this.totalRecords = this.total; - if (config.count === undefined) { - this.count = this.records.length; - } - } -}); + e = new Ext.EventObjectImpl(e); + + this.timer = Ext.defer(this.click, this.delay || this.interval, this, [e]); + }, -Ext.define('Ext.data.writer.Writer', { - alias: 'writer.base', - alternateClassName: ['Ext.data.DataWriter', 'Ext.data.Writer'], - - - writeAllFields: true, - - nameProperty: 'name', + click : function(e){ + this.fireEvent("click", this, e); + this.timer = Ext.defer(this.click, this.accelerate ? + this.easeOutExpo(Ext.Date.getElapsed(this.mousedownTime), + 400, + -390, + 12000) : + this.interval, this, [e]); + }, - constructor: function(config) { - Ext.apply(this, config); + easeOutExpo : function (t, b, c, d) { + return (t==d) ? b+c : c * (-Math.pow(2, -10 * t/d) + 1) + b; }, - write: function(request) { - var operation = request.operation, - records = operation.records || [], - len = records.length, - i = 0, - data = []; + handleMouseOut : function(){ + clearTimeout(this.timer); + if(this.pressedCls){ + this.el.removeCls(this.pressedCls); + } + this.el.on("mouseover", this.handleMouseReturn, this); + }, - for (; i < len; i++) { - data.push(this.getRecordData(records[i])); + + handleMouseReturn : function(){ + this.el.un("mouseover", this.handleMouseReturn, this); + if(this.pressedCls){ + this.el.addCls(this.pressedCls); } - return this.writeRecords(request, data); + this.click(); }, - getRecordData: function(record) { - var isPhantom = record.phantom === true, - writeAll = this.writeAllFields || isPhantom, - nameProperty = this.nameProperty, - fields = record.fields, - data = {}, - changes, - name, - field, - key; - - if (writeAll) { - fields.each(function(field){ - if (field.persist) { - name = field[nameProperty] || field.name; - data[name] = record.get(field.name); - } - }); - } else { - - changes = record.getChanges(); - for (key in changes) { - if (changes.hasOwnProperty(key)) { - field = fields.get(key); - name = field[nameProperty] || field.name; - data[name] = changes[key]; - } - } - if (!isPhantom) { - - data[record.idProperty] = record.getId(); - } + handleMouseUp : function(e){ + clearTimeout(this.timer); + this.el.un("mouseover", this.handleMouseReturn, this); + this.el.un("mouseout", this.handleMouseOut, this); + Ext.getDoc().un("mouseup", this.handleMouseUp, this); + if(this.pressedCls){ + this.el.removeCls(this.pressedCls); } - return data; + this.fireEvent("mouseup", this, e); } }); -Ext.define('Ext.util.Floating', { - - uses: ['Ext.Layer', 'Ext.window.Window'], +Ext.define('Ext.layout.component.Component', { - focusOnToFront: true, + + extend: 'Ext.layout.Layout', - 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, - constrain: false, - shim: this.shim === false ? false : undefined - }), this.el); - }, + type: 'component', - onFloatRender: function() { - var me = this; - me.zIndexParent = me.getZIndexParent(); - me.setFloatParent(me.ownerCt); - delete me.ownerCt; + monitorChildren: true, - if (me.zIndexParent) { - me.zIndexParent.registerFloatingItem(me); - } else { - Ext.WindowManager.register(me); + 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); }, - setFloatParent: function(floatParent) { - var me = this; + beforeLayout : function(width, height, isSetSize, callingContainer) { + this.callParent(arguments); - - if (me.floatParent) { - me.mun(me.floatParent, { - hide: me.onFloatParentHide, - show: me.onFloatParentShow, - scope: me - }); - } + var me = this, + owner = me.owner, + ownerCt = owner.ownerCt, + layout = owner.layout, + isVisible = owner.isVisible(true), + ownerElChild = owner.el.child, + layoutCollection; - me.floatParent = floatParent; + + me.previousComponentSize = me.lastComponentSize; - if (floatParent) { - me.mon(me.floatParent, { - hide: me.onFloatParentHide, - show: me.onFloatParentShow, - scope: me - }); + if (!isSetSize + && ((!Ext.isNumber(width) && owner.isFixedWidth()) || + (!Ext.isNumber(height) && owner.isFixedHeight())) + + && callingContainer && callingContainer !== ownerCt) { + + me.doContainerLayout(); + return false; } - if ((me.constrain || me.constrainHeader) && !me.constrainTo) { - me.constrainTo = floatParent ? floatParent.getTargetEl() : me.container; + 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)) { + return owner.beforeComponentLayout(width, height, isSetSize, callingContainer); + } + else { + return false; } }, - onFloatParentHide: function() { - this.showOnParentShow = this.isVisible(); - this.hide(); + + needsLayout : function(width, height) { + var me = this, + 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); }, - onFloatParentShow: function() { - if (this.showOnParentShow) { - delete this.showOnParentShow; - this.show(); + + 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); } }, - getZIndexParent: function() { - var p = this.ownerCt, - c; + getTarget : function() { + return this.owner.el; + }, - if (p) { - while (p) { - c = p; - p = p.ownerCt; - } - if (c.floating) { - return c; - } - } + + getRenderTarget : function() { + return this.owner.el; }, - - - - - setZIndex: function(index) { + setTargetSize : function(width, height) { var me = this; - this.el.setZIndex(index); + me.setElementSize(me.owner.el, width, height); - - index += 10; + if (me.owner.frameBody) { + var targetInfo = me.getTargetInfo(), + padding = targetInfo.padding, + border = targetInfo.border, + frameSize = me.frameSize; - - - if (me.floatingItems) { - index = Math.floor(me.floatingItems.setBase(index) / 100) * 100 + 10000; + 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 + ); } - return index; - }, - - doConstrain: function(constrainTo) { - var me = this, - constrainEl, - vector, - xy; + me.autoSized = { + width: !Ext.isNumber(width), + height: !Ext.isNumber(height) + }; - if (me.constrain || me.constrainHeader) { - if (me.constrainHeader) { - constrainEl = me.header.el; - } else { - constrainEl = me.el; - } - vector = constrainEl.getConstrainVector(constrainTo || (me.floatParent && me.floatParent.getTargetEl()) || me.container); - if (vector) { - xy = me.getPosition(); - xy[0] += vector[0]; - xy[1] += vector[1]; - me.setPosition(xy); - } - } + me.lastComponentSize = { + width: width, + height: height + }; }, - - alignTo: function(element, position, offsets) { - if (element.isComponent) { - element = element.getEl(); + 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') + } + }; } - var xy = this.el.getAlignToXY(element, position, offsets); - this.setPagePosition(xy); - return this; + return this.targetInfo; }, - toFront: function(preventFocus) { - var me = this; + 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 (me.zIndexParent) { - me.zIndexParent.toFront(true); + if (!ownerCt || (!widthChange && !heightChange)) { + return; } - if (me.zIndexManager.bringToFront(me)) { - if (!Ext.isDefined(preventFocus)) { - preventFocus = !me.focusOnToFront; - } - if (!preventFocus) { - + + 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; + } - me.focus(false, true); + else if (ownerCtContainerLayout.bindToOwnerCtContainer === true) { + ownerCtContainerLayout.layout(); + } } } - return me; }, - - setActive: function(active, newActive) { - if (active) { - if ((this instanceof Ext.window.Window) && !this.maximized) { - this.el.enableShadow(true); - } - this.fireEvent('activate', this); - } else { - - - if ((this instanceof Ext.window.Window) && (newActive instanceof Ext.window.Window)) { - this.el.disableShadow(); + doContainerLayout: function() { + var me = this, + owner = me.owner, + ownerCt = owner.ownerCt, + layout = owner.layout, + ownerCtComponentLayout; + + + + if (!owner.suspendLayout && layout && layout.isLayout && !layout.layoutBusy && !layout.isAutoDock) { + layout.layout(); + } + + + if (ownerCt && ownerCt.componentLayout) { + ownerCtComponentLayout = ownerCt.componentLayout; + if (!owner.floating && ownerCtComponentLayout.monitorChildren && !ownerCtComponentLayout.layoutBusy) { + ownerCtComponentLayout.childrenChanged = true; } - this.fireEvent('deactivate', this); } }, - - toBack: function() { - this.zIndexManager.sendToBack(this); - return this; + afterLayout : function(width, height, isSetSize, layoutOwner) { + this.doContainerLayout(); + this.owner.afterComponentLayout(width, height, isSetSize, layoutOwner); + } +}); + + +Ext.define('Ext.util.TextMetrics', { + statics: { + shared: null, + + measure: function(el, text, fixedWidth){ + var me = this, + shared = me.shared; + + if(!shared){ + shared = me.shared = new me(el, fixedWidth); + } + shared.bind(el); + shared.setFixedWidth(fixedWidth || 'auto'); + return shared.getSize(text); + }, + + + destroy: function(){ + var me = this; + Ext.destroy(me.shared); + me.shared = null; + } }, + + + constructor: function(bindTo, fixedWidth){ + var measure = this.measure = Ext.getBody().createChild({ + cls: 'x-textmetrics' + }); + this.el = Ext.get(bindTo); + + measure.position('absolute'); + measure.setLeftTop(-1000, -1000); + measure.hide(); + if (fixedWidth) { + measure.setWidth(fixedWidth); + } + }, - center: function() { - var xy = this.el.getAlignToXY(this.container, 'c-c'); - this.setPagePosition(xy); - return this; + + getSize: function(text){ + var measure = this.measure, + size; + + measure.update(text); + size = measure.getSize(); + measure.update(''); + return size; }, - - syncShadow : function(){ - if (this.floating) { - this.el.sync(true); - } + + bind: function(el){ + var me = this; + + me.el = Ext.get(el); + me.measure.setStyle( + me.el.getStyles('font-size','font-style', 'font-weight', 'font-family','line-height', 'text-transform', 'letter-spacing') + ); }, - - fitContainer: function() { - var parent = this.floatParent, - container = parent ? parent.getTargetEl() : this.container, - size = container.getViewSize(false); - - this.setSize(size); - } + + setFixedWidth : function(width){ + this.measure.setWidth(width); + }, + + + getWidth : function(text){ + this.measure.dom.style.width = 'auto'; + return this.getSize(text).width; + }, + + + getHeight : function(text){ + return this.getSize(text).height; + }, + + + destroy: function(){ + var me = this; + me.measure.remove(); + delete me.el; + delete me.measure; + } +}, function(){ + 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); + } + }); }); -Ext.define('Ext.layout.container.AbstractContainer', { +Ext.define('Ext.layout.container.boxOverflow.Scroller', { - extend: 'Ext.layout.Layout', - + extend: 'Ext.layout.container.boxOverflow.None', + requires: ['Ext.util.ClickRepeater', 'Ext.Element'], + alternateClassName: 'Ext.layout.boxOverflow.Scroller', + mixins: { + observable: 'Ext.util.Observable' + }, - - type: 'container', - - fixedLayout: true, - - managedHeight: true, + - managedWidth: true, + animateScroll: false, - bindToOwnerCtComponent: false, + scrollIncrement: 20, - bindToOwnerCtContainer: false, + wheelIncrement: 10, + scrollRepeatInterval: 60, - isManaged: function(dimension) { - dimension = Ext.String.capitalize(dimension); - var me = this, - child = me, - managed = me['managed' + dimension], - ancestor = me.owner.ownerCt; + + scrollDuration: 400, - if (ancestor && ancestor.layout) { - while (ancestor && ancestor.layout) { - if (managed === false || ancestor.layout['managed' + dimension] === false) { - managed = false; - break; - } - ancestor = ancestor.ownerCt; - } - } - return managed; - }, + - layout: function() { - var me = this, - owner = me.owner; - if (Ext.isNumber(owner.height) || owner.isViewport) { - me.managedHeight = false; - } - if (Ext.isNumber(owner.width) || owner.isViewport) { - me.managedWidth = false; - } - me.callParent(arguments); - }, + - setItemSize: function(item, width, height) { - if (Ext.isObject(width)) { - height = width.height; - width = width.width; - } - item.setCalculatedSize(width, height, this.owner); - }, + scrollerCls: Ext.baseCSSPrefix + 'box-scroller', - getLayoutItems: function() { - return this.owner && this.owner.items && this.owner.items.items || []; - }, - afterLayout: function() { - this.owner.afterLayout(this); - }, - getTarget: function() { - return this.owner.getTargetEl(); - }, - getRenderTarget: function() { - return this.owner.getTargetEl(); - } -}); - - -Ext.define('Ext.ZIndexManager', { - - alternateClassName: 'Ext.WindowGroup', + constructor: function(layout, config) { + this.layout = layout; + Ext.apply(this, config || {}); + + this.addEvents( + + 'scroll' + ); + }, + + initCSSClasses: function() { + var me = this, + layout = me.layout; - statics: { - zBase : 9000 + if (!me.CSSinitialized) { + me.beforeCtCls = me.beforeCtCls || Ext.baseCSSPrefix + 'box-scroller-' + layout.parallelBefore; + me.afterCtCls = me.afterCtCls || Ext.baseCSSPrefix + 'box-scroller-' + layout.parallelAfter; + me.beforeScrollerCls = me.beforeScrollerCls || Ext.baseCSSPrefix + layout.owner.getXType() + '-scroll-' + layout.parallelBefore; + me.afterScrollerCls = me.afterScrollerCls || Ext.baseCSSPrefix + layout.owner.getXType() + '-scroll-' + layout.parallelAfter; + me.CSSinitializes = true; + } }, - constructor: function(container) { - var me = this; + handleOverflow: function(calculations, targetSize) { + var me = this, + layout = me.layout, + methodName = 'get' + layout.parallelPrefixCap, + newSize = {}; - me.list = {}; - me.zIndexStack = []; - me.front = null; + me.initCSSClasses(); + me.callParent(arguments); + this.createInnerElements(); + this.showScrollers(); + newSize[layout.perpendicularPrefix] = targetSize[layout.perpendicularPrefix]; + newSize[layout.parallelPrefix] = targetSize[layout.parallelPrefix] - (me.beforeCt[methodName]() + me.afterCt[methodName]()); + return { targetSize: newSize }; + }, - if (container) { + + createInnerElements: function() { + var me = this, + target = me.layout.getRenderTarget(); - - if (container.isContainer) { - container.on('resize', me._onContainerResize, me); - me.zseed = Ext.Number.from(container.getEl().getStyle('zIndex'), me.getNextZSeed()); - - me.targetEl = container.getTargetEl(); - me.container = container; - } - - else { - Ext.EventManager.onWindowResize(me._onContainerResize, me); - me.zseed = me.getNextZSeed(); - me.targetEl = Ext.get(container); - } - } - else { - Ext.EventManager.onWindowResize(me._onContainerResize, me); - me.zseed = me.getNextZSeed(); - Ext.onDocumentReady(function() { - me.targetEl = Ext.getBody(); - }); + if (!me.beforeCt) { + target.addCls(Ext.baseCSSPrefix + me.layout.direction + '-box-overflow-body'); + me.beforeCt = target.insertSibling({cls: Ext.layout.container.Box.prototype.innerCls + ' ' + me.beforeCtCls}, 'before'); + me.afterCt = target.insertSibling({cls: Ext.layout.container.Box.prototype.innerCls + ' ' + me.afterCtCls}, 'after'); + me.createWheelListener(); } }, - getNextZSeed: function() { - return (Ext.ZIndexManager.zBase += 10000); - }, + + createWheelListener: function() { + this.layout.innerCt.on({ + scope : this, + mousewheel: function(e) { + e.stopEvent(); - setBase: function(baseZIndex) { - this.zseed = baseZIndex; - return this.assignZIndices(); + this.scrollBy(e.getWheelDelta() * this.wheelIncrement * -1, false); + } + }); }, - assignZIndices: function() { - var a = this.zIndexStack, - len = a.length, - i = 0, - zIndex = this.zseed, - comp; - - for (; i < len; i++) { - comp = a[i]; - if (comp && !comp.hidden) { - - - - - - - - - zIndex = comp.setZIndex(zIndex); - } - } - this._activateLast(); - return zIndex; + clearOverflow: function() { + this.hideScrollers(); }, - _setActiveChild: function(comp) { - if (comp != this.front) { + showScrollers: function() { + this.createScrollers(); + this.beforeScroller.show(); + this.afterScroller.show(); + this.updateScrollButtons(); + + this.layout.owner.addClsWithUI('scroller'); + }, - if (this.front) { - this.front.setActive(false, comp); - } - this.front = comp; - if (comp) { - comp.setActive(true); - if (comp.modal) { - this._showModalMask(comp.el.getStyle('zIndex') - 4); - } - } + + hideScrollers: function() { + if (this.beforeScroller != undefined) { + this.beforeScroller.hide(); + this.afterScroller.hide(); + + this.layout.owner.removeClsWithUI('scroller'); } }, - _activateLast: function(justHidden) { - var comp, - lastActivated = false, - i; + createScrollers: function() { + if (!this.beforeScroller && !this.afterScroller) { + var before = this.beforeCt.createChild({ + cls: Ext.String.format("{0} {1} ", this.scrollerCls, this.beforeScrollerCls) + }); - - - - for (i = this.zIndexStack.length-1; i >= 0; --i) { - comp = this.zIndexStack[i]; - if (!comp.hidden) { - if (!lastActivated) { - this._setActiveChild(comp); - lastActivated = true; - } + var after = this.afterCt.createChild({ + cls: Ext.String.format("{0} {1}", this.scrollerCls, this.afterScrollerCls) + }); - - if (comp.modal) { - this._showModalMask(comp.el.getStyle('zIndex') - 4); - return; - } - } - } + before.addClsOnOver(this.beforeScrollerCls + '-hover'); + after.addClsOnOver(this.afterScrollerCls + '-hover'); - - - this._hideModalMask(); - if (!lastActivated) { - this._setActiveChild(null); - } - }, + before.setVisibilityMode(Ext.Element.DISPLAY); + after.setVisibilityMode(Ext.Element.DISPLAY); - _showModalMask: function(zIndex) { - if (!this.mask) { - this.mask = this.targetEl.createChild({ - cls: Ext.baseCSSPrefix + 'mask' + this.beforeRepeater = Ext.create('Ext.util.ClickRepeater', before, { + interval: this.scrollRepeatInterval, + handler : this.scrollLeft, + scope : this }); - this.mask.setVisibilityMode(Ext.core.Element.DISPLAY); - this.mask.on('click', this._onMaskClick, this); + + this.afterRepeater = Ext.create('Ext.util.ClickRepeater', after, { + interval: this.scrollRepeatInterval, + handler : this.scrollRight, + scope : this + }); + + + this.beforeScroller = before; + + + this.afterScroller = after; } - Ext.getBody().addCls(Ext.baseCSSPrefix + 'body-masked'); - this.mask.setSize(this.targetEl.getViewSize(true)); - this.mask.setStyle('zIndex', zIndex); - this.mask.show(); }, - _hideModalMask: function() { - if (this.mask) { - Ext.getBody().removeCls(Ext.baseCSSPrefix + 'body-masked'); - this.mask.hide(); - } + + destroy: function() { + Ext.destroy(this.beforeRepeater, this.afterRepeater, this.beforeScroller, this.afterScroller, this.beforeCt, this.afterCt); }, - _onMaskClick: function() { - if (this.front) { - this.front.focus(); - } + + scrollBy: function(delta, animate) { + this.scrollTo(this.getScrollPosition() + delta, animate); }, - _onContainerResize: function() { - if (this.mask && this.mask.isVisible()) { - this.mask.setSize(this.targetEl.getViewSize(true)); - } + + getScrollAnim: function() { + return { + duration: this.scrollDuration, + callback: this.updateScrollButtons, + scope : this + }; }, - register : function(comp) { - if (comp.zIndexManager) { - comp.zIndexManager.unregister(comp); + updateScrollButtons: function() { + if (this.beforeScroller == undefined || this.afterScroller == undefined) { + return; } - comp.zIndexManager = this; - this.list[comp.id] = comp; - this.zIndexStack.push(comp); - comp.on('hide', this._activateLast, this); + var beforeMeth = this.atExtremeBefore() ? 'addCls' : 'removeCls', + afterMeth = this.atExtremeAfter() ? 'addCls' : 'removeCls', + beforeCls = this.beforeScrollerCls + '-disabled', + afterCls = this.afterScrollerCls + '-disabled'; + + this.beforeScroller[beforeMeth](beforeCls); + this.afterScroller[afterMeth](afterCls); + this.scrolling = false; }, - unregister : function(comp) { - delete comp.zIndexManager; - if (this.list && this.list[comp.id]) { - delete this.list[comp.id]; - comp.un('hide', this._activateLast); - Ext.Array.remove(this.zIndexStack, comp); + atExtremeBefore: function() { + return this.getScrollPosition() === 0; + }, - - this._activateLast(comp); - } + + scrollLeft: function() { + this.scrollBy(-this.scrollIncrement, false); }, - get : function(id) { - return typeof id == "object" ? id : this.list[id]; + scrollRight: function() { + this.scrollBy(this.scrollIncrement, false); }, - - bringToFront : function(comp) { - comp = this.get(comp); - 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(); - } - return false; + + getScrollPosition: function(){ + var layout = this.layout; + return parseInt(layout.innerCt.dom['scroll' + layout.parallelBeforeCap], 10) || 0; }, - sendToBack : function(comp) { - comp = this.get(comp); - Ext.Array.remove(this.zIndexStack, comp); - this.zIndexStack.unshift(comp); - this.assignZIndices(); - return comp; + getMaxScrollPosition: function() { + var layout = this.layout; + return layout.innerCt.dom['scroll' + layout.parallelPrefixCap] - this.layout.innerCt['get' + layout.parallelPrefixCap](); }, - hideAll : function() { - for (var id in this.list) { - if (this.list[id].isComponent && this.list[id].isVisible()) { - this.list[id].hide(); - } - } + atExtremeAfter: function() { + return this.getScrollPosition() >= this.getMaxScrollPosition(); }, - hide: function() { - var i = 0, - ln = this.zIndexStack.length, - comp; + scrollTo: function(position, animate) { + var me = this, + layout = me.layout, + oldPosition = me.getScrollPosition(), + newPosition = Ext.Number.constrain(position, 0, me.getMaxScrollPosition()); - this.tempHidden = []; - for (; i < ln; i++) { - comp = this.zIndexStack[i]; - if (comp.isVisible()) { - this.tempHidden.push(comp); - comp.hide(); + if (newPosition != oldPosition && !me.scrolling) { + if (animate == undefined) { + animate = me.animateScroll; + } + + layout.innerCt.scrollTo(layout.parallelBefore, newPosition, animate ? me.getScrollAnim() : false); + if (animate) { + me.scrolling = true; + } else { + me.scrolling = false; + me.updateScrollButtons(); } + + me.fireEvent('scroll', me, newPosition, animate ? me.getScrollAnim() : false); } }, - show: function() { - var i = 0, - ln = this.tempHidden.length, - comp, - x, - y; + scrollToItem: function(item, animate) { + var me = this, + layout = me.layout, + visibility, + box, + newPos; - for (; i < ln; i++) { - comp = this.tempHidden[i]; - x = comp.x; - y = comp.y; - comp.show(); - comp.setPosition(x, y); + item = me.getItem(item); + if (item != undefined) { + visibility = this.getItemVisibility(item); + if (!visibility.fullyVisible) { + box = item.getBox(true, true); + newPos = box[layout.parallelPosition]; + if (visibility.hiddenEnd) { + newPos -= (this.layout.innerCt['get' + layout.parallelPrefixCap]() - box[layout.parallelPrefix]); + } + this.scrollTo(newPos, animate); + } } - delete this.tempHidden; }, - getActive : function() { - return this.front; - }, + getItemVisibility: function(item) { + var me = this, + box = me.getItem(item).getBox(true, true), + layout = me.layout, + itemStart = box[layout.parallelPosition], + itemEnd = itemStart + box[layout.parallelPrefix], + scrollStart = me.getScrollPosition(), + scrollEnd = scrollStart + layout.innerCt['get' + layout.parallelPrefixCap](); + + return { + hiddenStart : itemStart < scrollStart, + hiddenEnd : itemEnd > scrollEnd, + fullyVisible: itemStart > scrollStart && itemEnd < scrollEnd + }; + } +}); + +Ext.define('Ext.util.Offset', { - getBy : function(fn, scope) { - var r = [], - i = 0, - len = this.zIndexStack.length, - comp; - for (; i < len; i++) { - comp = this.zIndexStack[i]; - if (fn.call(scope||comp, comp) !== false) { - r.push(comp); - } + statics: { + fromObject: function(obj) { + return new this(obj.x, obj.y); } - return r; }, - each : function(fn, scope) { - var comp; - for (var id in this.list) { - comp = this.list[id]; - if (comp.isComponent && fn.call(scope || comp, comp) === false) { - return; - } - } + + constructor: function(x, y) { + this.x = (x != null && !isNaN(x)) ? x : 0; + this.y = (y != null && !isNaN(y)) ? y : 0; + + return this; }, - - eachBottomUp: function (fn, scope) { - var comp, - stack = this.zIndexStack, - i, n; + copy: function() { + return new Ext.util.Offset(this.x, this.y); + }, - for (i = 0, n = stack.length ; i < n; i++) { - comp = stack[i]; - if (comp.isComponent && fn.call(scope || comp, comp) === false) { - return; - } - } + copyFrom: function(p) { + this.x = p.x; + this.y = p.y; }, - - eachTopDown: function (fn, scope) { - var comp, - stack = this.zIndexStack, - i; + toString: function() { + return "Offset[" + this.x + "," + this.y + "]"; + }, - for (i = stack.length ; i-- > 0; ) { - comp = stack[i]; - if (comp.isComponent && fn.call(scope || comp, comp) === false) { - return; - } + equals: function(offset) { + + return (this.x == offset.x && this.y == offset.y); + }, + + round: function(to) { + if (!isNaN(to)) { + var factor = Math.pow(10, to); + this.x = Math.round(this.x * factor) / factor; + this.y = Math.round(this.y * factor) / factor; + } else { + this.x = Math.round(this.x); + this.y = Math.round(this.y); } }, - destroy: function() { - delete this.zIndexStack; - delete this.list; - delete this.container; - delete this.targetEl; + isZero: function() { + return this.x == 0 && this.y == 0; } -}, function() { - - Ext.WindowManager = Ext.WindowMgr = new this(); }); -Ext.define('Ext.layout.container.boxOverflow.None', { +Ext.define('Ext.util.KeyNav', { - alternateClassName: 'Ext.layout.boxOverflow.None', + alternateClassName: 'Ext.KeyNav', - constructor: function(layout, config) { - this.layout = layout; - Ext.apply(this, config || {}); - }, - - handleOverflow: Ext.emptyFn, - - clearOverflow: Ext.emptyFn, - + requires: ['Ext.util.KeyMap'], - getItem: function(item) { - return this.layout.owner.getComponent(item); - } -}); + statics: { + keyOptions: { + left: 37, + right: 39, + up: 38, + down: 40, + space: 32, + pageUp: 33, + pageDown: 34, + del: 46, + backspace: 8, + home: 36, + end: 35, + enter: 13, + esc: 27, + tab: 9 + } + }, -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, - bindings: [] - }); - if (binding) { - me.addBinding(binding); - } - me.enable(); + constructor: function(el, config){ + this.setConfig(el, config || {}); }, - eventName: 'keydown', - - addBinding : function(binding){ - if (Ext.isArray(binding)) { - Ext.each(binding, this.addBinding, this); - return; - } - - var keyCode = binding.key, - processed = false, - key, - keys, - keyString, - i, - len; - - if (Ext.isString(keyCode)) { - keys = []; - keyString = keyCode.toLowerCase(); - - for (i = 0, len = keyString.length; i < len; ++i){ - keys.push(keyString.charCodeAt(i)); - } - keyCode = keys; - processed = true; + setConfig: function(el, config) { + if (this.map) { + this.map.destroy(); } - if (!Ext.isArray(keyCode)) { - keyCode = [keyCode]; - } + var map = Ext.create('Ext.util.KeyMap', el, null, this.getKeyEvent('forceKeyDown' in config ? config.forceKeyDown : this.forceKeyDown)), + keys = Ext.util.KeyNav.keyOptions, + scope = config.scope || this, + key; - if (!processed) { - for (i = 0, len = keyCode.length; i < len; ++i) { - key = keyCode[i]; - if (Ext.isString(key)) { - keyCode[i] = key.toLowerCase().charCodeAt(0); + this.map = map; + for (key in keys) { + if (keys.hasOwnProperty(key)) { + if (config[key]) { + map.addBinding({ + scope: scope, + key: keys[key], + handler: Ext.Function.bind(this.handleEvent, scope, [config[key]], true), + defaultEventAction: config.defaultEventAction || this.defaultEventAction + }); } } } - this.bindings.push(Ext.apply({ - keyCode: keyCode - }, binding)); + map.disable(); + if (!config.disabled) { + map.enable(); + } }, - 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); - } - } + handleEvent: function(map, event, handler){ + return handler.call(this, event); }, - processEvent: function(event){ - return event; - }, + disabled: false, - processBinding: function(binding, event){ - if (this.checkModifiers(binding, event)) { - var key = event.getKey(), - handler = binding.fn || binding.handler, - scope = binding.scope || this, - keyCode = binding.keyCode, - defaultEventAction = binding.defaultEventAction, - 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) { - keydownEvent[defaultEventAction](); - } - break; - } - } - } - }, + defaultEventAction: "stopEvent", - 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]; - if (!(val === undefined || (val === e[key + 'Key']))) { - return false; - } - } - return true; - }, - + forceKeyDown: false, - on: function(key, fn, scope) { - var keyCode, shift, ctrl, alt; - if (Ext.isObject(key) && !Ext.isArray(key)) { - keyCode = key.key; - shift = key.shift; - ctrl = key.ctrl; - alt = key.alt; - } else { - keyCode = key; - } - this.addBinding({ - key: keyCode, - shift: shift, - ctrl: ctrl, - alt: alt, - fn: fn, - scope: scope - }); - }, - - isEnabled : function(){ - return this.enabled; + destroy: function(removeEl){ + this.map.destroy(removeEl); + delete this.map; }, - enable: function(){ - if(!this.enabled){ - this.el.on(this.eventName, this.handleKeyDown, this); - this.enabled = true; - } + enable: function() { + this.map.enable(); + this.disabled = false; }, - disable: function(){ - if(this.enabled){ - this.el.removeListener(this.eventName, this.handleKeyDown, this); - this.enabled = false; - } + disable: function() { + this.map.disable(); + this.disabled = true; }, - + setDisabled : function(disabled){ - if (disabled) { - this.disable(); - } else { - this.enable(); - } + this.map.setDisabled(disabled); + this.disabled = disabled; }, - destroy: function(removeEl){ - var me = this; - - me.bindings = []; - me.disable(); - if (removeEl === true) { - me.el.remove(); - } - delete me.el; + getKeyEvent: function(forceKeyDown){ + return (forceKeyDown || Ext.EventManager.useKeyDown) ? 'keydown' : 'keypress'; } }); -Ext.define('Ext.util.ClickRepeater', { - extend: 'Ext.util.Observable', - - constructor : function(el, config){ - this.el = Ext.get(el); - this.el.unselectable(); - - Ext.apply(this, config); - - this.addEvents( - - "mousedown", - - "click", - - "mouseup" - ); - if(!this.disabled){ - this.disabled = true; - this.enable(); - } +Ext.define('Ext.fx.Queue', { - - if(this.handler){ - this.on("click", this.handler, this.scope || this); - } + requires: ['Ext.util.HashMap'], - this.callParent(); + constructor: function() { + this.targets = Ext.create('Ext.util.HashMap'); + this.fxQueue = {}; }, + getFxDefaults: function(targetId) { + var target = this.targets.get(targetId); + if (target) { + return target.fxDefaults; + } + return {}; + }, + setFxDefaults: function(targetId, obj) { + var target = this.targets.get(targetId); + if (target) { + target.fxDefaults = Ext.apply(target.fxDefaults || {}, obj); + } + }, + stopAnimation: function(targetId) { + var me = this, + queue = me.getFxQueue(targetId), + ln = queue.length; + while (ln) { + queue[ln - 1].end(); + ln--; + } + }, - interval : 20, + getActiveAnimation: function(targetId) { + var queue = this.getFxQueue(targetId); + return (queue && !!queue.length) ? queue[0] : false; + }, - delay: 250, + hasFxBlock: function(targetId) { + var queue = this.getFxQueue(targetId); + return queue && queue[0] && queue[0].block; + }, - preventDefault : true, - - stopDefault : false, + getFxQueue: function(targetId) { + if (!targetId) { + return false; + } + var me = this, + queue = me.fxQueue[targetId], + target = me.targets.get(targetId); - timer : 0, + if (!target) { + return false; + } - - enable: function(){ - if(this.disabled){ - this.el.on('mousedown', this.handleMouseDown, this); - if (Ext.isIE){ - this.el.on('dblclick', this.handleDblClick, this); - } - if(this.preventDefault || this.stopDefault){ - this.el.on('click', this.eventOptions, this); + if (!queue) { + me.fxQueue[targetId] = []; + + if (target.type != 'element') { + target.target.on('destroy', function() { + me.fxQueue[targetId] = []; + }); } } - this.disabled = false; + return me.fxQueue[targetId]; }, - disable: function( force){ - if(force || !this.disabled){ - clearTimeout(this.timer); - if(this.pressedCls){ - this.el.removeCls(this.pressedCls); - } - Ext.getDoc().un('mouseup', this.handleMouseUp, this); - this.el.removeAllListeners(); + queueFx: function(anim) { + var me = this, + target = anim.target, + queue, ln; + + if (!target) { + return; } - this.disabled = true; - }, - - setDisabled: function(disabled){ - this[disabled ? 'disable' : 'enable'](); - }, + queue = me.getFxQueue(target.getId()); + ln = queue.length; - eventOptions: function(e){ - if(this.preventDefault){ - e.preventDefault(); + if (ln) { + if (anim.concurrent) { + anim.paused = false; + } + else { + queue[ln - 1].on('afteranimate', function() { + anim.paused = false; + }); + } } - if(this.stopDefault){ - e.stopEvent(); + else { + anim.paused = false; } - }, + anim.on('afteranimate', function() { + Ext.Array.remove(queue, anim); + if (anim.remove) { + if (target.type == 'element') { + var el = Ext.get(target.id); + if (el) { + el.remove(); + } + } + } + }, this); + queue.push(anim); + } +}); - - destroy : function() { - this.disable(true); - Ext.destroy(this.el); - this.clearListeners(); - }, +Ext.define('Ext.fx.target.Target', { - handleDblClick : function(e){ - clearTimeout(this.timer); - this.el.blur(); + isAnimTarget: true, - this.fireEvent("mousedown", this, e); - this.fireEvent("click", this, e); + + constructor: function(target) { + this.target = target; + this.id = this.getId(); }, - - handleMouseDown : function(e){ - clearTimeout(this.timer); - this.el.blur(); - if(this.pressedCls){ - this.el.addCls(this.pressedCls); - } - this.mousedownTime = new Date(); + getId: function() { + return this.target.id; + } +}); - Ext.getDoc().on("mouseup", this.handleMouseUp, this); - this.el.on("mouseout", this.handleMouseOut, this); - this.fireEvent("mousedown", this, e); - this.fireEvent("click", this, e); - - if (this.accelerate) { - this.delay = 400; - } +Ext.define('Ext.fx.target.Sprite', { - - - e = new Ext.EventObjectImpl(e); + - this.timer = Ext.defer(this.click, this.delay || this.interval, this, [e]); - }, + extend: 'Ext.fx.target.Target', - click : function(e){ - this.fireEvent("click", this, e); - this.timer = Ext.defer(this.click, this.accelerate ? - this.easeOutExpo(Ext.Date.getElapsed(this.mousedownTime), - 400, - -390, - 12000) : - this.interval, this, [e]); - }, - easeOutExpo : function (t, b, c, d) { - return (t==d) ? b+c : c * (-Math.pow(2, -10 * t/d) + 1) + b; - }, + type: 'draw', - - handleMouseOut : function(){ - clearTimeout(this.timer); - if(this.pressedCls){ - this.el.removeCls(this.pressedCls); + getFromPrim: function(sprite, attr) { + var o; + if (attr == 'translate') { + o = { + x: sprite.attr.translation.x || 0, + y: sprite.attr.translation.y || 0 + }; } - this.el.on("mouseover", this.handleMouseReturn, this); + else if (attr == 'rotate') { + o = { + degrees: sprite.attr.rotation.degrees || 0, + x: sprite.attr.rotation.x, + y: sprite.attr.rotation.y + }; + } + else { + o = sprite.attr[attr]; + } + return o; }, - - handleMouseReturn : function(){ - this.el.un("mouseover", this.handleMouseReturn, this); - if(this.pressedCls){ - this.el.addCls(this.pressedCls); - } - this.click(); + getAttr: function(attr, val) { + return [[this.target, val != undefined ? val : this.getFromPrim(this.target, attr)]]; }, - - handleMouseUp : function(e){ - clearTimeout(this.timer); - this.el.un("mouseover", this.handleMouseReturn, this); - this.el.un("mouseout", this.handleMouseOut, this); - Ext.getDoc().un("mouseup", this.handleMouseUp, this); - if(this.pressedCls){ - this.el.removeCls(this.pressedCls); + setAttr: function(targetData) { + var ln = targetData.length, + spriteArr = [], + attrs, attr, attrArr, attPtr, spritePtr, idx, value, i, j, x, y, ln2; + for (i = 0; i < ln; i++) { + attrs = targetData[i].attrs; + for (attr in attrs) { + attrArr = attrs[attr]; + ln2 = attrArr.length; + for (j = 0; j < ln2; j++) { + spritePtr = attrArr[j][0]; + attPtr = attrArr[j][1]; + if (attr === 'translate') { + value = { + x: attPtr.x, + y: attPtr.y + }; + } + else if (attr === 'rotate') { + x = attPtr.x; + if (isNaN(x)) { + x = null; + } + y = attPtr.y; + if (isNaN(y)) { + y = null; + } + value = { + degrees: attPtr.degrees, + x: x, + y: y + }; + } + else if (attr === 'width' || attr === 'height' || attr === 'x' || attr === 'y') { + value = parseFloat(attPtr); + } + else { + value = attPtr; + } + idx = Ext.Array.indexOf(spriteArr, spritePtr); + if (idx == -1) { + spriteArr.push([spritePtr, {}]); + idx = spriteArr.length - 1; + } + spriteArr[idx][1][attr] = value; + } + } } - this.fireEvent("mouseup", this, e); + ln = spriteArr.length; + for (i = 0; i < ln; i++) { + spritePtr = spriteArr[i]; + spritePtr[0].setAttributes(spritePtr[1]); + } + this.target.redraw(); } }); -Ext.define('Ext.layout.component.Button', { + +Ext.define('Ext.fx.target.CompositeSprite', { - alias: ['layout.button'], + extend: 'Ext.fx.target.Sprite', - extend: 'Ext.layout.component.Component', + + getAttr: function(attr, val) { + var out = [], + target = this.target; + target.each(function(sprite) { + out.push([sprite, val != undefined ? val : this.getFromPrim(sprite, attr)]); + }, this); + return out; + } +}); + + +Ext.define('Ext.fx.target.Component', { + + + + extend: 'Ext.fx.target.Target', + - type: 'button', + type: 'component', - cellClsRE: /-btn-(tl|br)\b/, - htmlRE: /<.*>/, + + getPropMethod: { + top: function() { + return this.getPosition(true)[1]; + }, + left: function() { + return this.getPosition(true)[0]; + }, + x: function() { + return this.getPosition()[0]; + }, + y: function() { + return this.getPosition()[1]; + }, + height: function() { + return this.getHeight(); + }, + width: function() { + return this.getWidth(); + }, + opacity: function() { + return this.el.getStyle('opacity'); + } + }, - beforeLayout: function() { - return this.callParent(arguments) || this.lastText !== this.owner.text; + compMethod: { + top: 'setPosition', + left: 'setPosition', + x: 'setPagePosition', + y: 'setPagePosition', + height: 'setSize', + width: 'setSize', + opacity: 'setOpacity' }, - onLayout: function(width, height) { - 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; - - me.getTargetInfo(); - me.callParent(arguments); + getAttr: function(attr, val) { + return [[this.target, val !== undefined ? val : this.getPropMethod[attr].call(this.target)]]; + }, - btnInnerEl.unclip(); - me.setTargetSize(width, height); + setAttr: function(targetData, isFirstFrame, isLastFrame) { + var me = this, + target = me.target, + ln = targetData.length, + attrs, attr, o, i, j, meth, targets, left, top, w, h; + for (i = 0; i < ln; i++) { + attrs = targetData[i].attrs; + for (attr in attrs) { + targets = attrs[attr].length; + meth = { + setPosition: {}, + setPagePosition: {}, + setSize: {}, + setOpacity: {} + }; + for (j = 0; j < targets; j++) { + o = attrs[attr][j]; + + + + + meth[me.compMethod[attr]].target = o[0]; + meth[me.compMethod[attr]][attr] = o[1]; + } + if (meth.setPosition.target) { + o = meth.setPosition; + left = (o.left === undefined) ? undefined : parseInt(o.left, 10); + top = (o.top === undefined) ? undefined : parseInt(o.top, 10); + o.target.setPosition(left, top); + } + if (meth.setPagePosition.target) { + o = meth.setPagePosition; + o.target.setPagePosition(o.x, o.y); + } + if (meth.setSize.target && meth.setSize.target.el) { + o = meth.setSize; + + w = (o.width === undefined) ? o.target.getWidth() : parseInt(o.width, 10); + h = (o.height === undefined) ? o.target.getHeight() : parseInt(o.height, 10); - if (!isNum(width)) { - - - - 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); - } + + + + + + + + if (isLastFrame || me.dynamic) { + o.target.componentLayout.childrenChanged = true; - - if (minWidth || maxWidth) { - ownerWidth = ownerEl.getWidth(); - if (minWidth && (ownerWidth < minWidth)) { - me.setTargetSize(minWidth, height); + + if (me.layoutAnimation) { + o.target.setCalculatedSize(w, h); + } else { + o.target.setSize(w, h); + } + } + else { + o.target.el.setSize(w, h); + } } - else if (maxWidth && (ownerWidth > maxWidth)) { - btnInnerEl.clip(); - me.setTargetSize(maxWidth, height); + if (meth.setOpacity.target) { + o = meth.setOpacity; + o.target.el.setStyle('opacity', o.opacity); } } } + } +}); - 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; +Ext.define('Ext.fx.CubicBezier', { - me.callParent(arguments); - me.setElementSize(owner.btnEl, btnWidth, btnHeight); - me.setElementSize(btnInnerEl, btnWidth, btnHeight); - if (isNum(btnHeight)) { - 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); - } - }, + singleton: true, - 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') - }); + cubicBezierAtTime: function(t, p1x, p1y, p2x, p2y, duration) { + var cx = 3 * p1x, + bx = 3 * (p2x - p1x) - cx, + ax = 1 - cx - bx, + cy = 3 * p1y, + by = 3 * (p2y - p1y) - cy, + ay = 1 - cy - by; + function sampleCurveX(t) { + return ((ax * t + bx) * t + cx) * t; + } + function solve(x, epsilon) { + var t = solveCurveX(x, epsilon); + return ((ay * t + by) * t + cy) * t; + } + function solveCurveX(x, epsilon) { + var t0, t1, t2, x2, d2, i; + for (t2 = x, i = 0; i < 8; i++) { + x2 = sampleCurveX(t2) - x; + if (Math.abs(x2) < epsilon) { + return t2; + } + d2 = (3 * ax * t2 + 2 * bx) * t2 + cx; + if (Math.abs(d2) < 1e-6) { + break; + } + t2 = t2 - x2 / d2; + } + t0 = 0; + t1 = 1; + t2 = x; + if (t2 < t0) { + return t0; + } + if (t2 > t1) { + return t1; + } + while (t0 < t1) { + x2 = sampleCurveX(t2); + if (Math.abs(x2 - x) < epsilon) { + return t2; + } + if (x > x2) { + t0 = t2; + } else { + t1 = t2; + } + t2 = (t1 - t0) / 2 + t0; + } + return t2; } + return solve(t, 1 / (200 * duration)); + }, - return me.callParent(); + cubicBezier: function(x1, y1, x2, y2) { + var fn = function(pos) { + return Ext.fx.CubicBezier.cubicBezierAtTime(pos, x1, y1, x2, y2, 1); + }; + fn.toCSS3 = function() { + return 'cubic-bezier(' + [x1, y1, x2, y2].join(',') + ')'; + }; + fn.reverse = function() { + return Ext.fx.CubicBezier.cubicBezier(1 - x2, 1 - y2, 1 - x1, 1 - y1); + }; + return fn; } }); -Ext.define('Ext.util.TextMetrics', { - statics: { - shared: null, - - measure: function(el, text, fixedWidth){ - var me = this, - shared = me.shared; - - if(!shared){ - shared = me.shared = new me(el, fixedWidth); - } - shared.bind(el); - shared.setFixedWidth(fixedWidth || 'auto'); - return shared.getSize(text); - }, - - - destroy: function(){ - var me = this; - Ext.destroy(me.shared); - me.shared = null; - } - }, +Ext.define('Ext.draw.Color', { + + - constructor: function(bindTo, fixedWidth){ - var measure = this.measure = Ext.getBody().createChild({ - cls: 'x-textmetrics' - }); - this.el = Ext.get(bindTo); - - measure.position('absolute'); - measure.setLeftTop(-1000, -1000); - measure.hide(); - if (fixedWidth) { - measure.setWidth(fixedWidth); - } + colorToHexRe: /(.*?)rgb\((\d+),\s*(\d+),\s*(\d+)\)/, + rgbRe: /\s*rgb\s*\(\s*([0-9]+)\s*,\s*([0-9]+)\s*,\s*([0-9]+)\s*\)\s*/, + hexRe: /\s*#([0-9a-fA-F][0-9a-fA-F]?)([0-9a-fA-F][0-9a-fA-F]?)([0-9a-fA-F][0-9a-fA-F]?)\s*/, + + + lightnessFactor: 0.2, + + + constructor : function(red, green, blue) { + var me = this, + clamp = Ext.Number.constrain; + me.r = clamp(red, 0, 255); + me.g = clamp(green, 0, 255); + me.b = clamp(blue, 0, 255); }, + + getRed: function() { + return this.r; + }, + - getSize: function(text){ - var measure = this.measure, - size; - - measure.update(text); - size = measure.getSize(); - measure.update(''); - return size; + getGreen: function() { + return this.g; }, + + getBlue: function() { + return this.b; + }, + - bind: function(el){ + getRGB: function() { var me = this; - - me.el = Ext.get(el); - me.measure.setStyle( - me.el.getStyles('font-size','font-style', 'font-weight', 'font-family','line-height', 'text-transform', 'letter-spacing') - ); + return [me.r, me.g, me.b]; }, + - - setFixedWidth : function(width){ - this.measure.setWidth(width); - }, - - - getWidth : function(text){ - this.measure.dom.style.width = 'auto'; - return this.getSize(text).width; - }, - - - getHeight : function(text){ - return this.getSize(text).height; - }, - - - destroy: function(){ - var me = this; - me.measure.remove(); - delete me.el; - delete me.measure; - } -}, function(){ - Ext.core.Element.addMethods({ + getHSL: function() { + var me = this, + r = me.r / 255, + g = me.g / 255, + b = me.b / 255, + max = Math.max(r, g, b), + min = Math.min(r, g, b), + delta = max - min, + h, + s = 0, + l = 0.5 * (max + min); + - 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); + if (min != max) { + s = (l < 0.5) ? delta / (max + min) : delta / (2 - max - min); + if (r == max) { + h = 60 * (g - b) / delta; + } else if (g == max) { + h = 120 + 60 * (b - r) / delta; + } else { + h = 240 + 60 * (r - g) / delta; + } + if (h < 0) { + h += 360; + } + if (h >= 360) { + h -= 360; + } } - }); -}); - - -Ext.define('Ext.layout.container.boxOverflow.Scroller', { + return [h, s, l]; + }, - - extend: 'Ext.layout.container.boxOverflow.None', - requires: ['Ext.util.ClickRepeater', 'Ext.core.Element'], - alternateClassName: 'Ext.layout.boxOverflow.Scroller', - mixins: { - observable: 'Ext.util.Observable' + getLighter: function(factor) { + var hsl = this.getHSL(); + factor = factor || this.lightnessFactor; + hsl[2] = Ext.Number.constrain(hsl[2] + factor, 0, 1); + return this.fromHSL(hsl[0], hsl[1], hsl[2]); }, - - - animateScroll: false, + getDarker: function(factor) { + factor = factor || this.lightnessFactor; + return this.getLighter(-factor); + }, - scrollIncrement: 20, + toString: function() { + var me = this, + round = Math.round, + r = round(me.r).toString(16), + g = round(me.g).toString(16), + b = round(me.b).toString(16); + r = (r.length == 1) ? '0' + r : r; + g = (g.length == 1) ? '0' + g : g; + b = (b.length == 1) ? '0' + b : b; + return ['#', r, g, b].join(''); + }, - wheelIncrement: 10, + toHex: function(color) { + if (Ext.isArray(color)) { + color = color[0]; + } + if (!Ext.isString(color)) { + return ''; + } + if (color.substr(0, 1) === '#') { + return color; + } + var digits = this.colorToHexRe.exec(color); - - scrollRepeatInterval: 60, + if (Ext.isArray(digits)) { + var red = parseInt(digits[2], 10), + green = parseInt(digits[3], 10), + blue = parseInt(digits[4], 10), + rgb = blue | (green << 8) | (red << 16); + return digits[1] + '#' + ("000000" + rgb.toString(16)).slice(-6); + } + else { + return ''; + } + }, - scrollDuration: 400, + fromString: function(str) { + var values, r, g, b, + parse = parseInt; + + if ((str.length == 4 || str.length == 7) && str.substr(0, 1) === '#') { + values = str.match(this.hexRe); + if (values) { + r = parse(values[1], 16) >> 0; + g = parse(values[2], 16) >> 0; + b = parse(values[3], 16) >> 0; + if (str.length == 4) { + r += (r * 16); + g += (g * 16); + b += (b * 16); + } + } + } + else { + values = str.match(this.rgbRe); + if (values) { + r = values[1]; + g = values[2]; + b = values[3]; + } + } + + return (typeof r == 'undefined') ? undefined : Ext.create('Ext.draw.Color', r, g, b); + }, + getGrayscale: function() { + + return this.r * 0.3 + this.g * 0.59 + this.b * 0.11; + }, + fromHSL: function(h, s, l) { + var C, X, m, i, rgb = [], + abs = Math.abs, + floor = Math.floor; + + if (s == 0 || h == null) { + + rgb = [l, l, l]; + } + else { + + + + + h /= 60; + C = s * (1 - abs(2 * l - 1)); + X = C * (1 - abs(h - 2 * floor(h / 2) - 1)); + m = l - C / 2; + switch (floor(h)) { + case 0: + rgb = [C, X, 0]; + break; + case 1: + rgb = [X, C, 0]; + break; + case 2: + rgb = [0, C, X]; + break; + case 3: + rgb = [0, X, C]; + break; + case 4: + rgb = [X, 0, C]; + break; + case 5: + rgb = [C, 0, X]; + break; + } + rgb = [rgb[0] + m, rgb[1] + m, rgb[2] + m]; + } + return Ext.create('Ext.draw.Color', rgb[0] * 255, rgb[1] * 255, rgb[2] * 255); + } +}, function() { + var prototype = this.prototype; - scrollerCls: Ext.baseCSSPrefix + 'box-scroller', + this.addStatics({ + fromHSL: function() { + return prototype.fromHSL.apply(prototype, arguments); + }, + fromString: function() { + return prototype.fromString.apply(prototype, arguments); + }, + toHex: function() { + return prototype.toHex.apply(prototype, arguments); + } + }); +}); + + +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: '
' + + '
', + cls: Ext.baseCSSPrefix + 'dd-drag-proxy ' + this.dropNotAllowed, + shadow: !config || config.shadow !== false, + renderTo: document.body + }); + + this.el = this.proxy.el; + this.el.show(); + this.el.setVisibilityMode(Ext.Element.VISIBILITY); + this.el.hide(); + this.ghost = Ext.get(this.el.dom.childNodes[1]); + this.dropStatus = this.dropNotAllowed; + }, + dropAllowed : Ext.baseCSSPrefix + 'dd-drop-ok', - constructor: function(layout, config) { - this.layout = layout; - Ext.apply(this, config || {}); - - this.addEvents( - - 'scroll' - ); - }, + dropNotAllowed : Ext.baseCSSPrefix + 'dd-drop-nodrop', + - initCSSClasses: function() { - var me = this, - layout = me.layout; + setStatus : function(cssClass){ + cssClass = cssClass || this.dropNotAllowed; + if(this.dropStatus != cssClass){ + this.el.replaceCls(this.dropStatus, cssClass); + this.dropStatus = cssClass; + } + }, - if (!me.CSSinitialized) { - me.beforeCtCls = me.beforeCtCls || Ext.baseCSSPrefix + 'box-scroller-' + layout.parallelBefore; - me.afterCtCls = me.afterCtCls || Ext.baseCSSPrefix + 'box-scroller-' + layout.parallelAfter; - me.beforeScrollerCls = me.beforeScrollerCls || Ext.baseCSSPrefix + layout.owner.getXType() + '-scroll-' + layout.parallelBefore; - me.afterScrollerCls = me.afterScrollerCls || Ext.baseCSSPrefix + layout.owner.getXType() + '-scroll-' + layout.parallelAfter; - me.CSSinitializes = true; + + reset : function(clearGhost){ + this.el.dom.className = Ext.baseCSSPrefix + 'dd-drag-proxy ' + this.dropNotAllowed; + this.dropStatus = this.dropNotAllowed; + if(clearGhost){ + this.ghost.update(""); } }, - handleOverflow: function(calculations, targetSize) { - var me = this, - layout = me.layout, - methodName = 'get' + layout.parallelPrefixCap, - newSize = {}; + + update : function(html){ + if(typeof html == "string"){ + this.ghost.update(html); + }else{ + this.ghost.update(""); + html.style.margin = "0"; + this.ghost.dom.appendChild(html); + } + var el = this.ghost.dom.firstChild; + if(el){ + Ext.fly(el).setStyle('float', 'none'); + } + }, - me.initCSSClasses(); - me.callParent(arguments); - this.createInnerElements(); - this.showScrollers(); - newSize[layout.perpendicularPrefix] = targetSize[layout.perpendicularPrefix]; - newSize[layout.parallelPrefix] = targetSize[layout.parallelPrefix] - (me.beforeCt[methodName]() + me.afterCt[methodName]()); - return { targetSize: newSize }; + + getEl : function(){ + return this.el; }, - createInnerElements: function() { - var me = this, - target = me.layout.getRenderTarget(); + getGhost : function(){ + return this.ghost; + }, - - - if (!me.beforeCt) { - target.addCls(Ext.baseCSSPrefix + me.layout.direction + '-box-overflow-body'); - me.beforeCt = target.insertSibling({cls: Ext.layout.container.Box.prototype.innerCls + ' ' + me.beforeCtCls}, 'before'); - me.afterCt = target.insertSibling({cls: Ext.layout.container.Box.prototype.innerCls + ' ' + me.afterCtCls}, 'after'); - me.createWheelListener(); + + hide : function(clear) { + this.proxy.hide(); + if (clear) { + this.reset(true); } }, - createWheelListener: function() { - this.layout.innerCt.on({ - scope : this, - mousewheel: function(e) { - e.stopEvent(); - - this.scrollBy(e.getWheelDelta() * this.wheelIncrement * -1, false); - } - }); + stop : function(){ + if(this.anim && this.anim.isAnimated && this.anim.isAnimated()){ + this.anim.stop(); + } }, - clearOverflow: function() { - this.hideScrollers(); + show : function() { + this.proxy.show(); + this.proxy.toFront(); }, - showScrollers: function() { - this.createScrollers(); - this.beforeScroller.show(); - this.afterScroller.show(); - this.updateScrollButtons(); - - this.layout.owner.addClsWithUI('scroller'); + sync : function(){ + this.proxy.el.sync(); }, - hideScrollers: function() { - if (this.beforeScroller != undefined) { - this.beforeScroller.hide(); - this.afterScroller.hide(); - - this.layout.owner.removeClsWithUI('scroller'); + repair : function(xy, callback, scope){ + this.callback = callback; + this.scope = scope; + if (xy && this.animRepair !== false) { + this.el.addCls(Ext.baseCSSPrefix + 'dd-drag-repair'); + this.el.hideUnders(true); + this.anim = this.el.animate({ + duration: this.repairDuration || 500, + easing: 'ease-out', + to: { + x: xy[0], + y: xy[1] + }, + stopAnimation: true, + callback: this.afterRepair, + scope: this + }); + } else { + this.afterRepair(); } }, - createScrollers: function() { - if (!this.beforeScroller && !this.afterScroller) { - var before = this.beforeCt.createChild({ - cls: Ext.String.format("{0} {1} ", this.scrollerCls, this.beforeScrollerCls) - }); - - var after = this.afterCt.createChild({ - cls: Ext.String.format("{0} {1}", this.scrollerCls, this.afterScrollerCls) - }); + afterRepair : function(){ + this.hide(true); + if(typeof this.callback == "function"){ + this.callback.call(this.scope || this); + } + this.callback = null; + this.scope = null; + }, - before.addClsOnOver(this.beforeScrollerCls + '-hover'); - after.addClsOnOver(this.afterScrollerCls + '-hover'); + destroy: function(){ + Ext.destroy(this.ghost, this.proxy, this.el); + } +}); - before.setVisibilityMode(Ext.core.Element.DISPLAY); - after.setVisibilityMode(Ext.core.Element.DISPLAY); +Ext.define('Ext.panel.Proxy', { - this.beforeRepeater = Ext.create('Ext.util.ClickRepeater', before, { - interval: this.scrollRepeatInterval, - handler : this.scrollLeft, - scope : this - }); + alternateClassName: 'Ext.dd.PanelProxy', - this.afterRepeater = Ext.create('Ext.util.ClickRepeater', after, { - interval: this.scrollRepeatInterval, - handler : this.scrollRight, - scope : this - }); + + constructor: function(panel, config){ + + this.panel = panel; + this.id = this.panel.id +'-ddproxy'; + Ext.apply(this, config); + }, - - this.beforeScroller = before; + + insertProxy: true, - - this.afterScroller = after; - } - }, + + setStatus: Ext.emptyFn, + reset: Ext.emptyFn, + update: Ext.emptyFn, + stop: Ext.emptyFn, + sync: Ext.emptyFn, - destroy: function() { - Ext.destroy(this.beforeRepeater, this.afterRepeater, this.beforeScroller, this.afterScroller, this.beforeCt, this.afterCt); + getEl: function(){ + return this.ghost.el; }, - scrollBy: function(delta, animate) { - this.scrollTo(this.getScrollPosition() + delta, animate); + getGhost: function(){ + return this.ghost; }, - getScrollAnim: function() { - return { - duration: this.scrollDuration, - callback: this.updateScrollButtons, - scope : this - }; + getProxy: function(){ + return this.proxy; }, - updateScrollButtons: function() { - if (this.beforeScroller == undefined || this.afterScroller == undefined) { - return; - } + hide : function(){ + if (this.ghost) { + if (this.proxy) { + this.proxy.remove(); + delete this.proxy; + } - var beforeMeth = this.atExtremeBefore() ? 'addCls' : 'removeCls', - afterMeth = this.atExtremeAfter() ? 'addCls' : 'removeCls', - beforeCls = this.beforeScrollerCls + '-disabled', - afterCls = this.afterScrollerCls + '-disabled'; - - this.beforeScroller[beforeMeth](beforeCls); - this.afterScroller[afterMeth](afterCls); - this.scrolling = false; + + this.panel.unghost(null, false); + delete this.ghost; + } }, - atExtremeBefore: function() { - return this.getScrollPosition() === 0; + show: function(){ + if (!this.ghost) { + var panelSize = this.panel.getSize(); + this.panel.el.setVisibilityMode(Ext.Element.DISPLAY); + this.ghost = this.panel.ghost(); + if (this.insertProxy) { + + + this.proxy = this.panel.el.insertSibling({cls: Ext.baseCSSPrefix + 'panel-dd-spacer'}); + this.proxy.setSize(panelSize); + } + } }, - scrollLeft: function() { - this.scrollBy(-this.scrollIncrement, false); + repair: function(xy, callback, scope) { + this.hide(); + if (typeof callback == "function") { + callback.call(scope || this); + } }, - scrollRight: function() { - this.scrollBy(this.scrollIncrement, false); - }, + moveProxy : function(parentNode, before){ + if (this.proxy) { + parentNode.insertBefore(this.proxy.dom, before); + } + } +}); + + +Ext.define('Ext.layout.component.AbstractDock', { - getScrollPosition: function(){ - var layout = this.layout; - return parseInt(layout.innerCt.dom['scroll' + layout.parallelBeforeCap], 10) || 0; - }, + + extend: 'Ext.layout.component.Component', - getMaxScrollPosition: function() { - var layout = this.layout; - return layout.innerCt.dom['scroll' + layout.parallelPrefixCap] - this.layout.innerCt['get' + layout.parallelPrefixCap](); - }, + + type: 'dock', - atExtremeAfter: function() { - return this.getScrollPosition() >= this.getMaxScrollPosition(); + autoSizing: true, + + beforeLayout: function() { + var returnValue = this.callParent(arguments); + if (returnValue !== false && (!this.initializedBorders || this.childrenChanged) && (!this.owner.border || this.owner.manageBodyBorders)) { + this.handleItemBorders(); + this.initializedBorders = true; + } + return returnValue; }, + + handleItemBorders: function() { + var owner = this.owner, + body = owner.body, + docked = this.getLayoutItems(), + borders = { + top: [], + right: [], + bottom: [], + left: [] + }, + oldBorders = this.borders, + opposites = { + top: 'bottom', + right: 'left', + bottom: 'top', + left: 'right' + }, + i, ln, item, dock, side; + + for (i = 0, ln = docked.length; i < ln; i++) { + item = docked[i]; + dock = item.dock; + + if (item.ignoreBorderManagement) { + continue; + } + + if (!borders[dock].satisfied) { + borders[dock].push(item); + borders[dock].satisfied = true; + } + + if (!borders.top.satisfied && opposites[dock] !== 'top') { + borders.top.push(item); + } + if (!borders.right.satisfied && opposites[dock] !== 'right') { + borders.right.push(item); + } + if (!borders.bottom.satisfied && opposites[dock] !== 'bottom') { + borders.bottom.push(item); + } + if (!borders.left.satisfied && opposites[dock] !== 'left') { + borders.left.push(item); + } + } + if (oldBorders) { + for (side in oldBorders) { + if (oldBorders.hasOwnProperty(side)) { + ln = oldBorders[side].length; + if (!owner.manageBodyBorders) { + for (i = 0; i < ln; i++) { + oldBorders[side][i].removeCls(Ext.baseCSSPrefix + 'docked-noborder-' + side); + } + if (!oldBorders[side].satisfied && !owner.bodyBorder) { + body.removeCls(Ext.baseCSSPrefix + 'docked-noborder-' + side); + } + } + else if (oldBorders[side].satisfied) { + body.setStyle('border-' + side + '-width', ''); + } + } + } + } + + for (side in borders) { + if (borders.hasOwnProperty(side)) { + ln = borders[side].length; + if (!owner.manageBodyBorders) { + for (i = 0; i < ln; i++) { + borders[side][i].addCls(Ext.baseCSSPrefix + 'docked-noborder-' + side); + } + if ((!borders[side].satisfied && !owner.bodyBorder) || owner.bodyBorder === false) { + body.addCls(Ext.baseCSSPrefix + 'docked-noborder-' + side); + } + } + else if (borders[side].satisfied) { + body.setStyle('border-' + side + '-width', '1px'); + } + } + } + + this.borders = borders; + }, - scrollTo: function(position, animate) { + + onLayout: function(width, height) { + if (this.onLayout_running) { + return; + } + this.onLayout_running = true; var me = this, - layout = me.layout, - oldPosition = me.getScrollPosition(), - newPosition = Ext.Number.constrain(position, 0, me.getMaxScrollPosition()); + owner = me.owner, + body = owner.body, + layout = owner.layout, + target = me.getTarget(), + autoWidth = false, + autoHeight = false, + padding, border, frameSize; - if (newPosition != oldPosition && !me.scrolling) { - if (animate == undefined) { - animate = me.animateScroll; + + var info = me.info = { + boxes: [], + size: { + width: width, + height: height + }, + bodyBox: {} + }; + + delete layout.isAutoDock; + + Ext.applyIf(info, me.getTargetInfo()); + + + if (owner && owner.ownerCt && owner.ownerCt.layout && owner.ownerCt.layout.isLayout) { + if (!Ext.isNumber(owner.height) || !Ext.isNumber(owner.width)) { + owner.ownerCt.layout.bindToOwnerCtComponent = true; + } + else { + owner.ownerCt.layout.bindToOwnerCtComponent = false; } + } - layout.innerCt.scrollTo(layout.parallelBefore, newPosition, animate ? me.getScrollAnim() : false); - if (animate) { - me.scrolling = true; - } else { - me.scrolling = false; - me.updateScrollButtons(); + + if (height == null || width == null) { + padding = info.padding; + border = info.border; + frameSize = me.frameSize; + + + if ((height == null) && (width == null)) { + autoHeight = true; + autoWidth = true; + me.setTargetSize(null); + me.setBodyBox({width: null, height: null}); } - me.fireEvent('scroll', me, newPosition, animate ? me.getScrollAnim() : false); + else if (height == null) { + autoHeight = true; + + me.setTargetSize(width); + me.setBodyBox({width: width - padding.left - border.left - padding.right - border.right - frameSize.left - frameSize.right, height: null}); + + } + else { + autoWidth = true; + + me.setTargetSize(null, height); + me.setBodyBox({width: null, height: height - padding.top - padding.bottom - border.top - border.bottom - frameSize.top - frameSize.bottom}); + } + + + if (layout && layout.isLayout) { + + layout.bindToOwnerCtComponent = true; + + layout.isAutoDock = layout.autoSize !== true; + layout.layout(); + + + + + + + + + + + + + + info.autoSizedCtLayout = layout.autoSize === true; + info.autoHeight = autoHeight; + info.autoWidth = autoWidth; + } + + + + + + + me.dockItems(); + me.setTargetSize(info.size.width, info.size.height); + } + else { + me.setTargetSize(width, height); + me.dockItems(); } + me.callParent(arguments); + this.onLayout_running = false; }, - scrollToItem: function(item, animate) { - var me = this, - layout = me.layout, - visibility, - box, - newPos; + dockItems : function() { + this.calculateDockBoxes(); - item = me.getItem(item); - if (item != undefined) { - visibility = this.getItemVisibility(item); - if (!visibility.fullyVisible) { - box = item.getBox(true, true); - newPos = box[layout.parallelPosition]; - if (visibility.hiddenEnd) { - newPos -= (this.layout.innerCt['get' + layout.parallelPrefixCap]() - box[layout.parallelPrefix]); - } - this.scrollTo(newPos, animate); + + + + var info = this.info, + autoWidth = info.autoWidth, + autoHeight = info.autoHeight, + boxes = info.boxes, + ln = boxes.length, + dock, i, item; + + + + for (i = 0; i < ln; i++) { + dock = boxes[i]; + item = dock.item; + item.setPosition(dock.x, dock.y); + if ((autoWidth || autoHeight) && item.layout && item.layout.isLayout) { + + item.layout.bindToOwnerCtComponent = true; + } + } + + + + if (!info.autoSizedCtLayout) { + if (autoWidth) { + info.bodyBox.width = null; + } + if (autoHeight) { + info.bodyBox.height = null; } } + + + + this.setBodyBox(info.bodyBox); }, - getItemVisibility: function(item) { - var me = this, - box = me.getItem(item).getBox(true, true), - layout = me.layout, - itemStart = box[layout.parallelPosition], - itemEnd = itemStart + box[layout.parallelPrefix], - scrollStart = me.getScrollPosition(), - scrollEnd = scrollStart + layout.innerCt['get' + layout.parallelPrefixCap](); + calculateDockBoxes : function() { + if (this.calculateDockBoxes_running) { + + return; + } + this.calculateDockBoxes_running = true; + + + + var me = this, + target = me.getTarget(), + items = me.getLayoutItems(), + owner = me.owner, + bodyEl = owner.body, + info = me.info, + autoWidth = info.autoWidth, + autoHeight = info.autoHeight, + size = info.size, + ln = items.length, + padding = info.padding, + border = info.border, + frameSize = me.frameSize, + item, i, box, rect; - return { - hiddenStart : itemStart < scrollStart, - hiddenEnd : itemEnd > scrollEnd, - fullyVisible: itemStart > scrollStart && itemEnd < scrollEnd + + + if (autoHeight) { + size.height = bodyEl.getHeight() + padding.top + border.top + padding.bottom + border.bottom + frameSize.top + frameSize.bottom; + } + else { + size.height = target.getHeight(); + } + if (autoWidth) { + size.width = bodyEl.getWidth() + padding.left + border.left + padding.right + border.right + frameSize.left + frameSize.right; + } + else { + size.width = target.getWidth(); + } + + info.bodyBox = { + x: padding.left + frameSize.left, + y: padding.top + frameSize.top, + width: size.width - padding.left - border.left - padding.right - border.right - frameSize.left - frameSize.right, + height: size.height - border.top - padding.top - border.bottom - padding.bottom - frameSize.top - frameSize.bottom }; - } -}); -Ext.define('Ext.util.Offset', { + + for (i = 0; i < ln; i++) { + item = items[i]; + + + + box = me.initBox(item); - + if (autoHeight === true) { + box = me.adjustAutoBox(box, i); + } + else { + box = me.adjustSizedBox(box, i); + } - statics: { - fromObject: function(obj) { - return new this(obj.x, obj.y); + + + + info.boxes.push(box); } + this.calculateDockBoxes_running = false; }, + adjustSizedBox : function(box, index) { + var bodyBox = this.info.bodyBox, + frameSize = this.frameSize, + info = this.info, + padding = info.padding, + pos = box.type, + border = info.border; - constructor: function(x, y) { - this.x = (x != null && !isNaN(x)) ? x : 0; - this.y = (y != null && !isNaN(y)) ? y : 0; + switch (pos) { + case 'top': + box.y = bodyBox.y; + break; - return this; - }, + case 'left': + box.x = bodyBox.x; + break; - copy: function() { - return new Ext.util.Offset(this.x, this.y); - }, + case 'bottom': + box.y = (bodyBox.y + bodyBox.height) - box.height; + break; - copyFrom: function(p) { - this.x = p.x; - this.y = p.y; - }, + case 'right': + box.x = (bodyBox.x + bodyBox.width) - box.width; + break; + } - toString: function() { - return "Offset[" + this.x + "," + this.y + "]"; + if (box.ignoreFrame) { + if (pos == 'bottom') { + box.y += (frameSize.bottom + padding.bottom + border.bottom); + } + else { + box.y -= (frameSize.top + padding.top + border.top); + } + if (pos == 'right') { + box.x += (frameSize.right + padding.right + border.right); + } + else { + box.x -= (frameSize.left + padding.left + border.left); + } + } + + + if (!box.overlay) { + switch (pos) { + case 'top': + bodyBox.y += box.height; + bodyBox.height -= box.height; + break; + + case 'left': + bodyBox.x += box.width; + bodyBox.width -= box.width; + break; + + case 'bottom': + bodyBox.height -= box.height; + break; + + case 'right': + bodyBox.width -= box.width; + break; + } + } + return box; }, - equals: function(offset) { - if(!(offset instanceof this.statics())) { - Ext.Error.raise('Offset must be an instance of Ext.util.Offset'); + + adjustAutoBox : function (box, index) { + var info = this.info, + owner = this.owner, + bodyBox = info.bodyBox, + size = info.size, + boxes = info.boxes, + boxesLn = boxes.length, + pos = box.type, + frameSize = this.frameSize, + padding = info.padding, + border = info.border, + autoSizedCtLayout = info.autoSizedCtLayout, + ln = (boxesLn < index) ? boxesLn : index, + i, adjustBox; + + if (pos == 'top' || pos == 'bottom') { + + for (i = 0; i < ln; i++) { + adjustBox = boxes[i]; + if (adjustBox.stretched && adjustBox.type == 'left' || adjustBox.type == 'right') { + adjustBox.height += box.height; + } + else if (adjustBox.type == 'bottom') { + adjustBox.y += box.height; + } + } } - return (this.x == offset.x && this.y == offset.y); - }, + switch (pos) { + case 'top': + box.y = bodyBox.y; + if (!box.overlay) { + bodyBox.y += box.height; + if (info.autoHeight) { + size.height += box.height; + } else { + bodyBox.height -= box.height; + } + } + break; - round: function(to) { - if (!isNaN(to)) { - var factor = Math.pow(10, to); - this.x = Math.round(this.x * factor) / factor; - this.y = Math.round(this.y * factor) / factor; - } else { - this.x = Math.round(this.x); - this.y = Math.round(this.y); - } - }, + case 'bottom': + if (!box.overlay) { + if (info.autoHeight) { + size.height += box.height; + } else { + bodyBox.height -= box.height; + } + } + box.y = (bodyBox.y + bodyBox.height); + break; - isZero: function() { - return this.x == 0 && this.y == 0; - } -}); + case 'left': + box.x = bodyBox.x; + if (!box.overlay) { + bodyBox.x += box.width; + if (info.autoWidth) { + size.width += box.width; + } else { + bodyBox.width -= box.width; + } + } + break; + case 'right': + if (!box.overlay) { + if (info.autoWidth) { + size.width += box.width; + } else { + bodyBox.width -= box.width; + } + } + box.x = (bodyBox.x + bodyBox.width); + break; + } -Ext.define('Ext.util.KeyNav', { - - alternateClassName: 'Ext.KeyNav', - - requires: ['Ext.util.KeyMap'], - - statics: { - keyOptions: { - left: 37, - right: 39, - up: 38, - down: 40, - space: 32, - pageUp: 33, - pageDown: 34, - del: 46, - backspace: 8, - home: 36, - end: 35, - enter: 13, - esc: 27, - tab: 9 + if (box.ignoreFrame) { + if (pos == 'bottom') { + box.y += (frameSize.bottom + padding.bottom + border.bottom); + } + else { + box.y -= (frameSize.top + padding.top + border.top); + } + if (pos == 'right') { + box.x += (frameSize.right + padding.right + border.right); + } + else { + box.x -= (frameSize.left + padding.left + border.left); + } } + return box; }, + - constructor: function(el, config){ - this.setConfig(el, config || {}); - }, - - - setConfig: function(el, config) { - if (this.map) { - this.map.destroy(); - } - - var map = Ext.create('Ext.util.KeyMap', el, null, this.getKeyEvent('forceKeyDown' in config ? config.forceKeyDown : this.forceKeyDown)), - keys = Ext.util.KeyNav.keyOptions, - scope = config.scope || this, - key; + initBox : function(item) { + var me = this, + bodyBox = me.info.bodyBox, + horizontal = (item.dock == 'top' || item.dock == 'bottom'), + owner = me.owner, + frameSize = me.frameSize, + info = me.info, + padding = info.padding, + border = info.border, + box = { + item: item, + overlay: item.overlay, + type: item.dock, + offsets: Ext.Element.parseBox(item.offsets || {}), + ignoreFrame: item.ignoreParentFrame + }; - this.map = map; - for (key in keys) { - if (keys.hasOwnProperty(key)) { - if (config[key]) { - map.addBinding({ - scope: scope, - key: keys[key], - handler: Ext.Function.bind(this.handleEvent, scope, [config[key]], true), - defaultEventAction: config.defaultEventAction || this.defaultEventAction - }); + if (item.stretch !== false) { + box.stretched = true; + if (horizontal) { + box.x = bodyBox.x + box.offsets.left; + box.width = bodyBox.width - (box.offsets.left + box.offsets.right); + if (box.ignoreFrame) { + box.width += (frameSize.left + frameSize.right + border.left + border.right + padding.left + padding.right); + } + item.setCalculatedSize(box.width - item.el.getMargin('lr'), undefined, owner); + } + else { + box.y = bodyBox.y + box.offsets.top; + box.height = bodyBox.height - (box.offsets.bottom + box.offsets.top); + if (box.ignoreFrame) { + box.height += (frameSize.top + frameSize.bottom + border.top + border.bottom + padding.top + padding.bottom); + } + item.setCalculatedSize(undefined, box.height - item.el.getMargin('tb'), owner); + + + + if (!Ext.supports.ComputedStyle) { + item.el.repaint(); } } } + else { + item.doComponentLayout(); + box.width = item.getWidth() - (box.offsets.left + box.offsets.right); + box.height = item.getHeight() - (box.offsets.bottom + box.offsets.top); + box.y += box.offsets.top; + if (horizontal) { + box.x = (item.align == 'right') ? bodyBox.width - box.width : bodyBox.x; + box.x += box.offsets.left; + } + } + - map.disable(); - if (!config.disabled) { - map.enable(); + + if (box.width === undefined) { + box.width = item.getWidth() + item.el.getMargin('lr'); + } + if (box.height === undefined) { + box.height = item.getHeight() + item.el.getMargin('tb'); } - }, - - - handleEvent: function(map, event, handler){ - return handler.call(this, event); - }, - - - disabled: false, - - - defaultEventAction: "stopEvent", - - - forceKeyDown: false, - - - destroy: function(removeEl){ - this.map.destroy(removeEl); - delete this.map; - }, - - enable: function() { - this.map.enable(); - this.disabled = false; + return box; }, - disable: function() { - this.map.disable(); - this.disabled = true; - }, - - - setDisabled : function(disabled){ - this.map.setDisabled(disabled); - this.disabled = disabled; + getLayoutItems : function() { + var it = this.owner.getDockedItems(), + ln = it.length, + i = 0, + result = []; + for (; i < ln; i++) { + if (it[i].isVisible(true)) { + result.push(it[i]); + } + } + return result; }, - - - getKeyEvent: function(forceKeyDown){ - return (forceKeyDown || Ext.EventManager.useKeyDown) ? 'keydown' : 'keypress'; - } -}); - + + renderItems: function(items, target) { + var cns = target.dom.childNodes, + cnsLn = cns.length, + ln = items.length, + domLn = 0, + i, j, cn, item; -Ext.define('Ext.fx.Queue', { + + for (i = 0; i < cnsLn; i++) { + cn = Ext.get(cns[i]); + for (j = 0; j < ln; j++) { + item = items[j]; + if (item.rendered && (cn.id == item.el.id || cn.contains(item.el.id))) { + break; + } + } - requires: ['Ext.util.HashMap'], + if (j === ln) { + domLn++; + } + } - constructor: function() { - this.targets = Ext.create('Ext.util.HashMap'); - this.fxQueue = {}; - }, + + for (i = 0, j = 0; i < ln; i++, j++) { + item = items[i]; - - getFxDefaults: function(targetId) { - var target = this.targets.get(targetId); - if (target) { - return target.fxDefaults; - } - return {}; - }, + + + + + + + + + if (i === j && (item.dock === 'right' || item.dock === 'bottom')) { + j += domLn; + } - - setFxDefaults: function(targetId, obj) { - var target = this.targets.get(targetId); - if (target) { - target.fxDefaults = Ext.apply(target.fxDefaults || {}, obj); + + if (item && !item.rendered) { + this.renderItem(item, target, j); + } + else if (!this.isValidParent(item, target, j)) { + this.moveItem(item, target, j); + } } }, - stopAnimation: function(targetId) { + setBodyBox : function(box) { var me = this, - queue = me.getFxQueue(targetId), - ln = queue.length; - while (ln) { - queue[ln - 1].end(); - ln--; + owner = me.owner, + body = owner.body, + info = me.info, + bodyMargin = info.bodyMargin, + padding = info.padding, + border = info.border, + frameSize = me.frameSize; + + + if (owner.collapsed) { + return; + } + + if (Ext.isNumber(box.width)) { + box.width -= bodyMargin.left + bodyMargin.right; + } + + if (Ext.isNumber(box.height)) { + box.height -= bodyMargin.top + bodyMargin.bottom; + } + + me.setElementSize(body, box.width, box.height); + if (Ext.isNumber(box.x)) { + body.setLeft(box.x - padding.left - frameSize.left); + } + if (Ext.isNumber(box.y)) { + body.setTop(box.y - padding.top - frameSize.top); } }, - getActiveAnimation: function(targetId) { - var queue = this.getFxQueue(targetId); - return (queue && !!queue.length) ? queue[0] : false; - }, - - - hasFxBlock: function(targetId) { - var queue = this.getFxQueue(targetId); - return queue && queue[0] && queue[0].block; + 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); }, - - getFxQueue: function(targetId) { - if (!targetId) { - return false; + afterRemove : function(item) { + this.callParent(arguments); + if (this.itemCls) { + item.el.removeCls(this.itemCls + '-' + item.dock); } - var me = this, - queue = me.fxQueue[targetId], - target = me.targets.get(targetId); + var dom = item.el.dom; - if (!target) { - return false; + if (!item.destroying && dom) { + dom.parentNode.removeChild(dom); } + this.childrenChanged = true; + } +}); - if (!queue) { - me.fxQueue[targetId] = []; - - if (target.type != 'element') { - target.target.on('destroy', function() { - me.fxQueue[targetId] = []; - }); - } - } - return me.fxQueue[targetId]; - }, +Ext.define('Ext.util.Memento', function () { - - queueFx: function(anim) { - var me = this, - target = anim.target, - queue, ln; + function captureOne (src, target, prop) { + src[prop] = target[prop]; + } - if (!target) { - return; + 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); } + } - queue = me.getFxQueue(target.getId()); - ln = queue.length; + function restoreValue (target, prop, value) { + if (Ext.isDefined(value)) { + target[prop] = value; + } else { + delete target[prop]; + } + } - if (ln) { - if (anim.concurrent) { - anim.paused = false; - } - else { - queue[ln - 1].on('afteranimate', function() { - anim.paused = false; + 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); } } - else { - anim.paused = false; - } - anim.on('afteranimate', function() { - Ext.Array.remove(queue, anim); - if (anim.remove) { - if (target.type == 'element') { - var el = Ext.get(target.id); - if (el) { - el.remove(); - } - } - } - }, this); - queue.push(anim); } -}); - -Ext.define('Ext.fx.target.Target', { + return { + + data: null, - isAnimTarget: true, + + target: null, - constructor: function(target) { - this.target = target; - this.id = this.getId(); - }, - - getId: function() { - return this.target.id; - } -}); + + 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); + }, -Ext.define('Ext.fx.target.Sprite', { + + 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; - extend: 'Ext.fx.target.Target', + Ext.Object.each(me.data, function (prop, value) { + restoreValue(t, prop, value); + }); - + if (clear !== false) { + delete me.data; + } + } + }; +}()); - type: 'draw', - getFromPrim: function(sprite, attr) { - var o; - if (attr == 'translate') { - o = { - x: sprite.attr.translation.x || 0, - y: sprite.attr.translation.y || 0 - }; - } - else if (attr == 'rotate') { - o = { - degrees: sprite.attr.rotation.degrees || 0, - x: sprite.attr.rotation.x, - y: sprite.attr.rotation.y - }; - } - else { - o = sprite.attr[attr]; - } - return o; +Ext.define('Ext.app.EventBus', { + requires: [ + 'Ext.util.Event' + ], + mixins: { + observable: 'Ext.util.Observable' }, - getAttr: function(attr, val) { - return [[this.target, val != undefined ? val : this.getFromPrim(this.target, attr)]]; - }, + constructor: function() { + this.mixins.observable.constructor.call(this); - setAttr: function(targetData) { - var ln = targetData.length, - spriteArr = [], - attrs, attr, attrArr, attPtr, spritePtr, idx, value, i, j, x, y, ln2; - for (i = 0; i < ln; i++) { - attrs = targetData[i].attrs; - for (attr in attrs) { - attrArr = attrs[attr]; - ln2 = attrArr.length; - for (j = 0; j < ln2; j++) { - spritePtr = attrArr[j][0]; - attPtr = attrArr[j][1]; - if (attr === 'translate') { - value = { - x: attPtr.x, - y: attPtr.y - }; - } - else if (attr === 'rotate') { - x = attPtr.x; - if (isNaN(x)) { - x = null; - } - y = attPtr.y; - if (isNaN(y)) { - y = null; + this.bus = {}; + + var me = this; + Ext.override(Ext.Component, { + fireEvent: function(ev) { + if (Ext.util.Observable.prototype.fireEvent.apply(this, arguments) !== false) { + return me.dispatch.call(me, ev, this, arguments); + } + return false; + } + }); + }, + + dispatch: function(ev, target, args) { + var bus = this.bus, + selectors = bus[ev], + selector, controllers, id, events, event, i, ln; + + if (selectors) { + + for (selector in selectors) { + + if (target.is(selector)) { + + controllers = selectors[selector]; + for (id in controllers) { + + events = controllers[id]; + for (i = 0, ln = events.length; i < ln; i++) { + event = events[i]; + + if (event.fire.apply(event, Array.prototype.slice.call(args, 1)) === false) { + return false; + }; } - value = { - degrees: attPtr.degrees, - x: x, - y: y - }; - } - else if (attr === 'width' || attr === 'height' || attr === 'x' || attr === 'y') { - value = parseFloat(attPtr); - } - else { - value = attPtr; - } - idx = Ext.Array.indexOf(spriteArr, spritePtr); - if (idx == -1) { - spriteArr.push([spritePtr, {}]); - idx = spriteArr.length - 1; } - spriteArr[idx][1][attr] = value; } } } - ln = spriteArr.length; - for (i = 0; i < ln; i++) { - spritePtr = spriteArr[i]; - spritePtr[0].setAttributes(spritePtr[1]); - } - this.target.redraw(); - } -}); + }, + control: function(selectors, listeners, controller) { + var bus = this.bus, + selector, fn; + if (Ext.isString(selectors)) { + selector = selectors; + selectors = {}; + selectors[selector] = listeners; + this.control(selectors, null, controller); + return; + } -Ext.define('Ext.fx.target.CompositeSprite', { + Ext.Object.each(selectors, function(selector, listeners) { + Ext.Object.each(listeners, function(ev, listener) { + var options = {}, + scope = controller, + event = Ext.create('Ext.util.Event', controller, ev); - + + if (Ext.isObject(listener)) { + options = listener; + listener = options.fn; + scope = options.scope || controller; + delete options.fn; + delete options.scope; + } - extend: 'Ext.fx.target.Sprite', + 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] || []; - getAttr: function(attr, val) { - var out = [], - target = this.target; - target.each(function(sprite) { - out.push([sprite, val != undefined ? val : this.getFromPrim(sprite, attr)]); - }, this); - return out; + + bus[ev][selector][controller.id].push(event); + }); + }); } }); +Ext.define('Ext.data.Types', { + singleton: true, + requires: ['Ext.data.SortTypes'] +}, function() { + var st = Ext.data.SortTypes; -Ext.define('Ext.fx.target.Component', { - - - - extend: 'Ext.fx.target.Target', - - - - type: 'component', + Ext.apply(Ext.data.Types, { + + stripRe: /[\$,%]/g, - - getPropMethod: { - top: function() { - return this.getPosition(true)[1]; - }, - left: function() { - return this.getPosition(true)[0]; - }, - x: function() { - return this.getPosition()[0]; + + AUTO: { + convert: function(v) { + return v; + }, + sortType: st.none, + type: 'auto' }, - y: function() { - return this.getPosition()[1]; + + + STRING: { + convert: function(v) { + var defaultValue = this.useNull ? null : ''; + return (v === undefined || v === null) ? defaultValue : String(v); + }, + sortType: st.asUCString, + type: 'string' }, - height: function() { - return this.getHeight(); + + + INT: { + convert: function(v) { + return v !== undefined && v !== null && v !== '' ? + parseInt(String(v).replace(Ext.data.Types.stripRe, ''), 10) : (this.useNull ? null : 0); + }, + sortType: st.none, + type: 'int' }, - width: function() { - return this.getWidth(); + + + FLOAT: { + convert: function(v) { + return v !== undefined && v !== null && v !== '' ? + parseFloat(String(v).replace(Ext.data.Types.stripRe, ''), 10) : (this.useNull ? null : 0); + }, + sortType: st.none, + type: 'float' }, - opacity: function() { - return this.el.getStyle('opacity'); - } - }, - compMethod: { - top: 'setPosition', - left: 'setPosition', - x: 'setPagePosition', - y: 'setPagePosition', - height: 'setSize', - width: 'setSize', - opacity: 'setOpacity' - }, + + BOOL: { + convert: function(v) { + if (this.useNull && (v === undefined || v === null || v === '')) { + return null; + } + return v === true || v === 'true' || v == 1; + }, + sortType: st.none, + type: 'bool' + }, - - getAttr: function(attr, val) { - return [[this.target, val !== undefined ? val : this.getPropMethod[attr].call(this.target)]]; - }, + + DATE: { + convert: function(v) { + var df = this.dateFormat, + parsed; - setAttr: function(targetData, isFirstFrame, isLastFrame) { - var me = this, - target = me.target, - ln = targetData.length, - attrs, attr, o, i, j, meth, targets, left, top, w, h; - for (i = 0; i < ln; i++) { - attrs = targetData[i].attrs; - for (attr in attrs) { - targets = attrs[attr].length; - meth = { - setPosition: {}, - setPagePosition: {}, - setSize: {}, - setOpacity: {} - }; - for (j = 0; j < targets; j++) { - o = attrs[attr][j]; - - - - - meth[me.compMethod[attr]].target = o[0]; - meth[me.compMethod[attr]][attr] = o[1]; - } - if (meth.setPosition.target) { - o = meth.setPosition; - left = (o.left === undefined) ? undefined : parseInt(o.left, 10); - top = (o.top === undefined) ? undefined : parseInt(o.top, 10); - o.target.setPosition(left, top); + if (!v) { + return null; } - if (meth.setPagePosition.target) { - o = meth.setPagePosition; - o.target.setPagePosition(o.x, o.y); + if (Ext.isDate(v)) { + return v; } - if (meth.setSize.target) { - o = meth.setSize; - - w = (o.width === undefined) ? o.target.getWidth() : parseInt(o.width, 10); - h = (o.height === undefined) ? o.target.getHeight() : parseInt(o.height, 10); - - - - - - - - - if (isLastFrame || me.dynamic) { - o.target.componentLayout.childrenChanged = true; - - - if (me.layoutAnimation) { - o.target.setCalculatedSize(w, h); - } else { - o.target.setSize(w, h); - } + if (df) { + if (df == 'timestamp') { + return new Date(v*1000); } - else { - o.target.el.setSize(w, h); + if (df == 'time') { + return new Date(parseInt(v, 10)); } + return Ext.Date.parse(v, df); } - if (meth.setOpacity.target) { - o = meth.setOpacity; - o.target.el.setStyle('opacity', o.opacity); - } - } + + parsed = Date.parse(v); + return parsed ? new Date(parsed) : null; + }, + sortType: st.asDate, + type: 'date' } - } -}); + }); + Ext.apply(Ext.data.Types, { + + BOOLEAN: this.BOOL, -Ext.define('Ext.fx.CubicBezier', { + + INTEGER: this.INT, - + + NUMBER: this.FLOAT + }); +}); - singleton: true, +Ext.define('Ext.data.Field', { + requires: ['Ext.data.Types', 'Ext.data.SortTypes'], + alias: 'data.field', - - cubicBezierAtTime: function(t, p1x, p1y, p2x, p2y, duration) { - var cx = 3 * p1x, - bx = 3 * (p2x - p1x) - cx, - ax = 1 - cx - bx, - cy = 3 * p1y, - by = 3 * (p2y - p1y) - cy, - ay = 1 - cy - by; - function sampleCurveX(t) { - return ((ax * t + bx) * t + cx) * t; - } - function solve(x, epsilon) { - var t = solveCurveX(x, epsilon); - return ((ay * t + by) * t + cy) * t; + constructor : function(config) { + if (Ext.isString(config)) { + config = {name: config}; } - function solveCurveX(x, epsilon) { - var t0, t1, t2, x2, d2, i; - for (t2 = x, i = 0; i < 8; i++) { - x2 = sampleCurveX(t2) - x; - if (Math.abs(x2) < epsilon) { - return t2; - } - d2 = (3 * ax * t2 + 2 * bx) * t2 + cx; - if (Math.abs(d2) < 1e-6) { - break; - } - t2 = t2 - x2 / d2; - } - t0 = 0; - t1 = 1; - t2 = x; - if (t2 < t0) { - return t0; - } - if (t2 > t1) { - return t1; - } - while (t0 < t1) { - x2 = sampleCurveX(t2); - if (Math.abs(x2 - x) < epsilon) { - return t2; - } - if (x > x2) { - t0 = t2; - } else { - t1 = t2; - } - t2 = (t1 - t0) / 2 + t0; + Ext.apply(this, config); + + var types = Ext.data.Types, + st = this.sortType, + t; + + if (this.type) { + if (Ext.isString(this.type)) { + this.type = types[this.type.toUpperCase()] || types.AUTO; } - return t2; + } else { + this.type = types.AUTO; } - return solve(t, 1 / (200 * duration)); - }, - - cubicBezier: function(x1, y1, x2, y2) { - var fn = function(pos) { - return Ext.fx.CubicBezier.cubicBezierAtTime(pos, x1, y1, x2, y2, 1); - }; - fn.toCSS3 = function() { - return 'cubic-bezier(' + [x1, y1, x2, y2].join(',') + ')'; - }; - fn.reverse = function() { - return Ext.fx.CubicBezier.cubicBezier(1 - x2, 1 - y2, 1 - x1, 1 - y1); - }; - return fn; - } -}); -Ext.define('Ext.draw.Color', { + + if (Ext.isString(st)) { + this.sortType = Ext.data.SortTypes[st]; + } else if(Ext.isEmpty(st)) { + this.sortType = this.type.sortType; + } + if (!this.convert) { + this.convert = this.type.convert; + } + }, + + + + - - colorToHexRe: /(.*?)rgb\((\d+),\s*(\d+),\s*(\d+)\)/, - rgbRe: /\s*rgb\s*\(\s*([0-9]+)\s*,\s*([0-9]+)\s*,\s*([0-9]+)\s*\)\s*/, - hexRe: /\s*#([0-9a-fA-F][0-9a-fA-F]?)([0-9a-fA-F][0-9a-fA-F]?)([0-9a-fA-F][0-9a-fA-F]?)\s*/, + + dateFormat: null, + + + useNull: false, + + + defaultValue: "", - lightnessFactor: 0.2, + mapping: null, - constructor : function(red, green, blue) { - var me = this, - clamp = Ext.Number.constrain; - me.r = clamp(red, 0, 255); - me.g = clamp(green, 0, 255); - me.b = clamp(blue, 0, 255); - }, + sortType : null, - getRed: function() { - return this.r; - }, + sortDir : "ASC", - getGreen: function() { - return this.g; - }, + allowBlank : true, - getBlue: function() { - return this.b; + persist: true +}); + + +Ext.define('Ext.util.AbstractMixedCollection', { + requires: ['Ext.util.Filter'], + + mixins: { + observable: 'Ext.util.Observable' }, - - getRGB: function() { + constructor: function(allowFunctions, keyFn) { var me = this; - return [me.r, me.g, me.b]; - }, - - getHSL: function() { - var me = this, - r = me.r / 255, - g = me.g / 255, - b = me.b / 255, - max = Math.max(r, g, b), - min = Math.min(r, g, b), - delta = max - min, - h, - s = 0, - l = 0.5 * (max + min); + me.items = []; + me.map = {}; + me.keys = []; + me.length = 0; - - if (min != max) { - s = (l < 0.5) ? delta / (max + min) : delta / (2 - max - min); - if (r == max) { - h = 60 * (g - b) / delta; - } else if (g == max) { - h = 120 + 60 * (b - r) / delta; - } else { - h = 240 + 60 * (r - g) / delta; - } - if (h < 0) { - h += 360; - } - if (h >= 360) { - h -= 360; - } + me.addEvents( + + 'clear', + + + 'add', + + + 'replace', + + + 'remove' + ); + + me.allowFunctions = allowFunctions === true; + + if (keyFn) { + me.getKey = keyFn; } - return [h, s, l]; + + me.mixins.observable.constructor.call(me); }, - getLighter: function(factor) { - var hsl = this.getHSL(); - factor = factor || this.lightnessFactor; - hsl[2] = Ext.Number.constrain(hsl[2] + factor, 0, 1); - return this.fromHSL(hsl[0], hsl[1], hsl[2]); - }, + allowFunctions : false, - getDarker: function(factor) { - factor = factor || this.lightnessFactor; - return this.getLighter(-factor); + add : function(key, obj){ + var me = this, + myObj = obj, + myKey = key, + old; + + 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); + } + me.map[myKey] = myObj; + } + me.length++; + me.items.push(myObj); + me.keys.push(myKey); + me.fireEvent('add', me.length - 1, myObj, myKey); + return myObj; }, - toString: function() { - var me = this, - round = Math.round, - r = round(me.r).toString(16), - g = round(me.g).toString(16), - b = round(me.b).toString(16); - r = (r.length == 1) ? '0' + r : r; - g = (g.length == 1) ? '0' + g : g; - b = (b.length == 1) ? '0' + b : b; - return ['#', r, g, b].join(''); + getKey : function(o){ + return o.id; }, - toHex: function(color) { - if (Ext.isArray(color)) { - color = color[0]; - } - if (!Ext.isString(color)) { - return ''; - } - if (color.substr(0, 1) === '#') { - return color; - } - var digits = this.colorToHexRe.exec(color); + replace : function(key, o){ + var me = this, + old, + index; - if (Ext.isArray(digits)) { - var red = parseInt(digits[2], 10), - green = parseInt(digits[3], 10), - blue = parseInt(digits[4], 10), - rgb = blue | (green << 8) | (red << 16); - return digits[1] + '#' + ("000000" + rgb.toString(16)).slice(-6); + if (arguments.length == 1) { + o = arguments[0]; + key = me.getKey(o); } - else { - return ''; + 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; }, - fromString: function(str) { - var values, r, g, b, - parse = parseInt; + addAll : function(objs){ + var me = this, + i = 0, + args, + len, + key; - if ((str.length == 4 || str.length == 7) && str.substr(0, 1) === '#') { - values = str.match(this.hexRe); - if (values) { - r = parse(values[1], 16) >> 0; - g = parse(values[2], 16) >> 0; - b = parse(values[3], 16) >> 0; - if (str.length == 4) { - r += (r * 16); - g += (g * 16); - b += (b * 16); - } + 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 { - values = str.match(this.rgbRe); - if (values) { - r = values[1]; - g = values[2]; - b = values[3]; + } else { + for (key in objs) { + if (objs.hasOwnProperty(key)) { + if (me.allowFunctions || typeof objs[key] != 'function') { + me.add(key, objs[key]); + } + } } } - - return (typeof r == 'undefined') ? undefined : Ext.create('Ext.draw.Color', r, g, b); - }, - - - getGrayscale: function() { - - return this.r * 0.3 + this.g * 0.59 + this.b * 0.11; }, - fromHSL: function(h, s, l) { - var C, X, m, i, rgb = [], - abs = Math.abs, - floor = Math.floor; + each : function(fn, scope){ + var items = [].concat(this.items), + i = 0, + len = items.length, + item; - if (s == 0 || h == null) { - - rgb = [l, l, l]; - } - else { - - - - - h /= 60; - C = s * (1 - abs(2 * l - 1)); - X = C * (1 - abs(h - 2 * floor(h / 2) - 1)); - m = l - C / 2; - switch (floor(h)) { - case 0: - rgb = [C, X, 0]; - break; - case 1: - rgb = [X, C, 0]; - break; - case 2: - rgb = [0, C, X]; - break; - case 3: - rgb = [0, X, C]; - break; - case 4: - rgb = [X, 0, C]; - break; - case 5: - rgb = [C, 0, X]; - break; + for (; i < len; i++) { + item = items[i]; + if (fn.call(scope || item, item, i, len) === false) { + break; } - rgb = [rgb[0] + m, rgb[1] + m, rgb[2] + m]; } - return Ext.create('Ext.draw.Color', rgb[0] * 255, rgb[1] * 255, rgb[2] * 255); - } -}, function() { - var prototype = this.prototype; + }, - this.addStatics({ - fromHSL: function() { - return prototype.fromHSL.apply(prototype, arguments); - }, - fromString: function() { - return prototype.fromString.apply(prototype, arguments); - }, - toHex: function() { - return prototype.toHex.apply(prototype, arguments); - } - }); -}); - - -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, - id: this.id, - html: '
' + - '
', - cls: Ext.baseCSSPrefix + 'dd-drag-proxy ' + this.dropNotAllowed, - shadow: !config || config.shadow !== false, - renderTo: document.body - }); - - this.el = this.proxy.el; - this.el.show(); - this.el.setVisibilityMode(Ext.core.Element.VISIBILITY); - this.el.hide(); + eachKey : function(fn, scope){ + var keys = this.keys, + items = this.items, + i = 0, + len = keys.length; - this.ghost = Ext.get(this.el.dom.childNodes[1]); - this.dropStatus = this.dropNotAllowed; + for (; i < len; i++) { + fn.call(scope || window, keys[i], items[i], i, len); + } }, - - dropAllowed : Ext.baseCSSPrefix + 'dd-drop-ok', - - dropNotAllowed : Ext.baseCSSPrefix + 'dd-drop-nodrop', - setStatus : function(cssClass){ - cssClass = cssClass || this.dropNotAllowed; - if(this.dropStatus != cssClass){ - this.el.replaceCls(this.dropStatus, cssClass); - this.dropStatus = cssClass; + findBy : function(fn, scope) { + var keys = this.keys, + items = this.items, + i = 0, + len = items.length; + + for (; i < len; i++) { + if (fn.call(scope || window, items[i], keys[i])) { + return items[i]; + } } + return null; }, - - reset : function(clearGhost){ - this.el.dom.className = Ext.baseCSSPrefix + 'dd-drag-proxy ' + this.dropNotAllowed; - this.dropStatus = this.dropNotAllowed; - if(clearGhost){ - this.ghost.update(""); + 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); }, - update : function(html){ - if(typeof html == "string"){ - this.ghost.update(html); - }else{ - this.ghost.update(""); - html.style.margin = "0"; - this.ghost.dom.appendChild(html); + insert : function(index, key, obj){ + var me = this, + myKey = key, + myObj = obj; + + if (arguments.length == 2) { + myObj = myKey; + myKey = me.getKey(myObj); } - var el = this.ghost.dom.firstChild; - if(el){ - Ext.fly(el).setStyle('float', 'none'); + 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; }, - getEl : function(){ - return this.el; + remove : function(o){ + return this.removeAt(this.indexOf(o)); }, - getGhost : function(){ - return this.ghost; - }, + removeAll : function(items){ + Ext.each(items || [], function(item) { + this.remove(item); + }, this); - - hide : function(clear) { - this.proxy.hide(); - if (clear) { - this.reset(true); - } + return this; }, - stop : function(){ - if(this.anim && this.anim.isAnimated && this.anim.isAnimated()){ - this.anim.stop(); + removeAt : function(index){ + var me = this, + o, + key; + + 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 false; }, - show : function() { - this.proxy.show(); - this.proxy.toFront(); + removeAtKey : function(key){ + return this.removeAt(this.indexOfKey(key)); }, - sync : function(){ - this.proxy.el.sync(); + getCount : function(){ + return this.length; }, - repair : function(xy, callback, scope){ - this.callback = callback; - this.scope = scope; - if (xy && this.animRepair !== false) { - this.el.addCls(Ext.baseCSSPrefix + 'dd-drag-repair'); - this.el.hideUnders(true); - this.anim = this.el.animate({ - duration: this.repairDuration || 500, - easing: 'ease-out', - to: { - x: xy[0], - y: xy[1] - }, - stopAnimation: true, - callback: this.afterRepair, - scope: this - }); - } else { - this.afterRepair(); - } + indexOf : function(o){ + return Ext.Array.indexOf(this.items, o); }, - afterRepair : function(){ - this.hide(true); - if(typeof this.callback == "function"){ - this.callback.call(this.scope || this); - } - this.callback = null; - this.scope = null; + indexOfKey : function(key){ + return Ext.Array.indexOf(this.keys, key); }, - destroy: function(){ - Ext.destroy(this.ghost, this.proxy, this.el); - } -}); - -Ext.define('Ext.panel.Proxy', { - - alternateClassName: 'Ext.dd.PanelProxy', - constructor: function(panel, config){ - - this.panel = panel; - this.id = this.panel.id +'-ddproxy'; - Ext.apply(this, config); + 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; }, - insertProxy: true, - - - setStatus: Ext.emptyFn, - reset: Ext.emptyFn, - update: Ext.emptyFn, - stop: Ext.emptyFn, - sync: Ext.emptyFn, + getAt : function(index) { + return this.items[index]; + }, - getEl: function(){ - return this.ghost.el; + getByKey : function(key) { + return this.map[key]; }, - getGhost: function(){ - return this.ghost; + contains : function(o){ + return Ext.Array.contains(this.items, o); }, - getProxy: function(){ - return this.proxy; + containsKey : function(key){ + return typeof this.map[key] != 'undefined'; }, - hide : function(){ - if (this.ghost) { - if (this.proxy) { - this.proxy.remove(); - delete this.proxy; - } + clear : function(){ + var me = this; - - this.panel.unghost(null, false); - delete this.ghost; - } + me.length = 0; + me.items = []; + me.keys = []; + me.map = {}; + me.fireEvent('clear'); }, - show: function(){ - if (!this.ghost) { - var panelSize = this.panel.getSize(); - this.panel.el.setVisibilityMode(Ext.core.Element.DISPLAY); - this.ghost = this.panel.ghost(); - if (this.insertProxy) { - - - this.proxy = this.panel.el.insertSibling({cls: Ext.baseCSSPrefix + 'panel-dd-spacer'}); - this.proxy.setSize(panelSize); - } - } + first : function() { + return this.items[0]; }, - repair: function(xy, callback, scope) { - this.hide(); - if (typeof callback == "function") { - callback.call(scope || this); - } + last : function() { + return this.items[this.length - 1]; }, - moveProxy : function(parentNode, before){ - if (this.proxy) { - parentNode.insertBefore(this.proxy.dom, before); - } - } -}); - - -Ext.define('Ext.layout.component.AbstractDock', { - - - - extend: 'Ext.layout.component.Component', - - - - type: 'dock', + sum: function(property, root, start, end) { + var values = this.extractValues(property, root), + length = values.length, + sum = 0, + i; - - autoSizing: true, + start = start || 0; + end = (end || end === 0) ? end : length - 1; - beforeLayout: function() { - var returnValue = this.callParent(arguments); - if (returnValue !== false && (!this.initializedBorders || this.childrenChanged) && (!this.owner.border || this.owner.manageBodyBorders)) { - this.handleItemBorders(); - this.initializedBorders = true; + for (i = start; i <= end; i++) { + sum += values[i]; } - return returnValue; - }, - - handleItemBorders: function() { - var owner = this.owner, - body = owner.body, - docked = this.getLayoutItems(), - borders = { - top: [], - right: [], - bottom: [], - left: [] - }, - oldBorders = this.borders, - opposites = { - top: 'bottom', - right: 'left', - bottom: 'top', - left: 'right' - }, - i, ln, item, dock, side; - for (i = 0, ln = docked.length; i < ln; i++) { - item = docked[i]; - dock = item.dock; - - if (item.ignoreBorderManagement) { - continue; - } - - if (!borders[dock].satisfied) { - borders[dock].push(item); - borders[dock].satisfied = true; - } - - if (!borders.top.satisfied && opposites[dock] !== 'top') { - borders.top.push(item); - } - if (!borders.right.satisfied && opposites[dock] !== 'right') { - borders.right.push(item); - } - if (!borders.bottom.satisfied && opposites[dock] !== 'bottom') { - borders.bottom.push(item); - } - if (!borders.left.satisfied && opposites[dock] !== 'left') { - borders.left.push(item); - } - } + return sum; + }, - if (oldBorders) { - for (side in oldBorders) { - if (oldBorders.hasOwnProperty(side)) { - ln = oldBorders[side].length; - if (!owner.manageBodyBorders) { - for (i = 0; i < ln; i++) { - oldBorders[side][i].removeCls(Ext.baseCSSPrefix + 'docked-noborder-' + side); - } - if (!oldBorders[side].satisfied && !owner.bodyBorder) { - body.removeCls(Ext.baseCSSPrefix + 'docked-noborder-' + side); - } - } - else if (oldBorders[side].satisfied) { - body.setStyle('border-' + side + '-width', ''); - } - } - } - } - - for (side in borders) { - if (borders.hasOwnProperty(side)) { - ln = borders[side].length; - if (!owner.manageBodyBorders) { - for (i = 0; i < ln; i++) { - borders[side][i].addCls(Ext.baseCSSPrefix + 'docked-noborder-' + side); - } - if ((!borders[side].satisfied && !owner.bodyBorder) || owner.bodyBorder === false) { - body.addCls(Ext.baseCSSPrefix + 'docked-noborder-' + side); - } - } - else if (borders[side].satisfied) { - body.setStyle('border-' + side + '-width', '1px'); - } + + 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.borders = borders; + + return unique; }, + + extractValues: function(property, root) { + var values = this.items; + + if (root) { + values = Ext.Array.pluck(values, root); + } + + return Ext.Array.pluck(values, property); + }, + - onLayout: function(width, height) { + getRange : function(start, end){ var me = this, - owner = me.owner, - body = owner.body, - layout = owner.layout, - target = me.getTarget(), - autoWidth = false, - autoHeight = false, - padding, border, frameSize; - - - var info = me.info = { - boxes: [], - size: { - width: width, - height: height - }, - bodyBox: {} - }; + items = me.items, + range = [], + i; - Ext.applyIf(info, me.getTargetInfo()); + if (items.length < 1) { + return range; + } - - if (owner && owner.ownerCt && owner.ownerCt.layout && owner.ownerCt.layout.isLayout) { - if (!Ext.isNumber(owner.height) || !Ext.isNumber(owner.width)) { - owner.ownerCt.layout.bindToOwnerCtComponent = true; + 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 { - owner.ownerCt.layout.bindToOwnerCtComponent = false; + } else { + for (i = start; i >= end; i--) { + range[range.length] = items[i]; } } + return range; + }, + + + filter : function(property, value, anyMatch, caseSensitive) { + var filters = [], + filterFn; - if (height === undefined || height === null || width === undefined || width === null) { - padding = info.padding; - border = info.border; - frameSize = me.frameSize; + 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 ((height === undefined || height === null) && (width === undefined || width === null)) { - autoHeight = true; - autoWidth = true; - me.setTargetSize(null); - me.setBodyBox({width: null, height: null}); - } - - else if (height === undefined || height === null) { - autoHeight = true; - - me.setTargetSize(width); - me.setBodyBox({width: width - padding.left - border.left - padding.right - border.right - frameSize.left - frameSize.right, height: null}); - - } - else { - autoWidth = true; - - me.setTargetSize(null, height); - me.setBodyBox({width: null, height: height - padding.top - padding.bottom - border.top - border.bottom - frameSize.top - frameSize.bottom}); - } + + + filterFn = function(record) { + var isMatch = true, + length = filters.length, + i; - - if (layout && layout.isLayout) { - - layout.bindToOwnerCtComponent = true; - layout.layout(); + for (i = 0; i < length; i++) { + var filter = filters[i], + fn = filter.filterFn, + scope = filter.scope; - - - - - - - - - - - - - info.autoSizedCtLayout = layout.autoSize === true; + isMatch = isMatch && fn.call(scope, record); } - - - - - - me.dockItems(autoWidth, autoHeight); - me.setTargetSize(info.size.width, info.size.height); - } - else { - me.setTargetSize(width, height); - me.dockItems(); - } - me.callParent(arguments); + return isMatch; + }; + + return this.filterBy(filterFn); }, - dockItems : function(autoWidth, autoHeight) { - this.calculateDockBoxes(autoWidth, autoHeight); + filterBy : function(fn, scope) { + var me = this, + newMC = new this.self(), + keys = me.keys, + items = me.items, + length = items.length, + i; - - - - var info = this.info, - boxes = info.boxes, - ln = boxes.length, - dock, i; + newMC.getKey = me.getKey; - - - for (i = 0; i < ln; i++) { - dock = boxes[i]; - dock.item.setPosition(dock.x, dock.y); - if ((autoWidth || autoHeight) && dock.layout && dock.layout.isLayout) { - - dock.layout.bindToOwnerCtComponent = true; + for (i = 0; i < length; i++) { + if (fn.call(scope || me, items[i], keys[i])) { + newMC.add(keys[i], items[i]); } } - - - if (!info.autoSizedCtLayout) { - if (autoWidth) { - info.bodyBox.width = null; - } - if (autoHeight) { - info.bodyBox.height = null; - } - } + return newMC; + }, - - - this.setBodyBox(info.bodyBox); + + 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); }, - calculateDockBoxes : function(autoWidth, autoHeight) { - - - + findIndexBy : function(fn, scope, start){ var me = this, - target = me.getTarget(), - items = me.getLayoutItems(), - owner = me.owner, - bodyEl = owner.body, - info = me.info, - size = info.size, - ln = items.length, - padding = info.padding, - border = info.border, - frameSize = me.frameSize, - item, i, box, rect; + keys = me.keys, + items = me.items, + i = start || 0, + len = items.length; - - - if (autoHeight) { - size.height = bodyEl.getHeight() + padding.top + border.top + padding.bottom + border.bottom + frameSize.top + frameSize.bottom; - } - else { - size.height = target.getHeight(); - } - if (autoWidth) { - size.width = bodyEl.getWidth() + padding.left + border.left + padding.right + border.right + frameSize.left + frameSize.right; - } - else { - size.width = target.getWidth(); + for (; i < len; i++) { + if (fn.call(scope || me, items[i], keys[i])) { + return i; + } } + return -1; + }, - info.bodyBox = { - x: padding.left + frameSize.left, - y: padding.top + frameSize.top, - width: size.width - padding.left - border.left - padding.right - border.right - frameSize.left - frameSize.right, - height: size.height - border.top - padding.top - border.bottom - padding.bottom - frameSize.top - frameSize.bottom - }; - - - for (i = 0; i < ln; i++) { - item = items[i]; - - - - box = me.initBox(item); + + createValueMatcher : function(value, anyMatch, caseSensitive, exactMatch) { + if (!value.exec) { + var er = Ext.String.escapeRegex; + value = String(value); - if (autoHeight === true) { - box = me.adjustAutoBox(box, i); - } - else { - box = me.adjustSizedBox(box, i); + if (anyMatch === true) { + value = er(value); + } else { + value = '^' + er(value); + if (exactMatch === true) { + value += '$'; + } } - - - - - info.boxes.push(box); + value = new RegExp(value, caseSensitive ? '' : 'i'); } + return value; }, - adjustSizedBox : function(box, index) { - var bodyBox = this.info.bodyBox, - frameSize = this.frameSize, - info = this.info, - padding = info.padding, - pos = box.type, - border = info.border; + clone : function() { + var me = this, + copy = new this.self(), + keys = me.keys, + items = me.items, + i = 0, + len = items.length; - switch (pos) { - case 'top': - box.y = bodyBox.y; - break; + for(; i < len; i++){ + copy.add(keys[i], items[i]); + } + copy.getKey = me.getKey; + return copy; + } +}); - case 'left': - box.x = bodyBox.x; - break; - case 'bottom': - box.y = (bodyBox.y + bodyBox.height) - box.height; - break; +Ext.define("Ext.util.Sortable", { + + isSortable: true, - case 'right': - box.x = (bodyBox.x + bodyBox.width) - box.width; - break; - } + + defaultSortDirection: "ASC", - if (box.ignoreFrame) { - if (pos == 'bottom') { - box.y += (frameSize.bottom + padding.bottom + border.bottom); - } - else { - box.y -= (frameSize.top + padding.top + border.top); - } - if (pos == 'right') { - box.x += (frameSize.right + padding.right + border.right); - } - else { - box.x -= (frameSize.left + padding.left + border.left); - } - } + requires: [ + 'Ext.util.Sorter' + ], - - if (!box.overlay) { - switch (pos) { - case 'top': - bodyBox.y += box.height; - bodyBox.height -= box.height; - break; + - case 'left': - bodyBox.x += box.width; - bodyBox.width -= box.width; - break; + + initSortable: function() { + var me = this, + sorters = me.sorters; - case 'bottom': - bodyBox.height -= box.height; - break; + + me.sorters = Ext.create('Ext.util.AbstractMixedCollection', false, function(item) { + return item.id || item.property; + }); - case 'right': - bodyBox.width -= box.width; - break; - } + if (sorters) { + me.sorters.addAll(me.decodeSorters(sorters)); } - return box; }, - adjustAutoBox : function (box, index) { - var info = this.info, - bodyBox = info.bodyBox, - size = info.size, - boxes = info.boxes, - boxesLn = boxes.length, - pos = box.type, - frameSize = this.frameSize, - padding = info.padding, - border = info.border, - autoSizedCtLayout = info.autoSizedCtLayout, - ln = (boxesLn < index) ? boxesLn : index, - i, adjustBox; + sort: function(sorters, direction, where, doSort) { + var me = this, + sorter, sorterFn, + newSorters; - if (pos == 'top' || pos == 'bottom') { - - for (i = 0; i < ln; i++) { - adjustBox = boxes[i]; - if (adjustBox.stretched && adjustBox.type == 'left' || adjustBox.type == 'right') { - adjustBox.height += box.height; - } - else if (adjustBox.type == 'bottom') { - adjustBox.y += box.height; - } - } + 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); - switch (pos) { - case 'top': - box.y = bodyBox.y; - if (!box.overlay) { - bodyBox.y += box.height; - } - size.height += box.height; - break; + if (!sorter) { + sorter = { + property : sorters, + direction: direction + }; + newSorters = [sorter]; + } + else if (direction === undefined) { + sorter.toggle(); + } + else { + sorter.setDirection(direction); + } + } - case 'bottom': - box.y = (bodyBox.y + bodyBox.height); - size.height += box.height; - break; + if (newSorters && newSorters.length) { + newSorters = me.decodeSorters(newSorters); + if (Ext.isString(where)) { + if (where === 'prepend') { + sorters = me.sorters.clone().items; - case 'left': - box.x = bodyBox.x; - if (!box.overlay) { - bodyBox.x += box.width; - if (autoSizedCtLayout) { - size.width += box.width; - } else { - bodyBox.width -= box.width; - } + me.sorters.clear(); + me.sorters.addAll(newSorters); + me.sorters.addAll(sorters); } - break; - - case 'right': - if (!box.overlay) { - if (autoSizedCtLayout) { - size.width += box.width; - } else { - bodyBox.width -= box.width; - } + else { + me.sorters.addAll(newSorters); } - box.x = (bodyBox.x + bodyBox.width); - break; - } - - if (box.ignoreFrame) { - if (pos == 'bottom') { - box.y += (frameSize.bottom + padding.bottom + border.bottom); } else { - box.y -= (frameSize.top + padding.top + border.top); - } - if (pos == 'right') { - box.x += (frameSize.right + padding.right + border.right); + me.sorters.clear(); + me.sorters.addAll(newSorters); } - else { - box.x -= (frameSize.left + padding.left + border.left); + } + + 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 box; + + return sorters; }, + onBeforeSort: Ext.emptyFn, + - initBox : function(item) { - var me = this, - bodyBox = me.info.bodyBox, - horizontal = (item.dock == 'top' || item.dock == 'bottom'), - owner = me.owner, - frameSize = me.frameSize, - info = me.info, - padding = info.padding, - border = info.border, - box = { - item: item, - overlay: item.overlay, - type: item.dock, - offsets: Ext.core.Element.parseBox(item.offsets || {}), - ignoreFrame: item.ignoreParentFrame - }; - - if (item.stretch !== false) { - box.stretched = true; - if (horizontal) { - box.x = bodyBox.x + box.offsets.left; - box.width = bodyBox.width - (box.offsets.left + box.offsets.right); - if (box.ignoreFrame) { - box.width += (frameSize.left + frameSize.right + border.left + border.right + padding.left + padding.right); - } - item.setCalculatedSize(box.width - item.el.getMargin('lr'), undefined, owner); + decodeSorters: function(sorters) { + if (!Ext.isArray(sorters)) { + if (sorters === undefined) { + sorters = []; + } else { + sorters = [sorters]; } - else { - box.y = bodyBox.y + box.offsets.top; - box.height = bodyBox.height - (box.offsets.bottom + box.offsets.top); - if (box.ignoreFrame) { - box.height += (frameSize.top + frameSize.bottom + border.top + border.bottom + padding.top + padding.bottom); + } + + 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; } - item.setCalculatedSize(undefined, box.height - item.el.getMargin('tb'), owner); + if (typeof config == 'function') { + config = { + sorterFn: config + }; + } + - if (!Ext.supports.ComputedStyle) { - item.el.repaint(); + if (fields && !config.transform) { + field = fields.get(config.property); + config.transform = field ? field.sortType : undefined; } - } - } - else { - item.doComponentLayout(); - box.width = item.getWidth() - (box.offsets.left + box.offsets.right); - box.height = item.getHeight() - (box.offsets.bottom + box.offsets.top); - box.y += box.offsets.top; - if (horizontal) { - box.x = (item.align == 'right') ? bodyBox.width - box.width : bodyBox.x; - box.x += box.offsets.left; + sorters[i] = Ext.create('Ext.util.Sorter', config); } } - - - if (box.width == undefined) { - box.width = item.getWidth() + item.el.getMargin('lr'); - } - if (box.height == undefined) { - box.height = item.getHeight() + item.el.getMargin('tb'); - } + return sorters; + }, - return box; + getSorters: function() { + return this.sorters.items; + } +}); + +Ext.define('Ext.util.MixedCollection', { + extend: 'Ext.util.AbstractMixedCollection', + mixins: { + sortable: 'Ext.util.Sortable' }, - getLayoutItems : function() { - var it = this.owner.getDockedItems(), - ln = it.length, - i = 0, - result = []; - for (; i < ln; i++) { - if (it[i].isVisible(true)) { - result.push(it[i]); - } - } - return result; + constructor: function() { + var me = this; + me.callParent(arguments); + me.addEvents('sort'); + me.mixins.sortable.initSortable.call(me); + }, + + doSort: function(sorterFn) { + this.sortBy(sorterFn); }, - renderItems: function(items, target) { - var cns = target.dom.childNodes, - cnsLn = cns.length, - ln = items.length, - domLn = 0, - i, j, cn, item; + _sort : function(property, dir, fn){ + var me = this, + i, len, + dsc = String(dir).toUpperCase() == 'DESC' ? -1 : 1, + + + c = [], + keys = me.keys, + items = me.items; - for (i = 0; i < cnsLn; i++) { - 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))) { - break; - } - } + fn = fn || function(a, b) { + return a - b; + }; - if (j === ln) { - domLn++; - } + + for(i = 0, len = items.length; i < len; i++){ + c[c.length] = { + key : keys[i], + value: items[i], + index: i + }; } - for (i = 0, j = 0; i < ln; i++, j++) { - item = items[i]; - - - - - - - - - - if (i === j && (item.dock === 'right' || item.dock === 'bottom')) { - j += domLn; + 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; + }); - - if (item && !item.rendered) { - this.renderItem(item, target, j); - } - else if (!this.isValidParent(item, target, j)) { - this.moveItem(item, target, j); - } + + for(i = 0, len = c.length; i < len; i++){ + items[i] = c[i].value; + keys[i] = c[i].key; } + + me.fireEvent('sort', me); }, - setBodyBox : function(box) { - var me = this, - owner = me.owner, - body = owner.body, - info = me.info, - bodyMargin = info.bodyMargin, - padding = info.padding, - border = info.border, - frameSize = me.frameSize; - - - if (owner.collapsed) { - return; - } + sortBy: function(sorterFn) { + var me = this, + items = me.items, + keys = me.keys, + length = items.length, + temp = [], + i; + - if (Ext.isNumber(box.width)) { - box.width -= bodyMargin.left + bodyMargin.right; + 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; + }); + - if (Ext.isNumber(box.height)) { - box.height -= bodyMargin.top + bodyMargin.bottom; + for (i = 0; i < length; i++) { + items[i] = temp[i].value; + keys[i] = temp[i].key; } - me.setElementSize(body, box.width, box.height); - if (Ext.isNumber(box.x)) { - body.setLeft(box.x - padding.left - frameSize.left); - } - if (Ext.isNumber(box.y)) { - body.setTop(box.y - padding.top - frameSize.top); - } + me.fireEvent('sort', me, items, keys); }, - configureItem : function(item, pos) { - this.callParent(arguments); - - item.addCls(Ext.baseCSSPrefix + 'docked'); - item.addClsWithUI('docked-' + item.dock); - }, + reorder: function(mapping) { + var me = this, + items = me.items, + index = 0, + length = items.length, + order = [], + remaining = [], + oldIndex; - afterRemove : function(item) { - this.callParent(arguments); - if (this.itemCls) { - item.el.removeCls(this.itemCls + '-' + item.dock); - } - var dom = item.el.dom; + me.suspendEvents(); - if (!item.destroying && dom) { - dom.parentNode.removeChild(dom); + + for (oldIndex in mapping) { + order[mapping[oldIndex]] = items[oldIndex]; } - this.childrenChanged = true; - } -}); -Ext.define('Ext.app.EventBus', { - requires: [ - 'Ext.util.Event' - ], - 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) { - if (Ext.util.Observable.prototype.fireEvent.apply(this, arguments) !== false) { - return me.dispatch.call(me, ev, this, arguments); - } - return false; + for (index = 0; index < length; index++) { + if (mapping[index] == undefined) { + remaining.push(items[index]); } - }); - }, + } - dispatch: function(ev, target, args) { - var bus = this.bus, - selectors = bus[ev], - selector, controllers, id, events, event, i, ln; - - if (selectors) { - - for (selector in selectors) { - - if (target.is(selector)) { - - controllers = selectors[selector]; - for (id in controllers) { - - events = controllers[id]; - for (i = 0, ln = events.length; i < ln; i++) { - event = events[i]; - - return event.fire.apply(event, Array.prototype.slice.call(args, 1)); - } - } - } + 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); }, - - control: function(selectors, listeners, controller) { - var bus = this.bus, - selector, fn; - - if (Ext.isString(selectors)) { - selector = selectors; - selectors = {}; - selectors[selector] = listeners; - this.control(selectors, null, controller); - return; - } - - Ext.Object.each(selectors, function(selector, listeners) { - Ext.Object.each(listeners, function(ev, listener) { - var options = {}, - scope = controller, - event = Ext.create('Ext.util.Event', controller, ev); - - - if (Ext.isObject(listener)) { - options = listener; - listener = options.fn; - scope = options.scope || controller; - 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].push(event); - }); + + 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.Types', { - singleton: true, - requires: ['Ext.data.SortTypes'] -}, function() { - var st = Ext.data.SortTypes; - - Ext.apply(Ext.data.Types, { - - stripRe: /[\$,%]/g, - - - AUTO: { - convert: function(v) { - return v; - }, - sortType: st.none, - type: 'auto' - }, - - STRING: { - convert: function(v) { - var defaultValue = this.useNull ? null : ''; - return (v === undefined || v === null) ? defaultValue : String(v); - }, - sortType: st.asUCString, - type: 'string' - }, +Ext.define('Ext.data.Errors', { + extend: 'Ext.util.MixedCollection', - - INT: { - convert: function(v) { - return v !== undefined && v !== null && v !== '' ? - parseInt(String(v).replace(Ext.data.Types.stripRe, ''), 10) : (this.useNull ? null : 0); - }, - sortType: st.none, - type: 'int' - }, - - - FLOAT: { - convert: function(v) { - return v !== undefined && v !== null && v !== '' ? - parseFloat(String(v).replace(Ext.data.Types.stripRe, ''), 10) : (this.useNull ? null : 0); - }, - sortType: st.none, - type: 'float' - }, - - - BOOL: { - convert: function(v) { - if (this.useNull && v === undefined || v === null || v === '') { - return null; - } - return v === true || v === 'true' || v == 1; - }, - sortType: st.none, - type: 'bool' - }, - - - DATE: { - convert: function(v) { - var df = this.dateFormat; - if (!v) { - return null; - } - if (Ext.isDate(v)) { - return v; - } - if (df) { - if (df == 'timestamp') { - return new Date(v*1000); - } - if (df == 'time') { - return new Date(parseInt(v, 10)); - } - return Ext.Date.parse(v, df); - } - - var 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 - }); -}); - + isValid: function() { + return this.length === 0; + }, -Ext.define('Ext.data.Field', { - requires: ['Ext.data.Types', 'Ext.data.SortTypes'], - alias: 'data.field', - constructor : function(config) { - if (Ext.isString(config)) { - config = {name: config}; - } - Ext.apply(this, config); - - var types = Ext.data.Types, - st = this.sortType, - t; + getByField: function(fieldName) { + var errors = [], + error, field, i; - if (this.type) { - if (Ext.isString(this.type)) { - this.type = types[this.type.toUpperCase()] || types.AUTO; - } - } else { - this.type = types.AUTO; - } + for (i = 0; i < this.length; i++) { + error = this.items[i]; - - if (Ext.isString(st)) { - this.sortType = Ext.data.SortTypes[st]; - } else if(Ext.isEmpty(st)) { - this.sortType = this.type.sortType; + if (error.field == fieldName) { + errors.push(error); + } } - if (!this.convert) { - this.convert = this.type.convert; - } - }, - - - - - - - - dateFormat: null, - - - useNull: false, - - - defaultValue: "", - - mapping: null, - - sortType : null, - - sortDir : "ASC", - - allowBlank : true, - - - persist: true + return errors; + } }); @@ -24943,6 +25117,7 @@ Ext.define('Ext.data.reader.Reader', { isReader: true, + constructor: function(config) { var me = this; @@ -25063,8 +25238,7 @@ Ext.define('Ext.data.reader.Reader', { id = me.getId(node); - record = new Model(values, id); - record.raw = node; + record = new Model(values, id, node); records.push(record); if (me.implicitIncludes) { @@ -25143,7 +25317,6 @@ Ext.define('Ext.data.reader.Reader', { getResponseData: function(response) { - Ext.Error.raise("getResponseData must be implemented in the Ext.data.reader.Reader subclass"); }, @@ -25254,14 +25427,14 @@ Ext.define('Ext.data.reader.Json', { extend: 'Ext.data.reader.Reader', alternateClassName: 'Ext.data.JsonReader', alias : 'reader.json', - + root: '', + - - + useSimpleAccessors: false, - + readRecords: function(data) { @@ -25276,8 +25449,9 @@ Ext.define('Ext.data.reader.Json', { getResponseData: function(response) { + var data; try { - var data = Ext.decode(response.responseText); + data = Ext.decode(response.responseText); } catch (ex) { Ext.Error.raise({ @@ -25287,9 +25461,6 @@ Ext.define('Ext.data.reader.Json', { msg: 'Unable to parse the JSON returned by the server: ' + ex.toString() }); } - if (!data) { - Ext.Error.raise('JSON object not found'); - } return data; }, @@ -25297,7 +25468,7 @@ Ext.define('Ext.data.reader.Json', { buildExtractors : function() { var me = this; - + me.callParent(arguments); if (me.root) { @@ -25308,16 +25479,21 @@ Ext.define('Ext.data.reader.Json', { }; } }, - + 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]; } @@ -25330,7 +25506,7 @@ Ext.define('Ext.data.reader.Json', { createAccessor: function() { var re = /[\[\.]/; - + return function(expr) { if (Ext.isEmpty(expr)) { return Ext.emptyFn; @@ -25379,7 +25555,6 @@ Ext.define('Ext.data.writer.Json', { request.params[root] = Ext.encode(data); } else { - Ext.Error.raise('Must specify a root when using encode'); } } else { @@ -25425,8 +25600,13 @@ Ext.define('Ext.data.proxy.Proxy', { + + + + isProxy: true, + constructor: function(config) { config = config || {}; @@ -25579,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, @@ -25677,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 { @@ -25730,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, @@ -25772,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, @@ -25789,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, @@ -25802,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; @@ -25837,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); } @@ -25942,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', @@ -25971,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; @@ -26009,6 +26163,10 @@ Ext.define('Ext.data.Model', { data.fields = fieldsMixedCollection; + if (idgen) { + data.idgen = Ext.data.IdGenerator.get(idgen); + } + if (belongsTo) { @@ -26088,7 +26246,7 @@ Ext.define('Ext.data.Model', { Ext.ModelManager.onModelDefined(cls); }); - } + }; }, inheritableStatics: { @@ -26156,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, @@ -26164,7 +26335,7 @@ Ext.define('Ext.data.Model', { dirty : false, - persistanceProperty: 'data', + persistenceProperty: 'data', evented: false, isModel: true, @@ -26179,30 +26350,51 @@ Ext.define('Ext.data.Model', { defaultProxyType: 'ajax', + + + + + + + + + + - constructor: function(data, id) { + + + + 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); @@ -26214,7 +26406,7 @@ Ext.define('Ext.data.Model', { field = fields[i]; name = field.name; - if (isArray){ + if (isArray){ newData[name] = data[i]; @@ -26225,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); @@ -26267,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); @@ -26286,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) { @@ -26298,7 +26527,7 @@ Ext.define('Ext.data.Model', { } } }, - + isEqual: function(a, b){ if (Ext.isDate(a) && Ext.isDate(b)) { @@ -26306,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; @@ -26325,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 = {}, @@ -26361,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) { @@ -26382,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, @@ -26398,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]; } } } @@ -26415,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) { @@ -26429,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); }, @@ -26573,7 +26814,7 @@ Ext.define('Ext.data.Model', { }, - unjoin: function() { + unjoin: function(store) { delete this.store; }, @@ -26669,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', { @@ -26697,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 }, @@ -26717,7 +27054,7 @@ Ext.define('Ext.Component', { - + @@ -26740,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; @@ -26759,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; @@ -26787,10 +27131,12 @@ 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()]); } - me.setAutoScroll(me.autoScroll); + if (Ext.isDefined(me.autoScroll)) { + me.setAutoScroll(me.autoScroll); + } me.callParent(); if (!(me.x && me.y) && (me.pageX || me.pageY)) { @@ -26840,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() { @@ -26857,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) { @@ -26867,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); }, @@ -26935,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(); }, @@ -26976,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; }, @@ -27000,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) { @@ -27033,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() { @@ -27071,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, @@ -27104,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) { @@ -27128,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, @@ -27144,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; }, @@ -27234,6 +27583,7 @@ Ext.define('Ext.Component', { if (me.rendered) { Ext.destroy( me.proxy, + me.proxyWrap, me.resizer ); @@ -27241,6 +27591,7 @@ Ext.define('Ext.Component', { me.container.remove(); } } + delete me.focusTask; me.callParent(); }, @@ -27259,7 +27610,10 @@ Ext.define('Ext.Component', { focusEl; if (delay) { - me.focusTask.delay(Ext.isNumber(delay) ? delay: 10, null, me, [selectText, false]); + if (!me.focusTask) { + me.focusTask = Ext.create('Ext.util.DelayedTask', me.focus); + } + me.focusTask.delay(Ext.isNumber(delay) ? delay : 10, null, me, [selectText, false]); return me; } @@ -27333,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); @@ -27380,17 +27736,72 @@ 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; } -}, function() { +}); + + +Ext.define('Ext.layout.container.AbstractContainer', { + + + + extend: 'Ext.layout.Layout', - this.prototype.focusTask = Ext.create('Ext.util.DelayedTask', this.prototype.focus); + 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(); + } }); @@ -27400,14 +27811,14 @@ 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(); } }, @@ -27440,11 +27851,6 @@ Ext.define('Ext.layout.container.Container', { } }, - afterLayout: function() { - this.owner.afterLayout(arguments); - this.callParent(arguments); - }, - getRenderedItems: function() { var me = this, @@ -27483,7 +27889,6 @@ Ext.define('Ext.layout.container.Container', { } }); - Ext.define('Ext.layout.container.Auto', { @@ -27496,8 +27901,6 @@ Ext.define('Ext.layout.container.Auto', { type: 'autocontainer', - fixedLayout: false, - bindToOwnerCtComponent: true, @@ -27524,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; } }); @@ -27557,11 +27968,14 @@ Ext.define('Ext.container.AbstractContainer', { isContainer : true, + + layoutCounter : 0, + baseCls: Ext.baseCSSPrefix + 'container', bubbleEvents: ['add', 'remove'], - + initComponent : function(){ var me = this; @@ -27575,11 +27989,7 @@ Ext.define('Ext.container.AbstractContainer', { 'add', - 'remove', - - 'beforecardswitch', - - 'cardswitch' + 'remove' ); @@ -27611,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; @@ -27640,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(); @@ -27663,6 +28087,7 @@ Ext.define('Ext.container.AbstractContainer', { afterLayout : function(layout) { + ++this.layoutCounter; this.fireEvent('afterlayout', this, layout); }, @@ -27698,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; @@ -27756,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 { @@ -27794,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, @@ -27827,7 +28236,7 @@ Ext.define('Ext.container.AbstractContainer', { onBeforeAdd : function(item) { var me = this; - + if (item.ownerCt) { item.ownerCt.remove(item, false); } @@ -27841,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); @@ -27903,7 +28309,9 @@ Ext.define('Ext.container.AbstractContainer', { me.suspendLayout = false; - me.doLayout(); + if (len) { + me.doLayout(); + } return items; }, @@ -27975,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; }, @@ -28013,8 +28423,8 @@ Ext.define('Ext.container.AbstractContainer', { } } layoutCollection.clear(); - }, - + }, + //@private @@ -28022,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() { @@ -28058,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', @@ -28211,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(); + } } }, @@ -28316,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', { @@ -28380,6 +28930,9 @@ Ext.define('Ext.button.Button', { menuAlign: 'tl-bl?', + textAlign: 'center', + + @@ -28388,7 +28941,7 @@ Ext.define('Ext.button.Button', { clickEvent: 'click', - + preventDefault: true, @@ -28403,42 +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'], - + @@ -28457,7 +29022,7 @@ Ext.define('Ext.button.Button', { - + maskOnDisable: false, @@ -28538,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) { @@ -28554,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; } @@ -28589,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); } @@ -28614,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, { @@ -28677,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 @@ -28685,13 +29259,17 @@ Ext.define('Ext.button.Button', { getHref: function() { - var me = this; - return me.href ? Ext.urlAppend(me.href, me.params + Ext.Object.toQueryString(Ext.apply(Ext.apply({}, me.baseParams)))) : false; + 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; }, - setParams: function(p) { - this.params = p; + setParams: function(params) { + this.params = params; this.btnEl.dom.href = this.getHref(); }, @@ -28712,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; }, @@ -28738,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; @@ -28747,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); @@ -28772,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(); }, @@ -28784,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; } @@ -28816,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; @@ -28833,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); @@ -28847,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()) { @@ -28893,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(); } }, @@ -28959,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); @@ -28995,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; @@ -29010,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; @@ -29145,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++) { @@ -29158,6 +29773,7 @@ Ext.define('Ext.button.Button', { } } } + Ext.ButtonToggleManager = { register: function(btn) { @@ -29228,6 +29844,10 @@ Ext.define('Ext.layout.container.boxOverflow.Menu', { me.menuItems = []; }, + + onRemove: function(comp){ + Ext.Array.remove(this.menuItems, comp); + }, handleOverflow: function(calculations, targetSize) { var me = this, @@ -29279,7 +29899,7 @@ Ext.define('Ext.layout.container.boxOverflow.Menu', { hideTrigger: function() { - if (this.menuTrigger != undefined) { + if (this.menuTrigger !== undefined) { this.menuTrigger.hide(); } }, @@ -29405,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 @@ -29415,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 '';}, @@ -29454,7 +30073,6 @@ Ext.define('Ext.layout.container.boxOverflow.Menu', { } }); - Ext.define('Ext.util.Region', { @@ -29695,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) { @@ -29741,7 +30358,7 @@ Ext.define('Ext.dd.DragDropManager', { alternateClassName: ['Ext.dd.DragDropMgr', 'Ext.dd.DDM'], - + ids: {}, @@ -29957,7 +30574,7 @@ Ext.define('Ext.dd.DragDropManager', { this.handleMouseUp(e); } - + this.currentTarget = e.getTarget(); this.dragCurrent = oDD; @@ -29993,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) { @@ -30297,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) { @@ -30417,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); }, @@ -30461,7 +31081,7 @@ Ext.define('Ext.dd.DragDropManager', { body = doc.body, top = 0, left = 0; - + if (Ext.isGecko4) { top = window.scrollYOffset; left = window.scrollXOffset; @@ -30472,7 +31092,7 @@ Ext.define('Ext.dd.DragDropManager', { } else if (body) { top = body.scrollTop; left = body.scrollLeft; - } + } } return { top: top, @@ -30497,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); }, @@ -30556,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', @@ -30593,15 +31213,16 @@ Ext.define('Ext.layout.container.Box', { bindToOwnerCtContainer: true, - fixedLayout: false, - availableSpaceOffset: 0, - + reserveOffset: true, + + shrinkToFit: true, + clearInnerCtOnLayout: false, @@ -30636,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 }; }, @@ -30684,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', @@ -30699,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]; @@ -30744,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)); @@ -30779,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, @@ -30811,6 +31445,7 @@ Ext.define('Ext.layout.container.Box', { box[parallelPrefix] = newSize; shortfall -= reduction; } + tooNarrow = (shortfall > 0); } else { remainingSpace = availableSpace; @@ -30900,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); } @@ -30924,6 +31559,13 @@ Ext.define('Ext.layout.container.Box', { }; }, + onRemove: function(comp){ + this.callParent(arguments); + if (this.overflowHandler) { + this.overflowHandler.onRemove(comp); + } + }, + initOverflowHandler: function() { var handler = this.overflowHandler; @@ -30935,7 +31577,7 @@ Ext.define('Ext.layout.container.Box', { } var handlerType = 'None'; - if (handler && handler.type != undefined) { + if (handler && handler.type !== undefined) { handlerType = handler.type; } @@ -30980,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; } @@ -30999,6 +31641,8 @@ Ext.define('Ext.layout.container.Box', { me.updateChildBoxes(boxes); me.handleTargetOverflow(targetSize); }, + + animCallback: Ext.emptyFn, updateChildBoxes: function(boxes) { @@ -31087,6 +31731,7 @@ Ext.define('Ext.layout.container.Box', { length -= 1; if (!length) { + me.animCallback(anim); me.layoutBusy = false; if (Ext.isFunction(animCallback)) { animCallback(); @@ -31231,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'; @@ -31239,7 +31886,7 @@ Ext.define('Ext.layout.container.Box', { destroy: function() { - Ext.destroy(this.overflowHandler); + Ext.destroy(this.innerCt, this.overflowHandler); this.callParent(arguments); } }); @@ -31251,7 +31898,7 @@ Ext.define('Ext.layout.container.HBox', { alias: ['layout.hbox'], extend: 'Ext.layout.container.Box', alternateClassName: 'Ext.layout.HBoxLayout', - + @@ -31284,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', { @@ -31294,7 +31955,7 @@ Ext.define('Ext.layout.container.VBox', { alias: ['layout.vbox'], extend: 'Ext.layout.container.Box', alternateClassName: 'Ext.layout.VBoxLayout', - + @@ -31327,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', { @@ -31619,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); } }, @@ -31666,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) { @@ -31788,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(); } @@ -32087,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, @@ -32101,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; @@ -32115,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; } @@ -32124,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, { @@ -32148,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; + }, + @@ -32190,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); } @@ -32206,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); }, @@ -32232,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(); @@ -32263,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'], @@ -32273,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' @@ -32301,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(); }, @@ -32322,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) { @@ -32353,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)) { @@ -32381,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; @@ -32396,7 +33101,7 @@ Ext.define('Ext.panel.AbstractPanel', { } return cls.length > 0 ? cls : undefined; }, - + initRenderData: function() { return Ext.applyIf(this.callParent(), { @@ -32432,7 +33137,10 @@ Ext.define('Ext.panel.AbstractPanel', { item.onAdded(me, i); me.onDockedAdd(item); } - if (me.rendered) { + + + me.componentLayout.childrenChanged = true; + if (me.rendered && !me.suspendLayout) { me.doComponentLayout(); } return items; @@ -32452,7 +33160,7 @@ Ext.define('Ext.panel.AbstractPanel', { var me = this, layout, hasLayout; - + if (!me.dockedItems.contains(item)) { return item; } @@ -32470,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(); } @@ -32486,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) { @@ -32501,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)) { @@ -32509,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; + } } }, @@ -32575,7 +33348,7 @@ Ext.define('Ext.panel.AbstractPanel', { ln = dockedItems.length, i = 0, item; - + for (; i < ln; i++) { item = dockedItems[i]; @@ -32583,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(){ @@ -32601,7 +33374,7 @@ Ext.define('Ext.panel.AbstractPanel', { } this.callParent(); }, - + setBorder: function(border) { var me = this; me.border = (border !== undefined) ? border : true; @@ -32621,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, @@ -32642,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)) { @@ -32679,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; } @@ -32695,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' } @@ -32713,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(); }, @@ -32742,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 }); }, @@ -32782,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) { @@ -32821,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) { @@ -32889,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; @@ -33629,7 +34480,6 @@ Ext.require('Ext.fx.CubicBezier', function() { }); }); - Ext.define('Ext.draw.Draw', { @@ -33695,10 +34545,16 @@ Ext.define('Ext.draw.Draw', { } }, + path2string: function () { return this.join(",").replace(Ext.draw.Draw.pathToStringRE, "$1"); }, + + pathToString: function(arrayPath) { + return arrayPath.join(",").replace(Ext.draw.Draw.pathToStringRE, "$1"); + }, + parsePathString: function (pathString) { if (!pathString) { return null; @@ -33717,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; } @@ -33753,10 +34609,7 @@ Ext.define('Ext.draw.Draw', { pathClone: function(pathArray) { var res = [], - j, - jj, - i, - ii; + j, jj, i, ii; if (!this.is(pathArray, "array") || !this.is(pathArray && pathArray[0], "array")) { pathArray = this.parsePathString(pathArray); } @@ -33779,80 +34632,93 @@ Ext.define('Ext.draw.Draw', { y = 0, mx = 0, my = 0, - start = 0, - i, - ii, - r, - pa, - j, - jj, - k, - kk; - if (pathArray[0][0] == "M") { + i = 0, + ln = pathArray.length, + r, pathSegment, j, ln2; + + if (ln && pathArray[0][0] == "M") { x = +pathArray[0][1]; y = +pathArray[0][2]; mx = x; my = y; - start++; + i++; res[0] = ["M", x, y]; } - for (i = start, ii = pathArray.length; i < ii; i++) { + for (; i < ln; i++) { r = res[i] = []; - pa = pathArray[i]; - if (pa[0] != pa[0].toUpperCase()) { - r[0] = pa[0].toUpperCase(); + pathSegment = pathArray[i]; + if (pathSegment[0] != pathSegment[0].toUpperCase()) { + r[0] = pathSegment[0].toUpperCase(); switch (r[0]) { + case "A": - r[1] = pa[1]; - r[2] = pa[2]; - r[3] = pa[3]; - r[4] = pa[4]; - r[5] = pa[5]; - r[6] = +(pa[6] + x); - r[7] = +(pa[7] + y); + r[1] = pathSegment[1]; + r[2] = pathSegment[2]; + r[3] = pathSegment[3]; + r[4] = pathSegment[4]; + r[5] = pathSegment[5]; + r[6] = +(pathSegment[6] + x); + r[7] = +(pathSegment[7] + y); break; + case "V": - r[1] = +pa[1] + y; + r[1] = +pathSegment[1] + y; break; + case "H": - r[1] = +pa[1] + x; + r[1] = +pathSegment[1] + x; break; case "M": - mx = +pa[1] + x; - my = +pa[2] + y; + + mx = +pathSegment[1] + x; + my = +pathSegment[2] + y; default: - for (j = 1, jj = pa.length; j < jj; j++) { - r[j] = +pa[j] + ((j % 2) ? x : y); + j = 1; + ln2 = pathSegment.length; + for (; j < ln2; j++) { + r[j] = +pathSegment[j] + ((j % 2) ? x : y); } } - } else { - for (k = 0, kk = pa.length; k < kk; k++) { - res[i][k] = pa[k]; + } + else { + j = 0; + ln2 = pathSegment.length; + for (; j < ln2; j++) { + res[i][j] = pathSegment[j]; } } switch (r[0]) { + case "Z": x = mx; y = my; break; + case "H": x = r[1]; break; + case "V": y = r[1]; break; + case "M": - mx = res[i][res[i].length - 2]; - my = res[i][res[i].length - 1]; + pathSegment = res[i]; + ln2 = pathSegment.length; + mx = pathSegment[ln2 - 2]; + my = pathSegment[ln2 - 1]; default: - x = res[i][res[i].length - 2]; - y = res[i][res[i].length - 1]; + pathSegment = res[i]; + ln2 = pathSegment.length; + x = pathSegment[ln2 - 2]; + y = pathSegment[ln2 - 1]; } } res.toString = this.path2string; return res; }, + pathToRelative: function (pathArray) { if (!this.is(pathArray, "array") || !this.is(pathArray && pathArray[0], "array")) { pathArray = this.parsePathString(pathArray); @@ -33942,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]; @@ -33968,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]; @@ -34175,27 +35041,8 @@ Ext.define('Ext.draw.Draw', { return newres; } }, - - rotatePoint: function (x, y, alpha, cx, cy) { - if (!alpha) { - return { - x: x, - y: y - }; - } - cx = cx || 0; - cy = cy || 0; - x = x - cx; - y = y - cy; - alpha = alpha * this.radian; - var cos = Math.cos(alpha), - sin = Math.sin(alpha); - return { - x: x * cos - y * sin + cx, - y: x * sin + y * cos + cy - }; - }, + rotateAndTranslatePath: function (sprite) { var alpha = sprite.rotation.degrees, cx = sprite.rotation.x, @@ -34232,7 +35079,28 @@ Ext.define('Ext.draw.Draw', { } return res; }, + + rotatePoint: function (x, y, alpha, cx, cy) { + if (!alpha) { + return { + x: x, + y: y + }; + } + cx = cx || 0; + cy = cy || 0; + x = x - cx; + y = y - cy; + alpha = alpha * this.radian; + var cos = Math.cos(alpha), + sin = Math.sin(alpha); + return { + x: x * cos - y * sin + cx, + y: x * sin + y * cos + cy + }; + }, + pathDimensions: function (path) { if (!path || !(path + "")) { return {x: 0, y: 0, width: 0, height: 0}; @@ -34242,13 +35110,10 @@ Ext.define('Ext.draw.Draw', { y = 0, X = [], Y = [], - p, - i, - ii, - xmin, - ymin, - dim; - for (i = 0, ii = path.length; i < ii; i++) { + i = 0, + ln = path.length, + p, xmin, ymin, dim; + for (; i < ln; i++) { p = path[i]; if (p[0] == "M") { x = p[1]; @@ -34274,42 +35139,50 @@ Ext.define('Ext.draw.Draw', { height: Math.max.apply(0, Y) - ymin }; }, - + + intersectInside: function(path, cp1, cp2) { + return (cp2[0] - cp1[0]) * (path[1] - cp1[1]) > (cp2[1] - cp1[1]) * (path[0] - cp1[0]); + }, + + intersectIntersection: function(s, e, cp1, cp2) { + var p = [], + dcx = cp1[0] - cp2[0], + dcy = cp1[1] - cp2[1], + dpx = s[0] - e[0], + dpy = s[1] - e[1], + n1 = cp1[0] * cp2[1] - cp1[1] * cp2[0], + n2 = s[0] * e[1] - s[1] * e[0], + n3 = 1 / (dcx * dpy - dcy * dpx); + + p[0] = (n1 * dpx - n2 * dcx) * n3; + p[1] = (n1 * dpy - n2 * dcy) * n3; + return p; + }, + intersect: function(subjectPolygon, clipPolygon) { - var cp1, cp2, s, e, point; - var inside = function(p) { - return (cp2[0]-cp1[0]) * (p[1]-cp1[1]) > (cp2[1]-cp1[1]) * (p[0]-cp1[0]); - }; - var intersection = function() { - var p = []; - var dcx = cp1[0]-cp2[0], - dcy = cp1[1]-cp2[1], - dpx = s[0]-e[0], - dpy = s[1]-e[1], - n1 = cp1[0]*cp2[1] - cp1[1]*cp2[0], - n2 = s[0]*e[1] - s[1]*e[0], - n3 = 1 / (dcx*dpy - dcy*dpx); - - p[0] = (n1*dpx - n2*dcx) * n3; - p[1] = (n1*dpy - n2*dcy) * n3; - return p; - }; - var outputList = subjectPolygon; - cp1 = clipPolygon[clipPolygon.length -1]; - for (var i = 0, l = clipPolygon.length; i < l; ++i) { + var me = this, + i = 0, + ln = clipPolygon.length, + cp1 = clipPolygon[ln - 1], + outputList = subjectPolygon, + cp2, s, e, point, ln2, inputList, j; + for (; i < ln; ++i) { cp2 = clipPolygon[i]; - var inputList = outputList; + inputList = outputList; outputList = []; - s = inputList[inputList.length -1]; - for (var j = 0, ln = inputList.length; j < ln; j++) { + s = inputList[inputList.length - 1]; + j = 0; + ln2 = inputList.length; + for (; j < ln2; j++) { e = inputList[j]; - if (inside(e)) { - if (!inside(s)) { - outputList.push(intersection()); + if (me.intersectInside(e, cp1, cp2)) { + if (!me.intersectInside(s, cp1, cp2)) { + outputList.push(me.intersectIntersection(s, e, cp1, cp2)); } outputList.push(e); - } else if (inside(s)) { - outputList.push(intersection()); + } + else if (me.intersectInside(s, cp1, cp2)) { + outputList.push(me.intersectIntersection(s, e, cp1, cp2)); } s = e; } @@ -34317,7 +35190,7 @@ Ext.define('Ext.draw.Draw', { } return outputList; }, - + curveDim: function (p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y) { var a = (c2x - 2 * c1x + p1x) - (p2x - 2 * c2x + c1x), b = 2 * (c1x - p1x) - 2 * (c2x - c1x), @@ -34370,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 + }; }, @@ -34459,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), @@ -34497,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; }, @@ -34578,6 +35586,7 @@ Ext.define('Ext.draw.Draw', { }); + Ext.define('Ext.fx.PropertyHandler', { @@ -34586,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; @@ -34918,6 +35929,11 @@ Ext.define('Ext.fx.Anim', { isAnimation: true, + + + + + duration: 250, @@ -34972,7 +35988,9 @@ Ext.define('Ext.fx.Anim', { constructor: function(config) { - var me = this; + var me = this, + curve; + config = config || {}; if (config.keyframes) { @@ -34992,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-'); @@ -35148,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); } }, - + @@ -35325,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}; @@ -35372,7 +36391,6 @@ Ext.define('Ext.dd.DragDrop', { initTarget: function(id, sGroup, config) { - this.config = config || {}; @@ -35429,7 +36447,7 @@ Ext.define('Ext.dd.DragDrop', { this.onAvailable(); }, - + setPadding: function(iTop, iRight, iBot, iLeft) { if (!iRight && 0 !== iRight) { @@ -35452,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; @@ -35465,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]; @@ -35788,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); @@ -35824,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) { @@ -35856,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]; } @@ -35867,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(); @@ -35997,6 +37017,7 @@ Ext.define('Ext.dd.DDProxy', { dragElId: "ygddfdiv" }, + constructor: function(id, sGroup, config) { if (id) { this.init(id, sGroup, config); @@ -36145,7 +37166,6 @@ Ext.define('Ext.dd.DragSource', { - dropAllowed : Ext.baseCSSPrefix + 'dd-drop-ok', dropNotAllowed : Ext.baseCSSPrefix + 'dd-drop-nodrop', @@ -36156,6 +37176,7 @@ Ext.define('Ext.dd.DragSource', { repairHighlightColor: 'c3daf9', + constructor: function(el, config) { this.el = Ext.get(el); if(!this.dragData){ @@ -36480,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', @@ -36514,6 +37536,8 @@ Ext.define('Ext.panel.Panel', { floatable: true, + + collapsible: false, @@ -36540,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) { @@ -36584,7 +37630,7 @@ Ext.define('Ext.panel.Panel', { - + this.callParent(arguments); }, @@ -36647,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', @@ -36665,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; } @@ -36690,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'; @@ -36706,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) : []; @@ -36798,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); }, @@ -36883,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) { @@ -36938,7 +38031,6 @@ Ext.define('Ext.panel.Panel', { reExpanderOrientation, reExpanderDock, getDimension, - setDimension, collapseDimension; if (!direction) { @@ -36961,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; } } @@ -36989,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()) { @@ -37006,6 +38094,8 @@ Ext.define('Ext.panel.Panel', { } else { me.hiddenDocked.push(comp); } + } else if (comp === me.reExpander) { + reExpander = comp; } } @@ -37020,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(); } @@ -37037,7 +38121,8 @@ Ext.define('Ext.panel.Panel', { - if (reExpander) { + if (reExpander && reExpander.rendered) { + reExpander.addClsWithUI(me.collapsedCls); reExpander.addClsWithUI(me.collapsedCls + '-' + reExpander.dock); @@ -37046,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); } @@ -37075,12 +38160,14 @@ Ext.define('Ext.panel.Panel', { cls: me.baseCls + '-collapsed-placeholder ' + ' ' + Ext.baseCSSPrefix + 'docked ' + me.baseCls + '-' + me.ui + '-collapsed', renderTo: me.el }; - reExpander[(reExpander.orientation == 'horizontal') ? 'tools' : 'items'] = [{ - xtype: 'tool', - type: 'expand-' + me.expandDirection, - handler: me.toggleCollapse, - scope: me - }]; + if (!me.hideCollapseTool) { + reExpander[(reExpander.orientation == 'horizontal') ? 'tools' : 'items'] = [{ + xtype: 'tool', + type: 'expand-' + me.expandDirection, + handler: me.toggleCollapse, + scope: me + }]; + } @@ -37110,12 +38197,21 @@ 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); @@ -37134,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(); } @@ -37146,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) { @@ -37171,16 +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; } - 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) { @@ -37212,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); @@ -37239,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(); @@ -37255,7 +38380,7 @@ Ext.define('Ext.panel.Panel', { } else { - anim.to.height = me.expandedSize; + anim.to.height = me.height; } @@ -37267,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(); @@ -37283,7 +38412,7 @@ Ext.define('Ext.panel.Panel', { } else { - anim.to.width = me.expandedSize; + anim.to.width = me.width; } @@ -37297,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); } @@ -37312,7 +38441,6 @@ Ext.define('Ext.panel.Panel', { afterExpand: function(animated) { var me = this; - me.setAutoScroll(me.initialConfig.autoScroll); if (me.savedFlex) { @@ -37323,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) { @@ -37367,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) { @@ -37379,8 +38512,7 @@ Ext.define('Ext.panel.Panel', { type: tool.type }); }); - } - else { + } else { tools = [{ type: 'placeholder' }]; @@ -37392,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; @@ -37419,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); @@ -37454,6 +38595,8 @@ Ext.define('Ext.panel.Panel', { } this.callParent([resizable]); } +}, function(){ + this.prototype.animCollapse = Ext.enableFx; }); @@ -37562,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]); @@ -37599,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); @@ -37664,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); }, @@ -37679,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, { @@ -37710,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); } @@ -37735,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, @@ -37818,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); } @@ -38151,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(); @@ -38163,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; @@ -38183,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) { @@ -38198,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; }, @@ -38227,9 +39376,9 @@ Ext.define('Ext.tip.QuickTip', { elTarget, cfg, ns, - ttp, + tipConfig, autoHide; - + if (me.disabled) { return; } @@ -38242,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); @@ -38271,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) { @@ -38298,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; @@ -38314,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()); @@ -38339,7 +39495,7 @@ Ext.define('Ext.tip.QuickTip', { } me.setWidth(target.width); - + if (me.anchor) { me.constrainPosition = false; } else if (target.align) { @@ -38368,8 +39524,9 @@ Ext.define('Ext.tip.QuickTipManager', function() { requires: ['Ext.tip.QuickTip'], singleton: true, alternateClassName: 'Ext.QuickTips', + - init : function(autoRender){ + init : function (autoRender, config) { if (!tip) { if (!Ext.isReady) { Ext.onReady(function(){ @@ -38377,10 +39534,24 @@ Ext.define('Ext.tip.QuickTipManager', function() { }); return; } - tip = Ext.create('Ext.tip.QuickTip', { - disabled: disabled, - renderTo: autoRender !== false ? document.body : undefined - }); + + var tipConfig = Ext.apply({ disabled: disabled }, config), + className = tipConfig.className, + xtype = tipConfig.xtype; + + if (className) { + delete tipConfig.className; + } else if (xtype) { + className = 'widget.' + xtype; + delete tipConfig.xtype; + } + + if (autoRender !== false) { + tipConfig.renderTo = document.body; + + } + + tip = Ext.create(className || 'Ext.tip.QuickTip', tipConfig); } }, @@ -38478,8 +39649,9 @@ Ext.define('Ext.app.Application', { appFolder: 'app', - autoCreateViewport: true, + autoCreateViewport: false, + constructor: function(config) { config = config || {}; Ext.apply(this, config); @@ -38498,8 +39670,8 @@ Ext.define('Ext.app.Application', { this.eventbus = Ext.create('Ext.app.EventBus'); - var controllers = this.controllers, - ln = controllers.length, + var controllers = Ext.Array.from(this.controllers), + ln = controllers && controllers.length, i, controller; this.controllers = Ext.create('Ext.util.MixedCollection'); @@ -38825,7 +39997,7 @@ Ext.define('Ext.draw.CompositeSprite', { mouseout: me.onMouseOut, click: me.onClick }); - me.callParent(arguments); + return me.callParent(arguments); }, @@ -38874,25 +40046,25 @@ Ext.define('Ext.draw.CompositeSprite', { }, - hide: function(attrs) { + hide: function(redraw) { var i = 0, items = this.items, len = this.length; for (; i < len; i++) { - items[i].hide(); + items[i].hide(redraw); } return this; }, - show: function(attrs) { + show: function(redraw) { var i = 0, items = this.items, len = this.length; for (; i < len; i++) { - items[i].show(); + items[i].show(redraw); } return this; }, @@ -38981,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); } }); @@ -39031,7 +40202,6 @@ Ext.define('Ext.chart.theme.Theme', { return; } } - Ext.Error.raise('No theme found named "' + theme + '"'); } } }, @@ -39135,6 +40305,8 @@ function() { Ext.define('Ext.chart.Mask', { + require: ['Ext.chart.MaskLayer'], + constructor: function(config) { var me = this; @@ -39277,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 @@ -39323,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', { @@ -39547,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( @@ -39599,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, @@ -39627,20 +40801,19 @@ Ext.define('Ext.draw.Surface', { this.add(items); } }, - + initBackground: function(config) { - var gradientId, - gradient, - backgroundSprite, - width = this.width, - height = this.height; + var me = this, + width = me.width, + height = me.height, + gradientId, gradient, backgroundSprite; if (config) { if (config.gradient) { gradient = config.gradient; gradientId = gradient.id; - this.addGradient(gradient); - this.background = this.add({ + me.addGradient(gradient); + me.background = me.add({ type: 'rect', x: 0, y: 0, @@ -39649,7 +40822,7 @@ Ext.define('Ext.draw.Surface', { fill: 'url(#' + gradientId + ')' }); } else if (config.fill) { - this.background = this.add({ + me.background = me.add({ type: 'rect', x: 0, y: 0, @@ -39658,7 +40831,7 @@ Ext.define('Ext.draw.Surface', { fill: config.fill }); } else if (config.image) { - this.background = this.add({ + me.background = me.add({ type: 'image', x: 0, y: 0, @@ -39669,7 +40842,7 @@ Ext.define('Ext.draw.Surface', { } } }, - + setSize: function(w, h) { if (this.background) { @@ -39679,6 +40852,7 @@ Ext.define('Ext.draw.Surface', { hidden: false }, true); } + this.applyViewBox(); }, @@ -39687,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)) { @@ -39762,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; }, @@ -39834,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); @@ -39943,7 +41177,9 @@ Ext.define('Ext.draw.Surface', { getPathellipse: function (el) { var a = el.attr; - return this.ellipsePath(a.x, a.y, a.radiusX, a.radiusY); + return this.ellipsePath(a.x, a.y, + a.radiusX || (a.width / 2) || 0, + a.radiusY || (a.height / 2) || 0); }, @@ -40006,10 +41242,10 @@ Ext.define('Ext.draw.Surface', { } return items; }, - + setText: Ext.emptyFn, - + //@private Creates an item and appends it to the surface. Called @@ -40027,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', { @@ -40054,9 +41309,8 @@ Ext.define('Ext.draw.Component', { autoSize: false, - - + initComponent: function() { this.callParent(arguments); @@ -40078,22 +41332,22 @@ Ext.define('Ext.draw.Component', { bbox, items, width, height, x, y; me.callParent(arguments); - me.createSurface(); + if (me.createSurface() !== false) { + items = me.surface.items; - 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(); + } } } }, @@ -40115,6 +41369,7 @@ Ext.define('Ext.draw.Component', { }, true); if (me.rendered) { me.setSize(width, height); + me.surface.setSize(width, height); } else { me.surface.setSize(width, height); @@ -40129,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); @@ -40360,6 +41620,7 @@ Ext.define('Ext.chart.LegendItem', { } }); + Ext.define('Ext.chart.Legend', { @@ -40406,6 +41667,7 @@ Ext.define('Ext.chart.Legend', { boxZIndex: 100, + constructor: function(config) { var me = this; if (config) { @@ -40414,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; @@ -40423,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; @@ -40460,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; @@ -40487,7 +41749,7 @@ Ext.define('Ext.chart.Legend', { bbox = item.getBBox(); - width = bbox.width; + width = bbox.width; height = bbox.height; if (i + j === 0) { @@ -40534,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(); }, @@ -40560,7 +41829,7 @@ Ext.define('Ext.chart.Legend', { chartY = chartBBox.y + insets, surface = chart.surface, mfloor = Math.floor; - + if (me.isDisplayed()) { switch(me.position) { @@ -40643,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 }); @@ -40670,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, @@ -40946,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); @@ -40959,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); @@ -41190,7 +42470,7 @@ Ext.define('Ext.chart.Chart', { destroy: function() { - this.surface.destroy(); + Ext.destroy(this.surface); this.bindStore(null); this.callParent(arguments); } @@ -41237,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; @@ -41250,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) { @@ -41281,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', { @@ -41306,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]) { @@ -41330,6 +42605,8 @@ Ext.define('Ext.chart.Highlight', { } } if (animate) { + + sprite._endStyle = obj; sprite._anim = Ext.create('Ext.fx.Anim', { target: sprite, to: obj, @@ -41370,18 +42647,6 @@ Ext.define('Ext.chart.Label', { requires: ['Ext.draw.Color'], - - - - - - - - - - - - @@ -41390,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) { @@ -41419,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, @@ -41427,86 +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, 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++) { - for (j = 0; j < ratio; j++) { - item = items[count]; - label = group.getAt(count); - storeItem = store.getAt(i); - - if (!item && label) { - label.hide(true); - } + } - if (item && field[j]) { - if (!label) { - label = me.onCreateLabel(storeItem, item, i, display, j, count); + if (!item && label) { + label.hide(true); + groupIndex++; } - me.onPlaceLabel(label, storeItem, item, i, display, animate, j, count); - - 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++; } } - 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', { @@ -41616,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; @@ -41686,6 +42978,7 @@ Ext.define('Ext.chart.axis.Abstract', { + constructor: function(config) { config = config || {}; @@ -41741,47 +43034,56 @@ Ext.define('Ext.chart.axis.Axis', { - dashSize: 3, + + + + //@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; @@ -41798,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++) { @@ -41807,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); } } }); @@ -41819,12 +43121,41 @@ 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; + if (me.forceMinMax) { + if (!isNaN(max)) { + out.to = max; + } + if (!isNaN(min)) { + out.from = min; + } + } if (!isNaN(me.maximum)) { @@ -41835,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; } @@ -41878,7 +43209,7 @@ Ext.define('Ext.chart.axis.Axis', { dashesX, dashesY, delta; - + @@ -41898,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]; } @@ -41985,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, @@ -41999,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; @@ -42014,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"); @@ -42071,7 +43402,7 @@ Ext.define('Ext.chart.axis.Axis', { type: 'path', path: evenPath }); - } + } me.gridEven.setAttributes(Ext.apply({ path: evenPath, hidden: false @@ -42129,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); @@ -42139,7 +43470,7 @@ Ext.define('Ext.chart.axis.Axis', { } return textLabel; }, - + rect2pointArray: function(sprite) { var surface = this.chart.surface, rect = surface.getBBox(sprite, true), @@ -42155,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, @@ -42196,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]); @@ -42219,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, @@ -42232,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, @@ -42262,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) { @@ -42278,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, @@ -42291,7 +43622,7 @@ Ext.define('Ext.chart.axis.Axis', { } prevLabel = textLabel; } - + return maxWidth; }, @@ -42306,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(); } @@ -42473,7 +43804,9 @@ Ext.define('Ext.chart.axis.Gauge', { extend: 'Ext.chart.axis.Abstract', + + @@ -42542,7 +43875,7 @@ Ext.define('Ext.chart.axis.Gauge', { this.drawTitle(); } }, - + drawTitle: function() { var me = this, chart = me.chart, @@ -42550,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 @@ -42645,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, @@ -42948,11 +44279,14 @@ Ext.define('Ext.data.AbstractStore', { + + sortRoot: 'data', constructor: function(config) { - var me = this; + var me = this, + filters; me.addEvents( @@ -42972,6 +44306,9 @@ Ext.define('Ext.data.AbstractStore', { 'load', + + + 'write', 'beforesync', @@ -42980,12 +44317,13 @@ Ext.define('Ext.data.AbstractStore', { ); Ext.apply(me, config); + me.removed = []; me.mixins.observable.constructor.apply(me, arguments); - me.model = Ext.ModelManager.getModel(config.model || me.model); + me.model = Ext.ModelManager.getModel(me.model); Ext.applyIf(me, { @@ -43004,9 +44342,10 @@ Ext.define('Ext.data.AbstractStore', { me.implicitModel = true; } + - me.setProxy(config.proxy || me.proxy || me.model.getProxy()); + me.setProxy(me.proxy || me.model.getProxy()); if (me.id && !me.storeId) { me.storeId = me.id; @@ -43020,8 +44359,9 @@ Ext.define('Ext.data.AbstractStore', { me.mixins.sortable.initSortable.call(me); + filters = me.decodeFilters(me.filters); me.filters = Ext.create('Ext.util.MixedCollection'); - me.filters.addAll(me.decodeFilters(config.filters)); + me.filters.addAll(filters); }, @@ -43394,7 +44734,7 @@ Ext.define('Ext.data.AbstractStore', { isLoading: function() { - return this.loading; + return !!this.loading; } }); @@ -43419,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'], @@ -43427,11 +44767,9 @@ Ext.define('Ext.data.Store', { remoteFilter: false, - - - remoteGroup : false, + remoteGroup : false, @@ -43457,35 +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, + 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', @@ -43505,21 +44861,22 @@ Ext.define('Ext.data.Store', { me.inlineData = data; delete config.data; } - - if (!groupers && config.groupField) { + + if (!groupers && groupField) { groupers = [{ - property : config.groupField, - direction: config.groupDir + property : groupField, + direction: config.groupDir || me.groupDir }]; } 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); } @@ -43543,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)) { @@ -43571,7 +44931,7 @@ Ext.define('Ext.data.Store', { property: config }; } - + Ext.applyIf(config, { root : 'data', direction: "ASC" @@ -43595,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)) { @@ -43621,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; @@ -43657,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); }, @@ -43785,7 +45148,7 @@ Ext.define('Ext.data.Store', { record.set(me.modelDefaults); records[i] = record; - + me.data.insert(index + i, record); record.join(me); @@ -43859,11 +45222,11 @@ Ext.define('Ext.data.Store', { 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) { @@ -43897,7 +45260,7 @@ Ext.define('Ext.data.Store', { load: function(options) { var me = this; - + options = options || {}; if (Ext.isFunction(options)) { @@ -43912,7 +45275,7 @@ Ext.define('Ext.data.Store', { start: (me.currentPage - 1) * me.pageSize, limit: me.pageSize, addRecords: false - }); + }); return me.callParent([options]); }, @@ -43942,7 +45305,7 @@ Ext.define('Ext.data.Store', { Ext.callback(operation.callback, operation.scope || me, [records, operation, successful]); }, - + onCreateRecords: function(records, operation, success) { if (success) { @@ -43980,1425 +45343,2131 @@ Ext.define('Ext.data.Store', { }, - onUpdateRecords: function(records, operation, success){ - if (success) { - var i = 0, - length = records.length, - data = this.data, - snapshot = this.snapshot, - record; + 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); + } + + }, + + + getRequestId: function() { + this.requestSeed = this.requestSeed || 1; + return this.requestSeed++; + }, + + + 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); + } + + + Ext.callback(operation.callback, operation.scope || me, [records, operation, successful]); + }, + + + 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(); + } + + }, + + + + 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); + } + }, + + + 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; + }, + + + getPageFromRecordIndex: function(index) { + return Math.floor(index / this.pageSize) + 1; + }, + + + onGuaranteedRange: function() { + var me = this, + totalCount = me.getTotalCount(), + start = me.requestStart, + end = ((totalCount - 1) < me.requestEnd) ? totalCount - 1 : me.requestEnd, + range = [], + record, + i = start; + + end = Math.max(0, end); + + + 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.unmask(); + }, + + + mask: function() { + this.masked = true; + this.fireEvent('beforeload'); + }, + + + unmask: function() { + if (this.masked) { + this.fireEvent('load'); + } + }, + + + hasPendingRequests: function() { + return this.pendingRequests.length; + }, + + + + onWaitForGuarantee: function() { + if (!this.hasPendingRequests()) { + this.onGuaranteedRange(); + } + }, + + + guaranteeRange: function(start, end, cb, scope) { + + 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 + }); + + } else { + me.mask(); + me.prefetchPage(startPage, { + + callback: me.onWaitForGuarantee, + scope: me + }); + me.prefetchPage(endPage, { + + callback: me.onWaitForGuarantee, + scope: me + }); + } + + } else { + me.onGuaranteedRange(); + } + }, + + + + sort: function() { + var me = this, + prefetchData = me.prefetchData, + sorters, + start, + end, + range; - for (; i < length; ++i) { - record = records[i]; - data.replace(record); - if (snapshot) { - snapshot.replace(record); + 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); } - record.join(this); + me.callParent(arguments); } + } else { + me.callParent(arguments); } }, - 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); + + + 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; } } - me.removed = []; + me.fireEvent('datachanged', me); } }, - getNewRecords: function() { - return this.data.filterBy(this.filterNew).items; + 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; }, - getUpdatedRecords: function() { - return this.data.filterBy(this.filterUpdated).items; + findRecord: function() { + var me = this, + index = me.find.apply(me, arguments); + return index !== -1 ? me.getAt(index) : null; }, - filter: function(filters, value) { - if (Ext.isString(filters)) { - filters = { - property: filters, - value: value - }; + 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]); + }; + }, + + + findExact: function(property, value, start) { + return this.data.findIndexBy(function(rec) { + return rec.get(property) == value; + }, + this, start); + }, + + + 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)); }, - filterBy: function(fn, scope) { + removeAll: function(silent) { var me = this; - me.snapshot = me.snapshot || me.data.clone(); - me.data = me.queryBy(fn, scope || me); - me.fireEvent('datachanged', me); + me.clearData(); + if (me.snapshot) { + me.snapshot.clear(); + } + if (silent !== true) { + me.fireEvent('clear', 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, - i, - record; - - - for (i = 0; i < length; i++) { - record = data[i]; + first: function(grouped) { + var me = this; - if (! (record instanceof Ext.data.Model)) { - data[i] = Ext.ModelManager.create(record, model); - } + if (grouped && me.isGrouped()) { + return me.aggregate(function(records) { + return records.length ? records[0] : undefined; + }, me, true); + } else { + return me.data.first(); } + }, + + + last: function(grouped) { + var me = this; - this.loadRecords(data, {addRecords: append}); + 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(); + } }, - loadRecords: function(records, options) { - var me = this, - i = 0, - length = records.length; + sum: function(field, grouped) { + var me = this; - options = options || {}; + if (grouped && me.isGrouped()) { + return me.aggregate(me.getSum, me, true, [field]); + } else { + return me.getSum(me.data.items, field); + } + }, + + getSum: function(records, field) { + var total = 0, + i = 0, + len = records.length; - if (!options.addRecords) { - delete me.snapshot; - me.data.clear(); + for (; i < len; ++i) { + total += records[i].get(field); } - me.data.addAll(records); + return total; + }, - - for (; i < length; i++) { - if (options.start !== undefined) { - records[i].index = options.start + i; + + count: function(grouped) { + var me = this; - } - records[i].join(me); + if (grouped && me.isGrouped()) { + return me.aggregate(function(records) { + return records.length; + }, me, true); + } else { + return me.getCount(); } + }, - - me.suspendEvents(); + + min: function(field, grouped) { + var me = this; - if (me.filterOnLoad && !me.remoteFilter) { - me.filter(); + if (grouped && me.isGrouped()) { + return me.aggregate(me.getMin, me, true, [field]); + } else { + return me.getMin(me.data.items, field); } + }, - if (me.sortOnLoad && !me.remoteSort) { - me.sort(); + + getMin: function(records, field){ + var i = 1, + len = records.length, + value, min; + + if (len > 0) { + min = records[0].get(field); } - me.resumeEvents(); - me.fireEvent('datachanged', me, records); + for (; i < len; ++i) { + value = records[i].get(field); + if (value < min) { + min = value; + } + } + return min; }, - - loadPage: function(page) { + max: function(field, grouped) { var me = this; - me.currentPage = page; - - me.read({ - page: page, - start: (page - 1) * me.pageSize, - limit: me.pageSize, - addRecords: !me.clearOnPageLoad - }); + if (grouped && me.isGrouped()) { + return me.aggregate(me.getMax, me, true, [field]); + } else { + return me.getMax(me.data.items, field); + } }, - nextPage: function() { - this.loadPage(this.currentPage + 1); + getMax: function(records, field) { + var i = 1, + len = records.length, + value, + max; + + if (len > 0) { + max = records[0].get(field); + } + + for (; i < len; ++i) { + value = records[i].get(field); + if (value > max) { + max = value; + } + } + return max; }, - previousPage: 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); + } }, - clearData: function() { - this.data.each(function(record) { - record.unjoin(); - }); + getAverage: function(records, field) { + var i = 0, + len = records.length, + sum = 0; - this.data.clear(); + if (records.length > 0) { + for (; i < len; ++i) { + sum += records[i].get(field); + } + return sum / len; + } + return 0; }, + + + aggregate: function(fn, scope, grouped, args) { + args = args || []; + if (grouped && this.isGrouped()) { + var groups = this.getGroups(), + i = 0, + len = groups.length, + out = {}, + group; + + 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); - } - - }, - - getRequestId: function() { - this.requestSeed = this.requestSeed || 1; - return this.requestSeed++; - }, + + extend: 'Ext.chart.axis.Numeric', + + alternateClassName: 'Ext.chart.TimeAxis', + + alias: 'axis.time', + + requires: ['Ext.data.Store', 'Ext.data.JsonStore'], + + - 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); - } + dateFormat: false, - - Ext.callback(operation.callback, operation.scope || me, [records, operation, successful]); - }, + fromDate: false, + - 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(); - } - - }, + toDate: false, + + step: [Ext.Date.DAY, 1], - purgeRecords: function() { - var me = this, - prefetchCount = me.prefetchData.getCount(), - purgeCount = me.purgePageCount * me.pageSize, - numRecordsToPurge = prefetchCount - purgeCount - 1, - i = 0; + constrain: false, - for (; i <= numRecordsToPurge; i++) { - me.prefetchData.removeAt(0); - } - }, + roundToDecimal: false, - 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."); - } - break; + 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); + }; } } - return satisfied; - }, - - - getPageFromRecordIndex: function(index) { - return Math.floor(index / this.pageSize) + 1; }, - - - onGuaranteedRange: function() { + + doConstrain: 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 + ")"); + 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; } - - 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"); + store.each(function(record) { + for (i = 0; i < ln; i++) { + if (excludes[i]) { + continue; } - range.push(record); - } - me.fireEvent('guaranteedrange', range, start, end); - if (me.cb) { - me.cb.call(me.scope || me, range); + value = record.get(fields[i]); + if (+value < +min) return; + if (+value > +max) return; } - } - - me.unmask(); + data.push(record); + }) + me.chart.substore = Ext.create('Ext.data.JsonStore', { model: store.model, data: data }); }, + + processView: function () { + var me = this; + if (me.fromDate) { + me.minimum = +me.fromDate; + } + if (me.toDate) { + me.maximum = +me.toDate; + } + if (me.constrain) { + me.doConstrain(); + } + }, + - mask: function() { - this.masked = true; - this.fireEvent('beforeload'); + 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; + } + if (me.maximum) { + range.to = me.maximum; + } + range.step = (range.to - range.from) / range.steps; + return range; + } else { + return me.callParent(arguments); + } + } + }); + + + +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' }, + + - 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; - range; - - 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); - }, - - - removeAll: function(silent) { - var me = this; - - me.clearData(); - if (me.snapshot) { - me.snapshot.clear(); - } - if (silent !== true) { - me.fireEvent('clear', me); + visibleInLegend: function(index){ + var excludes = this.__excludes; + if (excludes) { + return !excludes[index]; } + return !this.seriesIsHidden; }, + setTitle: function(index, title) { + var me = this, + oldTitle = me.title; - - first: function(grouped) { - var me = this; + if (Ext.isString(index)) { + title = index; + index = 0; + } - if (grouped && me.isGrouped()) { - return me.aggregate(function(records) { - return records.length ? records[0] : undefined; - }, me, true); + if (Ext.isArray(oldTitle)) { + oldTitle[index] = title; } else { - return me.data.first(); + me.title = title; } - }, + + me.fireEvent('titlechange', title, index); + } +}); + + +Ext.define('Ext.chart.series.Cartesian', { - last: function(grouped) { - var me = this; - 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(); - } - }, + extend: 'Ext.chart.series.Series', + + alternateClassName: ['Ext.chart.CartesianSeries', 'Ext.chart.CartesianChart'], - 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); - } - }, + + xField: null, - getSum: function(records, field) { - var total = 0, - i = 0, - len = records.length; + yField: null, + + + axis: 'left', + + getLegendLabels: function() { + var me = this, + labels = [], + combinations = me.combinations; - for (; i < len; ++i) { - total += records[i].get(field); + 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 total; + return labels; }, - count: function(grouped) { - var me = this; - - if (grouped && me.isGrouped()) { - return me.aggregate(function(records) { - return records.length; - }, me, true); - } else { - return me.getCount(); - } + eachYValue: function(record, fn, scope) { + Ext.each(this.getYValueAccessors(), function(accessor, i) { + fn.call(scope, accessor(record), i); + }); }, - min: function(field, grouped) { - var me = this; - - if (grouped && me.isGrouped()) { - return me.aggregate(me.getMin, me, true, [field]); - } else { - return me.getMin(me.data.items, field); - } + getYValueCount: function() { + return this.getYValueAccessors().length; }, - - getMin: function(records, field){ - var i = 1, - len = records.length, - value, min; + combine: function(index1, index2) { + var me = this, + accessors = me.getYValueAccessors(), + accessor1 = accessors[index1], + accessor2 = accessors[index2]; - if (len > 0) { - min = records[0].get(field); - } + + accessors[index2] = function(record) { + return accessor1(record) + accessor2(record); + }; + accessors.splice(index1, 1); - for (; i < len; ++i) { - value = records[i].get(field); - if (value < min) { - min = value; - } + me.callParent([index1, index2]); + }, + + clearCombinations: function() { + + delete this.yValueAccessors; + this.callParent(); + }, + + + 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 min; + return accessors; }, - max: function(field, grouped) { - var me = this; + getMinMaxXValues: function() { + var me = this, + min, max, + xField = me.xField; - if (grouped && me.isGrouped()) { - return me.aggregate(me.getMax, 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.getMax(me.data.items, field); + min = max = 0; } + return [min, max]; }, - getMax: function(records, field) { - var i = 1, - len = records.length, - value, - max; + getMinMaxYValues: function() { + var me = this, + stacked = me.stacked, + min, max, + positiveTotal, negativeTotal; - if (len > 0) { - max = 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 > max) { - max = value; + function eachYValue(yValue, i) { + if (!me.isExcluded(i)) { + if (yValue > max) { + max = yValue; + } + if (yValue < min) { + min = yValue; + } } } - return max; - }, - - average: function(field, grouped) { - var me = this; - if (grouped && me.isGrouped()) { - return me.aggregate(me.getAverage, 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.getAverage(me.data.items, field); + min = max = 0; } + return [min, max]; }, - - getAverage: function(records, field) { - var i = 0, - len = records.length, - sum = 0; + getAxesForXAndYFields: function() { + var me = this, + axes = me.chart.axes, + axis = [].concat(me.axis), + xAxis, yAxis; - if (records.length > 0) { - for (; i < len; ++i) { - sum += records[i].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'; } - return sum / len; } - return 0; - }, - - - aggregate: function(fn, scope, grouped, args) { - args = args || []; - if (grouped && this.isGrouped()) { - var groups = this.getGroups(), - i = 0, - len = groups.length, - out = {}, - group; - for (; i < len; ++i) { - group = groups[i]; - out[group.name] = fn.apply(scope || this, [group.children].concat(args)); - } - return out; + if (Ext.Array.indexOf(axis, 'left') > -1) { + yAxis = 'left'; + } else if (Ext.Array.indexOf(axis, 'right') > -1) { + yAxis = 'right'; } else { - return fn.apply(scope || this, [this.data.items].concat(args)); + if (axes.get('left')) { + yAxis = 'left'; + } else if (axes.get('right')) { + yAxis = 'right'; + } } - } -}); + return { + xAxis: xAxis, + yAxis: yAxis + }; + } -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' - } - }); - this.callParent([config]); - } }); -Ext.define('Ext.chart.axis.Time', { +Ext.define('Ext.chart.series.Area', { - extend: 'Ext.chart.axis.Category', - - alternateClassName: 'Ext.chart.TimeAxis', + extend: 'Ext.chart.series.Cartesian', - alias: 'axis.time', + alias: 'series.area', - requires: ['Ext.data.Store', 'Ext.data.JsonStore'], + requires: ['Ext.chart.axis.Axis', 'Ext.draw.Color', 'Ext.fx.Anim'], - - calculateByLabelSize: true, - - - dateFormat: false, - - - groupBy: 'year,month,day', - - - aggregateOp: 'sum', - - - fromDate: false, - - - toDate: false, - - - step: [Ext.Date.DAY, 1], - - - constrain: false, + type: 'area', + + stacked: true, + - 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(); + 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); }, + - - 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]; - } - return Math.max.apply(Math, list); - }, - 'min': function(list) { - if (!list.length || etype(list[0]) != 'Number') { - return list[0]; - } - 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]; + 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; } - for (; i < l; i++) { - acum += list[i]; + yRes.push(ySum); + + xSum = 0; + for (j = 0, ySum = []; j < yCompLen; ++j) { + ySum[j] = 0; } - return acum / l; } + } + return { + x: xRes, + y: yRes }; - })(), - + }, + - 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; - }; - })(); + 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; + - if (!this.constrain) { - this.chart.filteredStore = this.chart.store; - return; + 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); + } } - 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]); + 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); } - - 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; + + if (!Ext.isNumber(minY)) { + minY = 0; + } + if (!Ext.isNumber(maxY)) { + maxY = 0; + } + + store.each(function(record, i) { + xValue = record.get(me.xField); + yValue = []; + if (typeof xValue != 'number') { + xValue = i; } - - value = rec.get(field); - - for (i = 0; i < l; i++) { - if (i == 0) { - key = String(dateMethods[fields[i]](value)); + 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); + + xScale = bbox.width / ((maxX - minX) || 1); + yScale = bbox.height / ((maxY - minY) || 1); + + ln = xValues.length; + if ((ln > bbox.width) && me.areas) { + sumValues = me.shrink(xValues, yValues, bbox.width); + xValues = sumValues.x; + yValues = sumValues.y; + } + + 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; + + 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; + } + if (!componentPaths[areaIndex]) { + componentPaths[areaIndex] = []; + } + 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 { - key += '||' + dateMethods[fields[i]](value); + paths[areaIndex].push('L', x, y); + componentPaths[areaIndex].push(['L', x, y]); + } + if (!items[areaIndex]) { + items[areaIndex] = { + pointsUp: [], + pointsDown: [], + series: me + }; } + items[areaIndex].pointsUp.push([x, y]); } + } + + + for (areaIndex = 0; areaIndex < bounds.areasLen; areaIndex++) { - if (key in aggStore) { - obj = aggStore[key]; - } else { - obj = aggStore[key] = {}; - aggKeys.push(key); - dates.push(value); + if (me.__excludes[areaIndex]) { + continue; } + path = paths[areaIndex]; - 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)); - } + if (areaIndex == 0 || first) { + first = false; + path.push('L', x, bbox.y + bbox.height, + 'L', bbox.x, bbox.y + bbox.height, + 'Z'); } - }); - - for (key in aggStore) { - obj = aggStore[key]; - for (i = 0; i < recFieldsLen; i++) { - curField = recFields[i]; - obj[curField] = aggregateFn[op](obj[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'); } - json.push(obj); + prevAreaIndex = areaIndex; } - this.chart.substore = Ext.create('Ext.data.JsonStore', { - fields: recFields, - data: json - }); - - this.dates = dates; + return { + paths: paths, + areasLen: bounds.areasLen + }; }, + - - 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); - }, + 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; - processView: function() { - - if (this.constrain) { - this.constrainDates(); - this.aggregate(); - this.chart.substore = this.chart.filteredStore; - } else { - this.aggregate(); - } - }, + me.unHighlightItem(); + me.cleanHighlights(); - - applyData: function() { - this.setLabels(); - var count = this.chart.substore.getCount(); - return { - from: 0, - to: count, - steps: count - 1, - step: 1 - }; - } - }); + if (!store || !store.getCount()) { + return; + } + paths = me.getPaths(); + if (!me.areas) { + me.areas = []; + } -Ext.define('Ext.chart.series.Series', { + 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(); + }, - - mixins: { - observable: 'Ext.util.Observable', - labels: 'Ext.chart.Label', - highlights: 'Ext.chart.Highlight', - tips: 'Ext.chart.Tip', - callouts: 'Ext.chart.Callout' + onAnimate: function(sprite, attr) { + sprite.show(); + return this.callParent(arguments); }, + onCreateLabel: function(storeItem, item, i, display) { + var me = this, + group = me.labelsGroup, + config = me.label, + bbox = me.bbox, + endLabelStyle = Ext.apply(config, me.seriesLabelStyle); - + 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 || {})); + }, + onPlaceLabel: function(label, storeItem, item, i, display, animate, index) { + var me = this, + chart = me.chart, + 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; - - type: null, + label.setAttributes({ + text: format(storeItem.get(field[index])), + hidden: true + }, true); - - title: null, + bb = label.getBBox(); + width = bb.width / 2; + height = bb.height / 2; - - showInLegend: true, + 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; - - renderer: function(sprite, record, attributes, index, store) { - return attributes; + if (me.chart.animate && !me.chart.resizing) { + label.show(true); + me.onAnimate(label, { + to: { + x: x, + y: y + } + }); + } else { + label.setAttributes({ + x: x, + y: y + }, true); + if (resizing) { + me.animation.on('afteranimate', function() { + label.show(true); + }); + } else { + label.show(true); + } + } }, - shadowAttributes: null, - - //@private triggerdrawlistener flag + 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; - triggerAfterDraw: false, + + 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]); - - - constructor: function(config) { - var me = this; - if (config) { - Ext.apply(me, config); + 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; + 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; } + - me.shadowGroups = []; + x = cur[0] + normal[0] * offsetFromViz; + y = cur[1] + normal[1] * offsetFromViz; + - 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); + 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.addEvents({ - scope: me, - itemmouseover: true, - itemmouseout: true, - itemmousedown: true, - itemmouseup: true, - mouseleave: true, - afterdraw: true, + + + if (boxx < clipRect[0] || (boxx + boxw) > (clipRect[0] + clipRect[2])) { + normal[0] *= -1; + } + if (boxy < clipRect[1] || (boxy + boxh) > (clipRect[1] + clipRect[3])) { + normal[1] *= -1; + } - - titlechange: true - }); + + x = cur[0] + normal[0] * offsetFromViz; + y = cur[1] + normal[1] * offsetFromViz; - me.mixins.observable.constructor.call(me, config); + + 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.on({ - scope: me, - itemmouseover: me.onItemMouseOver, - itemmouseout: me.onItemMouseOut, - mouseleave: me.onMouseLeave - }); + + callout.lines.setAttributes({ + path: ["M", cur[0], cur[1], "L", x, y, "Z"] + }, 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); + } }, - - setBBox: function(noGutter) { + isItemInPoint: function(x, y, item, i) { 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; - }, + pointsUp = item.pointsUp, + pointsDown = item.pointsDown, + abs = Math.abs, + dist = Infinity, p, pln, point; - - onAnimate: function(sprite, attr) { - var me = this; - sprite.stopAnimation(); - if (me.triggerAfterDraw) { - return sprite.animate(Ext.applyIf(attr, me.chart.animate)); - } else { - me.triggerAfterDraw = true; - return sprite.animate(Ext.apply(Ext.applyIf(attr, me.chart.animate), { - listeners: { - 'afteranimate': function() { - me.triggerAfterDraw = false; - me.fireEvent('afterrender'); - } - } - })); + 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; + } + } } - }, - - - getGutters: function() { - return [0, 0]; + return false; }, - onItemMouseOver: function(item) { - var me = this; - if (item.series === me) { - if (me.highlight) { - me.highlightItem(item); + highlightSeries: function() { + var area, to, fillColor; + if (this._index !== undefined) { + area = this.areas[this._index]; + if (area.__highlightAnim) { + area.__highlightAnim.paused = true; } - if (me.tooltip) { - me.showTip(item); + 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); } } }, - onItemMouseOut: function(item) { - var me = this; - if (item.series === me) { - me.unHighlightItem(); - if (me.tooltip) { - me.hideTip(item); + 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 + } + }); } } }, - onMouseLeave: function() { - var me = this; - me.unHighlightItem(); - if (me.tooltip) { - me.hideTip(); + highlightItem: function(item) { + var me = this, + points, path; + if (!item) { + this.highlightSeries(); + return; } + 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); }, - 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; - - if (!Ext.draw.Draw.withinBox(x, y, bbox)) { - return null; + unHighlightItem: function(item) { + if (!item) { + this.unHighlightSeries(); } - for (i = 0, ln = items.length; i < ln; i++) { - if (items[i] && this.isItemInPoint(x, y, items[i], i)) { - return items[i]; - } + + if (this.highlightSprite) { + this.highlightSprite.hide(true); } - - return null; - }, - - isItemInPoint: function(x, y, item, i) { - return false; }, hideAll: function() { - var me = this, - items = me.items, - item, len, i, sprite; - - me.seriesIsHidden = true; - me._prevShowMarkers = me.showMarkers; - - 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); - } + if (!isNaN(this._index)) { + this.__excludes[this._index] = true; + this.areas[this._index].hide(true); + this.drawSeries(); } }, 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; - }, - - - 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'; - }, - - - visibleInLegend: function(index){ - var excludes = this.__excludes; - if (excludes) { - return !excludes[index]; + if (!isNaN(this._index)) { + this.__excludes[this._index] = false; + this.areas[this._index].show(true); + this.drawSeries(); } - return !this.seriesIsHidden; }, - setTitle: function(index, title) { - 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; - } - - me.fireEvent('titlechange', title, index); + getLegendColor: function(index) { + var me = this; + return me.colorArrayStyle[index % me.colorArrayStyle.length]; } }); - -Ext.define('Ext.chart.series.Cartesian', { - - - - extend: 'Ext.chart.series.Series', - - alternateClassName: ['Ext.chart.CartesianSeries', 'Ext.chart.CartesianChart'], - - - - - xField: null, - - - yField: null, - - - axis: 'left' -}); - - 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'], @@ -45484,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 = [], @@ -45551,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) { @@ -45577,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, @@ -45622,7 +47691,7 @@ Ext.define('Ext.chart.series.Area', { items[areaIndex].pointsUp.push([x, y]); } } - + for (areaIndex = 0; areaIndex < bounds.areasLen; areaIndex++) { @@ -45662,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, @@ -45677,7 +47746,7 @@ Ext.define('Ext.chart.series.Area', { if (!store || !store.getCount()) { return; } - + paths = me.getPaths(); if (!me.areas) { @@ -45703,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], @@ -45714,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, @@ -45763,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; @@ -45831,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; @@ -45848,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])) { @@ -45867,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"] @@ -45894,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])) { @@ -46049,10 +48118,10 @@ Ext.define('Ext.chart.series.Bar', { alias: 'series.bar', column: false, - + style: {}, - + gutter: 38.2, @@ -46078,7 +48147,7 @@ Ext.define('Ext.chart.series.Bar', { opacity: 0.8, color: '#f00' }, - + shadowAttributes: [{ "stroke-width": 6, "stroke-opacity": 0.05, @@ -46116,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); }, @@ -46136,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, @@ -46168,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; } } @@ -46179,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)) { @@ -46237,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, @@ -46268,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] }; @@ -46381,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 = [], @@ -46437,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, @@ -46449,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); @@ -46527,7 +48596,7 @@ Ext.define('Ext.chart.series.Bar', { } me.renderLabels(); }, - + onCreateLabel: function(storeItem, item, i, display) { var me = this, @@ -46541,9 +48610,9 @@ Ext.define('Ext.chart.series.Bar', { group: group }, endLabelStyle || {})); }, + - - onPlaceLabel: function(label, storeItem, item, i, display, animate, index) { + onPlaceLabel: function(label, storeItem, item, i, display, animate, j, index) { var me = this, @@ -46577,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)) { @@ -46585,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; @@ -46602,6 +48673,7 @@ Ext.define('Ext.chart.series.Bar', { else { if (width + offsetX > attr.width) { display = outside; + label.isOutside = true; } } x = display == insideStart ? @@ -46690,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; @@ -46727,15 +48799,35 @@ 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(); } }); - Ext.define('Ext.chart.series.Column', { @@ -46840,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) { @@ -46939,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), @@ -47153,7 +49245,6 @@ Ext.define('Ext.chart.series.Gauge', { - Ext.define('Ext.chart.series.Line', { @@ -47167,12 +49258,14 @@ Ext.define('Ext.chart.series.Line', { type: 'line', - + alias: 'series.line', - selectionTolerance: 20, + + selectionTolerance: 20, + showMarkers: true, @@ -47181,11 +49274,14 @@ Ext.define('Ext.chart.series.Line', { style: {}, - + smooth: false, + defaultSmoothness: 3, + + fill: false, constructor: function(config) { @@ -47229,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) { @@ -47245,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; @@ -47266,48 +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 = [], + yValueMap = {}, onbreak = false, + storeIndices = [], markerStyle = me.markerStyle, - seriesStyle = me.seriesStyle, - seriesLabelStyle = me.seriesLabelStyle, + seriesStyle = me.style, colorArrayStyle = me.colorArrayStyle, colorArrayLength = colorArrayStyle && colorArrayStyle.length || 0, - 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; - - - 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']) { @@ -47331,17 +49447,15 @@ 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]; - - for (i = 0, ln = axes.length; i < ln; i++) { - axis = chart.axes.get(axes[i]); + 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') { @@ -47357,8 +49471,9 @@ Ext.define('Ext.chart.series.Line', { - if (me.xField && !Ext.isNumber(minX) - && (me.axis == 'bottom' || me.axis == 'top')) { + 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) @@ -47366,8 +49481,9 @@ Ext.define('Ext.chart.series.Line', { minX = axis.from; maxX = axis.to; } - if (me.yField && !Ext.isNumber(minY) - && (me.axis == 'right' || me.axis == 'left')) { + 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) @@ -47375,47 +49491,53 @@ Ext.define('Ext.chart.series.Line', { 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')) { - 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')) { + || 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) { @@ -47426,6 +49548,7 @@ Ext.define('Ext.chart.series.Line', { me.items = []; + count = 0; ln = xValues.length; for (i = 0; i < ln; i++) { xValue = xValues[i]; @@ -47443,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) { @@ -47476,21 +49600,22 @@ Ext.define('Ext.chart.series.Line', { } } if (showMarkers) { - marker = markerGroup.getAt(i); + marker = markerGroup.getAt(count++); if (!marker) { marker = Ext.chart.Shape[type](surface, Ext.apply({ 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 { @@ -47501,7 +49626,8 @@ Ext.define('Ext.chart.series.Line', { }, true); marker._to = { translate: { - x: x, y: y + x: +x, + y: +y } }; } @@ -47511,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; } @@ -47542,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({ @@ -47553,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)); @@ -47566,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 }); } @@ -47586,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, @@ -47608,46 +49745,47 @@ 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 || {}) }); } if (showMarkers) { + count = 0; for(i = 0; i < ln; i++) { - item = markerGroup.getAt(i); - if (item) { - if (me.items[i]) { + if (me.items[i]) { + item = markerGroup.getAt(count++); + if (item) { rendererAttributes = me.renderer(item, store.getAt(i), item._to, i, store); me.onAnimate(item, { to: Ext.apply(rendererAttributes, endMarkerStyle || {}) }); - } else { - item.setAttributes(Ext.apply({ - hidden: true - }, item._to), true); + item.show(true); } } } - for(; i < markerCount; i++) { - item = markerGroup.getAt(i); + for(; count < markerCount; count++) { + item = markerGroup.getAt(count); item.hide(true); } @@ -47656,7 +49794,7 @@ Ext.define('Ext.chart.series.Line', { } } else { - rendererAttributes = me.renderer(me.line, false, { path: path, hidden: false }, i, store); + rendererAttributes = me.renderer(me.line, false, { path: renderPath, hidden: false }, i, store); Ext.apply(rendererAttributes, endLineStyle || {}, { stroke: endLineStyle.stroke || endLineStyle.fill }); @@ -47668,42 +49806,50 @@ 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) { + count = 0; for(i = 0; i < ln; i++) { - item = markerGroup.getAt(i); - if (item) { - if (me.items[i]) { + if (me.items[i]) { + item = markerGroup.getAt(count++); + if (item) { rendererAttributes = me.renderer(item, store.getAt(i), item._to, i, store); item.setAttributes(Ext.apply(endMarkerStyle || {}, rendererAttributes || {}), true); - } else { - item.hide(true); + item.show(true); } } } - for(; i < markerCount; i++) { - item = markerGroup.getAt(i); + for(; count < markerCount; count++) { + item = markerGroup.getAt(count); item.hide(true); } } } 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, @@ -47720,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, @@ -47734,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', @@ -47756,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(); @@ -47772,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, { @@ -47786,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); }); @@ -47801,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; } }, @@ -47823,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; } }, @@ -47840,7 +49986,7 @@ Ext.define('Ext.chart.series.Line', { if (!display) { return; } - + var me = this, chart = me.chart, surface = chart.surface, @@ -47872,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) { @@ -47896,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])) { @@ -47909,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, { @@ -47942,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, @@ -47961,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]; } @@ -47977,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({ @@ -48014,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', { @@ -48037,7 +50184,7 @@ Ext.define('Ext.chart.series.Pie', { type: "pie", - + alias: 'series.pie', rad: Math.PI / 180, @@ -48058,10 +50205,10 @@ Ext.define('Ext.chart.series.Pie', { showInLegend: false, - + style: {}, - + constructor: function(config) { this.callParent(arguments); var me = this, @@ -48076,7 +50223,7 @@ Ext.define('Ext.chart.series.Pie', { } } }); - Ext.apply(me, config, { + Ext.apply(me, config, { shadowAttributes: [{ "stroke-width": 6, "stroke-opacity": 1, @@ -48114,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) { @@ -48136,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"] + ] }; } }, @@ -48202,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, @@ -48217,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, @@ -48251,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, @@ -48278,7 +50449,7 @@ Ext.define('Ext.chart.series.Pie', { path, p, spriteOptions, bbox; - + Ext.apply(seriesStyle, me.style || {}); me.setBBox(); @@ -48289,12 +50460,12 @@ Ext.define('Ext.chart.series.Pie', { colorArrayStyle = me.colorSet; colorArrayLength = colorArrayStyle.length; } - + if (!store || !store.getCount()) { return; } - + me.unHighlightItem(); me.cleanHighlights(); @@ -48319,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, @@ -48353,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++) { @@ -48381,32 +50544,28 @@ 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++) { shadowAttr = shadowAttributes[shindex]; shadow = shadowGroups[shindex].getAt(i); if (!shadow) { - shadow = chart.surface.add(Ext.apply({}, - { + shadow = chart.surface.add(Ext.apply({}, { type: 'path', group: shadowGroups[shindex], strokeLinejoin: "round" - }, - rendererAttributes, shadowAttr)); + }, rendererAttributes, shadowAttr)); } if (animate) { - rendererAttributes = me.renderer(shadow, store.getAt(i), Ext.apply({}, - rendererAttributes, shadowAttr), i, store); + shadowAttr = me.renderer(shadow, store.getAt(i), Ext.apply({}, rendererAttributes, shadowAttr), i, store); me.onAnimate(shadow, { - to: rendererAttributes + to: shadowAttr }); } else { - rendererAttributes = me.renderer(shadow, store.getAt(i), Ext.apply(shadowAttr, { - hidden: false - }), i, store); - shadow.setAttributes(rendererAttributes, true); + shadowAttr = me.renderer(shadow, store.getAt(i), shadowAttr, i, store); + shadow.setAttributes(shadowAttr, true); } shadows.push(shadow); } @@ -48416,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); @@ -48433,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, { @@ -48484,7 +50640,7 @@ Ext.define('Ext.chart.series.Pie', { rhoAcum += deltaRho; } } - + ln = group.getCount(); for (i = 0; i < ln; i++) { @@ -48517,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', @@ -48549,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; } @@ -48595,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, { @@ -48706,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; @@ -48715,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; @@ -48741,7 +50901,7 @@ Ext.define('Ext.chart.series.Pie', { this.drawSeries(); } }, - + showAll: function() { if (!isNaN(this._index)) { @@ -48755,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; } @@ -48794,7 +50954,7 @@ Ext.define('Ext.chart.series.Pie', { if (Math.abs(y) < 1e-10) { y = 0; } - + if (animate) { label.stopAnimation(); label.animate({ @@ -48933,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]; } }); @@ -48956,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, @@ -48977,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, @@ -49003,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(); @@ -49090,7 +51250,7 @@ Ext.define('Ext.chart.series.Radar', { me.renderLabels(); me.renderCallouts(); }, - + drawMarkers: function() { var me = this, @@ -49098,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); @@ -49151,7 +51311,7 @@ Ext.define('Ext.chart.series.Radar', { } } }, - + isItemInPoint: function(x, y, item) { var point, tolerance = 10, @@ -49170,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', @@ -49202,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, { @@ -49246,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, @@ -49285,6 +51445,8 @@ Ext.define('Ext.chart.series.Scatter', { alias: 'series.scatter', + + @@ -49322,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(); @@ -49374,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); } @@ -49393,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, @@ -49413,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; @@ -49546,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, @@ -49593,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); } @@ -49625,7 +51789,7 @@ Ext.define('Ext.chart.series.Scatter', { me.renderLabels(); me.renderCallouts(); }, - + onCreateLabel: function(storeItem, item, i, display) { var me = this, @@ -49633,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, @@ -49641,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, @@ -49655,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', @@ -49677,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(); @@ -49711,7 +51875,7 @@ Ext.define('Ext.chart.series.Scatter', { y: y }, true); label.show(true); - }); + }); } else { label.show(true); @@ -49727,7 +51891,7 @@ Ext.define('Ext.chart.series.Scatter', { } } }, - + onPlaceCallout: function(callout, storeItem, item, i, display, animate, index) { var me = this, @@ -49745,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])) { @@ -49765,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, { @@ -50003,7 +52167,6 @@ Ext.define('Ext.data.ArrayStore', { alias: 'store.array', uses: ['Ext.data.reader.Array'], - constructor: function(config) { config = config || {}; @@ -50043,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); @@ -50143,9 +52307,9 @@ Ext.define('Ext.data.Batch', { me.runNextOperation(); } }; - + operation.setStarted(); - + me.proxy[operation.action](operation, onProxyReturn, me); } } @@ -50161,9 +52325,8 @@ Ext.define('Ext.data.BelongsToAssociation', { - - + constructor: function(config) { this.callParent(arguments); @@ -50223,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; } @@ -50279,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', @@ -50299,12 +52460,12 @@ Ext.define('Ext.direct.Manager', { SERVER: 'exception' } }, + - - + constructor: function(){ var me = this; - + me.addEvents( 'event', @@ -50313,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]); @@ -50345,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); @@ -50364,7 +52526,7 @@ Ext.define('Ext.direct.Manager', { } return null; }, - + addTransaction: function(transaction){ this.transactions.add(transaction); @@ -50382,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]); @@ -50396,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); @@ -50409,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, @@ -50427,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(), @@ -50456,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) { @@ -50485,7 +52644,7 @@ Ext.define('Ext.data.proxy.Direct', { } else { args.push(request.jsonData); } - + Ext.apply(request, { args: args, directFn: fn @@ -50493,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 ''; @@ -50524,7 +52683,6 @@ Ext.define('Ext.data.proxy.Direct', { }); - Ext.define('Ext.data.DirectStore', { @@ -50535,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 = { @@ -50554,7 +52712,6 @@ Ext.define('Ext.data.DirectStore', { }); - Ext.define('Ext.util.Inflector', { @@ -50586,7 +52743,7 @@ Ext.define('Ext.util.Inflector', { [(/s$/i), "s" ], [(/$/), "s" ] ], - + singulars: [ [(/(quiz)zes$/i), "$1" ], @@ -50615,7 +52772,7 @@ Ext.define('Ext.util.Inflector', { [(/people$/i), "person" ], [(/s$/i), "" ] ], - + uncountable: [ "sheep", @@ -50632,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; @@ -50667,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)) { @@ -50689,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"; @@ -50761,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); @@ -50879,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 = '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, @@ -50941,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]; @@ -50970,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); } @@ -51011,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]); @@ -51020,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'); @@ -51048,7 +53203,66 @@ Ext.define('Ext.data.JsonPStore', { Ext.define('Ext.data.NodeInterface', { requires: ['Ext.data.Field'], + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + statics: { decorate: function(record) { @@ -51059,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, @@ -51114,7 +53323,7 @@ Ext.define('Ext.data.NodeInterface', { }); record.commit(true); - + record.enableBubble([ "append", @@ -51139,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, @@ -51166,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, @@ -51192,7 +53401,7 @@ Ext.define('Ext.data.NodeInterface', { return Ext.data.NodeInterface.decorate(node); }, - + isLeaf : function() { return this.get('leaf') === true; @@ -51224,8 +53433,8 @@ Ext.define('Ext.data.NodeInterface', { while (parent.parentNode) { ++depth; parent = parent.parentNode; - } - + } + me.beginEdit(); me.set({ isFirst: isFirst, @@ -51238,7 +53447,7 @@ Ext.define('Ext.data.NodeInterface', { if (silent) { me.commit(); } - + for (i = 0; i < len; i++) { children[i].updateInfo(silent); } @@ -51261,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; }, @@ -51280,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; @@ -51306,7 +53520,7 @@ Ext.define('Ext.data.NodeInterface', { node.nextSibling = null; me.setLastChild(node); - + ps = me.childNodes[index - 1]; if (ps) { node.previousSibling = ps; @@ -51317,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; @@ -51348,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) { @@ -51363,7 +53577,7 @@ Ext.define('Ext.data.NodeInterface', { if (me.lastChild == node) { me.setLastChild(node.previousSibling); } - + if (node.previousSibling) { node.previousSibling.nextSibling = node.nextSibling; @@ -51377,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 { @@ -51412,7 +53626,7 @@ Ext.define('Ext.data.NodeInterface', { clear : function(destroy) { var me = this; - + me.parentNode = me.previousSibling = me.nextSibling = null; if (destroy) { @@ -51423,19 +53637,22 @@ Ext.define('Ext.data.NodeInterface', { destroy : function(silent) { - var me = this; - + var me = this, + options = me.destroyOptions; + if (silent === true) { me.clear(true); Ext.each(me.childNodes, function(n) { n.destroy(true); }); me.childNodes = null; + delete me.destroyOptions; + me.callOverridden([options]); } else { + me.destroyOptions = silent; + me.remove(true); } - - me.callOverridden(); }, @@ -51445,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; @@ -51457,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--; @@ -51479,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; @@ -51493,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()); @@ -51509,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) { @@ -51555,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; @@ -51567,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'); }, @@ -51666,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(); @@ -51686,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) { @@ -51724,7 +53956,7 @@ Ext.define('Ext.data.NodeInterface', { } return true; }, - + expand: function(recursive, callback, scope) { var me = this; @@ -51735,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, @@ -51787,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]); } }, @@ -51806,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) { @@ -51826,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, @@ -51846,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]); } } }; @@ -51882,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]); @@ -52101,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); } @@ -52136,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", @@ -52184,7 +54441,7 @@ Ext.define('Ext.data.Tree', { "rootchange" ]); - + node.on({ scope: me, insert: me.onNodeInsert, @@ -52192,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]); @@ -52213,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); }, @@ -52235,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); @@ -52261,6 +54529,8 @@ Ext.define('Ext.data.TreeStore', { requires: ['Ext.data.Tree', 'Ext.data.NodeInterface', 'Ext.data.NodeStore'], + + clearOnLoad : true, @@ -52268,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) { @@ -52290,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.'); @@ -52368,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); @@ -52393,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()) { @@ -52420,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); @@ -52433,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) { @@ -52463,12 +54731,12 @@ Ext.define('Ext.data.TreeStore', { } } }, - + setRootNode: function(root) { var me = this; - root = root || {}; + root = root || {}; if (!root.isNode) { Ext.applyIf(root, { @@ -52483,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(); @@ -52511,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) { @@ -52523,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) { @@ -52553,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; }, @@ -52569,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) { @@ -52643,7 +54915,7 @@ Ext.define('Ext.data.TreeStore', { removeAll: function() { - this.getRootNode().destroy(); + this.getRootNode().destroy(true); this.fireEvent('clear', this); }, @@ -52656,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', @@ -52687,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."); } }); @@ -52739,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; @@ -52763,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); @@ -52780,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)); } @@ -52837,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(); }, @@ -52868,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++) { @@ -52903,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(); @@ -52918,7 +55311,7 @@ Ext.define('Ext.data.proxy.WebStorage', { } operation.setSuccessful(); } - + operation.setCompleted(); operation.resultSet = Ext.create('Ext.data.ResultSet', { @@ -52944,7 +55337,7 @@ Ext.define('Ext.data.proxy.WebStorage', { for (i = 0; i < length; i++) { record = records[i]; this.setRecord(record); - + id = record.getId(); @@ -52978,7 +55371,7 @@ Ext.define('Ext.data.proxy.WebStorage', { } this.setIds(newIds); - + operation.setCompleted(); operation.setSuccessful(); @@ -53013,7 +55406,7 @@ Ext.define('Ext.data.proxy.WebStorage', { this.cache[id] = record; } - + return this.cache[id]; }, @@ -53047,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)); @@ -53060,7 +55453,7 @@ Ext.define('Ext.data.proxy.WebStorage', { removeRecord: function(id, updateIds) { var me = this, ids; - + if (id.isModel) { id = id.getId(); } @@ -53109,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); } @@ -53123,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; }, @@ -53160,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"); } }); @@ -53286,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; @@ -53307,58 +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; - createAccessor: function() { - var selectValue = function(expr, root){ - var node = Ext.DomQuery.selectNode(expr, root), - val; - - - - }; + if (Ext.isEmpty(expr)) { + return Ext.emptyFn; + } - return 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; - }; + if (Ext.isFunction(expr)) { + return expr; + } + + return function(root) { + 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; }, @@ -53372,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)) { @@ -53386,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 { @@ -53398,7 +55768,7 @@ Ext.define('Ext.data.reader.Xml', { } return this.callParent([root]); }, - + getAssociatedDataRoot: function(data, associationName) { return Ext.DomQuery.select(associationName, data)[0]; @@ -53410,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', { @@ -53486,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; @@ -53540,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; @@ -53577,7 +55947,7 @@ Ext.define('Ext.direct.Provider', { connect: Ext.emptyFn, - + disconnect: Ext.emptyFn }); @@ -53585,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)) { @@ -53614,7 +55984,7 @@ Ext.define('Ext.direct.JsonProvider', { event, i = 0, len; - + try{ data = this.parseResponse(response); } catch(e) { @@ -53626,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])); @@ -53636,7 +56006,7 @@ Ext.define('Ext.direct.JsonProvider', { } return events; }, - + createEvent: function(response){ return Ext.create('direct.' + response.type, response); @@ -53705,7 +56075,6 @@ Ext.define('Ext.direct.PollingProvider', { }); me.fireEvent('connect', me); } else if (!url) { - Ext.Error.raise('Error initializing PollingProvider, no url configured.'); } }, @@ -53744,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)) { @@ -53765,7 +56134,7 @@ Ext.define('Ext.direct.RemotingMethod', { }); } }, - + getCallData: function(args){ var me = this, @@ -53775,7 +56144,7 @@ Ext.define('Ext.direct.RemotingMethod', { callback, scope, name; - + if (me.ordered) { callback = args[len]; scope = args[len + 1]; @@ -53786,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)) { @@ -53796,11 +56165,11 @@ Ext.define('Ext.direct.RemotingMethod', { } } } - + return { data: data, callback: callback, - scope: scope + scope: scope }; } }); @@ -53818,7 +56187,8 @@ Ext.define('Ext.direct.Transaction', { }, - + + constructor: function(config){ var me = this; @@ -53950,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.'); } }, @@ -54321,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)]; }, @@ -54349,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]); @@ -54369,6 +56738,7 @@ Ext.define('Ext.draw.Matrix', { } }); + Ext.define('Ext.draw.SpriteDD', { extend: 'Ext.dd.DragSource', @@ -54398,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) { @@ -54417,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: { @@ -54460,6 +56827,38 @@ Ext.define('Ext.draw.Sprite', { + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + dirty: false, dirtyHidden: false, dirtyTransform: false, @@ -54538,12 +56937,13 @@ Ext.define('Ext.draw.Sprite', { }, + initDraggable: function() { var me = this; me.draggable = true; if (!me.el) { - me.surface.createSprite(me); + me.surface.createSpriteElement(me); } me.dd = Ext.create('Ext.draw.SpriteDD', me, Ext.isBoolean(me.draggable) ? null : me.draggable); me.on('beforedestroy', me.dd.destroy, me.dd); @@ -54561,6 +56961,7 @@ Ext.define('Ext.draw.Sprite', { spriteAttrs = me.attr, attr, i, translate, translation, rotate, rotation, scale, scaling; + attrs = Ext.apply({}, attrs); for (attr in custom) { if (attrs.hasOwnProperty(attr) && typeof custom[attr] == "function") { Ext.apply(attrs, custom[attr].apply(me, [].concat(attrs[attr]))); @@ -54609,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); @@ -54621,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)) { @@ -54644,7 +57045,7 @@ Ext.define('Ext.draw.Sprite', { getBBox: function() { return this.surface.getBBox(this); }, - + setText: function(text) { return this.surface.setText(this, text); }, @@ -54721,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'], @@ -54741,6 +57142,8 @@ Ext.define('Ext.draw.engine.Svg', { strokeOpacity: "stroke-opacity", strokeLinejoin: "stroke-linejoin" }, + + parsers: {}, minDefaults: { circle: { @@ -55144,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) { @@ -55158,8 +57567,8 @@ Ext.define('Ext.draw.engine.Svg', { attrs = me.scrubAttrs(sprite) || {}; - sprite.bbox.plain = 0; - sprite.bbox.transform = 0; + sprite.bbox.plain = 0; + sprite.bbox.transform = 0; if (sprite.type == "circle" || sprite.type == "ellipse") { attrs.cx = attrs.cx || attrs.x; attrs.cy = attrs.cy || attrs.y; @@ -55168,10 +57577,13 @@ Ext.define('Ext.draw.engine.Svg', { attrs.rx = attrs.ry = attrs.r; } else if (sprite.type == "path" && attrs.d) { - attrs.d = Ext.draw.Draw.pathToAbsolute(attrs.d); + attrs.d = Ext.draw.Draw.pathToString(Ext.draw.Draw.pathToAbsolute(attrs.d)); } sprite.dirtyPath = false; + + + if (attrs['clip-rect']) { me.setClip(sprite, attrs); @@ -55192,9 +57604,22 @@ Ext.define('Ext.draw.engine.Svg', { } for (key in attrs) { if (attrs.hasOwnProperty(key) && attrs[key] != null) { - el.dom.setAttribute(key, String(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); } @@ -55246,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; }, @@ -55269,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; }, @@ -55352,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); } } } @@ -55378,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'], @@ -55400,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, @@ -55445,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", @@ -55456,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", @@ -55523,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, @@ -55545,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, @@ -55553,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; @@ -55585,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) { @@ -55630,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; } @@ -55661,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, @@ -55682,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); @@ -55727,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') { @@ -55742,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); } @@ -55754,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; } @@ -55782,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) { @@ -55837,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"]; @@ -55845,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; @@ -55961,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) { @@ -56036,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"); @@ -56118,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); + } } } }, @@ -56368,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); + } } }, @@ -56388,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', { @@ -56419,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; @@ -56429,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, @@ -56514,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); } }); @@ -56553,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 = { @@ -56591,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); @@ -56625,32 +59144,46 @@ Ext.define('Ext.selection.Model', { } }, - selectAll: function(silent) { - var selections = this.store.getRange(), + + selectAll: function(suppressEvent) { + var me = this, + selections = me.store.getRange(), i = 0, - len = selections.length; - + len = selections.length, + start = me.getSelection().length; + + me.bulkChange = true; for (; i < len; i++) { - this.doSelect(selections[i], true, silent); + me.doSelect(selections[i], true, suppressEvent); } + delete me.bulkChange; + + me.maybeFireSelectionChange(me.getSelection().length !== start); }, - deselectAll: function() { - var selections = this.getSelection(), + + deselectAll: function(suppressEvent) { + var me = this, + selections = me.getSelection(), i = 0, - len = selections.length; - + len = selections.length, + start = me.getSelection().length; + + me.bulkChange = true; for (; i < len; i++) { - this.doDeselect(selections[i]); + me.doDeselect(selections[i], suppressEvent); } + delete me.bulkChange; + + me.maybeFireSelectionChange(me.getSelection().length !== start); }, - selectWithEvent: function(record, e) { + selectWithEvent: function(record, e, keepExisting) { var me = this; - + switch (me.selectionMode) { case 'MULTI': if (e.ctrlKey && me.isSelected(record)) { @@ -56660,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); } @@ -56693,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; @@ -56727,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) { @@ -56739,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; } @@ -56774,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(), true); } for (; i < len; i++) { @@ -56792,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); @@ -56807,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; } @@ -56847,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); }, @@ -56866,7 +59430,7 @@ Ext.define('Ext.selection.Model', { me.lastFocused = record; me.onLastFocusChanged(recordBeforeLast, record, supressFocus); }, - + isFocused: function(record) { return record === this.getLastFocused(); @@ -56876,8 +59440,8 @@ Ext.define('Ext.selection.Model', { maybeFireSelectionChange: function(fireEvent) { - if (fireEvent) { - var me = this; + var me = this; + if (fireEvent && !me.bulkChange) { me.fireEvent('selectionchange', me, me.getSelection()); } }, @@ -56886,7 +59450,7 @@ Ext.define('Ext.selection.Model', { getLastSelected: function() { return this.lastSelected; }, - + getLastFocused: function() { return this.lastFocused; }, @@ -56924,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; @@ -56957,7 +59521,7 @@ Ext.define('Ext.selection.Model', { } me.clearSelections(); - + if (me.store.indexOf(lastFocused) !== -1) { this.setLastFocused(lastFocused, true); @@ -56967,16 +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); }, @@ -56987,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); } }, @@ -57004,7 +59563,7 @@ Ext.define('Ext.selection.Model', { onStoreRemove: function(store, record) { var me = this, selected = me.selected; - + if (me.locked || !me.pruneRemoved) { return; } @@ -57020,6 +59579,7 @@ Ext.define('Ext.selection.Model', { } }, + getCount: function() { return this.selected.getCount(); }, @@ -57057,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 = { @@ -57105,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 }); @@ -57125,7 +59691,7 @@ Ext.define('Ext.selection.DataViewModel', { scope: me }); }, - + onNavKey: function(step) { step = step || 1; var me = this, @@ -57133,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(); } }); @@ -57178,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 = "/"; @@ -57187,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; @@ -57216,7 +59793,7 @@ Ext.define('Ext.state.CookieProvider', { matches, name, value; - + while((matches = re.exec(c)) != null){ name = matches[1]; value = matches[2]; @@ -57230,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)) + @@ -57241,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)) + @@ -57249,6 +59826,8 @@ Ext.define('Ext.state.CookieProvider', { } }); + + Ext.define('Ext.state.LocalStorageProvider', { @@ -57309,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', { @@ -57331,6 +59908,7 @@ Ext.define('Ext.util.Point', { + constructor: function(x, y) { this.callParent([y, x, y, x]); }, @@ -57368,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', @@ -57378,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, - + @@ -57432,12 +60206,12 @@ Ext.define('Ext.view.AbstractView', { last: false, - + triggerEvent: 'itemclick', triggerCtEvent: 'containerclick', - + addCmpEvents: function() { - + }, @@ -57446,7 +60220,7 @@ Ext.define('Ext.view.AbstractView', { isDef = Ext.isDefined, itemTpl = me.itemTpl, memberFn = {}; - + if (itemTpl) { if (Ext.isArray(itemTpl)) { @@ -57456,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', @@ -57518,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'; @@ -57585,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; } @@ -57603,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(); @@ -57623,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; }, @@ -57661,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); + } } }, @@ -57683,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); @@ -57698,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){ @@ -57720,7 +60494,7 @@ Ext.define('Ext.view.AbstractView', { } me.fireEvent('itemremove', record, index); }, - + doRemove: function(record, index) { this.all.removeElement(index, true); }, @@ -57733,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) { @@ -57752,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, @@ -57769,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; @@ -57785,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); + } } }, @@ -57810,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()); @@ -57849,7 +60647,7 @@ Ext.define('Ext.view.AbstractView', { getRecord: function(node){ return this.store.data.getByKey(Ext.getDom(node).viewRecordId); }, - + isSelected : function(node) { @@ -57857,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); @@ -57870,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, @@ -57926,7 +60729,7 @@ Ext.define('Ext.view.AbstractView', { onDestroy : function() { var me = this; - + me.all.clear(); me.callParent(); me.bindStore(null); @@ -57936,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; } @@ -57958,31 +60767,39 @@ Ext.define('Ext.view.AbstractView', { - + getSelectionCount : function(){ - console.warn("DataView: getSelectionCount will be removed, please interact with the Ext.selection.DataViewModel"); + if (Ext.global.console) { + Ext.global.console.warn("DataView: getSelectionCount will be removed, please interact with the Ext.selection.DataViewModel"); + } return this.selModel.getSelection().length; }, - + getSelectedRecords : function(){ - console.warn("DataView: getSelectedRecords will be removed, please interact with the Ext.selection.DataViewModel"); + if (Ext.global.console) { + Ext.global.console.warn("DataView: getSelectedRecords will be removed, please interact with the Ext.selection.DataViewModel"); + } return this.selModel.getSelection(); }, - + select: function(records, keepExisting, supressEvents) { - console.warn("DataView: select will be removed, please access select through a DataView's SelectionModel, ie: view.getSelectionModel().select()"); + 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()"); + } var sm = this.getSelectionModel(); return sm.select.apply(sm, arguments); }, - + clearSelections: function() { - console.warn("DataView: clearSelections will be removed, please access deselectAll through DataView's SelectionModel, ie: view.getSelectionModel().deselectAll()"); + if (Ext.global.console) { + Ext.global.console.warn("DataView: clearSelections will be removed, please access deselectAll through DataView's SelectionModel, ie: view.getSelectionModel().deselectAll()"); + } var sm = this.getSelectionModel(); return sm.deselectAll(); } - }); + }); }); }); @@ -58001,6 +60818,7 @@ Ext.define('Ext.Action', { + constructor : function(config){ this.initialConfig = config; this.itemId = config.itemId = (config.itemId || config.id || Ext.id()); @@ -58088,9 +60906,12 @@ Ext.define('Ext.Action', { callEach : function(fnName, args){ - var cs = this.items; - for(var i = 0, len = cs.length; i < len; i++){ - cs[i][fnName].apply(cs[i], args); + var items = this.items, + i = 0, + len = items.length; + + for(; i < len; i++){ + items[i][fnName].apply(items[i], args); } }, @@ -58102,7 +60923,7 @@ Ext.define('Ext.Action', { removeComponent : function(comp){ - this.items.remove(comp); + Ext.Array.remove(this.items, comp); }, @@ -58246,8 +61067,10 @@ Ext.define('Ext.Editor', { me.addEvents( 'beforestartedit', + 'startedit', + 'beforecomplete', @@ -58267,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' + ]); + } } }, @@ -58484,6 +61310,9 @@ Ext.define('Ext.Img', { }, + initRenderTpl: Ext.emptyFn, + + setSrc: function(src) { var me = this, img = me.el; @@ -58503,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; @@ -58537,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) { @@ -58567,7 +61397,7 @@ Ext.define('Ext.Layer', { if (config.hidden === true) { me.hide(); } else { - this.show(); + me.show(); } }, @@ -58599,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); } } }, @@ -58632,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); } @@ -58658,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'; @@ -58678,7 +61520,7 @@ Ext.define('Ext.Layer', { shim.setLeftTop(l, t); } } - return this; + return me; }, remove: function() { @@ -58708,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], @@ -58765,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; }, @@ -58810,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; }, @@ -58851,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); } }); @@ -58958,6 +61817,15 @@ Ext.define('Ext.ProgressBar', { ], uses: ['Ext.fx.Anim'], + + + + + + + + + baseCls: Ext.baseCSSPrefix + 'progress', @@ -58976,7 +61844,7 @@ Ext.define('Ext.ProgressBar', { '
', '
 
', '
', - '
', + '
', '
', '
 
', '
', @@ -58989,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( @@ -59004,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); @@ -59018,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) { @@ -59058,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; }, @@ -59089,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) { @@ -59154,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; @@ -59175,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) { @@ -59243,7 +62131,7 @@ Ext.define('Ext.Shadow', { break; } } - this.adjusts = adjusts; + me.adjusts = adjusts; }, @@ -59255,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"; }, @@ -59323,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; } }, @@ -59336,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', @@ -59360,7 +62267,7 @@ Ext.define('Ext.button.Split', { this.addEvents("arrowclick"); }, - + setArrowHandler : function(handler, scope){ this.arrowHandler = handler; this.scope = scope; @@ -59373,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', { @@ -59547,9 +62445,9 @@ Ext.define('Ext.container.ButtonGroup', { frame: true, - + frameHeader: false, - + internalDefaults: {removeMode: 'container', hideParent: true}, initComponent : function(){ @@ -59570,7 +62468,7 @@ Ext.define('Ext.container.ButtonGroup', { afterLayout: function() { var me = this; - + me.callParent(arguments); @@ -59579,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')) { @@ -59637,19 +62550,33 @@ Ext.define('Ext.container.Viewport', { + + + + + + + + + + + + + isViewport: true, ariaRole: 'application', + initComponent : function() { var me = this, html = Ext.fly(document.body.parentNode), @@ -59665,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); - } }); @@ -59684,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); @@ -59801,6 +62729,9 @@ Ext.define('Ext.dd.DragTracker', { 'mousemove', + 'beforedragstart', + + 'dragstart', @@ -59911,27 +62842,30 @@ Ext.define('Ext.dd.DragTracker', { this.startXY = this.lastXY = e.getXY(); this.startRegion = Ext.fly(this.dragTarget).getRegion(); - if (this.fireEvent('mousedown', this, e) !== false && this.onBeforeStart(e) !== false) { + if (this.fireEvent('mousedown', this, e) === false || + this.fireEvent('beforedragstart', this, e) === false || + this.onBeforeStart(e) === false) { + return; + } - - - this.mouseIsDown = true; + + + this.mouseIsDown = true; - - e.dragTracked = true; + + e.dragTracked = true; - if (this.preventDefault !== false) { - e.preventDefault(); - } - Ext.getDoc().on({ - scope: this, - mouseup: this.onMouseUp, - mousemove: this.onMouseMove, - selectstart: this.stopSelect - }); - if (this.autoStart) { - this.timer = Ext.defer(this.triggerStart, this.autoStart === true ? 1000 : this.autoStart, this, [e]); - } + if (this.preventDefault !== false) { + e.preventDefault(); + } + Ext.getDoc().on({ + scope: this, + mouseup: this.onMouseUp, + mousemove: this.onMouseMove, + selectstart: this.stopSelect + }); + if (this.autoStart) { + this.timer = Ext.defer(this.triggerStart, this.autoStart === true ? 1000 : this.autoStart, this, [e]); } }, @@ -59972,9 +62906,6 @@ Ext.define('Ext.dd.DragTracker', { this.mouseIsDown = false; - delete e.dragTracked; - - if (this.mouseIsOut) { this.mouseIsOut = false; this.onMouseOut(e); @@ -60000,6 +62931,9 @@ Ext.define('Ext.dd.DragTracker', { } delete this._constrainRegion; + + + delete Ext.EventObject.dragTracked; }, triggerStart: function(e) { @@ -60069,7 +63003,7 @@ Ext.define('Ext.dd.DragTracker', { }, getXY : function(constrain){ - return constrain ? this.constrainModes[constrain].call(this, this.lastXY) : this.lastXY; + return constrain ? this.constrainModes[constrain](this, this.lastXY) : this.lastXY; }, @@ -60082,9 +63016,9 @@ Ext.define('Ext.dd.DragTracker', { constrainModes: { - point: function(xy) { - var dr = this.dragRegion, - constrainTo = this.getConstrainRegion(); + point: function(me, xy) { + var dr = me.dragRegion, + constrainTo = me.getConstrainRegion(); if (!constrainTo) { @@ -60099,10 +63033,10 @@ Ext.define('Ext.dd.DragTracker', { }, - dragTarget: function(xy) { - var s = this.startXY, - dr = this.startRegion.copy(), - constrainTo = this.getConstrainRegion(), + dragTarget: function(me, xy) { + var s = me.startXY, + dr = me.startRegion.copy(), + constrainTo = me.getConstrainRegion(), adjust; @@ -60113,7 +63047,7 @@ Ext.define('Ext.dd.DragTracker', { - dr.translateBy.apply(dr, [xy[0]-s[0], xy[1]-s[1]]); + dr.translateBy(xy[0]-s[0], xy[1]-s[1]); if (dr.right > constrainTo.right) { @@ -60141,6 +63075,7 @@ Ext.define('Ext.dd.DragZone', { extend: 'Ext.dd.DragSource', + constructor : function(el, config){ this.callParent([el, config]); if (this.containerScroll) { @@ -60175,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(){ @@ -60363,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); @@ -60633,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( @@ -60755,7 +63685,7 @@ Ext.define('Ext.form.action.Action', { - + submitEmptyText : true, @@ -60764,8 +63694,7 @@ Ext.define('Ext.form.action.Action', { - - + constructor: function(config) { if (config) { Ext.apply(this, config); @@ -60922,7 +63851,7 @@ Ext.define('Ext.form.action.Submit', { tag: 'input', type: 'hidden', name: name, - value: val + value: Ext.String.htmlEncode(val) }); } @@ -60952,7 +63881,7 @@ Ext.define('Ext.form.action.Submit', { } - formEl = Ext.core.DomHelper.append(Ext.getBody(), formSpec); + formEl = Ext.DomHelper.append(Ext.getBody(), formSpec); @@ -61022,6 +63951,7 @@ Ext.define('Ext.util.ComponentDragger', { autoStart: 500, + constructor: function(comp, config) { this.comp = comp; this.initialConstrainTo = config.constrainTo; @@ -61089,7 +64019,7 @@ Ext.define('Ext.util.ComponentDragger', { comp = (me.proxy && !me.comp.liveDrag) ? me.proxy : me.comp, offset = me.getOffset(me.constrain || me.constrainDelegate ? 'dragTarget' : null); - comp.setPosition.apply(comp, [me.startPosition[0] + offset[0], me.startPosition[1] + offset[1]]); + comp.setPosition(me.startPosition[0] + offset[0], me.startPosition[1] + offset[1]); }, onEnd: function(e) { @@ -61105,12 +64035,13 @@ Ext.define("Ext.form.Labelable", { labelableRenderTpl: [ '', - ' for="{inputId}" class="{labelCls}" style="{labelStyle}">', + '', '', - '
id="{baseBodyCls}-{inputId}" role="presentation">{subTplMarkup}
', - '', + '', + '', '', { compiled: true, @@ -61135,6 +64066,8 @@ Ext.define("Ext.form.Labelable", { labelCls: Ext.baseCSSPrefix + 'form-item-label', + + errorMsgCls: Ext.baseCSSPrefix + 'form-error-msg', @@ -61203,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; @@ -61222,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' + ); }, @@ -61333,12 +64268,11 @@ Ext.define("Ext.form.Labelable", { Ext.define('Ext.form.field.Field', { - isFormField : true, - + @@ -61389,7 +64323,7 @@ Ext.define('Ext.form.field.Field', { getValue: function() { return this.value; }, - + setValue: function(value) { var me = this; @@ -61402,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() { @@ -61428,7 +64367,7 @@ Ext.define('Ext.form.field.Field', { reset : function(){ var me = this; - + me.setValue(me.originalValue); me.clearInvalid(); @@ -61507,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(); }, @@ -61581,6 +64525,7 @@ Ext.define('Ext.layout.component.field.Field', { autoHeight: autoHeight, width: autoWidth ? owner.getBodyNaturalWidth() : width, height: height, + setOuterWidth: false, insets: { @@ -61618,14 +64563,18 @@ Ext.define('Ext.layout.component.field.Field', { if (autoWidth && autoHeight) { - me.setElementSize(owner.el, info.width, info.height); + me.setElementSize(owner.el, (info.setOuterWidth ? info.width : undef), info.height); } else { - me.setTargetSize(info.width, info.height); + me.setTargetSize((!autoWidth || info.setOuterWidth ? info.width : undef), info.height); } me.sizeBody(info); me.activeError = owner.getActiveError(); }, + + onFocus: function(){ + this.getErrorStrategy().onFocus(this.owner); + }, @@ -61694,6 +64643,8 @@ Ext.define('Ext.layout.component.field.Field', { if (info.autoWidth) { info.width += (!owner.labelEl ? 0 : owner.labelWidth + owner.labelPad); } + + info.setOuterWidth = true; }, adjustHorizInsets: function(owner, info) { if (owner.labelEl) { @@ -61753,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, @@ -61763,7 +64726,8 @@ Ext.define('Ext.layout.component.field.Field', { adjustHorizInsets: emptyFn, adjustVertInsets: emptyFn, layoutHoriz: emptyFn, - layoutVert: emptyFn + layoutVert: emptyFn, + onFocus: emptyFn }; return { @@ -61792,7 +64756,8 @@ Ext.define('Ext.layout.component.field.Field', { if (owner.hasActiveError()) { setStyle(owner.errorEl, 'top', info.insets.top + 'px'); } - } + }, + onFocus: showTip }, base), @@ -61825,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), @@ -62020,7 +64986,6 @@ Ext.define('Ext.layout.component.field.TextArea', { }); - Ext.define('Ext.layout.container.Anchor', { @@ -62032,7 +64997,6 @@ Ext.define('Ext.layout.container.Anchor', { - type: 'anchor', @@ -62054,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; + box, newTargetSize, component, anchorSpec, calcWidth, calcHeight, + i, el, cleaner; if (ownerWidth < 20 && ownerHeight < 20) { return; @@ -62072,46 +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.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, @@ -62130,6 +65075,7 @@ Ext.define('Ext.layout.container.Anchor', { if (!Ext.supports.RightMargin) { target.removeCls(Ext.baseCSSPrefix + 'inline-children'); + cleaner(); } for (i = 0; i < len; i++) { @@ -62187,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); } }); @@ -62254,12 +65254,19 @@ Ext.define('Ext.window.Window', { alias: 'widget.window', + + + + + + + @@ -62314,11 +65321,11 @@ Ext.define('Ext.window.Window', { floating: true, ariaRole: 'alertdialog', - + itemCls: 'x-window-item', overlapHeader: true, - + ignoreHeaderBorderManagement: true, @@ -62327,13 +65334,18 @@ Ext.define('Ext.window.Window', { me.callParent(); me.addEvents( + + 'resize', + 'maximize', + 'minimize', + 'restore' ); @@ -62395,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); } }, @@ -62435,6 +65452,11 @@ Ext.define('Ext.window.Window', { me.mon(me.el, 'mousedown', me.onMouseDown, me); + + + me.el.set({ + tabIndex: -1 + }); if (me.maximized) { @@ -62445,7 +65467,15 @@ Ext.define('Ext.window.Window', { if (me.closable) { keyMap = me.getKeyMap(); keyMap.on(27, me.onEsc, me); - keyMap.disable(); + + + keyMap.disable(); + + } + + if (!hidden) { + me.syncMonitorWindowResize(); + me.doConstrain(); } }, @@ -62458,21 +65488,24 @@ Ext.define('Ext.window.Window', { me.updateHeader(true); } - ddConfig = Ext.applyIf({ - el: me.el, - delegate: '#' + me.header.id - }, me.draggable); - - if (me.constrain || me.constrainHeader) { - ddConfig.constrain = me.constrain; - ddConfig.constrainDelegate = me.constrainHeader; - ddConfig.constrainTo = me.constrainTo || me.container; - } + if (me.header) { + ddConfig = Ext.applyIf({ + el: me.el, + delegate: '#' + me.header.id + }, me.draggable); - - me.dd = Ext.create('Ext.util.ComponentDragger', this, ddConfig); - me.relayEvents(me.dd, ['dragstart', 'drag', 'dragend']); + + if (me.constrain || me.constrainHeader) { + ddConfig.constrain = me.constrain; + ddConfig.constrainDelegate = me.constrainHeader; + ddConfig.constrainTo = me.constrainTo || me.container; + } + + + me.dd = Ext.create('Ext.util.ComponentDragger', this, ddConfig); + me.relayEvents(me.dd, ['dragstart', 'drag', 'dragend']); + } }, @@ -62553,7 +65586,11 @@ Ext.define('Ext.window.Window', { afterShow: function(animateTarget) { var me = this, - size; + animating = animateTarget || me.animateTarget; + + + + @@ -62563,10 +65600,11 @@ Ext.define('Ext.window.Window', { me.fitContainer(); } - if (me.monitorResize || me.constrain || me.constrainHeader) { - Ext.EventManager.onWindowResize(me.onWindowResize, me); + me.syncMonitorWindowResize(); + if (!animating) { + me.doConstrain(); } - me.doConstrain(); + if (me.keyMap) { me.keyMap.enable(); } @@ -62579,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); } }, @@ -62591,9 +65631,7 @@ Ext.define('Ext.window.Window', { var me = this; - if (me.monitorResize || me.constrain || me.constrainHeader) { - Ext.EventManager.removeResizeListener(me.onWindowResize, me); - } + me.syncMonitorWindowResize(); if (me.keyMap) { @@ -62671,6 +65709,7 @@ Ext.define('Ext.window.Window', { me.el.addCls(Ext.baseCSSPrefix + 'window-maximized'); me.container.addCls(Ext.baseCSSPrefix + 'window-maximized-ct'); + me.syncMonitorWindowResize(); me.setPosition(0, 0); me.fitContainer(); me.fireEvent('maximize', me); @@ -62717,6 +65756,7 @@ Ext.define('Ext.window.Window', { me.container.removeCls(Ext.baseCSSPrefix + 'window-maximized-ct'); + me.syncMonitorWindowResize(); me.doConstrain(); me.fireEvent('restore', me); } @@ -62724,6 +65764,29 @@ Ext.define('Ext.window.Window', { }, + syncMonitorWindowResize: function () { + var me = this, + currentlyMonitoring = me._monitoringResize, + + yes = me.monitorResize || me.constrain || me.constrainHeader || me.maximized, + + veto = me.hidden || me.destroying || me.isDestroyed; + + if (yes && !veto) { + + if (!currentlyMonitoring) { + + Ext.EventManager.onWindowResize(me.onWindowResize, me); + me._monitoringResize = true; + } + } else if (currentlyMonitoring) { + + Ext.EventManager.removeResizeListener(me.onWindowResize, me); + me._monitoringResize = false; + } + }, + + toggleMaximize: function() { return this[this.maximized ? 'restore': 'maximize'](); } @@ -62731,6 +65794,7 @@ Ext.define('Ext.window.Window', { }); + Ext.define('Ext.form.field.Base', { extend: 'Ext.Component', mixins: { @@ -62741,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}" ', @@ -62797,9 +65862,9 @@ Ext.define('Ext.form.field.Base', { hasFocus : false, - + baseCls: Ext.baseCSSPrefix + 'field', - + maskOnDisable: false, @@ -62842,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, @@ -62852,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()); @@ -62882,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); @@ -63111,6 +66182,7 @@ Ext.define('Ext.form.field.Base', { } if (!me.hasFocus) { me.hasFocus = true; + me.componentLayout.onFocus(); me.fireEvent('focus', me); } }, @@ -63123,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); @@ -63216,7 +66293,7 @@ Ext.define('Ext.form.field.Text', { alternateClassName: ['Ext.form.TextField', 'Ext.form.Text'], - + @@ -63226,13 +66303,13 @@ Ext.define('Ext.form.field.Text', { growMin : 30, - + growMax : 800, growAppend: 'W', - + @@ -63241,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 : '', - + @@ -63298,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); @@ -63319,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); }, @@ -63327,7 +66404,7 @@ Ext.define('Ext.form.field.Text', { this.callParent(); this.autoSize(); }, - + afterRender: function(){ var me = this; if (me.enforceMaxLength) { @@ -63350,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) { @@ -63402,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) { @@ -63453,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; } @@ -63485,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(); @@ -63555,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; @@ -63721,8 +66799,6 @@ Ext.define('Ext.window.MessageBox', { 'Ext.layout.container.HBox', 'Ext.ProgressBar' ], - - alternateClassName: 'Ext.MessageBox', alias: 'widget.messagebox', @@ -63793,7 +66869,7 @@ Ext.define('Ext.window.MessageBox', { wait: 'Loading...', alert: 'Attention' }, - + iconHeight: 35, makeButton: function(btnIdx) { @@ -63917,7 +66993,7 @@ Ext.define('Ext.window.MessageBox', { onPromptKey: function(textField, e) { var me = this, blur; - + if (e.keyCode === Ext.EventObject.RETURN || e.keyCode === 10) { if (me.msgButtons.ok.isVisible()) { blur = true; @@ -63926,7 +67002,7 @@ Ext.define('Ext.window.MessageBox', { me.msgButtons.yes.handler.call(me, me.msgButtons.yes); blur = true; } - + if (blur) { me.textField.blur(); } @@ -63948,7 +67024,7 @@ Ext.define('Ext.window.MessageBox', { delete me.defaultFocus; - + me.animateTarget = cfg.animateTarget || undefined; @@ -63970,11 +67046,7 @@ Ext.define('Ext.window.MessageBox', { 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) { @@ -64052,17 +67124,16 @@ Ext.define('Ext.window.MessageBox', { } else { me.bottomTb.show(); } - me.hidden = true; }, show: function(cfg) { var me = this; - + me.reconfigure(cfg); me.addCls(cfg.cls); if (cfg.animateTarget) { - me.doAutoSize(false); + me.doAutoSize(true); me.callParent(); } else { me.callParent(); @@ -64070,11 +67141,11 @@ Ext.define('Ext.window.MessageBox', { } return me; }, - + afterShow: function(){ if (this.animateTarget) { this.center(); - } + } this.callParent(arguments); }, @@ -64086,7 +67157,7 @@ Ext.define('Ext.window.MessageBox', { if (!Ext.isDefined(me.frameWidth)) { me.frameWidth = me.el.getWidth() - me.body.getWidth(); } - + icon.setHeight(iconHeight); @@ -64223,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.window.MessageBox', 'Ext.data.Errors', 'Ext.util.DelayedTask'], + constructor: function(owner, config) { var me = this, onItemAddOrRemove = me.onItemAddOrRemove; @@ -64262,6 +67333,8 @@ Ext.define('Ext.form.Basic', { me.paramOrder = me.paramOrder.split(/[\s,|]/); } + me.checkValidityTask = Ext.create('Ext.util.DelayedTask', me.checkValidity, me); + me.addEvents( 'beforeaction', @@ -64284,7 +67357,9 @@ Ext.define('Ext.form.Basic', { }, + + @@ -64319,6 +67394,7 @@ Ext.define('Ext.form.Basic', { destroy: function() { this.clearListeners(); + this.checkValidityTask.cancel(); }, @@ -64341,18 +67417,24 @@ 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); + } } delete this._boundItems; + if (me.initialized) { - me.onValidityChange(!me.hasInvalidField()); + me.checkValidityTask.delay(10); } }, @@ -64366,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; }, @@ -64493,7 +67578,7 @@ Ext.define('Ext.form.Basic', { this._record = record; return this.setValues(record.data); }, - + getRecord: function() { return this._record; @@ -64973,7 +68058,7 @@ Ext.define('Ext.form.FieldContainer', { combineErrors: false, - + maskOnDisable: false, initComponent: function() { @@ -65002,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); }, @@ -65363,8 +68446,8 @@ Ext.define('Ext.form.FieldSet', { ariaRole: '', - renderTpl: ['
'], - + renderTpl: ['
'], + maskOnDisable: false, getElConfig: function(){ @@ -65381,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'); @@ -65423,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 }); @@ -65441,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; - }, @@ -65453,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, @@ -65472,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; @@ -65487,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), @@ -65515,7 +68631,7 @@ Ext.define('Ext.form.FieldSet', { expand : function(){ return this.setExpanded(true); }, - + collapse : function() { return this.setExpanded(false); @@ -65524,21 +68640,24 @@ Ext.define('Ext.form.FieldSet', { setExpanded: function(expanded) { var me = this, - checkboxCmp = me.checkboxCmp, - toggleCmp = me.toggleCmp; + checkboxCmp = me.checkboxCmp; expanded = !!expanded; - + if (checkboxCmp) { checkboxCmp.setValue(expanded); } - + if (expanded) { me.removeCls(me.baseCls + '-collapsed'); } else { me.addCls(me.baseCls + '-collapsed'); } me.collapsed = !expanded; + if (expanded) { + + me.getComponentLayout().childrenChanged = true; + } me.doComponentLayout(); return me; }, @@ -65625,11 +68744,11 @@ Ext.define('Ext.form.Panel', { initComponent: function() { var me = this; - + if (me.frame) { me.border = false; } - + me.initFieldAncestor(); me.callParent(); @@ -65650,7 +68769,7 @@ Ext.define('Ext.form.Panel', { initItems: function() { var me = this; - + me.form = me.createForm(); me.callParent(); me.form.initialize(); @@ -65665,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(); @@ -65752,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; + } }); @@ -65900,9 +69032,10 @@ Ext.define('Ext.form.field.Checkbox', { alternateClassName: 'Ext.form.Checkbox', requires: ['Ext.XTemplate', 'Ext.form.CheckboxManager'], + fieldSubTpl: [ '', - '', + '', '', @@ -65911,7 +69044,7 @@ Ext.define('Ext.form.field.Checkbox', { 'tabIndex="{tabIdx}" ', 'class="{fieldCls} {typeCls}" autocomplete="off" hidefocus="true" />', '', - '', + '', '', { disableFormats: true, @@ -65979,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, @@ -66018,11 +69151,9 @@ Ext.define('Ext.form.field.Checkbox', { getSubmitValue: function() { - return this.checked ? this.inputValue : (this.uncheckedValue || null); - }, - - getModelData: function() { - return this.getSubmitData(); + var unchecked = this.uncheckedValue, + uncheckedVal = Ext.isDefined(unchecked) ? unchecked : null; + return this.checked ? this.inputValue : uncheckedVal; }, @@ -66030,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); @@ -66078,6 +69209,12 @@ Ext.define('Ext.form.field.Checkbox', { }, + beforeDestroy: function(){ + this.callParent(); + this.getManager().removeAtKey(this.id); + }, + + getManager: function() { return Ext.form.CheckboxManager; }, @@ -66103,6 +69240,7 @@ Ext.define('Ext.form.field.Checkbox', { }, + getBodyNaturalWidth: function() { var me = this, bodyEl = me.bodyEl, @@ -66152,9 +69290,9 @@ 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: { EventMap: { mousedown: 'MouseDown', @@ -66166,10 +69304,11 @@ Ext.define('Ext.view.View', { mouseout: 'MouseOut', mouseenter: 'MouseEnter', mouseleave: 'MouseLeave', - keydown: 'KeyDown' + keydown: 'KeyDown', + focus: 'Focus' } }, - + addCmpEvents: function() { this.addEvents( @@ -66234,7 +69373,7 @@ Ext.define('Ext.view.View', { 'containercontextmenu', 'containerkeydown', - + 'selectionchange', @@ -66243,13 +69382,15 @@ Ext.define('Ext.view.View', { }, afterRender: function(){ - var me = this, + var me = this, listeners; - + me.callParent(); listeners = { scope: me, + + freezeEvent: true, click: me.handleEvent, mousedown: me.handleEvent, mouseup: me.handleEvent, @@ -66259,43 +69400,59 @@ Ext.define('Ext.view.View', { mouseout: me.handleEvent, keydown: me.handleEvent }; - + me.mon(me.getTargetEl(), listeners); - + if (me.store) { me.bindStore(me.store, true); } }, - + handleEvent: function(e) { if (this.processUIEvent(e) !== false) { this.processSpecialEvent(e); } }, - + processItemEvent: Ext.emptyFn, processContainerEvent: Ext.emptyFn, processSpecialEvent: Ext.emptyFn, + - processUIEvent: function(e, type) { - type = type || e.type; + stillOverItem: function (event, overItem) { + var nowOver; + + + + + + + + if (overItem && typeof(overItem.offsetParent) === "object") { + + + nowOver = (event.type == 'mouseout') ? event.getRelatedTarget() : event.getTarget(); + return Ext.fly(overItem).contains(nowOver); + } + + return false; + }, + + processUIEvent: function(e) { var me = this, item = e.getTarget(me.getItemSelector(), me.getTargetEl()), map = this.statics().EventMap, - index, record; - + index, record, + type = e.type, + overItem = me.mouseOverItem, + newType; + if (!item) { - - - - - - - if (type == 'mouseover' && me.mouseOverItem && typeof me.mouseOverItem.offsetParent === "object" && Ext.fly(me.mouseOverItem).getRegion().contains(e.getPoint())) { - item = me.mouseOverItem; + if (type == 'mouseover' && me.stillOverItem(e, overItem)) { + item = overItem; } - + if (type == 'keydown') { record = me.getSelectionModel().getLastSelected(); @@ -66304,54 +69461,53 @@ Ext.define('Ext.view.View', { } } } - + if (item) { index = me.indexOf(item); if (!record) { record = me.getRecord(item); } - - if (me.processItemEvent(type, record, item, index, e) === false) { + + if (me.processItemEvent(record, item, index, e) === false) { return false; } - - type = me.isNewItemEvent(type, item, e); - if (type === false) { + + newType = me.isNewItemEvent(item, e); + if (newType === false) { return false; } - + if ( - (me['onBeforeItem' + map[type]](record, item, index, e) === false) || - (me.fireEvent('beforeitem' + type, me, record, item, index, e) === false) || - (me['onItem' + map[type]](record, item, index, e) === false) - ) { + (me['onBeforeItem' + map[newType]](record, item, index, e) === false) || + (me.fireEvent('beforeitem' + newType, me, record, item, index, e) === false) || + (me['onItem' + map[newType]](record, item, index, e) === false) + ) { return false; } - - me.fireEvent('item' + type, me, record, item, index, e); - } + + me.fireEvent('item' + newType, me, record, item, index, e); + } else { if ( - (me.processContainerEvent(type, e) === false) || + (me.processContainerEvent(e) === false) || (me['onBeforeContainer' + map[type]](e) === false) || (me.fireEvent('beforecontainer' + type, me, e) === false) || (me['onContainer' + map[type]](e) === false) ) { return false; } - + me.fireEvent('container' + type, me, e); } - + return true; }, - - isNewItemEvent: function(type, item, e) { + + isNewItemEvent: function (item, e) { var me = this, overItem = me.mouseOverItem, - contains, - isItem; - + type = e.type; + switch (type) { case 'mouseover': if (item === overItem) { @@ -66359,24 +69515,18 @@ Ext.define('Ext.view.View', { } me.mouseOverItem = item; return 'mouseenter'; - break; - + case 'mouseout': - - if (overItem && typeof overItem.offsetParent === "object") { - contains = Ext.fly(me.mouseOverItem).getRegion().contains(e.getPoint()); - isItem = Ext.fly(e.getTarget()).hasCls(me.itemSelector); - if (contains && isItem) { - return false; - } + + if (me.stillOverItem(e, overItem)) { + return false; } me.mouseOverItem = null; return 'mouseleave'; - break; } return type; }, - + onItemMouseEnter: function(record, item, index, e) { if (this.trackOver) { @@ -66394,19 +69544,21 @@ 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, onBeforeItemDblClick: Ext.emptyFn, onBeforeItemContextMenu: Ext.emptyFn, onBeforeItemKeyDown: Ext.emptyFn, - + onContainerMouseDown: Ext.emptyFn, onContainerMouseUp: Ext.emptyFn, @@ -66424,7 +69576,7 @@ Ext.define('Ext.view.View', { onBeforeContainerDblClick: Ext.emptyFn, onBeforeContainerContextMenu: Ext.emptyFn, onBeforeContainerKeyDown: Ext.emptyFn, - + highlightItem: function(item) { var me = this; @@ -66437,7 +69589,7 @@ Ext.define('Ext.view.View', { clearHighlight: function() { var me = this, highlighted = me.highlightedItem; - + if (highlighted) { Ext.fly(highlighted).removeCls(me.overItemCls); delete me.highlightedItem; @@ -66445,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(); + } } }); @@ -66555,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 @@ -66584,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" />', - '