X-Git-Url: http://git.ithinksw.org/extjs.git/blobdiff_plain/0494b8d9b9bb03ab6c22b34dae81261e3cd7e3e6..7a654f8d43fdb43d78b63d90528bed6e86b608cc:/ext-all-debug.js diff --git a/ext-all-debug.js b/ext-all-debug.js index 00231c85..674494ad 100644 --- a/ext-all-debug.js +++ b/ext-all-debug.js @@ -1,33531 +1,71586 @@ -(function(){ -var EXTUTIL = Ext.util, - EACH = Ext.each, - TRUE = true, - FALSE = false; +(function() { + var global = this, + objectPrototype = Object.prototype, + toString = Object.prototype.toString, + enumerables = true, + enumerablesTest = { toString: 1 }, + i; -EXTUTIL.Observable = function(){ - - var me = this, e = me.events; - if(me.listeners){ - me.on(me.listeners); - delete me.listeners; + if (typeof Ext === 'undefined') { + global.Ext = {}; + } + + Ext.global = global; + + for (i in enumerablesTest) { + enumerables = null; + } + + if (enumerables) { + enumerables = ['hasOwnProperty', 'valueOf', 'isPrototypeOf', 'propertyIsEnumerable', + 'toLocaleString', 'toString', 'constructor']; } - me.events = e || {}; -}; -EXTUTIL.Observable.prototype = { - filterOptRe : /^(?:scope|delay|buffer|single)$/, + Ext.enumerables = enumerables; - fireEvent : function(){ - var a = Array.prototype.slice.call(arguments, 0), - ename = a[0].toLowerCase(), - me = this, - ret = TRUE, - ce = me.events[ename], - cc, - q, - c; - if (me.eventsSuspended === TRUE) { - if (q = me.eventQueue) { - q.push(a); - } + Ext.apply = function(object, config, defaults) { + if (defaults) { + Ext.apply(object, defaults); } - else if(typeof ce == 'object') { - if (ce.bubble){ - if(ce.fire.apply(ce, a.slice(1)) === FALSE) { - return FALSE; + + if (object && config && typeof config === 'object') { + var i, j, k; + + for (i in config) { + object[i] = config[i]; + } + + if (enumerables) { + for (j = enumerables.length; j--;) { + k = enumerables[j]; + if (config.hasOwnProperty(k)) { + object[k] = config[k]; + } } - c = me.getBubbleTarget && me.getBubbleTarget(); - if(c && c.enableBubble) { - cc = c.events[ename]; - if(!cc || typeof cc != 'object' || !cc.bubble) { - c.enableBubble(ename); + } + } + + return object; + }; + + Ext.buildSettings = Ext.apply({ + baseCSSPrefix: 'x-', + scopeResetCSS: false + }, Ext.buildSettings || {}); + + Ext.apply(Ext, { + + emptyFn: function() {}, + + baseCSSPrefix: Ext.buildSettings.baseCSSPrefix, + + + applyIf: function(object, config) { + var property; + + if (object) { + for (property in config) { + if (object[property] === undefined) { + object[property] = config[property]; } - return c.fireEvent.apply(c, a); } } + + return object; + }, + + + iterate: function(object, fn, scope) { + if (Ext.isEmpty(object)) { + return; + } + + if (scope === undefined) { + scope = object; + } + + if (Ext.isIterable(object)) { + Ext.Array.each.call(Ext.Array, object, fn, scope); + } else { - a.shift(); - ret = ce.fire.apply(ce, a); + Ext.Object.each.call(Ext.Object, object, fn, scope); } } - return ret; - }, + }); - - addListener : function(eventName, fn, scope, o){ - var me = this, - e, - oe, - ce; + Ext.apply(Ext, { + + + extend: function() { - if (typeof eventName == 'object') { - o = eventName; - for (e in o) { - oe = o[e]; - if (!me.filterOptRe.test(e)) { - me.addListener(e, oe.fn || oe, oe.scope || o.scope, oe.fn ? oe : o); + var objectConstructor = objectPrototype.constructor, + inlineOverrides = function(o) { + for (var m in o) { + if (!o.hasOwnProperty(m)) { + continue; + } + this[m] = o[m]; + } + }; + + return function(subclass, superclass, overrides) { + + if (Ext.isObject(superclass)) { + overrides = superclass; + superclass = subclass; + subclass = overrides.constructor !== objectConstructor ? overrides.constructor : function() { + superclass.apply(this, arguments); + }; + } + + 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() {}, + subclassProto, superclassProto = superclass.prototype; + + F.prototype = superclassProto; + subclassProto = subclass.prototype = new F(); + subclassProto.constructor = subclass; + subclass.superclass = superclassProto; + + if (superclassProto.constructor === objectConstructor) { + superclassProto.constructor = superclass; } + + subclass.override = function(overrides) { + Ext.override(subclass, overrides); + }; + + subclassProto.override = inlineOverrides; + subclassProto.proto = subclassProto; + + subclass.override(overrides); + subclass.extend = function(o) { + return Ext.extend(subclass, o); + }; + + return subclass; + }; + }(), + + + override: function(cls, overrides) { + if (cls.prototype.$className) { + return cls.override(overrides); } - } else { - eventName = eventName.toLowerCase(); - ce = me.events[eventName] || TRUE; - if (typeof ce == 'boolean') { - me.events[eventName] = ce = new EXTUTIL.Event(me, eventName); + else { + Ext.apply(cls.prototype, overrides); } - ce.addListener(fn, scope, typeof o == 'object' ? o : {}); } - }, + }); - removeListener : function(eventName, fn, scope){ - var ce = this.events[eventName.toLowerCase()]; - if (typeof ce == 'object') { - ce.removeListener(fn, scope); - } - }, + Ext.apply(Ext, { - - purgeListeners : function(){ - var events = this.events, - evt, - key; - for(key in events){ - evt = events[key]; - if(typeof evt == 'object'){ - evt.clearListeners(); + + valueFrom: function(value, defaultValue, allowBlank){ + return Ext.isEmpty(value, allowBlank) ? defaultValue : value; + }, + + + typeOf: function(value) { + if (value === null) { + return 'null'; } - } - }, - - addEvents : function(o){ - var me = this; - me.events = me.events || {}; - if (typeof o == 'string') { - var a = arguments, - i = a.length; - while(i--) { - me.events[a[i]] = me.events[a[i]] || TRUE; + var type = typeof value; + + if (type === 'undefined' || type === 'string' || type === 'number' || type === 'boolean') { + return type; } - } else { - Ext.applyIf(me.events, o); - } - }, - - hasListener : function(eventName){ - var e = this.events[eventName.toLowerCase()]; - return typeof e == 'object' && e.listeners.length > 0; - }, + var typeToString = toString.call(value); - - suspendEvents : function(queueSuspended){ - this.eventsSuspended = TRUE; - if(queueSuspended && !this.eventQueue){ - this.eventQueue = []; - } - }, + switch(typeToString) { + case '[object Array]': + return 'array'; + case '[object Date]': + return 'date'; + case '[object Boolean]': + return 'boolean'; + case '[object Number]': + return 'number'; + case '[object RegExp]': + return 'regexp'; + } - - resumeEvents : function(){ - var me = this, - queued = me.eventQueue || []; - me.eventsSuspended = FALSE; - delete me.eventQueue; - EACH(queued, function(e) { - me.fireEvent.apply(me, e); - }); - } -}; + if (type === 'function') { + return 'function'; + } -var OBSERVABLE = EXTUTIL.Observable.prototype; + if (type === 'object') { + if (value.nodeType !== undefined) { + if (value.nodeType === 3) { + return (/\S/).test(value.nodeValue) ? 'textnode' : 'whitespace'; + } + else { + return 'element'; + } + } -OBSERVABLE.on = OBSERVABLE.addListener; + return 'object'; + } -OBSERVABLE.un = OBSERVABLE.removeListener; + Ext.Error.raise({ + sourceClass: 'Ext', + sourceMethod: 'typeOf', + msg: 'Failed to determine the type of the specified value "' + value + '". This is most likely a bug.' + }); + }, + + isEmpty: function(value, allowEmptyString) { + return (value === null) || (value === undefined) || (!allowEmptyString ? value === '' : false) || (Ext.isArray(value) && value.length === 0); + }, -EXTUTIL.Observable.releaseCapture = function(o){ - o.fireEvent = OBSERVABLE.fireEvent; -}; + + isArray: ('isArray' in Array) ? Array.isArray : function(value) { + return toString.call(value) === '[object Array]'; + }, -function createTargeted(h, o, scope){ - return function(){ - if(o.target == arguments[0]){ - h.apply(scope, Array.prototype.slice.call(arguments, 0)); - } - }; -}; + + isDate: function(value) { + return toString.call(value) === '[object Date]'; + }, -function createBuffered(h, o, l, scope){ - l.task = new EXTUTIL.DelayedTask(); - return function(){ - l.task.delay(o.buffer, h, scope, Array.prototype.slice.call(arguments, 0)); - }; -}; + + isObject: (toString.call(null) === '[object Object]') ? + function(value) { + return value !== null && value !== undefined && toString.call(value) === '[object Object]' && value.nodeType === undefined; + } : + function(value) { + return toString.call(value) === '[object Object]'; + }, -function createSingle(h, e, fn, scope){ - return function(){ - e.removeListener(fn, scope); - return h.apply(scope, arguments); - }; -}; + + isPrimitive: function(value) { + var type = typeof value; -function createDelayed(h, o, l, scope){ - return function(){ - var task = new EXTUTIL.DelayedTask(), - args = Array.prototype.slice.call(arguments, 0); - if(!l.tasks) { - l.tasks = []; - } - l.tasks.push(task); - task.delay(o.delay || 10, function(){ - l.tasks.remove(task); - h.apply(scope, args); - }, scope); - }; -}; + return type === 'string' || type === 'number' || type === 'boolean'; + }, -EXTUTIL.Event = function(obj, name){ - this.name = name; - this.obj = obj; - this.listeners = []; -}; + + isFunction: + + + (typeof document !== 'undefined' && typeof document.getElementsByTagName('body') === 'function') ? function(value) { + return toString.call(value) === '[object Function]'; + } : function(value) { + return typeof value === 'function'; + }, -EXTUTIL.Event.prototype = { - addListener : function(fn, scope, options){ - var me = this, - l; - scope = scope || me.obj; - if(!me.isListening(fn, scope)){ - l = me.createListener(fn, scope, options); - if(me.firing){ - me.listeners = me.listeners.slice(0); - } - me.listeners.push(l); - } - }, + + isNumber: function(value) { + return typeof value === 'number' && isFinite(value); + }, - createListener: function(fn, scope, o){ - o = o || {}; - scope = scope || this.obj; - var l = { - fn: fn, - scope: scope, - options: o - }, h = fn; - if(o.target){ - h = createTargeted(h, o, scope); - } - if(o.delay){ - h = createDelayed(h, o, l, scope); - } - if(o.single){ - h = createSingle(h, this, fn, scope); - } - if(o.buffer){ - h = createBuffered(h, o, l, scope); - } - l.fireFn = h; - return l; - }, + + isNumeric: function(value) { + return !isNaN(parseFloat(value)) && isFinite(value); + }, - findListener : function(fn, scope){ - var list = this.listeners, - i = list.length, - l; + + isString: function(value) { + return typeof value === 'string'; + }, - scope = scope || this.obj; - while(i--){ - l = list[i]; - if(l){ - if(l.fn == fn && l.scope == scope){ - return i; - } - } + + isBoolean: function(value) { + return typeof value === 'boolean'; + }, + + + isElement: function(value) { + return value ? value.nodeType !== undefined : false; + }, + + + isTextNode: function(value) { + return value ? value.nodeName === "#text" : false; + }, + + + isDefined: function(value) { + return typeof value !== 'undefined'; + }, + + + isIterable: function(value) { + return (value && typeof value !== 'string') ? value.length !== undefined : false; } - return -1; - }, + }); - isListening : function(fn, scope){ - return this.findListener(fn, scope) != -1; - }, + Ext.apply(Ext, { - removeListener : function(fn, scope){ - var index, - l, - k, - me = this, - ret = FALSE; - if((index = me.findListener(fn, scope)) != -1){ - if (me.firing) { - me.listeners = me.listeners.slice(0); + + clone: function(item) { + if (item === null || item === undefined) { + return item; + } + + + + + if (item.nodeType && item.cloneNode) { + return item.cloneNode(true); } - l = me.listeners[index]; - if(l.task) { - l.task.cancel(); - delete l.task; + + var type = toString.call(item); + + + if (type === '[object Date]') { + return new Date(item.getTime()); } - k = l.tasks && l.tasks.length; - if(k) { - while(k--) { - l.tasks[k].cancel(); + + var i, j, k, clone, key; + + + if (type === '[object Array]') { + i = item.length; + + clone = []; + + while (i--) { + clone[i] = Ext.clone(item[i]); } - delete l.tasks; } - me.listeners.splice(index, 1); - ret = TRUE; - } - return ret; - }, - - - clearListeners : function(){ - var me = this, - l = me.listeners, - i = l.length; - while(i--) { - me.removeListener(l[i].fn, l[i].scope); - } - }, + + else if (type === '[object Object]' && item.constructor === Object) { + clone = {}; - fire : function(){ - var me = this, - listeners = me.listeners, - len = listeners.length, - i = 0, - l; + for (key in item) { + clone[key] = Ext.clone(item[key]); + } - if(len > 0){ - me.firing = TRUE; - var args = Array.prototype.slice.call(arguments, 0); - for (; i < len; i++) { - l = listeners[i]; - if(l && l.fireFn.apply(l.scope || me.obj || window, args) === FALSE) { - return (me.firing = FALSE); + if (enumerables) { + for (j = enumerables.length; j--;) { + k = enumerables[j]; + clone[k] = item[k]; + } } } - } - me.firing = FALSE; - return TRUE; - } -}; -})(); + return clone || item; + }, -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, - confRe = /tag|children|cn|html$/i, - tableElRe = /td|tr|tbody/i, - cssRe = /([a-z0-9-]+)\s*:\s*([^;\s]+(?:\s*[^;\s]+)*);?/gi, - endRe = /end/i, - pub, - afterbegin = 'afterbegin', - afterend = 'afterend', - beforebegin = 'beforebegin', - beforeend = 'beforeend', - ts = '', - te = '
', - tbs = ts+'', - tbe = ''+te, - trs = tbs + '', - tre = ''+tbe; + getUniqueGlobalNamespace: function() { + var uniqueGlobalNamespace = this.uniqueGlobalNamespace; - - function doInsert(el, o, returnElement, pos, sibling, append){ - var newNode = pub.insertHtml(pos, Ext.getDom(el), createHtml(o)); - return returnElement ? Ext.get(newNode, true) : newNode; - } + if (uniqueGlobalNamespace === undefined) { + var i = 0; - - function createHtml(o){ - var b = '', - attr, - val, - key, - cn; + do { + uniqueGlobalNamespace = 'ExtSandbox' + (++i); + } while (Ext.global[uniqueGlobalNamespace] !== undefined); - if(typeof o == "string"){ - b = o; - } else if (Ext.isArray(o)) { - for (var i=0; i < o.length; i++) { - if(o[i]) { - b += createHtml(o[i]); - } - }; - } else { - b += '<' + (o.tag = o.tag || 'div'); - for (attr in o) { - val = o[attr]; - if(!confRe.test(attr)){ - if (typeof val == "object") { - b += ' ' + attr + '="'; - for (key in val) { - b += key + ':' + val[key] + ';'; - }; - b += '"'; - }else{ - b += ' ' + ({cls : 'class', htmlFor : 'for'}[attr] || attr) + '="' + val + '"'; - } - } - }; - - if (emptyTags.test(o.tag)) { - b += '/>'; - } else { - b += '>'; - if ((cn = o.children || o.cn)) { - b += createHtml(cn); - } else if(o.html){ - b += o.html; - } - b += ''; + Ext.global[uniqueGlobalNamespace] = Ext; + this.uniqueGlobalNamespace = uniqueGlobalNamespace; } - } - return b; - } - function ieTable(depth, s, h, e){ - tempTableEl.innerHTML = [s, h, e].join(''); - var i = -1, - el = tempTableEl, - ns; - while(++i < depth){ - el = el.firstChild; - } + return uniqueGlobalNamespace; + }, - if(ns = el.nextSibling){ - var df = document.createDocumentFragment(); - while(el){ - ns = el.nextSibling; - df.appendChild(el); - el = ns; + + functionFactory: function() { + var args = Array.prototype.slice.call(arguments); + + if (args.length > 0) { + args[args.length - 1] = 'var Ext=window.' + this.getUniqueGlobalNamespace() + ';' + + args[args.length - 1]; } - el = df; + + return Function.prototype.constructor.apply(Function.prototype, args); } - return el; - } + }); - function insertIntoTable(tag, where, el, html) { - var node, - before; + Ext.type = Ext.typeOf; - tempTableEl = tempTableEl || document.createElement('div'); +})(); - if(tag == 'td' && (where == afterbegin || where == beforeend) || - !tableElRe.test(tag) && (where == beforebegin || where == afterend)) { - return; - } - before = where == beforebegin ? el : - where == afterend ? el.nextSibling : - where == afterbegin ? el.firstChild : null; - if (where == beforebegin || where == afterend) { - el = el.parentNode; - } +(function() { - if (tag == 'td' || (tag == 'tr' && (where == beforeend || where == afterbegin))) { - node = ieTable(4, trs, html, tre); - } else if ((tag == 'tbody' && (where == beforeend || where == afterbegin)) || - (tag == 'tr' && (where == beforebegin || where == afterend))) { - node = ieTable(3, tbs, html, tbe); - } else { - node = ieTable(2, ts, html, te); - } - el.insertBefore(node, before); - return node; - } +var version = '4.0.0', Version; + Ext.Version = Version = Ext.extend(Object, { - pub = { - markup : function(o){ - return createHtml(o); + constructor: function(version) { + var parts, releaseStartIndex; + + if (version instanceof Version) { + return version; + } + + this.version = this.shortVersion = String(version).toLowerCase().replace(/_/g, '.').replace(/[\-+]/g, ''); + + releaseStartIndex = this.version.search(/([^\d\.])/); + + if (releaseStartIndex !== -1) { + this.release = this.version.substr(releaseStartIndex, version.length); + this.shortVersion = this.version.substr(0, releaseStartIndex); + } + + this.shortVersion = this.shortVersion.replace(/[^\d]/g, ''); + + parts = this.version.split('.'); + + this.major = parseInt(parts.shift() || 0, 10); + this.minor = parseInt(parts.shift() || 0, 10); + this.patch = parseInt(parts.shift() || 0, 10); + this.build = parseInt(parts.shift() || 0, 10); + + return this; }, - applyStyles : function(el, styles){ - if (styles) { - var matches; + toString: function() { + return this.version; + }, - el = Ext.fly(el); - if (typeof styles == "function") { - styles = styles.call(); - } - if (typeof styles == "string") { - - cssRe.lastIndex = 0; - while ((matches = cssRe.exec(styles))) { - el.setStyle(matches[1], matches[2]); - } - } else if (typeof styles == "object") { - el.setStyle(styles); - } - } + + valueOf: function() { + return this.version; }, - insertHtml : function(where, el, html){ - var hash = {}, - hashVal, - setStart, - range, - frag, - rangeEl, - rs; + getMajor: function() { + return this.major || 0; + }, - where = where.toLowerCase(); - - hash[beforebegin] = ['BeforeBegin', 'previousSibling']; - hash[afterend] = ['AfterEnd', 'nextSibling']; + + getMinor: function() { + return this.minor || 0; + }, - 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']; - if ((hashVal = hash[where])) { - el.insertAdjacentHTML(hashVal[0], html); - return el[hashVal[1]]; - } - } else { - range = el.ownerDocument.createRange(); - setStart = 'setStart' + (endRe.test(where) ? 'After' : 'Before'); - if (hash[where]) { - range[setStart](el); - frag = range.createContextualFragment(html); - el.parentNode.insertBefore(frag, where == beforebegin ? el : el.nextSibling); - return el[(where == beforebegin ? 'previous' : 'next') + 'Sibling']; - } else { - rangeEl = (where == afterbegin ? 'first' : 'last') + 'Child'; - if (el.firstChild) { - range[setStart](el[rangeEl]); - frag = range.createContextualFragment(html); - if(where == afterbegin){ - el.insertBefore(frag, el.firstChild); - }else{ - el.appendChild(frag); - } - } else { - el.innerHTML = html; - } - return el[rangeEl]; - } - } - throw 'Illegal insertion point -> "' + where + '"'; + + getPatch: function() { + return this.patch || 0; }, - insertBefore : function(el, o, returnElement){ - return doInsert(el, o, returnElement, beforebegin); + getBuild: function() { + return this.build || 0; }, - insertAfter : function(el, o, returnElement){ - return doInsert(el, o, returnElement, afterend, 'nextSibling'); + getRelease: function() { + return this.release || ''; }, - insertFirst : function(el, o, returnElement){ - return doInsert(el, o, returnElement, afterbegin, 'firstChild'); + isGreaterThan: function(target) { + return Version.compare(this.version, target) === 1; }, - append : function(el, o, returnElement){ - return doInsert(el, o, returnElement, beforeend, '', true); + isLessThan: function(target) { + return Version.compare(this.version, target) === -1; }, - overwrite : function(el, o, returnElement){ - el = Ext.getDom(el); - el.innerHTML = createHtml(o); - return returnElement ? Ext.get(el.firstChild) : el.firstChild; + equals: function(target) { + return Version.compare(this.version, target) === 0; }, - createHtml : createHtml - }; - return pub; -}(); + + match: function(target) { + target = String(target); + return this.version.substr(0, target.length) === target; + }, -Ext.Template = function(html){ - var me = this, - a = arguments, - buf = [], - v; - - if (Ext.isArray(html)) { - html = html.join(""); - } else if (a.length > 1) { - for(var i = 0, len = a.length; i < len; i++){ - v = a[i]; - if(typeof v == 'object'){ - Ext.apply(me, v); - } else { - buf.push(v); - } - }; - html = buf.join(''); - } + + toArray: function() { + return [this.getMajor(), this.getMinor(), this.getPatch(), this.getBuild(), this.getRelease()]; + }, - - me.html = html; - - if (me.compiled) { - me.compile(); - } -}; -Ext.Template.prototype = { - - re : /\{([\w-]+)\}/g, - + + getShortVersion: function() { + return this.shortVersion; + } + }); - - applyTemplate : function(values){ - var me = this; + Ext.apply(Version, { + + releaseValueMap: { + 'dev': -6, + 'alpha': -5, + 'a': -5, + 'beta': -4, + 'b': -4, + 'rc': -3, + '#': -2, + 'p': -1, + 'pl': -1 + }, - return me.compiled ? - me.compiled(values) : - me.html.replace(me.re, function(m, name){ - return values[name] !== undefined ? values[name] : ""; - }); - }, + + getComponentValue: function(value) { + return !value ? 0 : (isNaN(value) ? this.releaseValueMap[value] || value : parseInt(value, 10)); + }, - - set : function(html, compile){ - var me = this; - me.html = html; - me.compiled = null; - return compile ? me.compile() : me; - }, + + compare: function(current, target) { + var currentValue, targetValue, i; - - compile : function(){ - var me = this, - sep = Ext.isGecko ? "+" : ","; + current = new Version(current).toArray(); + target = new Version(target).toArray(); + + for (i = 0; i < Math.max(current.length, target.length); i++) { + currentValue = this.getComponentValue(current[i]); + targetValue = this.getComponentValue(target[i]); + + if (currentValue < targetValue) { + return -1; + } else if (currentValue > targetValue) { + return 1; + } + } - function fn(m, name){ - name = "values['" + name + "']"; - return "'"+ sep + '(' + name + " == undefined ? '' : " + name + ')' + sep + "'"; + return 0; } + }); - eval("this.compiled = function(values){ return " + (Ext.isGecko ? "'" : "['") + - me.html.replace(/\\/g, '\\\\').replace(/(\r\n|\n)/g, '\\n').replace(/'/g, "\\'").replace(this.re, fn) + - (Ext.isGecko ? "';};" : "'].join('');};")); - return me; - }, + Ext.apply(Ext, { + + versions: {}, - - insertFirst: function(el, values, returnElement){ - return this.doInsert('afterBegin', el, values, returnElement); - }, + + lastRegisteredVersion: null, - - insertBefore: function(el, values, returnElement){ - return this.doInsert('beforeBegin', el, values, returnElement); - }, + + setVersion: function(packageName, version) { + Ext.versions[packageName] = new Version(version); + Ext.lastRegisteredVersion = Ext.versions[packageName]; - - insertAfter : function(el, values, returnElement){ - return this.doInsert('afterEnd', el, values, returnElement); - }, + return this; + }, - - append : function(el, values, returnElement){ - return this.doInsert('beforeEnd', el, values, returnElement); - }, + + getVersion: function(packageName) { + if (packageName === undefined) { + return Ext.lastRegisteredVersion; + } - 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; - }, + return Ext.versions[packageName]; + }, - - overwrite : function(el, values, returnElement){ - el = Ext.getDom(el); - el.innerHTML = this.applyTemplate(values); - return returnElement ? Ext.get(el.firstChild, true) : el.firstChild; - } -}; + + deprecate: function(packageName, since, closure, scope) { + if (Version.compare(Ext.getVersion(packageName), since) < 1) { + closure.call(scope); + } + } + }); -Ext.Template.prototype.apply = Ext.Template.prototype.applyTemplate; + Ext.setVersion('core', version); +})(); -Ext.Template.from = function(el, config){ - el = Ext.getDom(el); - return new Ext.Template(el.value || el.innerHTML, config || ''); -}; -Ext.DomQuery = function(){ - var cache = {}, - simpleCache = {}, - valueCache = {}, - nonSpace = /\S/, - trimRe = /^\s+|\s+$/g, - tplRe = /\{(\d+)\}/g, - modeRe = /^(\s?[\/>+~]\s?|\s|$)/, - tagTokenRe = /^(#)?([\w-\*]+)/, - nthRe = /(\d*)n\+?(\d*)/, - nthRe2 = /\D/, - - - - isIE = window.ActiveXObject ? true : false, - key = 30803; - - - - eval("var batch = 30803;"); +Ext.String = { + trimRegex: /^[\x09\x0a\x0b\x0c\x0d\x20\xa0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u2028\u2029\u202f\u205f\u3000]+|[\x09\x0a\x0b\x0c\x0d\x20\xa0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u2028\u2029\u202f\u205f\u3000]+$/g, + escapeRe: /('|\\)/g, + formatRe: /\{(\d+)\}/g, + escapeRegexRe: /([-.*+?^${}()|[\]\/\\])/g, - - - function child(parent, index){ - var i = 0, - n = parent.firstChild; - while(n){ - if(n.nodeType == 1){ - if(++i == index){ - return n; - } - } - n = n.nextSibling; + /** + * 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 + */ + htmlEncode: (function() { + var entities = { + '&': '&', + '>': '>', + '<': '<', + '"': '"' + }, keys = [], p, regex; + + for (p in entities) { + keys.push(p); } - return null; - } + + regex = new RegExp('(' + keys.join('|') + ')', 'g'); + + return function(value) { + return (!value) ? value : String(value).replace(regex, function(match, capture) { + return entities[capture]; + }); + }; + })(), - function next(n){ - while((n = n.nextSibling) && n.nodeType != 1); - return n; - } + htmlDecode: (function() { + var entities = { + '&': '&', + '>': '>', + '<': '<', + '"': '"' + }, keys = [], p, regex; + + for (p in entities) { + keys.push(p); + } + + regex = new RegExp('(' + keys.join('|') + '|&#[0-9]{1,5};' + ')', 'g'); + + return function(value) { + return (!value) ? value : String(value).replace(regex, function(match, capture) { + if (capture in entities) { + return entities[capture]; + } else { + return String.fromCharCode(parseInt(capture.substr(2), 10)); + } + }); + }; + })(), - function prev(n){ - while((n = n.previousSibling) && n.nodeType != 1); - return n; - } + urlAppend : function(url, string) { + if (!Ext.isEmpty(string)) { + return url + (url.indexOf('?') === -1 ? '?' : '&') + string; + } + + return url; + }, + trim: function(string) { + return string.replace(Ext.String.trimRegex, ""); + }, + - function children(parent){ - var n = parent.firstChild, - nodeIndex = -1, - nextNode; - while(n){ - nextNode = n.nextSibling; - - if(n.nodeType == 3 && !nonSpace.test(n.nodeValue)){ - parent.removeChild(n); - }else{ - - n.nodeIndex = ++nodeIndex; - } - n = nextNode; - } - return this; - } + capitalize: function(string) { + return string.charAt(0).toUpperCase() + string.substr(1); + }, + + + ellipsis: function(value, len, word) { + if (value && value.length > len) { + if (word) { + var vs = value.substr(0, len - 2), + index = Math.max(vs.lastIndexOf(' '), vs.lastIndexOf('.'), vs.lastIndexOf('!'), vs.lastIndexOf('?')); + if (index !== -1 && index >= (len - 15)) { + return vs.substr(0, index) + "..."; + } + } + return value.substr(0, len - 3) + "..."; + } + return value; + }, + + + escapeRegex: function(string) { + return string.replace(Ext.String.escapeRegexRe, "\\$1"); + }, + + escape: function(string) { + return string.replace(Ext.String.escapeRe, "\\$1"); + }, + toggle: function(string, value, other) { + return string === value ? other : value; + }, + - function byClassName(nodeSet, cls){ - if(!cls){ - return nodeSet; - } - var result = [], ri = -1; - for(var i = 0, ci; ci = nodeSet[i]; i++){ - if((' '+ci.className+' ').indexOf(cls) != -1){ - result[++ri] = ci; - } + leftPad: function(string, size, character) { + var result = String(string); + character = character || " "; + while (result.length < size) { + result = character + result; } return result; - }; + }, - function attrValue(n, attr){ - - if(!n.tagName && typeof n.length != "undefined"){ - n = n[0]; - } - if(!n){ - return null; - } + + format: function(format) { + var args = Ext.Array.toArray(arguments, 1); + return format.replace(Ext.String.formatRe, function(m, i) { + return args[i]; + }); + } +}; - if(attr == "for"){ - return n.htmlFor; - } - if(attr == "class" || attr == "className"){ - return n.className; - } - return n.getAttribute(attr) || n[attr]; - }; +(function() { + +var isToFixedBroken = (0.9).toFixed() !== '1'; +Ext.Number = { + constrain: function(number, min, max) { + number = parseFloat(number); + + if (!isNaN(min)) { + number = Math.max(number, min); + } + if (!isNaN(max)) { + number = Math.min(number, max); + } + return number; + }, + + toFixed: function(value, precision) { + if (isToFixedBroken) { + precision = precision || 0; + var pow = Math.pow(10, precision); + return (Math.round(value * pow) / pow).toFixed(precision); + } + + return value.toFixed(precision); + }, + - function getNodes(ns, mode, tagName){ - var result = [], ri = -1, cs; - if(!ns){ - return result; + from: function(value, defaultValue) { + if (isFinite(value)) { + value = parseFloat(value); } - tagName = tagName || "*"; - - if(typeof ns.getElementsByTagName != "undefined"){ - ns = [ns]; + + return !isNaN(value) ? value : defaultValue; + } +}; + +})(); + + +Ext.num = function() { + return Ext.Number.from.apply(this, arguments); +}; + +(function() { + + var arrayPrototype = Array.prototype, + slice = arrayPrototype.slice, + supportsForEach = 'forEach' in arrayPrototype, + supportsMap = 'map' in arrayPrototype, + supportsIndexOf = 'indexOf' in arrayPrototype, + supportsEvery = 'every' in arrayPrototype, + supportsSome = 'some' in arrayPrototype, + supportsFilter = 'filter' in arrayPrototype, + supportsSort = function() { + var a = [1,2,3,4,5].sort(function(){ return 0; }); + return a[0] === 1 && a[1] === 2 && a[2] === 3 && a[3] === 4 && a[4] === 5; + }(), + supportsSliceOnNodeList = true, + ExtArray; + try { + + if (typeof document !== 'undefined') { + slice.call(document.getElementsByTagName('body')); } - - - - if(!mode){ - for(var i = 0, ni; ni = ns[i]; i++){ - cs = ni.getElementsByTagName(tagName); - for(var j = 0, ci; ci = cs[j]; j++){ - result[++ri] = ci; - } - } - - - } else if(mode == "/" || mode == ">"){ - var utag = tagName.toUpperCase(); - for(var i = 0, ni, cn; ni = ns[i]; i++){ - cn = ni.childNodes; - for(var j = 0, cj; cj = cn[j]; j++){ - if(cj.nodeName == utag || cj.nodeName == tagName || tagName == '*'){ - result[++ri] = cj; + } catch (e) { + supportsSliceOnNodeList = false; + } + + ExtArray = Ext.Array = { + + each: function(array, fn, scope, reverse) { + array = ExtArray.from(array); + + var i, + ln = array.length; + + if (reverse !== true) { + for (i = 0; i < ln; i++) { + if (fn.call(scope || array[i], array[i], i, array) === false) { + return i; } } } - - - }else if(mode == "+"){ - var utag = tagName.toUpperCase(); - for(var i = 0, n; n = ns[i]; i++){ - while((n = n.nextSibling) && n.nodeType != 1); - if(n && (n.nodeName == utag || n.nodeName == tagName || tagName == '*')){ - result[++ri] = n; - } - } - - - }else if(mode == "~"){ - var utag = tagName.toUpperCase(); - for(var i = 0, n; n = ns[i]; i++){ - while((n = n.nextSibling)){ - if (n.nodeName == utag || n.nodeName == tagName || tagName == '*'){ - result[++ri] = n; + else { + for (i = ln - 1; i > -1; i--) { + if (fn.call(scope || array[i], array[i], i, array) === false) { + return i; } } } - } - return result; - } - function concat(a, b){ - if(b.slice){ - return a.concat(b); - } - for(var i = 0, l = b.length; i < l; i++){ - a[a.length] = b[i]; - } - return a; - } + return true; + }, - function byTag(cs, tagName){ - if(cs.tagName || cs == document){ - cs = [cs]; - } - if(!tagName){ - return cs; - } - var result = [], ri = -1; - tagName = tagName.toLowerCase(); - for(var i = 0, ci; ci = cs[i]; i++){ - if(ci.nodeType == 1 && ci.tagName.toLowerCase() == tagName){ - result[++ri] = ci; + + forEach: function(array, fn, scope) { + if (supportsForEach) { + return array.forEach(fn, scope); } - } - return result; - } - function byId(cs, id){ - if(cs.tagName || cs == document){ - cs = [cs]; - } - if(!id){ - return cs; - } - var result = [], ri = -1; - for(var i = 0, ci; ci = cs[i]; i++){ - if(ci && ci.id == id){ - result[++ri] = ci; - return result; + var i = 0, + ln = array.length; + + for (; i < ln; i++) { + fn.call(scope, array[i], i, array); } - } - return result; - } + }, - - - function byAttribute(cs, attr, value, op, custom){ - var result = [], - ri = -1, - useGetStyle = custom == "{", - fn = Ext.DomQuery.operators[op], - a, - xml, - hasXml; - - for(var i = 0, ci; ci = cs[i]; i++){ - - if(ci.nodeType != 1){ - continue; + + indexOf: function(array, item, from) { + if (supportsIndexOf) { + return array.indexOf(item, from); } - - if(!hasXml){ - xml = Ext.DomQuery.isXml(ci); - hasXml = true; + + var i, length = array.length; + + for (i = (from < 0) ? Math.max(0, length + from) : from || 0; i < length; i++) { + if (array[i] === item) { + return i; + } } - - - if(!xml){ - if(useGetStyle){ - a = Ext.DomQuery.getStyle(ci, attr); - } else if (attr == "class" || attr == "className"){ - a = ci.className; - } else if (attr == "for"){ - a = ci.htmlFor; - } else if (attr == "href"){ - - - a = ci.getAttribute("href", 2); - } else{ - a = ci.getAttribute(attr); + + return -1; + }, + + + contains: function(array, item) { + if (supportsIndexOf) { + return array.indexOf(item) !== -1; + } + + var i, ln; + + for (i = 0, ln = array.length; i < ln; i++) { + if (array[i] === item) { + return true; } - }else{ - a = ci.getAttribute(attr); } - if((fn && fn(a, value)) || (!fn && a)){ - result[++ri] = ci; + + return false; + }, + + + toArray: function(iterable, start, end){ + if (!iterable || !iterable.length) { + return []; } - } - return result; - } - function byPseudo(cs, name, value){ - return Ext.DomQuery.pseudos[name](cs, value); - } + if (typeof iterable === 'string') { + iterable = iterable.split(''); + } - function nodupIEXml(cs){ - var d = ++key, - r; - cs[0].setAttribute("_nodup", d); - r = [cs[0]]; - for(var i = 1, len = cs.length; i < len; i++){ - var c = cs[i]; - if(!c.getAttribute("_nodup") != d){ - c.setAttribute("_nodup", d); - r[r.length] = c; + if (supportsSliceOnNodeList) { + return slice.call(iterable, start || 0, end || iterable.length); } - } - for(var i = 0, len = cs.length; i < len; i++){ - cs[i].removeAttribute("_nodup"); - } - return r; - } - function nodup(cs){ - if(!cs){ - return []; - } - var len = cs.length, c, i, r = cs, cj, ri = -1; - if(!len || typeof cs.nodeType != "undefined" || len == 1){ - return cs; - } - if(isIE && typeof cs[0].selectSingleNode != "undefined"){ - return nodupIEXml(cs); - } - var d = ++key; - cs[0]._nodup = d; - for(i = 1; c = cs[i]; i++){ - if(c._nodup != d){ - c._nodup = d; - }else{ - r = []; - for(var j = 0; j < i; j++){ - r[++ri] = cs[j]; - } - for(j = i+1; cj = cs[j]; j++){ - if(cj._nodup != d){ - cj._nodup = d; - r[++ri] = cj; - } - } - return r; + var array = [], + i; + + start = start || 0; + end = end ? ((end < 0) ? iterable.length + end : end) : iterable.length; + + for (i = start; i < end; i++) { + array.push(iterable[i]); } - } - return r; - } - function quickDiffIEXml(c1, c2){ - var d = ++key, - r = []; - for(var i = 0, len = c1.length; i < len; i++){ - c1[i].setAttribute("_qdiff", d); - } - for(var i = 0, len = c2.length; i < len; i++){ - if(c2[i].getAttribute("_qdiff") != d){ - r[r.length] = c2[i]; + return array; + }, + + + pluck: function(array, propertyName) { + var ret = [], + i, ln, item; + + for (i = 0, ln = array.length; i < ln; i++) { + item = array[i]; + + ret.push(item[propertyName]); } - } - for(var i = 0, len = c1.length; i < len; i++){ - c1[i].removeAttribute("_qdiff"); - } - return r; - } - function quickDiff(c1, c2){ - var len1 = c1.length, - d = ++key, - r = []; - if(!len1){ - return c2; - } - if(isIE && typeof c1[0].selectSingleNode != "undefined"){ - return quickDiffIEXml(c1, c2); - } - for(var i = 0; i < len1; i++){ - c1[i]._qdiff = d; - } - for(var i = 0, len = c2.length; i < len; i++){ - if(c2[i]._qdiff != d){ - r[r.length] = c2[i]; + return ret; + }, + + + map: function(array, fn, scope) { + if (supportsMap) { + return array.map(fn, scope); } - } - return r; - } - function quickId(ns, mode, root, id){ - if(ns == root){ - var d = root.ownerDocument || root; - return d.getElementById(id); - } - ns = getNodes(ns, mode, "*"); - return byId(ns, id); - } + var results = [], + i = 0, + len = array.length; - return { - getStyle : function(el, name){ - return Ext.fly(el).getStyle(name); + for (; i < len; i++) { + results[i] = fn.call(scope, array[i], i, array); + } + + return results; }, + - compile : function(path, type){ - type = type || "select"; + 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); + } - - var fn = ["var f = function(root){\n var mode; ++batch; var n = root || document;\n"], - mode, - lastPath, - matchers = Ext.DomQuery.matchers, - matchersLn = matchers.length, - modeMatch, - - lmode = path.match(modeRe); - - if(lmode && lmode[1]){ - fn[fn.length] = 'mode="'+lmode[1].replace(trimRe, "")+'";'; - path = path.replace(lmode[1], ""); + var i = 0, + ln = array.length; + + for (; i < ln; ++i) { + if (!fn.call(scope, array[i], i, array)) { + return false; + } } - - - while(path.substr(0, 1)=="/"){ - path = path.substr(1); + + return true; + }, + + + 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); } - while(path && lastPath != path){ - lastPath = path; - var tokenMatch = path.match(tagTokenRe); - if(type == "select"){ - if(tokenMatch){ - - if(tokenMatch[1] == "#"){ - fn[fn.length] = 'n = quickId(n, mode, root, "'+tokenMatch[2]+'");'; - }else{ - fn[fn.length] = 'n = getNodes(n, mode, "'+tokenMatch[2]+'");'; - } - path = path.replace(tokenMatch[0], ""); - }else if(path.substr(0, 1) != '@'){ - fn[fn.length] = 'n = getNodes(n, mode, "*");'; - } - - }else{ - if(tokenMatch){ - if(tokenMatch[1] == "#"){ - fn[fn.length] = 'n = byId(n, "'+tokenMatch[2]+'");'; - }else{ - fn[fn.length] = 'n = byTag(n, "'+tokenMatch[2]+'");'; - } - path = path.replace(tokenMatch[0], ""); - } + var i = 0, + ln = array.length; + + for (; i < ln; ++i) { + if (fn.call(scope, array[i], i, array)) { + return true; } - while(!(modeMatch = path.match(modeRe))){ - var matched = false; - for(var j = 0; j < matchersLn; j++){ - var t = matchers[j]; - var m = path.match(t.re); - if(m){ - fn[fn.length] = t.select.replace(tplRe, function(x, i){ - return m[i]; - }); - path = path.replace(m[0], ""); - matched = true; - break; - } - } - - if(!matched){ - throw 'Error parsing selector, parsing failed at "' + path + '"'; - } + } + + return false; + }, + + + clean: function(array) { + var results = [], + i = 0, + ln = array.length, + item; + + for (; i < ln; i++) { + item = array[i]; + + if (!Ext.isEmpty(item)) { + results.push(item); } - if(modeMatch[1]){ - fn[fn.length] = 'mode="'+modeMatch[1].replace(trimRe, "")+'";'; - path = path.replace(modeMatch[1], ""); + } + + return results; + }, + + + unique: function(array) { + var clone = [], + i = 0, + ln = array.length, + item; + + for (; i < ln; i++) { + item = array[i]; + + if (ExtArray.indexOf(clone, item) === -1) { + clone.push(item); } } - - fn[fn.length] = "return nodup(n);\n}"; - - - eval(fn.join("")); - return f; + + return clone; }, - jsSelect: function(path, root, type){ - - root = root || document; - - if(typeof root == "string"){ - root = document.getElementById(root); + filter: function(array, fn, scope) { + if (supportsFilter) { + return array.filter(fn, scope); } - var paths = path.split(","), - results = []; - - - for(var i = 0, len = paths.length; i < len; i++){ - var subPath = paths[i].replace(trimRe, ""); - - if(!cache[subPath]){ - cache[subPath] = Ext.DomQuery.compile(subPath); - if(!cache[subPath]){ - throw subPath + " is not a valid selector"; - } - } - var result = cache[subPath](root); - if(result && result != document){ - results = results.concat(result); + + var results = [], + i = 0, + ln = array.length; + + for (; i < ln; i++) { + if (fn.call(scope, array[i], i, array)) { + results.push(array[i]); } } - - - - if(paths.length > 1){ - return nodup(results); - } + return results; }, - isXml: function(el) { - 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.toArray(cs); - } - catch (ex) {} - } - return Ext.DomQuery.jsSelect.call(this, path, root, type); - } : function(path, root, type) { - return Ext.DomQuery.jsSelect.call(this, path, root, type); - }, - selectNode : function(path, root){ - return Ext.DomQuery.select(path, root)[0]; + from: function(value, newReference) { + if (value === undefined || value === null) { + return []; + } + + if (Ext.isArray(value)) { + return (newReference) ? slice.call(value) : value; + } + + if (value && value.length !== undefined && typeof value !== 'string') { + return Ext.toArray(value); + } + + return [value]; }, - selectValue : function(path, root, defaultValue){ - path = path.replace(trimRe, ""); - if(!valueCache[path]){ - valueCache[path] = Ext.DomQuery.compile(path, "select"); + remove: function(array, item) { + var index = ExtArray.indexOf(array, item); + + if (index !== -1) { + array.splice(index, 1); } - var n = valueCache[path](root), v; - n = n[0] ? n[0] : n; - - - - - - if (typeof n.normalize == 'function') n.normalize(); - - v = (n && n.firstChild ? n.firstChild.nodeValue : null); - return ((v === null||v === undefined||v==='') ? defaultValue : v); + + return array; }, - selectNumber : function(path, root, defaultValue){ - var v = Ext.DomQuery.selectValue(path, root, defaultValue || 0); - return parseFloat(v); + include: function(array, item) { + if (!ExtArray.contains(array, item)) { + array.push(item); + } }, - is : function(el, ss){ - if(typeof el == "string"){ - el = document.getElementById(el); - } - var isArray = Ext.isArray(el), - result = Ext.DomQuery.filter(isArray ? el : [el], ss); - return isArray ? (result.length == el.length) : (result.length > 0); + clone: function(array) { + return slice.call(array); }, - filter : function(els, ss, nonMatches){ - ss = ss.replace(trimRe, ""); - if(!simpleCache[ss]){ - simpleCache[ss] = Ext.DomQuery.compile(ss, "simple"); + merge: function() { + var args = slice.call(arguments), + array = [], + i, ln; + + for (i = 0, ln = args.length; i < ln; i++) { + array = array.concat(args[i]); } - var result = simpleCache[ss](els); - return nonMatches ? quickDiff(result, els) : result; + + return ExtArray.unique(array); }, - matchers : [{ - re: /^\.([\w-]+)/, - select: 'n = byClassName(n, " {1} ");' - }, { - re: /^\:([\w-]+)(?:\(((?:[^\s>\/]*|.*?))\))?/, - select: 'n = byPseudo(n, "{1}", "{2}");' - },{ - re: /^(?:([\[\{])(?:@)?([\w-]+)\s?(?:(=|.=)\s?['"]?(.*?)["']?)?[\]\}])/, - select: 'n = byAttribute(n, "{2}", "{4}", "{3}", "{1}");' - }, { - re: /^#([\w-]+)/, - select: 'n = byId(n, "{1}");' - },{ - re: /^@([\w-]+)/, - select: 'return {firstChild:{nodeValue:attrValue(n, "{1}")}};' + intersect: function() { + var intersect = [], + arrays = slice.call(arguments), + i, j, k, minArray, array, x, y, ln, arraysLn, arrayLn; + + if (!arrays.length) { + return intersect; } - ], - - operators : { - "=" : function(a, v){ - return a == v; - }, - "!=" : function(a, v){ - return a != v; - }, - "^=" : function(a, v){ - return a && a.substr(0, v.length) == v; - }, - "$=" : function(a, v){ - return a && a.substr(a.length-v.length) == v; - }, - "*=" : function(a, v){ - return a && a.indexOf(v) !== -1; - }, - "%=" : function(a, v){ - return (a % v) == 0; - }, - "|=" : function(a, v){ - return a && (a == v || a.substr(0, v.length+1) == v+'-'); - }, - "~=" : function(a, v){ - return a && (' '+a+' ').indexOf(' '+v+' ') != -1; + + for (i = x = 0,ln = arrays.length; i < ln,array = arrays[i]; i++) { + if (!minArray || array.length < minArray.length) { + minArray = array; + x = i; + } } - }, - - pseudos : { - "first-child" : function(c){ - var r = [], ri = -1, n; - for(var i = 0, ci; ci = n = c[i]; i++){ - while((n = n.previousSibling) && n.nodeType != 1); - if(!n){ - r[++ri] = ci; + minArray = Ext.Array.unique(minArray); + arrays.splice(x, 1); + + + + + for (i = 0,ln = minArray.length; i < ln,x = minArray[i]; i++) { + var count = 0; + + for (j = 0,arraysLn = arrays.length; j < arraysLn,array = arrays[j]; j++) { + for (k = 0,arrayLn = array.length; k < arrayLn,y = array[k]; k++) { + if (x === y) { + count++; + break; + } } } - return r; - }, - "last-child" : function(c){ - var r = [], ri = -1, n; - for(var i = 0, ci; ci = n = c[i]; i++){ - while((n = n.nextSibling) && n.nodeType != 1); - if(!n){ - r[++ri] = ci; - } + if (count === arraysLn) { + intersect.push(x); } - return r; - }, + } - "nth-child" : function(c, a) { - var r = [], ri = -1, - m = nthRe.exec(a == "even" && "2n" || a == "odd" && "2n+1" || !nthRe2.test(a) && "n+" + a || a), - f = (m[1] || 1) - 0, l = m[2] - 0; - for(var i = 0, n; n = c[i]; i++){ - var pn = n.parentNode; - if (batch != pn._batch) { - var j = 0; - for(var cn = pn.firstChild; cn; cn = cn.nextSibling){ - if(cn.nodeType == 1){ - cn.nodeIndex = ++j; - } - } - pn._batch = batch; - } - if (f == 1) { - if (l == 0 || n.nodeIndex == l){ - r[++ri] = n; - } - } else if ((n.nodeIndex + l) % f == 0){ - r[++ri] = n; + return intersect; + }, + + + difference: function(arrayA, arrayB) { + var clone = slice.call(arrayA), + ln = clone.length, + i, j, lnB; + + for (i = 0,lnB = arrayB.length; i < lnB; i++) { + for (j = 0; j < ln; j++) { + if (clone[j] === arrayB[i]) { + clone.splice(j, 1); + j--; + ln--; } } + } - return r; - }, + return clone; + }, - "only-child" : function(c){ - var r = [], ri = -1;; - for(var i = 0, ci; ci = c[i]; i++){ - if(!prev(ci) && !next(ci)){ - r[++ri] = ci; - } + + sort: function(array, sortFn) { + if (supportsSort) { + if (sortFn) { + return array.sort(sortFn); + } else { + return array.sort(); } - return r; - }, + } - "empty" : function(c){ - var r = [], ri = -1; - for(var i = 0, ci; ci = c[i]; i++){ - var cns = ci.childNodes, j = 0, cn, empty = true; - while(cn = cns[j]){ - ++j; - if(cn.nodeType == 1 || cn.nodeType == 3){ - empty = false; - break; + var length = array.length, + i = 0, + comparison, + j, min, tmp; + + for (; i < length; i++) { + min = i; + for (j = i + 1; j < length; j++) { + if (sortFn) { + comparison = sortFn(array[j], array[min]); + if (comparison < 0) { + min = j; } - } - if(empty){ - r[++ri] = ci; + } else if (array[j] < array[min]) { + min = j; } } - return r; - }, - - "contains" : function(c, v){ - var r = [], ri = -1; - for(var i = 0, ci; ci = c[i]; i++){ - if((ci.textContent||ci.innerText||'').indexOf(v) != -1){ - r[++ri] = ci; - } + if (min !== i) { + tmp = array[i]; + array[i] = array[min]; + array[min] = tmp; } - return r; - }, + } - "nodeValue" : function(c, v){ - var r = [], ri = -1; - for(var i = 0, ci; ci = c[i]; i++){ - if(ci.firstChild && ci.firstChild.nodeValue == v){ - r[++ri] = ci; - } - } - return r; - }, + return array; + }, - "checked" : function(c){ - var r = [], ri = -1; - for(var i = 0, ci; ci = c[i]; i++){ - if(ci.checked == true){ - r[++ri] = ci; - } - } - return r; - }, + + flatten: function(array) { + var worker = []; - "not" : function(c, ss){ - return Ext.DomQuery.filter(c, ss, true); - }, + function rFlatten(a) { + var i, ln, v; - "any" : function(c, selectors){ - var ss = selectors.split('|'), - r = [], ri = -1, s; - for(var i = 0, ci; ci = c[i]; i++){ - for(var j = 0; s = ss[j]; j++){ - if(Ext.DomQuery.is(ci, s)){ - r[++ri] = ci; - break; - } + for (i = 0, ln = a.length; i < ln; i++) { + v = a[i]; + + if (Ext.isArray(v)) { + rFlatten(v); + } else { + worker.push(v); } } - return r; - }, - - "odd" : function(c){ - return this["nth-child"](c, "odd"); - }, - "even" : function(c){ - return this["nth-child"](c, "even"); - }, + return worker; + } - "nth" : function(c, a){ - return c[a-1] || []; - }, + return rFlatten(array); + }, - "first" : function(c){ - return c[0] || []; - }, + + min: function(array, comparisonFn) { + var min = array[0], + i, ln, item; - "last" : function(c){ - return c[c.length-1] || []; - }, + for (i = 0, ln = array.length; i < ln; i++) { + item = array[i]; - "has" : function(c, ss){ - var s = Ext.DomQuery.select, - r = [], ri = -1; - for(var i = 0, ci; ci = c[i]; i++){ - if(s(ss, ci).length > 0){ - r[++ri] = ci; + if (comparisonFn) { + if (comparisonFn(min, item) === 1) { + min = item; } } - return r; - }, - - "next" : function(c, ss){ - var is = Ext.DomQuery.is, - r = [], ri = -1; - for(var i = 0, ci; ci = c[i]; i++){ - var n = next(ci); - if(n && is(n, ss)){ - r[++ri] = ci; + else { + if (item < min) { + min = item; } } - return r; - }, + } - "prev" : function(c, ss){ - var is = Ext.DomQuery.is, - r = [], ri = -1; - for(var i = 0, ci; ci = c[i]; i++){ - var n = prev(ci); - if(n && is(n, ss)){ - r[++ri] = ci; + return min; + }, + + + max: function(array, comparisonFn) { + var max = array[0], + i, ln, item; + + for (i = 0, ln = array.length; i < ln; i++) { + item = array[i]; + + if (comparisonFn) { + if (comparisonFn(max, item) === -1) { + max = item; + } + } + else { + if (item > max) { + max = item; } } - return r; } - } - }; -}(); - -Ext.query = Ext.DomQuery.select; + return max; + }, -Ext.util.DelayedTask = function(fn, scope, args){ - var me = this, - id, - call = function(){ - clearInterval(id); - id = null; - fn.apply(scope, args || []); - }; - - - me.delay = function(delay, newFn, newScope, newArgs){ - me.cancel(); - fn = newFn || fn; - scope = newScope || scope; - args = newArgs || args; - id = setInterval(call, delay); - }; + + mean: function(array) { + return array.length > 0 ? ExtArray.sum(array) / array.length : undefined; + }, - - me.cancel = function(){ - if(id){ - clearInterval(id); - id = null; - } - }; -}; -(function(){ -var DOC = document; + + sum: function(array) { + var sum = 0, + i, ln, item; -Ext.Element = function(element, forceNew){ - var dom = typeof element == "string" ? - DOC.getElementById(element) : element, - id; + for (i = 0,ln = array.length; i < ln; i++) { + item = array[i]; - if(!dom) return null; + sum += item; + } - id = dom.id; + return sum; + } - if(!forceNew && id && Ext.elCache[id]){ - return Ext.elCache[id].el; - } + }; - this.dom = dom; + Ext.each = Ext.Array.each; - this.id = id || Ext.id(dom); -}; - -var DH = Ext.DomHelper, - El = Ext.Element, - EC = Ext.elCache; + Ext.Array.union = Ext.Array.merge; -El.prototype = { - set : function(o, useSet){ - var el = this.dom, - attr, - val, - useSet = (useSet !== false) && !!el.setAttribute; - - for (attr in o) { - if (o.hasOwnProperty(attr)) { - val = o[attr]; - if (attr == 'style') { - DH.applyStyles(el, val); - } else if (attr == 'cls') { - el.className = val; - } else if (useSet) { - el.setAttribute(attr, val); - } else { - el[attr] = val; - } - } - } - return this; - }, + Ext.min = Ext.Array.min; - - - - - - - - - - + Ext.max = Ext.Array.max; - - - - + Ext.sum = Ext.Array.sum; - - - - - - + Ext.mean = Ext.Array.mean; - - + Ext.flatten = Ext.Array.flatten; + + Ext.clean = Ext.Array.clean; + + Ext.unique = Ext.Array.unique; + + Ext.pluck = Ext.Array.pluck; + + Ext.toArray = function() { + return ExtArray.toArray.apply(ExtArray, arguments); + } +})(); - - - +Ext.Function = { - - - - - - + flexSetter: function(fn) { + return function(a, b) { + var k, i; - - defaultUnit : "px", + if (a === null) { + return this; + } - - is : function(simpleSelector){ - return Ext.DomQuery.is(this.dom, simpleSelector); - }, + if (typeof a !== 'string') { + for (k in a) { + if (a.hasOwnProperty(k)) { + fn.call(this, k, a[k]); + } + } - - focus : function(defer, dom) { - var me = this, - dom = dom || me.dom; - try{ - if(Number(defer)){ - me.focus.defer(defer, null, [null, dom]); - }else{ - dom.focus(); + if (Ext.enumerables) { + for (i = Ext.enumerables.length; i--;) { + k = Ext.enumerables[i]; + if (a.hasOwnProperty(k)) { + fn.call(this, k, a[k]); + } + } + } + } else { + fn.call(this, a, b); } - }catch(e){} - return me; - }, - - blur : function() { - try{ - this.dom.blur(); - }catch(e){} - return this; + return this; + }; }, - - getValue : function(asNumber){ - var val = this.dom.value; - return asNumber ? parseInt(val, 10) : val; - }, + + bind: function(fn, scope, args, appendArgs) { + var method = fn, + applyArgs; - - addListener : function(eventName, fn, scope, options){ - Ext.EventManager.on(this.dom, eventName, fn, scope || this, options); - return this; - }, + return function() { + var callArgs = args || arguments; - - removeListener : function(eventName, fn, scope){ - Ext.EventManager.removeListener(this.dom, eventName, fn, scope || this); - return this; - }, + if (appendArgs === true) { + callArgs = Array.prototype.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); + } - - removeAllListeners : function(){ - Ext.EventManager.removeAll(this.dom); - return this; + return method.apply(scope || window, callArgs); + }; }, - purgeAllListeners : function() { - Ext.EventManager.purgeElement(this, true); - return this; - }, - - addUnits : function(size){ - if(size === "" || size == "auto" || size === undefined){ - size = size || ''; - } else if(!isNaN(size) || !unitPattern.test(size)){ - size = size + (this.defaultUnit || 'px'); + pass: function(fn, args, scope) { + if (args) { + args = Ext.Array.from(args); } - return size; - }, - - load : function(url, params, cb){ - Ext.Ajax.request(Ext.apply({ - params: params, - url: url.url || url, - callback: cb, - el: this.dom, - indicatorText: url.indicatorText || '' - }, Ext.isObject(url) ? url : {})); - return this; + return function() { + return fn.apply(scope, args.concat(Ext.Array.toArray(arguments))); + }; }, - isBorderBox : function(){ - return Ext.isBorderBox || Ext.isForcedBorderBox || noBoxAdjust[(this.dom.tagName || "").toLowerCase()]; + alias: function(object, methodName) { + return function() { + return object[methodName].apply(object, arguments); + }; }, - remove : function(){ - var me = this, - dom = me.dom; - - if (dom) { - delete me.dom; - Ext.removeNode(dom); + createInterceptor: function(origFn, newFn, scope, returnValue) { + var method = origFn; + if (!Ext.isFunction(newFn)) { + return origFn; + } + else { + return function() { + var me = this, + args = arguments; + newFn.target = me; + newFn.method = origFn; + return (newFn.apply(scope || me || window, args) !== false) ? origFn.apply(me || window, args) : returnValue || null; + }; } }, - hover : function(overFn, outFn, scope, options){ - var me = this; - me.on('mouseenter', overFn, scope || me.dom, options); - me.on('mouseleave', outFn, scope || me.dom, options); - return me; + createDelayed: function(fn, delay, scope, args, appendArgs) { + if (scope || args) { + fn = Ext.Function.bind(fn, scope, args, appendArgs); + } + return function() { + var me = this; + setTimeout(function() { + fn.apply(me, arguments); + }, delay); + }; }, - contains : function(el){ - return !el ? false : Ext.lib.Dom.isAncestor(this.dom, el.dom ? el.dom : el); + defer: function(fn, millis, obj, args, appendArgs) { + fn = Ext.Function.bind(fn, obj, args, appendArgs); + if (millis > 0) { + return setTimeout(fn, millis); + } + fn(); + return 0; }, - getAttributeNS : function(ns, name){ - return this.getAttribute(name, ns); + createSequence: function(origFn, newFn, scope) { + if (!Ext.isFunction(newFn)) { + return origFn; + } + else { + return function() { + var retval = origFn.apply(this || window, arguments); + newFn.apply(scope || this || window, arguments); + return retval; + }; + } }, - getAttribute : Ext.isIE ? function(name, ns){ - var d = this.dom, - type = typeof d[ns + ":" + name]; - - if(['undefined', 'unknown'].indexOf(type) == -1){ - return d[ns + ":" + name]; - } - return d[name]; - } : function(name, ns){ - var d = this.dom; - return d.getAttributeNS(ns, name) || d.getAttribute(ns + ":" + name) || d.getAttribute(name) || d[name]; + createBuffered: function(fn, buffer, scope, args) { + return function(){ + var timerId; + return function() { + var me = this; + if (timerId) { + clearInterval(timerId); + timerId = null; + } + timerId = setTimeout(function(){ + fn.apply(scope || me, args || arguments); + }, buffer); + }; + }(); }, - update : function(html) { - if (this.dom) { - this.dom.innerHTML = html; - } - return this; - } -}; + createThrottled: function(fn, interval, scope) { + var lastCallTime, elapsed, lastArgs, timer, execute = function() { + fn.apply(scope || this, lastArgs); + lastCallTime = new Date().getTime(); + }; -var ep = El.prototype; + return function() { + elapsed = new Date().getTime() - lastCallTime; + lastArgs = arguments; -El.addMethods = function(o){ - Ext.apply(ep, o); + clearTimeout(timer); + if (!lastCallTime || (elapsed >= interval)) { + execute(); + } else { + timer = setTimeout(execute, interval - elapsed); + } + }; + } }; -ep.on = ep.addListener; +Ext.defer = Ext.Function.alias(Ext.Function, 'defer'); -ep.un = ep.removeListener; +Ext.pass = Ext.Function.alias(Ext.Function, 'pass'); -ep.autoBoxAdjust = true; +Ext.bind = Ext.Function.alias(Ext.Function, 'bind'); -var unitPattern = /\d+(px|em|%|en|ex|pt|in|cm|mm|pc)$/i, - docEl; +(function() { +var ExtObject = Ext.Object = { + + toQueryObjects: function(name, value, recursive) { + var self = ExtObject.toQueryObjects, + objects = [], + i, ln; -El.get = function(el){ - var ex, - elm, - id; - if(!el){ return null; } - if (typeof el == "string") { - if (!(elm = DOC.getElementById(el))) { - return null; - } - if (EC[el] && EC[el].el) { - ex = EC[el].el; - ex.dom = elm; - } else { - ex = El.addToCache(new El(elm)); - } - return ex; - } else if (el.tagName) { - if(!(id = el.id)){ - id = Ext.id(el); - } - if (EC[id] && EC[id].el) { - ex = EC[id].el; - ex.dom = el; - } else { - ex = El.addToCache(new El(el)); + if (Ext.isArray(value)) { + for (i = 0, ln = value.length; i < ln; i++) { + if (recursive) { + objects = objects.concat(self(name + '[' + i + ']', value[i], true)); + } + else { + objects.push({ + name: name, + value: value[i] + }); + } + } } - return ex; - } else if (el instanceof El) { - if(el != docEl){ - - - - - if (Ext.isIE && (el.id == undefined || el.id == '')) { - el.dom = el.dom; - } else { - el.dom = DOC.getElementById(el.id) || el.dom; + else if (Ext.isObject(value)) { + for (i in value) { + if (value.hasOwnProperty(i)) { + if (recursive) { + objects = objects.concat(self(name + '[' + i + ']', value[i], true)); + } + else { + objects.push({ + name: name, + value: value[i] + }); + } + } } } - return el; - } else if(el.isComposite) { - return el; - } else if(Ext.isArray(el)) { - return El.select(el); - } else if(el == DOC) { - - if(!docEl){ - var f = function(){}; - f.prototype = El.prototype; - docEl = new f(); - docEl.dom = DOC; + else { + objects.push({ + name: name, + value: value + }); } - return docEl; - } - return null; -}; - -El.addToCache = function(el, id){ - id = id || el.id; - EC[id] = { - el: el, - data: {}, - events: {} - }; - return el; -}; - - -El.data = function(el, key, value){ - el = El.get(el); - if (!el) { - return null; - } - var c = EC[el.id].data; - if(arguments.length == 2){ - return c[key]; - }else{ - return (c[key] = value); - } -}; + return objects; + }, + + toQueryString: function(object, recursive) { + var paramObjects = [], + params = [], + i, j, ln, paramObject, value; + for (i in object) { + if (object.hasOwnProperty(i)) { + paramObjects = paramObjects.concat(ExtObject.toQueryObjects(i, object[i], recursive)); + } + } -function garbageCollect(){ - if(!Ext.enableGarbageCollector){ - clearInterval(El.collectorThreadId); - } else { - var eid, - el, - d, - o; + for (j = 0, ln = paramObjects.length; j < ln; j++) { + paramObject = paramObjects[j]; + value = paramObject.value; - for(eid in EC){ - o = EC[eid]; - if(o.skipGC){ - continue; - } - el = o.el; - d = el.dom; - - - - - - - - - - - - - - - - - - if(!d || !d.parentNode || (!d.offsetParent && !DOC.getElementById(eid))){ - if(Ext.enableListenerCollection){ - Ext.EventManager.removeAll(d); - } - delete EC[eid]; + if (Ext.isEmpty(value)) { + value = ''; } - } - - if (Ext.isIE) { - var t = {}; - for (eid in EC) { - t[eid] = EC[eid]; + else if (Ext.isDate(value)) { + value = Ext.Date.toString(value); } - EC = Ext.elCache = t; + + params.push(encodeURIComponent(paramObject.name) + '=' + encodeURIComponent(String(value))); } - } -} -El.collectorThreadId = setInterval(garbageCollect, 30000); -var flyFn = function(){}; -flyFn.prototype = El.prototype; + return params.join('&'); + }, + + fromQueryString: function(queryString, recursive) { + var parts = queryString.replace(/^\?/, '').split('&'), + object = {}, + temp, components, name, value, i, ln, + part, j, subLn, matchedKeys, matchedName, + keys, key, nextKey; -El.Flyweight = function(dom){ - this.dom = dom; -}; + for (i = 0, ln = parts.length; i < ln; i++) { + part = parts[i]; -El.Flyweight.prototype = new flyFn(); -El.Flyweight.prototype.isFlyweight = true; -El._flyweights = {}; + if (part.length > 0) { + components = part.split('='); + name = decodeURIComponent(components[0]); + value = (components[1] !== undefined) ? decodeURIComponent(components[1]) : ''; + if (!recursive) { + if (object.hasOwnProperty(name)) { + if (!Ext.isArray(object[name])) { + object[name] = [object[name]]; + } -El.fly = function(el, named){ - var ret = null; - named = named || '_global'; + object[name].push(value); + } + else { + object[name] = value; + } + } + else { + 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 + '"' + }); + } - if (el = Ext.getDom(el)) { - (El._flyweights[named] = El._flyweights[named] || new El.Flyweight()).dom = el; - ret = El._flyweights[named]; - } - return ret; -}; + name = matchedName[0]; + keys = []; + if (matchedKeys === null) { + object[name] = value; + continue; + } -Ext.get = El.get; + for (j = 0, subLn = matchedKeys.length; j < subLn; j++) { + key = matchedKeys[j]; + key = (key.length === 2) ? '' : key.substring(1, key.length - 1); + keys.push(key); + } + keys.unshift(name); -Ext.fly = El.fly; + temp = object; + for (j = 0, subLn = keys.length; j < subLn; j++) { + key = keys[j]; -var noBoxAdjust = Ext.isStrict ? { - select:1 -} : { - input:1, select:1, textarea:1 -}; -if(Ext.isIE || Ext.isGecko){ - noBoxAdjust['button'] = 1; -} + if (j === subLn - 1) { + if (Ext.isArray(temp) && key === '') { + temp.push(value); + } + else { + temp[key] = value; + } + } + else { + if (temp[key] === undefined || typeof temp[key] === 'string') { + nextKey = keys[j+1]; -})(); + temp[key] = (Ext.isNumeric(nextKey) || nextKey === '') ? [] : {}; + } -Ext.Element.addMethods(function(){ - var PARENTNODE = 'parentNode', - NEXTSIBLING = 'nextSibling', - PREVIOUSSIBLING = 'previousSibling', - DQ = Ext.DomQuery, - GET = Ext.get; - - return { - - findParent : function(simpleSelector, maxDepth, returnEl){ - var p = this.dom, - b = document.body, - depth = 0, - stopEl; - if(Ext.isGecko && Object.prototype.toString.call(p) == '[object XULElement]') { - return null; - } - maxDepth = maxDepth || 50; - if (isNaN(maxDepth)) { - stopEl = Ext.getDom(maxDepth); - maxDepth = Number.MAX_VALUE; - } - while(p && p.nodeType == 1 && depth < maxDepth && p != b && p != stopEl){ - if(DQ.is(p, simpleSelector)){ - return returnEl ? GET(p) : p; - } - depth++; - p = p.parentNode; - } - return null; - }, - - - findParentNode : function(simpleSelector, maxDepth, returnEl){ - var p = Ext.fly(this.dom.parentNode, '_internal'); - return p ? p.findParent(simpleSelector, maxDepth, returnEl) : null; - }, - - - up : function(simpleSelector, maxDepth){ - return this.findParentNode(simpleSelector, maxDepth, true); - }, - - - select : function(selector){ - return Ext.Element.select(selector, this.dom); - }, - - - query : function(selector){ - return DQ.select(selector, this.dom); - }, - - - child : function(selector, returnDom){ - var n = DQ.selectNode(selector, this.dom); - return returnDom ? n : GET(n); - }, - - - down : function(selector, returnDom){ - var n = DQ.selectNode(" > " + selector, this.dom); - return returnDom ? n : GET(n); - }, - - - parent : function(selector, returnDom){ - return this.matchNode(PARENTNODE, PARENTNODE, selector, returnDom); - }, - - - next : function(selector, returnDom){ - return this.matchNode(NEXTSIBLING, NEXTSIBLING, selector, returnDom); - }, - - - prev : function(selector, returnDom){ - return this.matchNode(PREVIOUSSIBLING, PREVIOUSSIBLING, selector, returnDom); - }, - - - - first : function(selector, returnDom){ - return this.matchNode(NEXTSIBLING, 'firstChild', selector, returnDom); - }, - - - last : function(selector, returnDom){ - return this.matchNode(PREVIOUSSIBLING, 'lastChild', selector, returnDom); - }, - - matchNode : function(dir, start, selector, returnDom){ - var n = this.dom[start]; - while(n){ - if(n.nodeType == 1 && (!selector || DQ.is(n, selector))){ - return !returnDom ? GET(n) : n; - } - n = n[dir]; - } - return null; - } - }; -}()); -Ext.Element.addMethods( -function() { - var GETDOM = Ext.getDom, - GET = Ext.get, - DH = Ext.DomHelper; - - return { - - appendChild: function(el){ - return GET(el).appendTo(this); - }, - - - appendTo: function(el){ - GETDOM(el).appendChild(this.dom); - return this; - }, - - - insertBefore: function(el){ - (el = GETDOM(el)).parentNode.insertBefore(this.dom, el); - return this; - }, - - - insertAfter: function(el){ - (el = GETDOM(el)).parentNode.insertBefore(this.dom, el.nextSibling); - return this; - }, - - - insertFirst: function(el, returnDom){ - el = el || {}; - if(el.nodeType || el.dom || typeof el == 'string'){ - el = GETDOM(el); - this.dom.insertBefore(el, this.dom.firstChild); - return !returnDom ? GET(el) : el; - }else{ - return this.createChild(el, this.dom.firstChild, returnDom); - } - }, - - - replace: function(el){ - el = GET(el); - this.insertBefore(el); - el.remove(); - return this; - }, - - - replaceWith: function(el){ - var me = this; - - if(el.nodeType || el.dom || typeof el == 'string'){ - el = GETDOM(el); - me.dom.parentNode.insertBefore(el, me.dom); - }else{ - el = DH.insertBefore(me.dom, el); + temp = temp[key]; + } + } + } } - - delete Ext.elCache[me.id]; - Ext.removeNode(me.dom); - me.id = Ext.id(me.dom = el); - Ext.Element.addToCache(me.isFlyweight ? new Ext.Element(me.dom) : me); - return me; - }, - - - createChild: function(config, insertBefore, returnDom){ - config = config || {tag:'div'}; - return insertBefore ? - DH.insertBefore(insertBefore, config, returnDom !== true) : - DH[!this.dom.firstChild ? 'overwrite' : 'append'](this.dom, config, returnDom !== true); - }, - - - wrap: function(config, returnDom){ - var newEl = DH.insertBefore(this.dom, config || {tag: "div"}, !returnDom); - newEl.dom ? newEl.dom.appendChild(this.dom) : newEl.appendChild(this.dom); - return newEl; - }, - - - insertHtml : function(where, html, returnEl){ - var el = DH.insertHtml(where, this.dom, html); - return returnEl ? Ext.get(el) : el; - } - }; -}()); -Ext.Element.addMethods(function(){ - - var supports = Ext.supports, - propCache = {}, - camelRe = /(-[a-z])/gi, - view = document.defaultView, - opacityRe = /alpha\(opacity=(.*)\)/i, - trimRe = /^\s+|\s+$/g, - EL = Ext.Element, - spacesRe = /\s+/, - wordsRe = /\w/g, - PADDING = "padding", - MARGIN = "margin", - BORDER = "border", - LEFT = "-left", - RIGHT = "-right", - TOP = "-top", - BOTTOM = "-bottom", - WIDTH = "-width", - MATH = Math, - HIDDEN = 'hidden', - ISCLIPPED = 'isClipped', - OVERFLOW = 'overflow', - OVERFLOWX = 'overflow-x', - OVERFLOWY = 'overflow-y', - ORIGINALCLIP = 'originalClip', - - 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.Element.data; + } + return object; + }, - function camelFn(m, a) { - return a.charAt(1).toUpperCase(); - } - - function chkCache(prop) { - return propCache[prop] || (propCache[prop] = prop == 'float' ? (supports.cssFloat ? 'cssFloat' : 'styleFloat') : prop.replace(camelRe, camelFn)); - } - - return { - - adjustWidth : function(width) { - var me = this; - var isNum = (typeof width == "number"); - if(isNum && me.autoBoxAdjust && !me.isBorderBox()){ - width -= (me.getBorderWidth("lr") + me.getPadding("lr")); - } - return (isNum && width < 0) ? 0 : width; - }, - - - adjustHeight : function(height) { - var me = this; - var isNum = (typeof height == "number"); - if(isNum && me.autoBoxAdjust && !me.isBorderBox()){ - height -= (me.getBorderWidth("tb") + me.getPadding("tb")); + each: function(object, fn, scope) { + for (var property in object) { + if (object.hasOwnProperty(property)) { + if (fn.call(scope || object, property, object[property], object) === false) { + return; + } } - return (isNum && height < 0) ? 0 : height; - }, - + } + }, - - addClass : function(className){ - var me = this, - i, - len, - v, - cls = []; - - if (!Ext.isArray(className)) { - if (typeof className == 'string' && !this.hasClass(className)) { - me.dom.className += " " + className; + + merge: function(source, key, value) { + if (typeof key === 'string') { + if (value && value.constructor === Object) { + if (source[key] && source[key].constructor === Object) { + ExtObject.merge(source[key], value); + } + else { + source[key] = Ext.clone(value); } } else { - for (i = 0, len = className.length; i < len; i++) { - v = className[i]; - if (typeof v == 'string' && (' ' + me.dom.className + ' ').indexOf(' ' + v + ' ') == -1) { - cls.push(v); - } - } - if (cls.length) { - me.dom.className += " " + cls.join(" "); - } + source[key] = value; } - return me; - }, - - removeClass : function(className){ - var me = this, - i, - idx, - len, - cls, - elClasses; - if (!Ext.isArray(className)){ - className = [className]; - } - if (me.dom && me.dom.className) { - elClasses = me.dom.className.replace(trimRe, '').split(spacesRe); - for (i = 0, len = className.length; i < len; i++) { - cls = className[i]; - if (typeof cls == 'string') { - cls = cls.replace(trimRe, ''); - idx = elClasses.indexOf(cls); - if (idx != -1) { - elClasses.splice(idx, 1); - } - } + return source; + } + + var i = 1, + ln = arguments.length, + object, property; + + for (; i < ln; i++) { + object = arguments[i]; + + for (property in object) { + if (object.hasOwnProperty(property)) { + ExtObject.merge(source, property, object[property]); } - me.dom.className = elClasses.join(" "); } - return me; - }, + } - - radioClass : function(className){ - var cn = this.dom.parentNode.childNodes, - v, - i, - len; - className = Ext.isArray(className) ? className : [className]; - for (i = 0, len = cn.length; i < len; i++) { - v = cn[i]; - if (v && v.nodeType == 1) { - Ext.fly(v, '_internal').removeClass(className); - } - }; - return this.addClass(className); - }, + return source; + }, - - toggleClass : function(className){ - return this.hasClass(className) ? this.removeClass(className) : this.addClass(className); - }, + + getKey: function(object, value) { + for (var property in object) { + if (object.hasOwnProperty(property) && object[property] === value) { + return property; + } + } - - hasClass : function(className){ - return className && (' '+this.dom.className+' ').indexOf(' '+className+' ') != -1; - }, + return null; + }, - - replaceClass : function(oldClassName, newClassName){ - return this.removeClass(oldClassName).addClass(newClassName); - }, + + getValues: function(object) { + var values = [], + property; - isStyle : function(style, val) { - return this.getStyle(style) == val; - }, + for (property in object) { + if (object.hasOwnProperty(property)) { + values.push(object[property]); + } + } - - getStyle : function(){ - return view && view.getComputedStyle ? - function(prop){ - var el = this.dom, - v, - cs, - out, - display; + return values; + }, - if(el == document){ - return null; - } - prop = chkCache(prop); - out = (v = el.style[prop]) ? v : - (cs = view.getComputedStyle(el, "")) ? cs[prop] : null; - - - - if(prop == 'marginRight' && out != '0px' && !supports.correctRightMargin){ - display = el.style.display; - el.style.display = 'inline-block'; - out = view.getComputedStyle(el, '').marginRight; - el.style.display = display; - } - - if(prop == 'backgroundColor' && out == 'rgba(0, 0, 0, 0)' && !supports.correctTransparentColor){ - out = 'transparent'; - } - return out; - } : - function(prop){ - var el = this.dom, - m, - cs; + + getKeys: ('keys' in Object.prototype) ? Object.keys : function(object) { + var keys = [], + property; - if(el == document) return null; - if (prop == 'opacity') { - if (el.style.filter.match) { - if(m = el.style.filter.match(opacityRe)){ - var fv = parseFloat(m[1]); - if(!isNaN(fv)){ - return fv ? fv / 100 : 0; - } - } - } - return 1; - } - prop = chkCache(prop); - return el.style[prop] || ((cs = el.currentStyle) ? cs[prop] : null); - }; - }(), + for (property in object) { + if (object.hasOwnProperty(property)) { + keys.push(property); + } + } - - getColor : function(attr, defaultValue, prefix){ - var v = this.getStyle(attr), - color = (typeof prefix != 'undefined') ? prefix : '#', - h; + return keys; + }, - if(!v || (/transparent|inherit/.test(v))) { - return defaultValue; - } - if(/^r/.test(v)){ - Ext.each(v.slice(4, v.length -1).split(','), function(s){ - h = parseInt(s, 10); - color += (h < 16 ? '0' : '') + h.toString(16); - }); - }else{ - v = v.replace('#', ''); - color += v.length == 3 ? v.replace(/^(\w)(\w)(\w)$/, '$1$1$2$2$3$3') : v; - } - return(color.length > 5 ? color.toLowerCase() : defaultValue); - }, + + getSize: function(object) { + var size = 0, + property; - - setStyle : function(prop, value){ - var tmp, style; - - if (typeof prop != 'object') { - tmp = {}; - tmp[prop] = value; - prop = tmp; - } - for (style in prop) { - value = prop[style]; - style == 'opacity' ? - this.setOpacity(value) : - this.dom.style[chkCache(style)] = value; + for (property in object) { + if (object.hasOwnProperty(property)) { + size++; } - return this; - }, + } - - setOpacity : function(opacity, animate){ - var me = this, - s = me.dom.style; + return size; + } +}; - if(!animate || !me.anim){ - if(Ext.isIE){ - var opac = opacity < 1 ? 'alpha(opacity=' + opacity * 100 + ')' : '', - val = s.filter.replace(opacityRe, '').replace(trimRe, ''); - s.zoom = 1; - s.filter = val + (val.length > 0 ? ' ' : '') + opac; - }else{ - s.opacity = opacity; - } - }else{ - me.anim({opacity: {to: opacity}}, me.preanim(arguments, 1), null, .35, 'easeIn'); - } - return me; - }, - - clearOpacity : function(){ - var style = this.dom.style; - if(Ext.isIE){ - if(!Ext.isEmpty(style.filter)){ - style.filter = style.filter.replace(opacityRe, '').replace(trimRe, ''); - } - }else{ - style.opacity = style['-moz-opacity'] = style['-khtml-opacity'] = ''; - } - return this; - }, +Ext.merge = Ext.Object.merge; - - getHeight : function(contentHeight){ - var me = this, - dom = me.dom, - hidden = Ext.isIE && me.isStyle('display', 'none'), - h = MATH.max(dom.offsetHeight, hidden ? 0 : dom.clientHeight) || 0; - h = !contentHeight ? h : h - me.getBorderWidth("tb") - me.getPadding("tb"); - return h < 0 ? 0 : h; - }, +Ext.urlEncode = function() { + var args = Ext.Array.from(arguments), + prefix = ''; - - getWidth : function(contentWidth){ - var me = this, - dom = me.dom, - hidden = Ext.isIE && me.isStyle('display', 'none'), - w = MATH.max(dom.offsetWidth, hidden ? 0 : dom.clientWidth) || 0; - w = !contentWidth ? w : w - me.getBorderWidth("lr") - me.getPadding("lr"); - return w < 0 ? 0 : w; - }, + + if ((typeof args[1] === 'string')) { + prefix = args[1] + '&'; + args[1] = false; + } - - setWidth : function(width, animate){ - var me = this; - width = me.adjustWidth(width); - !animate || !me.anim ? - me.dom.style.width = me.addUnits(width) : - me.anim({width : {to : width}}, me.preanim(arguments, 1)); - return me; - }, + return prefix + Ext.Object.toQueryString.apply(Ext.Object, args); +}; - - setHeight : function(height, animate){ - var me = this; - height = me.adjustHeight(height); - !animate || !me.anim ? - me.dom.style.height = me.addUnits(height) : - me.anim({height : {to : height}}, me.preanim(arguments, 1)); - return me; - }, - - getBorderWidth : function(side){ - return this.addStyles(side, borders); - }, +Ext.urlDecode = function() { + return Ext.Object.fromQueryString.apply(Ext.Object, arguments); +}; - - getPadding : function(side){ - return this.addStyles(side, paddings); - }, +})(); - - clip : function(){ - var me = this, - dom = me.dom; - if(!data(dom, ISCLIPPED)){ - data(dom, ISCLIPPED, true); - data(dom, ORIGINALCLIP, { - o: me.getStyle(OVERFLOW), - x: me.getStyle(OVERFLOWX), - y: me.getStyle(OVERFLOWY) - }); - me.setStyle(OVERFLOW, HIDDEN); - me.setStyle(OVERFLOWX, HIDDEN); - me.setStyle(OVERFLOWY, HIDDEN); - } - return me; - }, - - unclip : function(){ - var me = this, - dom = me.dom; - if(data(dom, ISCLIPPED)){ - data(dom, ISCLIPPED, false); - var o = data(dom, ORIGINALCLIP); - if(o.o){ - me.setStyle(OVERFLOW, o.o); - } - if(o.x){ - me.setStyle(OVERFLOWX, o.x); - } - if(o.y){ - me.setStyle(OVERFLOWY, o.y); - } - } - return me; - }, - - addStyles : function(sides, styles){ - var ttlSize = 0, - sidesArr = sides.match(wordsRe), - side, - size, - i, - len = sidesArr.length; - for (i = 0; i < len; i++) { - side = sidesArr[i]; - size = side && parseInt(this.getStyle(styles[side]), 10); - if (size) { - ttlSize += MATH.abs(size); - } - } - return ttlSize; - }, +(function() { - margins : margins - }; -}() -); -(function(){ -var D = Ext.lib.Dom, - LEFT = "left", - RIGHT = "right", - TOP = "top", - BOTTOM = "bottom", - POSITION = "position", - STATIC = "static", - RELATIVE = "relative", - AUTO = "auto", - ZINDEX = "z-index"; - -Ext.Element.addMethods({ - - getX : function(){ - return D.getX(this.dom); - }, - - getY : function(){ - return D.getY(this.dom); - }, - - getXY : function(){ - return D.getXY(this.dom); - }, +function xf(format) { + var args = Array.prototype.slice.call(arguments, 1); + return format.replace(/\{(\d+)\}/g, function(m, i) { + return args[i]; + }); +} +Ext.Date = { - getOffsetsTo : function(el){ - var o = this.getXY(), - e = Ext.fly(el, '_internal').getXY(); - return [o[0]-e[0],o[1]-e[1]]; + now: Date.now || function() { + return +new Date(); }, - setX : function(x, animate){ - return this.setXY([x, this.getY()], this.animTest(arguments, animate, 1)); - }, + toString: function(date) { + var pad = Ext.String.leftPad; - - setY : function(y, animate){ - return this.setXY([this.getX(), y], this.animTest(arguments, animate, 1)); + return date.getFullYear() + "-" + + pad(date.getMonth() + 1, 2, '0') + "-" + + pad(date.getDate(), 2, '0') + "T" + + pad(date.getHours(), 2, '0') + ":" + + pad(date.getMinutes(), 2, '0') + ":" + + pad(date.getSeconds(), 2, '0'); }, - setLeft : function(left){ - this.setStyle(LEFT, this.addUnits(left)); - return this; + getElapsed: function(dateA, dateB) { + return Math.abs(dateA - (dateB || new Date())); }, - setTop : function(top){ - this.setStyle(TOP, this.addUnits(top)); - return this; - }, + useStrict: false, - setRight : function(right){ - this.setStyle(RIGHT, this.addUnits(right)); - return this; + formatCodeToRegex: function(character, currentGroup) { + + var p = utilDate.parseCodes[character]; + + if (p) { + p = typeof p == 'function'? p() : p; + utilDate.parseCodes[character] = p; + } + + return p ? Ext.applyIf({ + c: p.c ? xf(p.c, currentGroup || "{0}") : p.c + }, p) : { + g: 0, + c: null, + s: Ext.String.escapeRegex(character) + }; }, - setBottom : function(bottom){ - this.setStyle(BOTTOM, this.addUnits(bottom)); - return this; + parseFunctions: { + "MS": function(input, strict) { + + + var re = new RegExp('\\/Date\\(([-+])?(\\d+)(?:[+-]\\d{4})?\\)\\/'); + var r = (input || '').match(re); + return r? new Date(((r[1] || '') + r[2]) * 1) : null; + } }, + parseRegexes: [], - setXY : function(pos, animate){ - var me = this; - if(!animate || !me.anim){ - D.setXY(me.dom, pos); - }else{ - me.anim({points: {to: pos}}, me.preanim(arguments, 1), 'motion'); + formatFunctions: { + "MS": function() { + + return '\\/Date(' + this.getTime() + ')\\/'; } - return me; }, + y2kYear : 50, + - setLocation : function(x, y, animate){ - return this.setXY([x, y], this.animTest(arguments, animate, 2)); - }, + MILLI : "ms", - moveTo : function(x, y, animate){ - return this.setXY([x, y], this.animTest(arguments, animate, 2)); - }, + SECOND : "s", + + MINUTE : "mi", + - getLeft : function(local){ - return !local ? this.getX() : parseInt(this.getStyle(LEFT), 10) || 0; - }, + HOUR : "h", - getRight : function(local){ - var me = this; - return !local ? me.getX() + me.getWidth() : (me.getLeft(true) + me.getWidth()) || 0; - }, + DAY : "d", - getTop : function(local) { - return !local ? this.getY() : parseInt(this.getStyle(TOP), 10) || 0; - }, + MONTH : "mo", - getBottom : function(local){ - var me = this; - return !local ? me.getY() + me.getHeight() : (me.getTop(true) + me.getHeight()) || 0; - }, + YEAR : "y", - position : function(pos, zIndex, x, y){ - var me = this; - - if(!pos && me.isStyle(POSITION, STATIC)){ - me.setStyle(POSITION, RELATIVE); - } else if(pos) { - me.setStyle(POSITION, pos); - } - if(zIndex){ - me.setStyle(ZINDEX, zIndex); - } - if(x || y) me.setXY([x || false, y || false]); - }, + defaults: {}, - clearPositioning : function(value){ - value = value || ''; - this.setStyle({ - left : value, - right : value, - top : value, - bottom : value, - "z-index" : "", - position : STATIC - }); - return this; - }, + dayNames : [ + "Sunday", + "Monday", + "Tuesday", + "Wednesday", + "Thursday", + "Friday", + "Saturday" + ], - getPositioning : function(){ - var l = this.getStyle(LEFT); - var t = this.getStyle(TOP); - return { - "position" : this.getStyle(POSITION), - "left" : l, - "right" : l ? "" : this.getStyle(RIGHT), - "top" : t, - "bottom" : t ? "" : this.getStyle(BOTTOM), - "z-index" : this.getStyle(ZINDEX) - }; - }, + monthNames : [ + "January", + "February", + "March", + "April", + "May", + "June", + "July", + "August", + "September", + "October", + "November", + "December" + ], + + monthNumbers : { + Jan:0, + Feb:1, + Mar:2, + Apr:3, + May:4, + Jun:5, + Jul:6, + Aug:7, + Sep:8, + Oct:9, + Nov:10, + Dec:11 + }, - setPositioning : function(pc){ - var me = this, - style = me.dom.style; - - me.setStyle(pc); - - if(pc.right == AUTO){ - style.right = ""; - } - if(pc.bottom == AUTO){ - style.bottom = ""; - } - - return me; - }, - + defaultFormat : "m/d/Y", - translatePoints : function(x, y){ - y = isNaN(x[1]) ? y : x[1]; - x = isNaN(x[0]) ? x : x[0]; - var me = this, - relative = me.isStyle(POSITION, RELATIVE), - o = me.getXY(), - l = parseInt(me.getStyle(LEFT), 10), - t = parseInt(me.getStyle(TOP), 10); - - l = !isNaN(l) ? l : (relative ? 0 : me.dom.offsetLeft); - t = !isNaN(t) ? t : (relative ? 0 : me.dom.offsetTop); - - return {left: (x - o[0] + l), top: (y - o[1] + t)}; + getShortMonthName : function(month) { + return utilDate.monthNames[month].substring(0, 3); }, + - animTest : function(args, animate, i) { - return !!animate && this.preanim ? this.preanim(args, i) : false; - } -}); -})(); -Ext.Element.addMethods({ - - isScrollable : function(){ - var dom = this.dom; - return dom.scrollHeight > dom.clientHeight || dom.scrollWidth > dom.clientWidth; + getShortDayName : function(day) { + return utilDate.dayNames[day].substring(0, 3); }, - scrollTo : function(side, value){ - this.dom["scroll" + (/top/i.test(side) ? "Top" : "Left")] = value; - return this; + getMonthNumber : function(name) { + + return utilDate.monthNumbers[name.substring(0, 1).toUpperCase() + name.substring(1, 3).toLowerCase()]; }, - getScroll : function(){ - var d = this.dom, - doc = document, - body = doc.body, - docElement = doc.documentElement, - l, - t, - ret; + formatContainsHourInfo : (function(){ + var stripEscapeRe = /(\\.)/g, + hourInfoRe = /([gGhHisucUOPZ]|MS)/; + return function(format){ + return hourInfoRe.test(format.replace(stripEscapeRe, '')); + }; + })(), - if(d == doc || d == body){ - if(Ext.isIE && Ext.isStrict){ - l = docElement.scrollLeft; - t = docElement.scrollTop; - }else{ - l = window.pageXOffset; - t = window.pageYOffset; - } - ret = {left: l || (body ? body.scrollLeft : 0), top: t || (body ? body.scrollTop : 0)}; + + formatContainsDateInfo : (function(){ + var stripEscapeRe = /(\\.)/g, + dateInfoRe = /([djzmnYycU]|MS)/; + + return function(format){ + return dateInfoRe.test(format.replace(stripEscapeRe, '')); + }; + })(), + + + formatCodes : { + d: "Ext.String.leftPad(this.getDate(), 2, '0')", + D: "Ext.Date.getShortDayName(this.getDay())", + j: "this.getDate()", + l: "Ext.Date.dayNames[this.getDay()]", + N: "(this.getDay() ? this.getDay() : 7)", + S: "Ext.Date.getSuffix(this)", + w: "this.getDay()", + z: "Ext.Date.getDayOfYear(this)", + W: "Ext.String.leftPad(Ext.Date.getWeekOfYear(this), 2, '0')", + F: "Ext.Date.monthNames[this.getMonth()]", + m: "Ext.String.leftPad(this.getMonth() + 1, 2, '0')", + M: "Ext.Date.getShortMonthName(this.getMonth())", + n: "(this.getMonth() + 1)", + t: "Ext.Date.getDaysInMonth(this)", + L: "(Ext.Date.isLeapYear(this) ? 1 : 0)", + o: "(this.getFullYear() + (Ext.Date.getWeekOfYear(this) == 1 && this.getMonth() > 0 ? +1 : (Ext.Date.getWeekOfYear(this) >= 52 && this.getMonth() < 11 ? -1 : 0)))", + Y: "Ext.String.leftPad(this.getFullYear(), 4, '0')", + y: "('' + this.getFullYear()).substring(2, 4)", + a: "(this.getHours() < 12 ? 'am' : 'pm')", + A: "(this.getHours() < 12 ? 'AM' : 'PM')", + g: "((this.getHours() % 12) ? this.getHours() % 12 : 12)", + G: "this.getHours()", + h: "Ext.String.leftPad((this.getHours() % 12) ? this.getHours() % 12 : 12, 2, '0')", + H: "Ext.String.leftPad(this.getHours(), 2, '0')", + i: "Ext.String.leftPad(this.getMinutes(), 2, '0')", + s: "Ext.String.leftPad(this.getSeconds(), 2, '0')", + u: "Ext.String.leftPad(this.getMilliseconds(), 3, '0')", + O: "Ext.Date.getGMTOffset(this)", + P: "Ext.Date.getGMTOffset(this, true)", + T: "Ext.Date.getTimezone(this)", + Z: "(this.getTimezoneOffset() * -60)", + + c: function() { + for (var c = "Y-m-dTH:i:sP", code = [], i = 0, l = c.length; i < l; ++i) { + var e = c.charAt(i); + code.push(e == "T" ? "'T'" : utilDate.getFormatCode(e)); + } + return code.join(" + "); + }, + + + U: "Math.round(this.getTime() / 1000)" + }, + + + isValid : function(y, m, d, h, i, s, ms) { + + h = h || 0; + i = i || 0; + s = s || 0; + ms = ms || 0; + + + var dt = utilDate.add(new Date(y < 100 ? 100 : y, m - 1, d, h, i, s, ms), utilDate.YEAR, y < 100 ? y - 100 : 0); + + return y == dt.getFullYear() && + m == dt.getMonth() + 1 && + d == dt.getDate() && + h == dt.getHours() && + i == dt.getMinutes() && + s == dt.getSeconds() && + ms == dt.getMilliseconds(); + }, + + + parse : function(input, format, strict) { + var p = utilDate.parseFunctions; + if (p[format] == null) { + utilDate.createParser(format); + } + return p[format](input, Ext.isDefined(strict) ? strict : utilDate.useStrict); + }, + + + parseDate: function(input, format, strict){ + return utilDate.parse(input, format, strict); + }, + + + + getFormatCode : function(character) { + var f = utilDate.formatCodes[character]; + + if (f) { + f = typeof f == 'function'? f() : f; + utilDate.formatCodes[character] = f; + } + + + return f || ("'" + Ext.String.escape(character) + "'"); + }, + + + createFormat : function(format) { + var code = [], + special = false, + ch = ''; + + for (var i = 0; i < format.length; ++i) { + ch = format.charAt(i); + if (!special && ch == "\\") { + special = true; + } else if (special) { + special = false; + code.push("'" + Ext.String.escape(ch) + "'"); + } else { + code.push(utilDate.getFormatCode(ch)); + } + } + utilDate.formatFunctions[format] = Ext.functionFactory("return " + code.join('+')); + }, + + + createParser : (function() { + var code = [ + "var dt, y, m, d, h, i, s, ms, o, z, zz, u, v,", + "def = Ext.Date.defaults,", + "results = String(input).match(Ext.Date.parseRegexes[{0}]);", + + "if(results){", + "{1}", + + "if(u != null){", + "v = new Date(u * 1000);", + "}else{", + + + + "dt = Ext.Date.clearTime(new Date);", + + + "y = Ext.Number.from(y, Ext.Number.from(def.y, dt.getFullYear()));", + "m = Ext.Number.from(m, Ext.Number.from(def.m - 1, dt.getMonth()));", + "d = Ext.Number.from(d, Ext.Number.from(def.d, dt.getDate()));", + + + "h = Ext.Number.from(h, Ext.Number.from(def.h, dt.getHours()));", + "i = Ext.Number.from(i, Ext.Number.from(def.i, dt.getMinutes()));", + "s = Ext.Number.from(s, Ext.Number.from(def.s, dt.getSeconds()));", + "ms = Ext.Number.from(ms, Ext.Number.from(def.ms, dt.getMilliseconds()));", + + "if(z >= 0 && y >= 0){", + + + + + + "v = Ext.Date.add(new Date(y < 100 ? 100 : y, 0, 1, h, i, s, ms), Ext.Date.YEAR, y < 100 ? y - 100 : 0);", + + + "v = !strict? v : (strict === true && (z <= 364 || (Ext.Date.isLeapYear(v) && z <= 365))? Ext.Date.add(v, Ext.Date.DAY, z) : null);", + "}else if(strict === true && !Ext.Date.isValid(y, m + 1, d, h, i, s, ms)){", + "v = null;", + "}else{", + + + "v = Ext.Date.add(new Date(y < 100 ? 100 : y, m, d, h, i, s, ms), Ext.Date.YEAR, y < 100 ? y - 100 : 0);", + "}", + "}", + "}", + + "if(v){", + + "if(zz != null){", + + "v = Ext.Date.add(v, Ext.Date.SECOND, -v.getTimezoneOffset() * 60 - zz);", + "}else if(o){", + + "v = Ext.Date.add(v, Ext.Date.MINUTE, -v.getTimezoneOffset() + (sn == '+'? -1 : 1) * (hr * 60 + mn));", + "}", + "}", + + "return v;" + ].join('\n'); + + return function(format) { + var regexNum = utilDate.parseRegexes.length, + currentGroup = 1, + calc = [], + regex = [], + special = false, + ch = ""; + + for (var i = 0; i < format.length; ++i) { + ch = format.charAt(i); + if (!special && ch == "\\") { + special = true; + } else if (special) { + special = false; + regex.push(Ext.String.escape(ch)); + } else { + var obj = utilDate.formatCodeToRegex(ch, currentGroup); + currentGroup += obj.g; + regex.push(obj.s); + if (obj.g && obj.c) { + calc.push(obj.c); + } + } + } + + utilDate.parseRegexes[regexNum] = new RegExp("^" + regex.join('') + "$", 'i'); + utilDate.parseFunctions[format] = Ext.functionFactory("input", "strict", xf(code, regexNum, calc.join(''))); + }; + })(), + + + parseCodes : { + + d: { + g:1, + c:"d = parseInt(results[{0}], 10);\n", + s:"(\\d{2})" + }, + j: { + g:1, + c:"d = parseInt(results[{0}], 10);\n", + s:"(\\d{1,2})" + }, + D: function() { + for (var a = [], i = 0; i < 7; a.push(utilDate.getShortDayName(i)), ++i); + return { + g:0, + c:null, + s:"(?:" + a.join("|") +")" + }; + }, + l: function() { + return { + g:0, + c:null, + s:"(?:" + utilDate.dayNames.join("|") + ")" + }; + }, + N: { + g:0, + c:null, + s:"[1-7]" + }, + S: { + g:0, + c:null, + s:"(?:st|nd|rd|th)" + }, + w: { + g:0, + c:null, + s:"[0-6]" + }, + z: { + g:1, + c:"z = parseInt(results[{0}], 10);\n", + s:"(\\d{1,3})" + }, + W: { + g:0, + c:null, + s:"(?:\\d{2})" + }, + F: function() { + return { + g:1, + c:"m = parseInt(Ext.Date.getMonthNumber(results[{0}]), 10);\n", + s:"(" + utilDate.monthNames.join("|") + ")" + }; + }, + M: function() { + for (var a = [], i = 0; i < 12; a.push(utilDate.getShortMonthName(i)), ++i); + return Ext.applyIf({ + s:"(" + a.join("|") + ")" + }, utilDate.formatCodeToRegex("F")); + }, + m: { + g:1, + c:"m = parseInt(results[{0}], 10) - 1;\n", + s:"(\\d{2})" + }, + n: { + g:1, + c:"m = parseInt(results[{0}], 10) - 1;\n", + s:"(\\d{1,2})" + }, + t: { + g:0, + c:null, + s:"(?:\\d{2})" + }, + L: { + g:0, + c:null, + s:"(?:1|0)" + }, + o: function() { + return utilDate.formatCodeToRegex("Y"); + }, + Y: { + g:1, + c:"y = parseInt(results[{0}], 10);\n", + s:"(\\d{4})" + }, + y: { + g:1, + c:"var ty = parseInt(results[{0}], 10);\n" + + "y = ty > Ext.Date.y2kYear ? 1900 + ty : 2000 + ty;\n", + s:"(\\d{1,2})" + }, + + a: { + g:1, + c:"if (/(am)/i.test(results[{0}])) {\n" + + "if (!h || h == 12) { h = 0; }\n" + + "} else { if (!h || h < 12) { h = (h || 0) + 12; }}", + s:"(am|pm|AM|PM)" + }, + A: { + g:1, + c:"if (/(am)/i.test(results[{0}])) {\n" + + "if (!h || h == 12) { h = 0; }\n" + + "} else { if (!h || h < 12) { h = (h || 0) + 12; }}", + s:"(AM|PM|am|pm)" + }, + g: function() { + return utilDate.formatCodeToRegex("G"); + }, + G: { + g:1, + c:"h = parseInt(results[{0}], 10);\n", + s:"(\\d{1,2})" + }, + h: function() { + return utilDate.formatCodeToRegex("H"); + }, + H: { + g:1, + c:"h = parseInt(results[{0}], 10);\n", + s:"(\\d{2})" + }, + i: { + g:1, + c:"i = parseInt(results[{0}], 10);\n", + s:"(\\d{2})" + }, + s: { + g:1, + c:"s = parseInt(results[{0}], 10);\n", + s:"(\\d{2})" + }, + u: { + g:1, + c:"ms = results[{0}]; ms = parseInt(ms, 10)/Math.pow(10, ms.length - 3);\n", + s:"(\\d+)" + }, + O: { + g:1, + c:[ + "o = results[{0}];", + "var sn = o.substring(0,1),", + "hr = o.substring(1,3)*1 + Math.floor(o.substring(3,5) / 60),", + "mn = o.substring(3,5) % 60;", + "o = ((-12 <= (hr*60 + mn)/60) && ((hr*60 + mn)/60 <= 14))? (sn + Ext.String.leftPad(hr, 2, '0') + Ext.String.leftPad(mn, 2, '0')) : null;\n" + ].join("\n"), + s: "([+\-]\\d{4})" + }, + P: { + g:1, + c:[ + "o = results[{0}];", + "var sn = o.substring(0,1),", + "hr = o.substring(1,3)*1 + Math.floor(o.substring(4,6) / 60),", + "mn = o.substring(4,6) % 60;", + "o = ((-12 <= (hr*60 + mn)/60) && ((hr*60 + mn)/60 <= 14))? (sn + Ext.String.leftPad(hr, 2, '0') + Ext.String.leftPad(mn, 2, '0')) : null;\n" + ].join("\n"), + s: "([+\-]\\d{2}:\\d{2})" + }, + T: { + g:0, + c:null, + s:"[A-Z]{1,4}" + }, + Z: { + g:1, + c:"zz = results[{0}] * 1;\n" + + "zz = (-43200 <= zz && zz <= 50400)? zz : null;\n", + s:"([+\-]?\\d{1,5})" + }, + c: function() { + var calc = [], + arr = [ + utilDate.formatCodeToRegex("Y", 1), + utilDate.formatCodeToRegex("m", 2), + utilDate.formatCodeToRegex("d", 3), + utilDate.formatCodeToRegex("h", 4), + utilDate.formatCodeToRegex("i", 5), + utilDate.formatCodeToRegex("s", 6), + {c:"ms = results[7] || '0'; ms = parseInt(ms, 10)/Math.pow(10, ms.length - 3);\n"}, + {c:[ + "if(results[8]) {", + "if(results[8] == 'Z'){", + "zz = 0;", + "}else if (results[8].indexOf(':') > -1){", + utilDate.formatCodeToRegex("P", 8).c, + "}else{", + utilDate.formatCodeToRegex("O", 8).c, + "}", + "}" + ].join('\n')} + ]; + + for (var i = 0, l = arr.length; i < l; ++i) { + calc.push(arr[i].c); + } + + return { + g:1, + c:calc.join(""), + s:[ + arr[0].s, + "(?:", "-", arr[1].s, + "(?:", "-", arr[2].s, + "(?:", + "(?:T| )?", + arr[3].s, ":", arr[4].s, + "(?::", arr[5].s, ")?", + "(?:(?:\\.|,)(\\d+))?", + "(Z|(?:[-+]\\d{2}(?::)?\\d{2}))?", + ")?", + ")?", + ")?" + ].join("") + }; + }, + U: { + g:1, + c:"u = parseInt(results[{0}], 10);\n", + s:"(-?\\d+)" + } + }, + + + + dateFormat: function(date, format) { + return utilDate.format(date, format); + }, + + + format: function(date, format) { + if (utilDate.formatFunctions[format] == null) { + utilDate.createFormat(format); + } + var result = utilDate.formatFunctions[format].call(date); + return result + ''; + }, + + + getTimezone : function(date) { + + + + + + + + + + + + + return date.toString().replace(/^.* (?:\((.*)\)|([A-Z]{1,4})(?:[\-+][0-9]{4})?(?: -?\d+)?)$/, "$1$2").replace(/[^A-Z]/g, ""); + }, + + + getGMTOffset : function(date, colon) { + var offset = date.getTimezoneOffset(); + return (offset > 0 ? "-" : "+") + + Ext.String.leftPad(Math.floor(Math.abs(offset) / 60), 2, "0") + + (colon ? ":" : "") + + Ext.String.leftPad(Math.abs(offset % 60), 2, "0"); + }, + + + getDayOfYear: function(date) { + var num = 0, + d = Ext.Date.clone(date), + m = date.getMonth(), + i; + + for (i = 0, d.setDate(1), d.setMonth(0); i < m; d.setMonth(++i)) { + num += utilDate.getDaysInMonth(d); + } + return num + date.getDate() - 1; + }, + + + getWeekOfYear : (function() { + + var ms1d = 864e5, + ms7d = 7 * ms1d; + + return function(date) { + var DC3 = Date.UTC(date.getFullYear(), date.getMonth(), date.getDate() + 3) / ms1d, + AWN = Math.floor(DC3 / 7), + Wyr = new Date(AWN * ms7d).getUTCFullYear(); + + return AWN - Math.floor(Date.UTC(Wyr, 0, 7) / ms7d) + 1; + }; + })(), + + + isLeapYear : function(date) { + var year = date.getFullYear(); + return !!((year & 3) == 0 && (year % 100 || (year % 400 == 0 && year))); + }, + + + getFirstDayOfMonth : function(date) { + var day = (date.getDay() - (date.getDate() - 1)) % 7; + return (day < 0) ? (day + 7) : day; + }, + + + getLastDayOfMonth : function(date) { + return utilDate.getLastDateOfMonth(date).getDay(); + }, + + + + getFirstDateOfMonth : function(date) { + return new Date(date.getFullYear(), date.getMonth(), 1); + }, + + + getLastDateOfMonth : function(date) { + return new Date(date.getFullYear(), date.getMonth(), utilDate.getDaysInMonth(date)); + }, + + + getDaysInMonth: (function() { + var daysInMonth = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]; + + return function(date) { + var m = date.getMonth(); + + return m == 1 && utilDate.isLeapYear(date) ? 29 : daysInMonth[m]; + }; + })(), + + + getSuffix : function(date) { + switch (date.getDate()) { + case 1: + case 21: + case 31: + return "st"; + case 2: + case 22: + return "nd"; + case 3: + case 23: + return "rd"; + default: + return "th"; + } + }, + + + clone : function(date) { + return new Date(date.getTime()); + }, + + + isDST : function(date) { + + + return new Date(date.getFullYear(), 0, 1).getTimezoneOffset() != date.getTimezoneOffset(); + }, + + + clearTime : function(date, clone) { + if (clone) { + return Ext.Date.clearTime(Ext.Date.clone(date)); + } + + + var d = date.getDate(); + + + date.setHours(0); + date.setMinutes(0); + date.setSeconds(0); + date.setMilliseconds(0); + + if (date.getDate() != d) { + + + + + for (var hr = 1, c = utilDate.add(date, Ext.Date.HOUR, hr); c.getDate() != d; hr++, c = utilDate.add(date, Ext.Date.HOUR, hr)); + + date.setDate(d); + date.setHours(c.getHours()); + } + + return date; + }, + + + add : function(date, interval, value) { + var d = Ext.Date.clone(date), + Date = Ext.Date; + if (!interval || value === 0) return d; + + switch(interval.toLowerCase()) { + case Ext.Date.MILLI: + d.setMilliseconds(d.getMilliseconds() + value); + break; + case Ext.Date.SECOND: + d.setSeconds(d.getSeconds() + value); + break; + case Ext.Date.MINUTE: + d.setMinutes(d.getMinutes() + value); + break; + case Ext.Date.HOUR: + d.setHours(d.getHours() + value); + break; + case Ext.Date.DAY: + d.setDate(d.getDate() + value); + break; + case Ext.Date.MONTH: + var day = date.getDate(); + if (day > 28) { + day = Math.min(day, Ext.Date.getLastDateOfMonth(Ext.Date.add(Ext.Date.getFirstDateOfMonth(date), 'mo', value)).getDate()); + } + d.setDate(day); + d.setMonth(date.getMonth() + value); + break; + case Ext.Date.YEAR: + d.setFullYear(date.getFullYear() + value); + break; + } + return d; + }, + + + between : function(date, start, end) { + var t = date.getTime(); + return start.getTime() <= t && t <= end.getTime(); + }, + + + compat: function() { + var nativeDate = window.Date, + p, u, + statics = ['useStrict', 'formatCodeToRegex', 'parseFunctions', 'parseRegexes', 'formatFunctions', 'y2kYear', 'MILLI', 'SECOND', 'MINUTE', 'HOUR', 'DAY', 'MONTH', 'YEAR', 'defaults', 'dayNames', 'monthNames', 'monthNumbers', 'getShortMonthName', 'getShortDayName', 'getMonthNumber', 'formatCodes', 'isValid', 'parseDate', 'getFormatCode', 'createFormat', 'createParser', 'parseCodes'], + proto = ['dateFormat', 'format', 'getTimezone', 'getGMTOffset', 'getDayOfYear', 'getWeekOfYear', 'isLeapYear', 'getFirstDayOfMonth', 'getLastDayOfMonth', 'getDaysInMonth', 'getSuffix', 'clone', 'isDST', 'clearTime', 'add', 'between']; + + + Ext.Array.forEach(statics, function(s) { + nativeDate[s] = utilDate[s]; + }); + + + Ext.Array.forEach(proto, function(s) { + nativeDate.prototype[s] = function() { + var args = Array.prototype.slice.call(arguments); + args.unshift(this); + return utilDate[s].apply(utilDate, args); + }; + }); + } +}; + +var utilDate = Ext.Date; + +})(); + + +(function(flexSetter) { + +var Base = Ext.Base = function() {}; + Base.prototype = { + $className: 'Ext.Base', + + $class: Base, + + + self: Base, + + + constructor: function() { + return this; + }, + + + initConfig: function(config) { + if (!this.$configInited) { + this.config = Ext.Object.merge({}, this.config || {}, config || {}); + + this.applyConfig(this.config); + + this.$configInited = true; + } + + return this; + }, + + + setConfig: function(config) { + this.applyConfig(config || {}); + + return this; + }, + + + applyConfig: flexSetter(function(name, value) { + var setter = 'set' + Ext.String.capitalize(name); + + if (typeof this[setter] === 'function') { + this[setter].call(this, value); + } + + return this; + }), + + + callParent: function(args) { + var method = this.callParent.caller, + 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; + } + + 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 || []); + }, + + + + statics: function() { + var method = this.statics.caller, + self = this.self; + + if (!method) { + return self; + } + + return method.$owner; + }, + + + 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 || []); + }, + + destroy: function() {} + }; + + + Ext.apply(Ext.Base, { + + create: function() { + return Ext.create.apply(Ext, [this].concat(Array.prototype.slice.call(arguments, 0))); + }, + + + own: flexSetter(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) { + originalFn = fn; + + fn = function() { + return originalFn.apply(this, arguments); + }; + } + + var className; + className = Ext.getClassName(this); + if (className) { + fn.displayName = className + '#' + name; + } + fn.$owner = this; + fn.$name = name; + + this.prototype[name] = fn; + }, + + + addStatics: function(members) { + for (var name in members) { + if (members.hasOwnProperty(name)) { + this[name] = members[name]; + } + } + + return this; + }, + + + implement: function(members) { + var prototype = this.prototype, + name, i, member, previous; + var className = Ext.getClassName(this); + for (name in members) { + if (members.hasOwnProperty(name)) { + member = members[name]; + + 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; + + for (i = enumerables.length; i--;) { + name = enumerables[i]; + + if (members.hasOwnProperty(name)) { + member = members[name]; + member.$owner = this; + member.$name = name; + prototype[name] = member; + } + } + } + }, + + + borrow: function(fromClass, members) { + var fromPrototype = fromClass.prototype, + i, ln, member; + + members = Ext.Array.from(members); + + for (i = 0, ln = members.length; i < ln; i++) { + member = members[i]; + + this.own(member, fromPrototype[member]); + } + + return this; + }, + + + override: function(members) { + var prototype = this.prototype, + name, i, member, previous; + + for (name in members) { + if (members.hasOwnProperty(name)) { + member = members[name]; + + if (typeof member === 'function') { + if (typeof prototype[name] === 'function') { + previous = prototype[name]; + member.$previous = previous; + } + + this.ownMethod(name, member); + } + else { + prototype[name] = member; + } + } + } + + if (Ext.enumerables) { + var enumerables = Ext.enumerables; + + for (i = enumerables.length; i--;) { + name = enumerables[i]; + + if (members.hasOwnProperty(name)) { + if (prototype[name] !== undefined) { + previous = prototype[name]; + members[name].$previous = previous; + } + + this.ownMethod(name, members[name]); + } + } + } + + return this; + }, + + + mixin: flexSetter(function(name, cls) { + var mixin = cls.prototype, + my = this.prototype, + i, fn; + + for (i in mixin) { + if (mixin.hasOwnProperty(i)) { + if (my[i] === undefined) { + if (typeof mixin[i] === 'function') { + fn = mixin[i]; + + if (fn.$owner === undefined) { + this.ownMethod(i, fn); + } + else { + my[i] = fn; + } + } + else { + my[i] = mixin[i]; + } + } + else if (i === 'config' && my.config && mixin.config) { + Ext.Object.merge(my.config, mixin.config); + } + } + } + + if (my.mixins === undefined) { + my.mixins = {}; + } + + my.mixins[name] = mixin; + }), + + + getName: function() { + return Ext.getClassName(this); + }, + + + createAlias: flexSetter(function(alias, origin) { + this.prototype[alias] = this.prototype[origin]; + }) + }); + +})(Ext.Function.flexSetter); + + +(function() { + + var Class, + Base = Ext.Base, + baseStaticProperties = [], + baseStaticProperty; + + for (baseStaticProperty in Base) { + if (Base.hasOwnProperty(baseStaticProperty)) { + baseStaticProperties.push(baseStaticProperty); + } + } + + + Ext.Class = Class = function(newClass, classData, onClassCreated) { + if (typeof newClass !== 'function') { + onClassCreated = classData; + classData = newClass; + newClass = function() { + return this.constructor.apply(this, arguments); + }; + } + + if (!classData) { + classData = {}; + } + + var preprocessorStack = classData.preprocessors || Class.getDefaultPreprocessors(), + registeredPreprocessors = Class.getPreprocessors(), + index = 0, + preprocessors = [], + preprocessor, preprocessors, staticPropertyName, process, i, j, ln; + + for (i = 0, ln = baseStaticProperties.length; i < ln; i++) { + staticPropertyName = baseStaticProperties[i]; + newClass[staticPropertyName] = Base[staticPropertyName]; + } + + delete classData.preprocessors; + + for (j = 0, ln = preprocessorStack.length; j < ln; j++) { + preprocessor = preprocessorStack[j]; + + if (typeof preprocessor === 'string') { + preprocessor = registeredPreprocessors[preprocessor]; + + if (!preprocessor.always) { + if (classData.hasOwnProperty(preprocessor.name)) { + preprocessors.push(preprocessor.fn); + } + } + else { + preprocessors.push(preprocessor.fn); + } + } + else { + preprocessors.push(preprocessor); + } + } + + classData.onClassCreated = onClassCreated; + + classData.onBeforeClassCreated = function(cls, data) { + onClassCreated = data.onClassCreated; + + delete data.onBeforeClassCreated; + delete data.onClassCreated; + + cls.implement(data); + + if (onClassCreated) { + onClassCreated.call(cls, cls); + } + }; + + process = function(cls, data) { + preprocessor = preprocessors[index++]; + + if (!preprocessor) { + data.onBeforeClassCreated.apply(this, arguments); + return; + } + + if (preprocessor.call(this, cls, data, process) !== false) { + process.apply(this, arguments); + } + }; + + process.call(Class, newClass, classData); + + return newClass; + }; + + Ext.apply(Class, { + + + preprocessors: {}, + + + registerPreprocessor: function(name, fn, always) { + this.preprocessors[name] = { + name: name, + always: always || false, + fn: fn + }; + + return this; + }, + + + getPreprocessor: function(name) { + return this.preprocessors[name]; + }, + + getPreprocessors: function() { + return this.preprocessors; + }, + + + getDefaultPreprocessors: function() { + return this.defaultPreprocessors || []; + }, + + + setDefaultPreprocessors: function(preprocessors) { + this.defaultPreprocessors = Ext.Array.from(preprocessors); + + return this; + }, + + + setDefaultPreprocessorPosition: function(name, offset, relativeName) { + var defaultPreprocessors = this.defaultPreprocessors, + index; + + if (typeof offset === 'string') { + if (offset === 'first') { + defaultPreprocessors.unshift(name); + + return this; + } + else if (offset === 'last') { + defaultPreprocessors.push(name); + + return this; + } + + offset = (offset === 'after') ? 1 : -1; + } + + index = Ext.Array.indexOf(defaultPreprocessors, relativeName); + + if (index !== -1) { + defaultPreprocessors.splice(Math.max(0, index + offset), 0, name); + } + + return this; + } + }); + + Class.registerPreprocessor('extend', function(cls, data) { + var extend = data.extend, + base = Ext.Base, + basePrototype = base.prototype, + prototype = function() {}, + parent, i, k, ln, staticName, parentStatics, + parentPrototype, clsPrototype; + + if (extend && extend !== Object) { + parent = extend; + } + else { + parent = base; + } + + parentPrototype = parent.prototype; + + prototype.prototype = parentPrototype; + clsPrototype = cls.prototype = new prototype(); + + if (!('$class' in parent)) { + for (i in basePrototype) { + if (!parentPrototype[i]) { + parentPrototype[i] = basePrototype[i]; + } + } + } + + clsPrototype.self = cls; + + cls.superclass = clsPrototype.superclass = parentPrototype; + + delete data.extend; + + + parentStatics = parentPrototype.$inheritableStatics; + + if (parentStatics) { + for (k = 0, ln = parentStatics.length; k < ln; k++) { + staticName = parentStatics[k]; + + if (!cls.hasOwnProperty(staticName)) { + cls[staticName] = parent[staticName]; + } + } + } + + + if (parentPrototype.config) { + clsPrototype.config = Ext.Object.merge({}, parentPrototype.config); + } + else { + clsPrototype.config = {}; + } + + if (clsPrototype.$onExtended) { + clsPrototype.$onExtended.call(cls, cls, data); + } + + if (data.onClassExtended) { + 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]; + } + } + + 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); + } + } + + 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; + + Ext.Object.each(data.config, function(name) { + var cName = name.charAt(0).toUpperCase() + name.substr(1), + pName = name, + apply = 'apply' + cName, + setter = 'set' + cName, + getter = 'get' + cName; + + if (!(apply in prototype) && !data.hasOwnProperty(apply)) { + data[apply] = function(val) { + return val; + }; + } + + if (!(setter in prototype) && !data.hasOwnProperty(setter)) { + data[setter] = function(val) { + var ret = this[apply].call(this, val, this[pName]); + + if (ret !== undefined) { + this[pName] = ret; + } + + return this; + }; + } + + if (!(getter in prototype) && !data.hasOwnProperty(getter)) { + data[getter] = function() { + return this[pName]; + }; + } + }); + + Ext.Object.merge(prototype.config, data.config); + delete data.config; + }); + + Class.setDefaultPreprocessors(['extend', 'statics', 'inheritableStatics', 'mixins', 'config']); + + + Ext.extend = function(subclass, superclass, members) { + if (arguments.length === 2 && Ext.isObject(superclass)) { + members = superclass; + superclass = subclass; + subclass = null; + } + + var cls; + + if (!superclass) { + Ext.Error.raise("Attempting to extend from a class which has not been loaded on the page."); + } + + members.extend = superclass; + members.preprocessors = ['extend', 'mixins', 'config', 'statics']; + + if (subclass) { + cls = new Class(subclass, members); + } + else { + cls = new Class(members); + } + + cls.prototype.override = function(o) { + for (var m in o) { + if (o.hasOwnProperty(m)) { + this[m] = o[m]; + } + } + }; + + return cls; + }; + +})(); + + +(function(Class, alias) { + + var slice = Array.prototype.slice; + + var Manager = Ext.ClassManager = { + + + classes: {}, + + + existCache: {}, + + + namespaceRewrites: [{ + from: 'Ext.', + to: Ext + }], + + + maps: { + alternateToName: {}, + aliasToName: {}, + nameToAliases: {} + }, + + + enableNamespaceParseCache: true, + + + namespaceParseCache: {}, + + + 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; + } + + root = Ext.global; + parts = this.parseNamespace(className); + + for (i = 0, ln = parts.length; i < ln; i++) { + part = parts[i]; + + if (typeof part !== 'string') { + root = part; + } else { + if (!root || !root[part]) { + return false; + } + + root = root[part]; + } + } + + Ext.Loader.historyPush(className); + + this.existCache[className] = true; + + return true; + }, + + + 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; + + if (this.enableNamespaceParseCache) { + if (cache.hasOwnProperty(namespace)) { + return cache[namespace]; + } + } + + var parts = [], + rewrites = this.namespaceRewrites, + rewrite, from, to, i, ln, root = Ext.global; + + for (i = 0, ln = rewrites.length; i < ln; i++) { + rewrite = rewrites[i]; + from = rewrite.from; + to = rewrite.to; + + if (namespace === from || namespace.substring(0, from.length) === from) { + namespace = namespace.substring(from.length); + + if (typeof to !== 'string') { + root = to; + } else { + parts = parts.concat(to.split('.')); + } + + break; + } + } + + parts.push(root); + + parts = parts.concat(namespace.split('.')); + + if (this.enableNamespaceParseCache) { + cache[namespace] = parts; + } + + return parts; + }, + + + setNamespace: function(name, value) { + var root = Ext.global, + parts = this.parseNamespace(name), + leaf = parts.pop(), + i, ln, part; + + for (i = 0, ln = parts.length; i < ln; i++) { + part = parts[i]; + + if (typeof part !== 'string') { + root = part; + } else { + if (!root[part]) { + root[part] = {}; + } + + root = root[part]; + } + } + + root[leaf] = value; + + return root[leaf]; + }, + + + createNamespaces: function() { + var root = Ext.global, + parts, part, i, j, ln, subLn; + + for (i = 0, ln = arguments.length; i < ln; i++) { + parts = this.parseNamespace(arguments[i]); + + for (j = 0, subLn = parts.length; j < subLn; j++) { + part = parts[j]; + + if (typeof part !== 'string') { + root = part; + } else { + if (!root[part]) { + root[part] = {}; + } + + root = root[part]; + } + } + } + + return root; + }, + + + set: function(name, value) { + var targetName = this.getName(value); + + this.classes[name] = this.setNamespace(name, value); + + if (targetName && targetName !== name) { + this.maps.alternateToName[name] = targetName; + } + + return this; + }, + + + get: function(name) { + if (this.classes.hasOwnProperty(name)) { + return this.classes[name]; + } + + var root = Ext.global, + parts = this.parseNamespace(name), + part, i, ln; + + for (i = 0, ln = parts.length; i < ln; i++) { + part = parts[i]; + + if (typeof part !== 'string') { + root = part; + } else { + if (!root || !root[part]) { + return null; + } + + root = root[part]; + } + } + + return root; + }, + + + setAlias: function(cls, alias) { + var aliasToNameMap = this.maps.aliasToName, + nameToAliasesMap = this.maps.nameToAliases, + className; + + if (typeof cls === 'string') { + className = cls; + } else { + className = this.getName(cls); + } + + 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; + } + + if (!nameToAliasesMap[className]) { + nameToAliasesMap[className] = []; + } + + if (alias) { + Ext.Array.include(nameToAliasesMap[className], alias); + } + + return this; + }, + + + getByAlias: function(alias) { + return this.get(this.getNameByAlias(alias)); + }, + + + getNameByAlias: function(alias) { + return this.maps.aliasToName[alias] || ''; + }, + + + getNameByAlternate: function(alternate) { + return this.maps.alternateToName[alternate] || ''; + }, + + + getAliasesByName: function(name) { + return this.maps.nameToAliases[name] || []; + }, + + + getName: function(object) { + return object && object.$className || ''; + }, + + + getClass: function(object) { + return object && object.self || null; + }, + + + 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; + + return new Class(data, function() { + var postprocessorStack = data.postprocessors || manager.defaultPostprocessors, + registeredPostprocessors = manager.postprocessors, + index = 0, + postprocessors = [], + postprocessor, postprocessors, process, i, ln; + + delete data.postprocessors; + + for (i = 0, ln = postprocessorStack.length; i < ln; i++) { + postprocessor = postprocessorStack[i]; + + if (typeof postprocessor === 'string') { + postprocessor = registeredPostprocessors[postprocessor]; + + if (!postprocessor.always) { + if (data[postprocessor.name] !== undefined) { + postprocessors.push(postprocessor.fn); + } + } + else { + postprocessors.push(postprocessor.fn); + } + } + else { + postprocessors.push(postprocessor); + } + } + + process = function(clsName, cls, clsData) { + postprocessor = postprocessors[index++]; + + if (!postprocessor) { + manager.set(className, cls); + + Ext.Loader.historyPush(className); + + if (createdFn) { + createdFn.call(cls, cls); + } + + return; + } + + if (postprocessor.call(this, clsName, cls, clsData, process) !== false) { + process.apply(this, arguments); + } + }; + + process.call(manager, className, this, data); + }); + }, + + + instantiateByAlias: function() { + var alias = arguments[0], + args = slice.call(arguments), + className = this.getNameByAlias(alias); + + 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); + } + + args[0] = className; + + return this.instantiate.apply(this, args); + }, + + + instantiate: function() { + var name = arguments[0], + args = slice.call(arguments, 1), + alias = name, + 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); + } + else { + cls = name; + } + + + if (!cls) { + possibleName = this.getNameByAlias(name); + + if (possibleName) { + name = possibleName; + + cls = this.get(name); + } + } + + + if (!cls) { + possibleName = this.getNameByAlternate(name); + + if (possibleName) { + name = possibleName; + + cls = this.get(name); + } + } + + + 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); + }, + + + dynInstantiate: function(name, args) { + args = Ext.Array.from(args, true); + args.unshift(name); + + return this.instantiate.apply(this, args); + }, + + + getInstantiator: function(length) { + if (!this.instantiators[length]) { + var i = length, + args = []; + + for (i = 0; i < length; i++) { + args.push('a['+i+']'); + } + + this.instantiators[length] = new Function('c', 'a', 'return new c('+args.join(',')+')'); + } + + return this.instantiators[length]; + }, + + + postprocessors: {}, + + + defaultPostprocessors: [], + + + registerPostprocessor: function(name, fn, always) { + this.postprocessors[name] = { + name: name, + always: always || false, + fn: fn + }; + + return this; + }, + + + setDefaultPostprocessors: function(postprocessors) { + this.defaultPostprocessors = Ext.Array.from(postprocessors); + + return this; + }, + + + setDefaultPostprocessorPosition: function(name, offset, relativeName) { + var defaultPostprocessors = this.defaultPostprocessors, + index; + + if (typeof offset === 'string') { + if (offset === 'first') { + defaultPostprocessors.unshift(name); + + return this; + } + else if (offset === 'last') { + defaultPostprocessors.push(name); + + return this; + } + + offset = (offset === 'after') ? 1 : -1; + } + + index = Ext.Array.indexOf(defaultPostprocessors, relativeName); + + if (index !== -1) { + defaultPostprocessors.splice(Math.max(0, index + offset), 0, name); + } + + return this; + }, + + + getNamesByExpression: function(expression) { + var nameToAliasesMap = this.maps.nameToAliases, + 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, '(.*?)'); + regex = new RegExp('^' + expression + '$'); + + for (name in nameToAliasesMap) { + if (nameToAliasesMap.hasOwnProperty(name)) { + aliases = nameToAliasesMap[name]; + + if (name.search(regex) !== -1) { + names.push(name); + } + else { + for (i = 0, ln = aliases.length; i < ln; i++) { + alias = aliases[i]; + + if (alias.search(regex) !== -1) { + names.push(name); + break; + } + } + } + } + } + + } else { + possibleName = this.getNameByAlias(expression); + + if (possibleName) { + names.push(possibleName); + } else { + possibleName = this.getNameByAlternate(expression); + + if (possibleName) { + names.push(possibleName); + } else { + names.push(expression); + } + } + } + + return names; + } + }; + + Manager.registerPostprocessor('alias', function(name, cls, data) { + var aliases = data.alias, + widgetPrefix = 'widget.', + i, ln, alias; + + if (!(aliases instanceof Array)) { + aliases = [aliases]; + } + + 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; + + if (!(alternates instanceof Array)) { + alternates = [alternates]; + } + + 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); + } + }); + + Manager.setDefaultPostprocessors(['alias', 'singleton', 'alternateClassName']); + + Ext.apply(Ext, { + + create: alias(Manager, 'instantiate'), + + + factory: function(item, namespace) { + if (item instanceof Array) { + var i, ln; + + for (i = 0, ln = item.length; i < ln; i++) { + item[i] = Ext.factory(item[i], namespace); + } + + return item; + } + + var isString = (typeof item === 'string'); + + if (isString || (item instanceof Object && item.constructor === Object)) { + var name, config = {}; + + if (isString) { + name = item; + } + else { + name = item.className; + config = item; + delete config.className; + } + + if (namespace !== undefined && name.indexOf(namespace) === -1) { + name = namespace + '.' + Ext.String.capitalize(name); + } + + return Ext.create(name, config); + } + + if (typeof item === 'function') { + return Ext.create(item); + } + + return item; + }, + + + widget: function(name) { + var args = slice.call(arguments); + args[0] = 'widget.' + name; + + return Manager.instantiateByAlias.apply(Manager, args); + }, + + + createByAlias: alias(Manager, 'instantiateByAlias'), + + + define: alias(Manager, 'create'), + + + getClassName: alias(Manager, 'getName'), + + + getDisplayName: function(object) { + if (object.displayName) { + return object.displayName; + } + + if (object.$name && object.$class) { + return Ext.getClassName(object.$class) + '#' + object.$name; + } + + if (object.$className) { + return object.$className; + } + + return 'Anonymous'; + }, + + + getClass: alias(Manager, 'getClass'), + + + namespace: alias(Manager, 'createNamespaces') + }); + + Ext.createWidget = Ext.widget; + + + Ext.ns = Ext.namespace; + + 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); + + + +(function(Manager, Class, flexSetter, alias) { + + var + dependencyProperties = ['extend', 'mixins', 'requires'], + Loader; + + Loader = Ext.Loader = { + + documentHead: typeof document !== 'undefined' && (document.head || document.getElementsByTagName('head')[0]), + + + isLoading: false, + + + queue: [], + + + isFileLoaded: {}, + + + readyListeners: [], + + + optionalRequires: [], + + + requiresMap: {}, + + + numPendingFiles: 0, + + + numLoadedFiles: 0, + + + hasFileLoadError: false, + + + classNameToFilePathMap: {}, + + + history: [], + + + config: { + + enabled: false, + + + disableCaching: true, + + + disableCachingParam: '_dc', + + + paths: { + 'Ext': '.' + } + }, + + + setConfig: function(name, value) { + if (Ext.isObject(name) && arguments.length === 1) { + Ext.Object.merge(this.config, name); + } + else { + this.config[name] = (Ext.isObject(value)) ? Ext.Object.merge(this.config[name], value) : value; + } + + return this; + }, + + + getConfig: function(name) { + if (name) { + return this.config[name]; + } + + return this.config; + }, + + + setPath: flexSetter(function(name, path) { + this.config.paths[name] = path; + + return this; + }), + + + getPath: function(className) { + var path = '', + paths = this.config.paths, + prefix = this.getPrefix(className); + + if (prefix.length > 0) { + if (prefix === className) { + return paths[prefix]; + } + + path = paths[prefix]; + className = className.substring(prefix.length + 1); + } + + if (path.length > 0) { + path += '/'; + } + + return path.replace(/\/\.\//g, '/') + className.replace(/\./g, "/") + '.js'; + }, + + + getPrefix: function(className) { + var paths = this.config.paths, + prefix, deepestPrefix = ''; + + if (paths.hasOwnProperty(className)) { + return className; + } + + for (prefix in paths) { + if (paths.hasOwnProperty(prefix) && prefix + '.' === className.substring(0, prefix.length + 1)) { + if (prefix.length > deepestPrefix.length) { + deepestPrefix = prefix; + } + } + } + + return deepestPrefix; + }, + + + refreshQueue: function() { + var ln = this.queue.length, + i, item, j, requires; + + if (ln === 0) { + this.triggerReady(); + return; + } + + for (i = 0; i < ln; i++) { + item = this.queue[i]; + + if (item) { + requires = item.requires; + + + + if (requires.length > this.numLoadedFiles) { + continue; + } + + j = 0; + + do { + if (Manager.isCreated(requires[j])) { + + requires.splice(j, 1); + } + else { + j++; + } + } while (j < requires.length); + + if (item.requires.length === 0) { + this.queue.splice(i, 1); + item.callback.call(item.scope); + this.refreshQueue(); + break; + } + } + } + + return this; + }, + + + injectScriptElement: function(url, onLoad, onError, scope) { + var script = document.createElement('script'), + me = this, + onLoadFn = function() { + me.cleanupScriptElement(script); + onLoad.call(scope); + }, + onErrorFn = function() { + me.cleanupScriptElement(script); + onError.call(scope); + }; + + script.type = 'text/javascript'; + script.src = url; + script.onload = onLoadFn; + script.onerror = onErrorFn; + script.onreadystatechange = function() { + if (this.readyState === 'loaded' || this.readyState === 'complete') { + onLoadFn(); + } + }; + + this.documentHead.appendChild(script); + + return script; + }, + + + cleanupScriptElement: function(script) { + script.onload = null; + script.onreadystatechange = null; + script.onerror = null; + + return this; + }, + + + loadScriptFile: function(url, onLoad, onError, scope, synchronous) { + var me = this, + noCacheUrl = url + (this.getConfig('disableCaching') ? ('?' + this.getConfig('disableCachingParam') + '=' + Ext.Date.now()) : ''), + fileName = url.split('/').pop(), + isCrossOriginRestricted = false, + xhr, status, onScriptError; + + scope = scope || this; + + this.isLoading = true; + + if (!synchronous) { + onScriptError = function() { + onError.call(scope, "Failed loading '" + url + "', please verify that the file exists", synchronous); + }; + + if (!Ext.isReady && Ext.onDocumentReady) { + Ext.onDocumentReady(function() { + me.injectScriptElement(noCacheUrl, onLoad, onScriptError, scope); + }); + } + else { + this.injectScriptElement(noCacheUrl, onLoad, onScriptError, scope); + } + } + else { + if (typeof XMLHttpRequest !== 'undefined') { + xhr = new XMLHttpRequest(); + } else { + xhr = new ActiveXObject('Microsoft.XMLHTTP'); + } + + try { + xhr.open('GET', noCacheUrl, false); + xhr.send(null); + } catch (e) { + isCrossOriginRestricted = true; + } + + status = (xhr.status === 1223) ? 204 : xhr.status; + + if (!isCrossOriginRestricted) { + isCrossOriginRestricted = (status === 0); + } + + if (isCrossOriginRestricted + ) { + onError.call(this, "Failed loading synchronously via XHR: '" + url + "'; It's likely that the file is either " + + "being loaded from a different domain or from the local file system whereby cross origin " + + "requests are not allowed due to security reasons. Use asynchronous loading with " + + "Ext.require instead.", synchronous); + } + else if (status >= 200 && status < 300 + ) { + + new Function(xhr.responseText + "\n//@ sourceURL=" + fileName)(); + + onLoad.call(scope); + } + else { + onError.call(this, "Failed loading synchronously via XHR: '" + url + "'; please " + + "verify that the file exists. " + + "XHR status code: " + status, synchronous); + } + + + xhr = null; + } + }, + + + exclude: function(excludes) { + var me = this; + + return { + require: function(expressions, fn, scope) { + return me.require(expressions, fn, scope, excludes); + }, + + syncRequire: function(expressions, fn, scope) { + return me.syncRequire(expressions, fn, scope, excludes); + } + }; + }, + + + syncRequire: function() { + this.syncModeEnabled = true; + this.require.apply(this, arguments); + this.refreshQueue(); + this.syncModeEnabled = false; + }, + + + require: function(expressions, fn, scope, excludes) { + var filePath, expression, exclude, className, excluded = {}, + excludedClassNames = [], + possibleClassNames = [], + possibleClassName, classNames = [], + i, j, ln, subLn; + + expressions = Ext.Array.from(expressions); + excludes = Ext.Array.from(excludes); + + fn = fn || Ext.emptyFn; + + scope = scope || Ext.global; + + for (i = 0, ln = excludes.length; i < ln; i++) { + exclude = excludes[i]; + + if (typeof exclude === 'string' && exclude.length > 0) { + excludedClassNames = Manager.getNamesByExpression(exclude); + + for (j = 0, subLn = excludedClassNames.length; j < subLn; j++) { + excluded[excludedClassNames[j]] = true; + } + } + } + + for (i = 0, ln = expressions.length; i < ln; i++) { + expression = expressions[i]; + + if (typeof expression === 'string' && expression.length > 0) { + possibleClassNames = Manager.getNamesByExpression(expression); + + for (j = 0, subLn = possibleClassNames.length; j < subLn; j++) { + possibleClassName = possibleClassNames[j]; + + if (!excluded.hasOwnProperty(possibleClassName) && !Manager.isCreated(possibleClassName)) { + Ext.Array.include(classNames, possibleClassName); + } + } + } + } + + + + if (!this.config.enabled) { + if (classNames.length > 0) { + Ext.Error.raise({ + sourceClass: "Ext.Loader", + sourceMethod: "require", + msg: "Ext.Loader is not enabled, so dependencies cannot be resolved dynamically. " + + "Missing required class" + ((classNames.length > 1) ? "es" : "") + ": " + classNames.join(', ') + }); + } + } + + if (classNames.length === 0) { + fn.call(scope); + return this; + } + + this.queue.push({ + requires: classNames, + callback: fn, + scope: scope + }); + + classNames = classNames.slice(); + + for (i = 0, ln = classNames.length; i < ln; i++) { + className = classNames[i]; + + if (!this.isFileLoaded.hasOwnProperty(className)) { + this.isFileLoaded[className] = false; + + filePath = this.getPath(className); + + this.classNameToFilePathMap[className] = filePath; + + this.numPendingFiles++; + + this.loadScriptFile( + filePath, + Ext.Function.pass(this.onFileLoaded, [className, filePath], this), + Ext.Function.pass(this.onFileLoadError, [className, filePath]), + this, + this.syncModeEnabled + ); + } + } + + return this; + }, + + + onFileLoaded: function(className, filePath) { + this.numLoadedFiles++; + + this.isFileLoaded[className] = true; + + this.numPendingFiles--; + + if (this.numPendingFiles === 0) { + 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("', '") + "'" + }); + } + }, + + + onFileLoadError: function(className, filePath, errorMessage, isSynchronous) { + this.numPendingFiles--; + this.hasFileLoadError = true; + + Ext.Error.raise({ + sourceClass: "Ext.Loader", + classToLoad: className, + loadPath: filePath, + loadingType: isSynchronous ? 'synchronous' : 'async', + msg: errorMessage + }); + }, + + + addOptionalRequires: function(requires) { + var optionalRequires = this.optionalRequires, + i, ln, require; + + requires = Ext.Array.from(requires); + + for (i = 0, ln = requires.length; i < ln; i++) { + require = requires[i]; + + Ext.Array.include(optionalRequires, require); + } + + return this; + }, + + + triggerReady: function(force) { + var readyListeners = this.readyListeners, + optionalRequires, listener; + + if (this.isLoading || force) { + this.isLoading = false; + + if (this.optionalRequires.length) { + + optionalRequires = Ext.Array.clone(this.optionalRequires); + + + this.optionalRequires.length = 0; + + this.require(optionalRequires, Ext.Function.pass(this.triggerReady, [true], this), this); + return this; + } + + while (readyListeners.length) { + listener = readyListeners.shift(); + listener.fn.call(listener.scope); + + if (this.isLoading) { + return this; + } + } + } + + return this; + }, + + + onReady: function(fn, scope, withDomReady, options) { + var oldFn; + + if (withDomReady !== false && Ext.onDocumentReady) { + oldFn = fn; + + fn = function() { + Ext.onDocumentReady(oldFn, scope, options); + }; + } + + if (!this.isLoading) { + fn.call(scope); + } + else { + this.readyListeners.push({ + fn: fn, + scope: scope + }); + } + }, + + + historyPush: function(className) { + if (className && this.isFileLoaded.hasOwnProperty(className)) { + Ext.Array.include(this.history, className); + } + + return this; + } + }; + + + Ext.require = alias(Loader, 'require'); + + + Ext.syncRequire = alias(Loader, 'syncRequire'); + + + Ext.exclude = alias(Loader, 'exclude'); + + + Ext.onReady = function(fn, scope, options) { + Loader.onReady(fn, scope, true, options); + }; + + Class.registerPreprocessor('loader', function(cls, data, continueFn) { + var me = this, + dependencies = [], + className = Manager.getName(cls), + i, j, ln, subLn, value, propertyName, propertyValue; + + + + for (i = 0, ln = dependencyProperties.length; i < ln; i++) { + propertyName = dependencyProperties[i]; + + if (data.hasOwnProperty(propertyName)) { + propertyValue = data[propertyName]; + + if (typeof propertyValue === 'string') { + dependencies.push(propertyValue); + } + else if (propertyValue instanceof Array) { + for (j = 0, subLn = propertyValue.length; j < subLn; j++) { + value = propertyValue[j]; + + if (typeof value === 'string') { + dependencies.push(value); + } + } + } + else { + for (j in propertyValue) { + if (propertyValue.hasOwnProperty(j)) { + value = propertyValue[j]; + + if (typeof value === 'string') { + dependencies.push(value); + } + } + } + } + } + } + + if (dependencies.length === 0) { + + 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++) { + propertyName = dependencyProperties[i]; + + if (data.hasOwnProperty(propertyName)) { + propertyValue = data[propertyName]; + + if (typeof propertyValue === 'string') { + data[propertyName] = Manager.get(propertyValue); + } + else if (propertyValue instanceof Array) { + for (j = 0, subLn = propertyValue.length; j < subLn; j++) { + value = propertyValue[j]; + + if (typeof value === 'string') { + data[propertyName][j] = Manager.get(value); + } + } + } + else { + for (var k in propertyValue) { + if (propertyValue.hasOwnProperty(k)) { + value = propertyValue[k]; + + if (typeof value === 'string') { + data[propertyName][k] = Manager.get(value); + } + } + } + } + } + } + + continueFn.call(me, cls, data); + }); + + return false; + }, true); + + Class.setDefaultPreprocessorPosition('loader', 'after', 'className'); + + Manager.registerPostprocessor('uses', function(name, cls, data) { + var uses = Ext.Array.from(data.uses), + items = [], + i, ln, item; + + for (i = 0, ln = uses.length; i < ln; i++) { + item = uses[i]; + + if (typeof item === 'string') { + items.push(item); + } + } + + Loader.addOptionalRequires(items); + }); + + Manager.setDefaultPostprocessorPosition('uses', 'last'); + +})(Ext.ClassManager, Ext.Class, Ext.Function.flexSetter, Ext.Function.alias); + + +Ext.Error = Ext.extend(Error, { + statics: { + + ignore: false, + + + raise: function(err){ + err = err || {}; + if (Ext.isString(err)) { + err = { msg: err }; + } + + var method = this.raise.caller; + + if (method) { + if (method.$name) { + err.sourceMethod = method.$name; + } + if (method.$owner) { + err.sourceClass = method.$owner.$className; + } + } + + 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); + } + + throw new Ext.Error(err); + } + }, + + + handle: function(){ + return Ext.Error.ignore; + } + }, + + + constructor: function(config){ + if (Ext.isString(config)) { + config = { msg: config }; + } + Ext.apply(this, config); + }, + + + toString: function(){ + var me = this, + className = me.className ? me.className : '', + methodName = me.methodName ? '.' + me.methodName + '(): ' : '', + msg = me.msg || '(No description provided)'; + + return className + methodName + msg; + } +}); + + + + +Ext.JSON = new(function() { + var useHasOwn = !! {}.hasOwnProperty, + isNative = function() { + var useNative = null; + + return function() { + if (useNative === null) { + useNative = Ext.USE_NATIVE_JSON && window.JSON && JSON.toString() == '[object JSON]'; + } + + return useNative; + }; + }(), + pad = function(n) { + return n < 10 ? "0" + n : n; + }, + doDecode = function(json) { + return eval("(" + json + ')'); + }, + doEncode = function(o) { + if (!Ext.isDefined(o) || o === null) { + return "null"; + } else if (Ext.isArray(o)) { + return encodeArray(o); + } else if (Ext.isDate(o)) { + return Ext.JSON.encodeDate(o); + } else if (Ext.isString(o)) { + return encodeString(o); + } else if (typeof o == "number") { + + return isFinite(o) ? String(o) : "null"; + } else if (Ext.isBoolean(o)) { + return String(o); + } else if (Ext.isObject(o)) { + return encodeObject(o); + } else if (typeof o === "function") { + return "null"; + } + return 'undefined'; + }, + m = { + "\b": '\\b', + "\t": '\\t', + "\n": '\\n', + "\f": '\\f', + "\r": '\\r', + '"': '\\"', + "\\": '\\\\', + '\x0b': '\\u000b' + }, + charToReplace = /[\\\"\x00-\x1f\x7f-\uffff]/g, + encodeString = function(s) { + return '"' + s.replace(charToReplace, function(a) { + var c = m[a]; + return typeof c === 'string' ? c : '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4); + }) + '"'; + }, + encodeArray = function(o) { + var a = ["[", ""], + + len = o.length, + i; + for (i = 0; i < len; i += 1) { + a.push(doEncode(o[i]), ','); + } + + a[a.length - 1] = ']'; + return a.join(""); + }, + encodeObject = function(o) { + var a = ["{", ""], + + i; + for (i in o) { + if (!useHasOwn || o.hasOwnProperty(i)) { + a.push(doEncode(i), ":", doEncode(o[i]), ','); + } + } + + a[a.length - 1] = '}'; + return a.join(""); + }; + + + this.encodeDate = function(o) { + return '"' + o.getFullYear() + "-" + + pad(o.getMonth() + 1) + "-" + + pad(o.getDate()) + "T" + + pad(o.getHours()) + ":" + + pad(o.getMinutes()) + ":" + + pad(o.getSeconds()) + '"'; + }; + + + this.encode = function() { + var ec; + return function(o) { + if (!ec) { + + ec = isNative() ? JSON.stringify : doEncode; + } + return ec(o); + }; + }(); + + + + this.decode = function() { + var dc; + return function(json, safe) { + if (!dc) { + + dc = isNative() ? JSON.parse : doDecode; + } + try { + return dc(json); + } catch (e) { + if (safe === true) { + return null; + } + Ext.Error.raise({ + sourceClass: "Ext.JSON", + sourceMethod: "decode", + msg: "You're trying to decode and invalid JSON String: " + json + }); + } + }; + }(); + +})(); + +Ext.encode = Ext.JSON.encode; + +Ext.decode = Ext.JSON.decode; + + + +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', + + + isReady: false, + + + enableGarbageCollector: true, + + + enableListenerCollection: true, + + + id: function(el, prefix) { + el = Ext.getDom(el, true) || {}; + if (el === document) { + el.id = this.documentId; + } + else if (el === window) { + el.id = this.windowId; + } + if (!el.id) { + el.id = (prefix || "ext-gen") + (++Ext.idSeed); + } + return el.id; + }, + + + getBody: function() { + return Ext.get(document.body || false); + }, + + + getHead: function() { + var head; + + return function() { + if (head == undefined) { + head = Ext.get(document.getElementsByTagName("head")[0]); + } + + return head; + }; + }(), + + + getDoc: function() { + return Ext.get(document); + }, + + + getCmp: function(id) { + return Ext.ComponentManager.get(id); + }, + + + getOrientation: function() { + return window.innerHeight > window.innerWidth ? 'portrait' : 'landscape'; + }, + + + destroy: function() { + var ln = arguments.length, + i, arg; + + for (i = 0; i < ln; i++) { + arg = arguments[i]; + if (arg) { + if (Ext.isArray(arg)) { + this.destroy.apply(this, arg); + } + else if (Ext.isFunction(arg.destroy)) { + arg.destroy(); + } + else if (arg.dom) { + arg.remove(); + } + } + } + }, + + + callback: function(callback, scope, args, delay){ + if(Ext.isFunction(callback)){ + args = args || []; + scope = scope || window; + if (delay) { + Ext.defer(callback, delay, scope, args); + } else { + callback.apply(scope, args); + } + } + }, + + + htmlEncode : function(value) { + return Ext.String.htmlEncode(value); + }, + + + htmlDecode : function(value) { + return Ext.String.htmlDecode(value); + }, + + + urlAppend : function(url, s) { + if (!Ext.isEmpty(s)) { + return url + (url.indexOf('?') === -1 ? '?' : '&') + s; + } + return url; + } +}); + + +Ext.ns = Ext.namespace; + + +window.undefined = window.undefined; + +(function(){ + var check = function(regex){ + return regex.test(Ext.userAgent); + }, + docMode = document.documentMode, + isOpera = check(/opera/), + isOpera10_5 = isOpera && check(/version\/10\.5/), + isChrome = check(/\bchrome\b/), + isWebKit = check(/webkit/), + isSafari = !isChrome && check(/safari/), + isSafari2 = isSafari && check(/applewebkit\/4/), + isSafari3 = isSafari && check(/version\/3/), + isSafari4 = isSafari && check(/version\/4/), + isIE = !isOpera && check(/msie/), + isIE7 = isIE && (check(/msie 7/) || docMode == 7), + isIE8 = isIE && (check(/msie 8/) && docMode != 7 && docMode != 9 || docMode == 8), + isIE9 = isIE && (check(/msie 9/) && docMode != 7 && docMode != 8 || docMode == 9), + isIE6 = isIE && check(/msie 6/), + isGecko = !isWebKit && check(/gecko/), + isGecko3 = isGecko && check(/rv:1\.9/), + isGecko4 = isGecko && check(/rv:2\.0/), + 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; + + + try { + document.execCommand("BackgroundImageCache", false, true); + } catch(e) {} + + Ext.setVersion('extjs', '4.0.0'); + Ext.apply(Ext, { + + SSL_SECURE_URL : Ext.isSecure && isIE ? 'javascript:""' : 'about:blank', + + + + + scopeResetCSS : Ext.buildSettings.scopeResetCSS, + + + enableNestedListenerRemoval : false, + + + USE_NATIVE_JSON : false, + + + getDom : function(el, strict) { + if (!el || !document) { + return null; + } + if (el.dom) { + return el.dom; + } else { + if (typeof el == 'string') { + var e = document.getElementById(el); + + + if (e && isIE && strict) { + if (el == e.getAttribute('id')) { + return e; + } else { + return null; + } + } + return e; + } else { + return el; + } + } + }, + + + removeNode : isIE6 || isIE7 ? function() { + var d; + return function(n){ + if(n && n.tagName != 'BODY'){ + (Ext.enableNestedListenerRemoval) ? Ext.EventManager.purgeElement(n) : Ext.EventManager.removeAll(n); + d = d || document.createElement('div'); + d.appendChild(n); + d.innerHTML = ''; + delete Ext.cache[n.id]; + } + }; + }() : function(n) { + if (n && n.parentNode && n.tagName != 'BODY') { + (Ext.enableNestedListenerRemoval) ? Ext.EventManager.purgeElement(n) : Ext.EventManager.removeAll(n); + n.parentNode.removeChild(n); + delete Ext.cache[n.id]; + } + }, + + + isOpera : isOpera, + + + isOpera10_5 : isOpera10_5, + + + isWebKit : isWebKit, + + + isChrome : isChrome, + + + isSafari : isSafari, + + + isSafari3 : isSafari3, + + + isSafari4 : isSafari4, + + + isSafari2 : isSafari2, + + + isIE : isIE, + + + isIE6 : isIE6, + + + isIE7 : isIE7, + + + isIE8 : isIE8, + + + isIE9 : isIE9, + + + isGecko : isGecko, + + + isGecko3 : isGecko3, + + + isGecko4 : isGecko4, + + + + isFF3_0 : isFF3_0, + + + isFF3_5 : isFF3_5, + + isFF3_6 : isFF3_6, + + + isLinux : isLinux, + + + isWindows : isWindows, + + + isMac : isMac, + + + BLANK_IMAGE_URL : (isIE6 || isIE7) ? 'http:/' + '/www.sencha.com/s.gif' : 'data:image/gif;base64,R0lGODlhAQABAID/AMDAwAAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==', + + + value : function(v, defaultValue, allowBlank){ + return Ext.isEmpty(v, allowBlank) ? defaultValue : v; + }, + + + escapeRe : function(s) { + return s.replace(/([-.*+?^${}()|[\]\/\\])/g, "\\$1"); + }, + + + addBehaviors : function(o){ + if(!Ext.isReady){ + Ext.onReady(function(){ + Ext.addBehaviors(o); + }); + } else { + var cache = {}, + parts, + b, + s; + for (b in o) { + if ((parts = b.split('@'))[1]) { + s = parts[0]; + if(!cache[s]){ + cache[s] = Ext.select(s); + } + cache[s].on(parts[1], o[b]); + } + } + cache = null; + } + }, + + + getScrollBarWidth: function(force){ + if(!Ext.isReady){ + return 0; + } + + if(force === true || scrollWidth === null){ + + + + var cssClass = Ext.isIE9 ? '' : Ext.baseCSSPrefix + 'hide-offsets'; + + var div = Ext.getBody().createChild('
'), + child = div.child('div', true); + var w1 = child.offsetWidth; + div.setStyle('overflow', (Ext.isWebKit || Ext.isGecko) ? 'auto' : 'scroll'); + var w2 = child.offsetWidth; + div.remove(); + + scrollWidth = w1 - w2 + 2; + } + return scrollWidth; + }, + + + copyTo : function(dest, source, names, usePrototypeKeys){ + if(typeof names == 'string'){ + names = names.split(/[,;\s]/); + } + Ext.each(names, function(name){ + if(usePrototypeKeys || source.hasOwnProperty(name)){ + dest[name] = source[name]; + } + }, this); + return dest; + }, + + + destroyMembers : function(o, arg1, arg2, etc){ + for (var i = 1, a = arguments, len = a.length; i < len; i++) { + Ext.destroy(o[a[i]]); + delete o[a[i]]; + } + }, + + + partition : function(arr, truth){ + var ret = [[],[]]; + Ext.each(arr, function(v, i, a) { + ret[ (truth && truth(v, i, a)) || (!truth && v) ? 0 : 1].push(v); + }); + return ret; + }, + + + invoke : function(arr, methodName){ + var ret = [], + args = Array.prototype.slice.call(arguments, 2); + Ext.each(arr, function(v,i) { + if (v && typeof v[methodName] == 'function') { + ret.push(v[methodName].apply(v, args)); + } else { + ret.push(undefined); + } + }); + return ret; + }, + + + zip : function(){ + var parts = Ext.partition(arguments, function( val ){ return typeof val != 'function'; }), + arrs = parts[0], + fn = parts[1][0], + len = Ext.max(Ext.pluck(arrs, "length")), + ret = []; + + for (var i = 0; i < len; i++) { + ret[i] = []; + if(fn){ + ret[i] = fn.apply(fn, Ext.pluck(arrs, i)); + }else{ + for (var j = 0, aLen = arrs.length; j < aLen; j++){ + ret[i].push( arrs[j][i] ); + } + } + } + return ret; + }, + + + toSentence: function(items, connector) { + var length = items.length; + + if (length <= 1) { + return items[0]; + } else { + var head = items.slice(0, length - 1), + tail = items[length - 1]; + + return Ext.util.Format.format("{0} {1} {2}", head.join(", "), connector || 'and', tail); + } + }, + + + useShims: isIE6 + }); +})(); + + +Ext.application = function(config) { + Ext.require('Ext.app.Application'); + + Ext.onReady(function() { + Ext.create('Ext.app.Application', config); + }); +}; + + +(function() { + Ext.ns('Ext.util'); + + Ext.util.Format = {}; + var UtilFormat = Ext.util.Format, + stripTagsRE = /<\/?[^>]+>/gi, + stripScriptsRe = /(?:)((\n|\r|.)*?)(?:<\/script>)/ig, + nl2brRe = /\r?\n/g, + + + formatCleanRe = /[^\d\.]/g, + + + + I18NFormatCleanRe; + + Ext.apply(UtilFormat, { + + thousandSeparator: ',', + + + decimalSeparator: '.', + + + currencyPrecision: 2, + + + currencySign: '$', + + + currencyAtEnd: false, + + + undef : function(value) { + return value !== undefined ? value : ""; + }, + + + defaultValue : function(value, defaultValue) { + return value !== undefined && value !== '' ? value : defaultValue; + }, + + + substr : function(value, start, length) { + return String(value).substr(start, length); + }, + + + lowercase : function(value) { + return String(value).toLowerCase(); + }, + + + uppercase : function(value) { + return String(value).toUpperCase(); + }, + + + usMoney : function(v) { + return UtilFormat.currency(v, '$', 2); + }, + + + currency: function(v, currencySign, decimals, end) { + var negativeSign = '', + format = ",0", + i = 0; + v = v - 0; + if (v < 0) { + v = -v; + negativeSign = '-'; + } + decimals = decimals || UtilFormat.currencyPrecision; + format += format + (decimals > 0 ? '.' : ''); + for (; i < decimals; i++) { + format += '0'; + } + v = UtilFormat.number(v, format); + if ((end || UtilFormat.currencyAtEnd) === true) { + return Ext.String.format("{0}{1}{2}", negativeSign, v, currencySign || UtilFormat.currencySign); + } else { + return Ext.String.format("{0}{1}{2}", negativeSign, currencySign || UtilFormat.currencySign, v); + } + }, + + + date: function(v, format) { + if (!v) { + return ""; + } + if (!Ext.isDate(v)) { + v = new Date(Date.parse(v)); + } + return Ext.Date.dateFormat(v, format || Ext.Date.defaultFormat); + }, + + + dateRenderer : function(format) { + return function(v) { + return UtilFormat.date(v, format); + }; + }, + + + stripTags : function(v) { + return !v ? v : String(v).replace(stripTagsRE, ""); + }, + + + stripScripts : function(v) { + return !v ? v : String(v).replace(stripScriptsRe, ""); + }, + + + fileSize : function(size) { + if (size < 1024) { + return size + " bytes"; + } else if (size < 1048576) { + return (Math.round(((size*10) / 1024))/10) + " KB"; + } else { + return (Math.round(((size*10) / 1048576))/10) + " MB"; + } + }, + + + math : function(){ + var fns = {}; + + return function(v, a){ + if (!fns[a]) { + fns[a] = Ext.functionFactory('v', 'return v ' + a + ';'); + } + return fns[a](v); + }; + }(), + + + round : function(value, precision) { + var result = Number(value); + if (typeof precision == 'number') { + precision = Math.pow(10, precision); + result = Math.round(value * precision) / precision; + } + return result; + }, + + + number: + function(v, formatString) { + if (!formatString) { + return v; + } + v = Ext.Number.from(v, NaN); + if (isNaN(v)) { + return ''; + } + var comma = UtilFormat.thousandSeparator, + dec = UtilFormat.decimalSeparator, + i18n = false, + neg = v < 0, + hasComma, + psplit; + + v = Math.abs(v); + + + + + + if (formatString.substr(formatString.length - 2) == '/i') { + if (!I18NFormatCleanRe) { + I18NFormatCleanRe = new RegExp('[^\\d\\' + UtilFormat.decimalSeparator + ']','g'); + } + formatString = formatString.substr(0, formatString.length - 2); + i18n = true; + hasComma = formatString.indexOf(comma) != -1; + psplit = formatString.replace(I18NFormatCleanRe, '').split(dec); + } else { + hasComma = formatString.indexOf(',') != -1; + psplit = formatString.replace(formatCleanRe, '').split('.'); + } + + 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); + } + + var fnum = v.toString(); + + psplit = fnum.split('.'); + + if (hasComma) { + var cnum = psplit[0], + parr = [], + j = cnum.length, + m = Math.floor(j / 3), + n = cnum.length % 3 || 3, + i; + + for (i = 0; i < j; i += n) { + if (i !== 0) { + n = 3; + } + + parr[parr.length] = cnum.substr(i, n); + m -= 1; + } + fnum = parr.join(comma); + if (psplit[1]) { + fnum += dec + psplit[1]; + } + } else { + if (psplit[1]) { + fnum = psplit[0] + dec + psplit[1]; + } + } + + return (neg ? '-' : '') + formatString.replace(/[\d,?\.?]+/, fnum); + }, + + + numberRenderer : function(format) { + return function(v) { + return UtilFormat.number(v, format); + }; + }, + + + plural : function(v, s, p) { + return v +' ' + (v == 1 ? s : (p ? p : s+'s')); + }, + + + nl2br : function(v) { + return Ext.isEmpty(v) ? '' : v.replace(nl2brRe, '
'); + }, + + + capitalize: Ext.String.capitalize, + + + ellipsis: Ext.String.ellipsis, + + + format: Ext.String.format, + + + htmlDecode: Ext.String.htmlDecode, + + + htmlEncode: Ext.String.htmlEncode, + + + leftPad: Ext.String.leftPad, + + + trim : Ext.String.trim, + + + parseBox : function(box) { + if (Ext.isNumber(box)) { + box = box.toString(); + } + var parts = box.split(' '), + ln = parts.length; + + if (ln == 1) { + parts[1] = parts[2] = parts[3] = parts[0]; + } + else if (ln == 2) { + parts[2] = parts[0]; + parts[3] = parts[1]; + } + else if (ln == 3) { + parts[3] = parts[1]; + } + + return { + top :parseInt(parts[0], 10) || 0, + right :parseInt(parts[1], 10) || 0, + bottom:parseInt(parts[2], 10) || 0, + left :parseInt(parts[3], 10) || 0 + }; + }, + + + escapeRegex : function(s) { + return s.replace(/([\-.*+?\^${}()|\[\]\/\\])/g, "\\$1"); + } + }); +})(); + + +Ext.ns('Ext.util'); + +Ext.util.TaskRunner = function(interval) { + interval = interval || 10; + var tasks = [], + removeQueue = [], + id = 0, + running = false, + + + stopThread = function() { + running = false; + clearInterval(id); + id = 0; + }, + + + startThread = function() { + if (!running) { + running = true; + id = setInterval(runTasks, interval); + } + }, + + + removeTask = function(t) { + removeQueue.push(t); + if (t.onStop) { + t.onStop.apply(t.scope || t); + } + }, + + + runTasks = function() { + var rqLen = removeQueue.length, + now = new Date().getTime(), + i; + + if (rqLen > 0) { + for (i = 0; i < rqLen; i++) { + Ext.Array.remove(tasks, removeQueue[i]); + } + removeQueue = []; + if (tasks.length < 1) { + stopThread(); + return; + } + } + i = 0; + var t, + itime, + rt, + len = tasks.length; + for (; i < len; ++i) { + t = tasks[i]; + itime = now - t.taskRunTime; + if (t.interval <= itime) { + rt = t.run.apply(t.scope || t, t.args || [++t.taskRunCount]); + t.taskRunTime = now; + if (rt === false || t.taskRunCount === t.repeat) { + removeTask(t); + return; + } + } + if (t.duration && t.duration <= (now - t.taskStartTime)) { + removeTask(t); + } + } + }; + + + this.start = function(task) { + tasks.push(task); + task.taskStartTime = new Date().getTime(); + task.taskRunTime = 0; + task.taskRunCount = 0; + startThread(); + return task; + }; + + + this.stop = function(task) { + removeTask(task); + return task; + }; + + + this.stopAll = function() { + stopThread(); + for (var i = 0, len = tasks.length; i < len; i++) { + if (tasks[i].onStop) { + tasks[i].onStop(); + } + } + tasks = []; + removeQueue = []; + }; +}; + + +Ext.TaskManager = Ext.create('Ext.util.TaskRunner'); + +Ext.is = { + init : function(navigator) { + var platforms = this.platforms, + ln = platforms.length, + i, platform; + + navigator = navigator || window.navigator; + + for (i = 0; i < ln; i++) { + platform = platforms[i]; + this[platform.identity] = platform.regex.test(navigator[platform.property]); + } + + + this.Desktop = this.Mac || this.Windows || (this.Linux && !this.Android); + + this.Tablet = this.iPad; + + this.Phone = !this.Desktop && !this.Tablet; + + this.iOS = this.iPhone || this.iPad || this.iPod; + + + this.Standalone = !!window.navigator.standalone; + }, + + + platforms: [{ + property: 'platform', + regex: /iPhone/i, + identity: 'iPhone' + }, + + + { + property: 'platform', + regex: /iPod/i, + identity: 'iPod' + }, + + + { + property: 'userAgent', + regex: /iPad/i, + identity: 'iPad' + }, + + + { + property: 'userAgent', + regex: /Blackberry/i, + identity: 'Blackberry' + }, + + + { + property: 'userAgent', + regex: /Android/i, + identity: 'Android' + }, + + + { + property: 'platform', + regex: /Mac/i, + identity: 'Mac' + }, + + + { + property: 'platform', + regex: /Win/i, + identity: 'Windows' + }, + + + { + property: 'platform', + regex: /Linux/i, + identity: 'Linux' + }] +}; + +Ext.is.init(); + + +Ext.supports = { + init : function() { + var doc = document, + div = doc.createElement('div'), + tests = this.tests, + ln = tests.length, + i, test; + + div.innerHTML = [ + '
', + '
', + '
', + '
', + '
', + '
', + '
' + ].join(''); + + doc.body.appendChild(div); + + for (i = 0; i < ln; i++) { + test = tests[i]; + this[test.identity] = test.fn.call(this, doc, div); + } + + doc.body.removeChild(div); + }, + + + CSS3BoxShadow: Ext.isDefined(document.documentElement.style.boxShadow), + + + ClassList: !!document.documentElement.classList, + + + OrientationChange: ((typeof window.orientation != 'undefined') && ('onorientationchange' in window)), + + + DeviceMotion: ('ondevicemotion' in window), + + + + + Touch: ('ontouchstart' in window) && (!Ext.is.Desktop), + + tests: [ + + { + identity: 'Transitions', + fn: function(doc, div) { + var prefix = [ + 'webkit', + 'Moz', + 'o', + 'ms', + 'khtml' + ], + TE = 'TransitionEnd', + transitionEndName = [ + prefix[0] + TE, + 'transitionend', + prefix[2] + TE, + prefix[3] + TE, + prefix[4] + TE + ], + ln = prefix.length, + i = 0, + out = false; + div = Ext.get(div); + for (; i < ln; i++) { + if (div.getStyle(prefix[i] + "TransitionProperty")) { + Ext.supports.CSS3Prefix = prefix[i]; + Ext.supports.CSS3TransitionEnd = transitionEndName[i]; + out = true; + break; + } + } + return out; + } + }, + + + { + identity: 'RightMargin', + fn: function(doc, div, view) { + view = doc.defaultView; + return !(view && view.getComputedStyle(div.firstChild.firstChild, null).marginRight != '0px'); + } + }, + + + { + identity: 'TransparentColor', + fn: function(doc, div, view) { + view = doc.defaultView; + return !(view && view.getComputedStyle(div.lastChild, null).backgroundColor != 'transparent'); + } + }, + + + { + identity: 'ComputedStyle', + fn: function(doc, div, view) { + view = doc.defaultView; + return view && view.getComputedStyle; + } + }, + + + { + identity: 'Svg', + fn: function(doc) { + return !!doc.createElementNS && !!doc.createElementNS( "http:/" + "/www.w3.org/2000/svg", "svg").createSVGRect; + } + }, + + + { + identity: 'Canvas', + fn: function(doc) { + return !!doc.createElement('canvas').getContext; + } + }, + + + { + identity: 'Vml', + fn: function(doc) { + var d = doc.createElement("div"); + d.innerHTML = ""; + return (d.childNodes.length == 2); + } + }, + + + { + identity: 'Float', + fn: function(doc, div) { + return !!div.lastChild.style.cssFloat; + } + }, + + + { + identity: 'AudioTag', + fn: function(doc) { + return !!doc.createElement('audio').canPlayType; + } + }, + + + { + identity: 'History', + fn: function() { + return !!(window.history && history.pushState); + } + }, + + + { + identity: 'CSS3DTransform', + fn: function() { + return (typeof WebKitCSSMatrix != 'undefined' && new WebKitCSSMatrix().hasOwnProperty('m41')); + } + }, + + + { + identity: 'CSS3LinearGradient', + fn: function(doc, div) { + var property = 'background-image:', + webkit = '-webkit-gradient(linear, left top, right bottom, from(black), to(white))', + w3c = 'linear-gradient(left top, black, white)', + moz = '-moz-' + w3c, + options = [property + webkit, property + w3c, property + moz]; + + div.style.cssText = options.join(';'); + + return ("" + div.style.backgroundImage).indexOf('gradient') !== -1; + } + }, + + + { + identity: 'CSS3BorderRadius', + fn: function(doc, div) { + var domPrefixes = ['borderRadius', 'BorderRadius', 'MozBorderRadius', 'WebkitBorderRadius', 'OBorderRadius', 'KhtmlBorderRadius'], + pass = false, + i; + for (i = 0; i < domPrefixes.length; i++) { + if (document.body.style[domPrefixes[i]] !== undefined) { + return true; + } + } + return pass; + } + }, + + + { + identity: 'GeoLocation', + fn: function() { + return (typeof navigator != 'undefined' && typeof navigator.geolocation != 'undefined') || (typeof google != 'undefined' && typeof google.gears != 'undefined'); + } + }, + + { + identity: 'MouseEnterLeave', + fn: function(doc, div){ + return ('onmouseenter' in div && 'onmouseleave' in div); + } + }, + + { + identity: 'MouseWheel', + fn: function(doc, div) { + return ('onmousewheel' in div); + } + }, + + { + identity: 'Opacity', + fn: function(doc, div){ + + if (Ext.isIE6 || Ext.isIE7 || Ext.isIE8) { + return false; + } + div.firstChild.style.cssText = 'opacity:0.73'; + return div.firstChild.style.opacity == '0.73'; + } + }, + + { + identity: 'Placeholder', + fn: function(doc) { + return 'placeholder' in doc.createElement('input'); + } + }, + + + { + identity: 'Direct2DBug', + fn: function() { + return Ext.isString(document.body.style.msTransformOrigin); + } + }, + + { + identity: 'BoundingClientRect', + fn: function(doc, div) { + return Ext.isFunction(div.getBoundingClientRect); + } + }, + { + identity: 'IncludePaddingInWidthCalculation', + fn: function(doc, div){ + var el = Ext.get(div.childNodes[1].firstChild); + return el.getWidth() == 210; + } + }, + { + identity: 'IncludePaddingInHeightCalculation', + fn: function(doc, div){ + var el = Ext.get(div.childNodes[1].firstChild); + return el.getHeight() == 210; + } + }, + + + { + identity: 'ArraySort', + fn: function() { + var a = [1,2,3,4,5].sort(function(){ return 0; }); + return a[0] === 1 && a[1] === 2 && a[2] === 3 && a[3] === 4 && a[4] === 5; + } + }, + + { + identity: 'Range', + fn: function() { + return !!document.createRange; + } + }, + + { + identity: 'CreateContextualFragment', + fn: function() { + var range = Ext.supports.Range ? document.createRange() : false; + + return range && !!range.createContextualFragment; + } + } + + ] +}; + + + + + +Ext.ns('Ext.core'); +Ext.core.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, + confRe = /tag|children|cn|html$/i, + tableElRe = /td|tr|tbody/i, + endRe = /end/i, + pub, + + afterbegin = 'afterbegin', + afterend = 'afterend', + beforebegin = 'beforebegin', + beforeend = 'beforeend', + ts = '', + te = '
', + tbs = ts+'', + tbe = ''+te, + trs = tbs + '', + tre = ''+tbe; + + + function doInsert(el, o, returnElement, pos, sibling, append){ + el = Ext.getDom(el); + var newNode; + if (pub.useDom) { + newNode = createDom(o, null); + if (append) { + el.appendChild(newNode); + } else { + (sibling == 'firstChild' ? el : el.parentNode).insertBefore(newNode, el[sibling] || el); + } + } else { + newNode = Ext.core.DomHelper.insertHtml(pos, el, Ext.core.DomHelper.createHtml(o)); + } + return returnElement ? Ext.get(newNode, true) : newNode; + } + + function createDom(o, parentNode){ + var el, + doc = document, + useSet, + attr, + val, + cn; + + if (Ext.isArray(o)) { + el = doc.createDocumentFragment(); + for (var i = 0, l = o.length; i < l; i++) { + createDom(o[i], el); + } + } else if (typeof o == 'string') { + el = doc.createTextNode(o); + } else { + el = doc.createElement( o.tag || 'div' ); + useSet = !!el.setAttribute; + for (attr in o) { + if(!confRe.test(attr)){ + val = o[attr]; + if(attr == 'cls'){ + el.className = val; + }else{ + if(useSet){ + el.setAttribute(attr, val); + }else{ + el[attr] = val; + } + } + } + } + Ext.core.DomHelper.applyStyles(el, o.style); + + if ((cn = o.children || o.cn)) { + createDom(cn, el); + } else if (o.html) { + el.innerHTML = o.html; + } + } + if(parentNode){ + parentNode.appendChild(el); + } + return el; + } + + + function createHtml(o){ + var b = '', + attr, + val, + key, + cn, + i; + + if(typeof o == "string"){ + b = o; + } else if (Ext.isArray(o)) { + for (i=0; i < o.length; i++) { + if(o[i]) { + b += createHtml(o[i]); + } + } + } else { + b += '<' + (o.tag = o.tag || 'div'); + for (attr in o) { + val = o[attr]; + if(!confRe.test(attr)){ + if (typeof val == "object") { + b += ' ' + attr + '="'; + for (key in val) { + b += key + ':' + val[key] + ';'; + } + b += '"'; + }else{ + b += ' ' + ({cls : 'class', htmlFor : 'for'}[attr] || attr) + '="' + val + '"'; + } + } + } + + if (emptyTags.test(o.tag)) { + b += '/>'; + } else { + b += '>'; + if ((cn = o.children || o.cn)) { + b += createHtml(cn); + } else if(o.html){ + b += o.html; + } + b += ''; + } + } + return b; + } + + function ieTable(depth, s, h, e){ + tempTableEl.innerHTML = [s, h, e].join(''); + var i = -1, + el = tempTableEl, + ns; + while(++i < depth){ + el = el.firstChild; + } + + ns = el.nextSibling; + if (ns){ + var df = document.createDocumentFragment(); + while(el){ + ns = el.nextSibling; + df.appendChild(el); + el = ns; + } + el = df; + } + return el; + } + + + function insertIntoTable(tag, where, el, html) { + var node, + before; + + tempTableEl = tempTableEl || document.createElement('div'); + + if(tag == 'td' && (where == afterbegin || where == beforeend) || + !tableElRe.test(tag) && (where == beforebegin || where == afterend)) { + return null; + } + before = where == beforebegin ? el : + where == afterend ? el.nextSibling : + where == afterbegin ? el.firstChild : null; + + if (where == beforebegin || where == afterend) { + el = el.parentNode; + } + + if (tag == 'td' || (tag == 'tr' && (where == beforeend || where == afterbegin))) { + node = ieTable(4, trs, html, tre); + } else if ((tag == 'tbody' && (where == beforeend || where == afterbegin)) || + (tag == 'tr' && (where == beforebegin || where == afterend))) { + node = ieTable(3, tbs, html, tbe); + } else { + node = ieTable(2, ts, html, te); + } + 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; + + for (; i < length; i++) { + fragment.appendChild(childNodes[i].cloneNode(true)); + } + + return fragment; + } + + pub = { + + markup : function(o){ + return createHtml(o); + }, + + + applyStyles : function(el, styles){ + if (styles) { + el = Ext.fly(el); + if (typeof styles == "function") { + styles = styles.call(); + } + if (typeof styles == "string") { + styles = Ext.core.Element.parseStyles(styles); + } + if (typeof styles == "object") { + el.setStyle(styles); + } + } + }, + + + insertHtml : function(where, el, html){ + var hash = {}, + hashVal, + range, + rangeEl, + setStart, + frag, + rs; + + where = where.toLowerCase(); + + 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']; + if ((hashVal = hash[where])) { + el.insertAdjacentHTML(hashVal[0], html); + return el[hashVal[1]]; + } + + } else { + + if (Ext.isTextNode(el)) { + where = where === 'afterbegin' ? 'beforebegin' : where; + where = where === 'beforeend' ? 'afterend' : where; + } + range = Ext.supports.CreateContextualFragment ? el.ownerDocument.createRange() : undefined; + setStart = 'setStart' + (endRe.test(where) ? 'After' : 'Before'); + if (hash[where]) { + if (range) { + range[setStart](el); + frag = range.createContextualFragment(html); + } else { + frag = createContextualFragment(html); + } + el.parentNode.insertBefore(frag, where == beforebegin ? el : el.nextSibling); + return el[(where == beforebegin ? 'previous' : 'next') + 'Sibling']; + } else { + rangeEl = (where == afterbegin ? 'first' : 'last') + 'Child'; + if (el.firstChild) { + if (range) { + range[setStart](el[rangeEl]); + frag = range.createContextualFragment(html); + } else { + frag = createContextualFragment(html); + } + + if(where == afterbegin){ + el.insertBefore(frag, el.firstChild); + }else{ + el.appendChild(frag); + } + } else { + el.innerHTML = html; + } + return el[rangeEl]; + } + } + Ext.Error.raise({ + sourceClass: 'Ext.core.DomHelper', + sourceMethod: 'insertHtml', + htmlToInsert: html, + targetElement: el, + msg: 'Illegal insertion point reached: "' + where + '"' + }); + }, + + + insertBefore : function(el, o, returnElement){ + return doInsert(el, o, returnElement, beforebegin); + }, + + + insertAfter : function(el, o, returnElement){ + return doInsert(el, o, returnElement, afterend, 'nextSibling'); + }, + + + insertFirst : function(el, o, returnElement){ + return doInsert(el, o, returnElement, afterbegin, 'firstChild'); + }, + + + append : function(el, o, returnElement){ + return doInsert(el, o, returnElement, beforeend, '', true); + }, + + + overwrite : function(el, o, returnElement){ + el = Ext.getDom(el); + el.innerHTML = createHtml(o); + return returnElement ? Ext.get(el.firstChild) : el.firstChild; + }, + + createHtml : createHtml, + + + createDom: createDom, + + + useDom : false, + + + createTemplate : function(o){ + var html = Ext.core.DomHelper.createHtml(o); + return Ext.create('Ext.Template', html); + } + }; + return pub; +}(); + + + +Ext.ns('Ext.core'); + +Ext.core.DomQuery = Ext.DomQuery = function(){ + var cache = {}, + simpleCache = {}, + valueCache = {}, + nonSpace = /\S/, + trimRe = /^\s+|\s+$/g, + tplRe = /\{(\d+)\}/g, + modeRe = /^(\s?[\/>+~]\s?|\s|$)/, + tagTokenRe = /^(#)?([\w-\*]+)/, + nthRe = /(\d*)n\+?(\d*)/, + nthRe2 = /\D/, + + + + isIE = window.ActiveXObject ? true : false, + key = 30803; + + + + eval("var batch = 30803;"); + + + + function child(parent, index){ + var i = 0, + n = parent.firstChild; + while(n){ + if(n.nodeType == 1){ + if(++i == index){ + return n; + } + } + n = n.nextSibling; + } + return null; + } + + + function next(n){ + while((n = n.nextSibling) && n.nodeType != 1); + return n; + } + + + function prev(n){ + while((n = n.previousSibling) && n.nodeType != 1); + return n; + } + + + + function children(parent){ + var n = parent.firstChild, + nodeIndex = -1, + nextNode; + while(n){ + nextNode = n.nextSibling; + + if(n.nodeType == 3 && !nonSpace.test(n.nodeValue)){ + parent.removeChild(n); + }else{ + + n.nodeIndex = ++nodeIndex; + } + n = nextNode; + } + return this; + } + + + + + function byClassName(nodeSet, cls){ + if(!cls){ + return nodeSet; + } + var result = [], ri = -1; + for(var i = 0, ci; ci = nodeSet[i]; i++){ + if((' '+ci.className+' ').indexOf(cls) != -1){ + result[++ri] = ci; + } + } + return result; + }; + + function attrValue(n, attr){ + + if(!n.tagName && typeof n.length != "undefined"){ + n = n[0]; + } + if(!n){ + return null; + } + + if(attr == "for"){ + return n.htmlFor; + } + if(attr == "class" || attr == "className"){ + return n.className; + } + return n.getAttribute(attr) || n[attr]; + + }; + + + + + + function getNodes(ns, mode, tagName){ + var result = [], ri = -1, cs; + if(!ns){ + return result; + } + tagName = tagName || "*"; + + if(typeof ns.getElementsByTagName != "undefined"){ + ns = [ns]; + } + + + + if(!mode){ + for(var i = 0, ni; ni = ns[i]; i++){ + cs = ni.getElementsByTagName(tagName); + for(var j = 0, ci; ci = cs[j]; j++){ + result[++ri] = ci; + } + } + + + } else if(mode == "/" || mode == ">"){ + var utag = tagName.toUpperCase(); + for(var i = 0, ni, cn; ni = ns[i]; i++){ + cn = ni.childNodes; + for(var j = 0, cj; cj = cn[j]; j++){ + if(cj.nodeName == utag || cj.nodeName == tagName || tagName == '*'){ + result[++ri] = cj; + } + } + } + + + }else if(mode == "+"){ + var utag = tagName.toUpperCase(); + for(var i = 0, n; n = ns[i]; i++){ + while((n = n.nextSibling) && n.nodeType != 1); + if(n && (n.nodeName == utag || n.nodeName == tagName || tagName == '*')){ + result[++ri] = n; + } + } + + + }else if(mode == "~"){ + var utag = tagName.toUpperCase(); + for(var i = 0, n; n = ns[i]; i++){ + while((n = n.nextSibling)){ + if (n.nodeName == utag || n.nodeName == tagName || tagName == '*'){ + result[++ri] = n; + } + } + } + } + return result; + } + + function concat(a, b){ + if(b.slice){ + return a.concat(b); + } + for(var i = 0, l = b.length; i < l; i++){ + a[a.length] = b[i]; + } + return a; + } + + function byTag(cs, tagName){ + if(cs.tagName || cs == document){ + cs = [cs]; + } + if(!tagName){ + return cs; + } + var result = [], ri = -1; + tagName = tagName.toLowerCase(); + for(var i = 0, ci; ci = cs[i]; i++){ + if(ci.nodeType == 1 && ci.tagName.toLowerCase() == tagName){ + result[++ri] = ci; + } + } + return result; + } + + function byId(cs, id){ + if(cs.tagName || cs == document){ + cs = [cs]; + } + if(!id){ + return cs; + } + var result = [], ri = -1; + for(var i = 0, ci; ci = cs[i]; i++){ + if(ci && ci.id == id){ + result[++ri] = ci; + return result; + } + } + return result; + } + + + + function byAttribute(cs, attr, value, op, custom){ + var result = [], + ri = -1, + useGetStyle = custom == "{", + fn = Ext.DomQuery.operators[op], + a, + xml, + hasXml; + + for(var i = 0, ci; ci = cs[i]; i++){ + + if(ci.nodeType != 1){ + continue; + } + + if(!hasXml){ + xml = Ext.DomQuery.isXml(ci); + hasXml = true; + } + + + if(!xml){ + if(useGetStyle){ + a = Ext.DomQuery.getStyle(ci, attr); + } else if (attr == "class" || attr == "className"){ + a = ci.className; + } else if (attr == "for"){ + a = ci.htmlFor; + } else if (attr == "href"){ + + + a = ci.getAttribute("href", 2); + } else{ + a = ci.getAttribute(attr); + } + }else{ + a = ci.getAttribute(attr); + } + if((fn && fn(a, value)) || (!fn && a)){ + result[++ri] = ci; + } + } + return result; + } + + function byPseudo(cs, name, value){ + return Ext.DomQuery.pseudos[name](cs, value); + } + + function nodupIEXml(cs){ + var d = ++key, + r; + cs[0].setAttribute("_nodup", d); + r = [cs[0]]; + for(var i = 1, len = cs.length; i < len; i++){ + var c = cs[i]; + if(!c.getAttribute("_nodup") != d){ + c.setAttribute("_nodup", d); + r[r.length] = c; + } + } + for(var i = 0, len = cs.length; i < len; i++){ + cs[i].removeAttribute("_nodup"); + } + return r; + } + + function nodup(cs){ + if(!cs){ + return []; + } + var len = cs.length, c, i, r = cs, cj, ri = -1; + if(!len || typeof cs.nodeType != "undefined" || len == 1){ + return cs; + } + if(isIE && typeof cs[0].selectSingleNode != "undefined"){ + return nodupIEXml(cs); + } + var d = ++key; + cs[0]._nodup = d; + for(i = 1; c = cs[i]; i++){ + if(c._nodup != d){ + c._nodup = d; + }else{ + r = []; + for(var j = 0; j < i; j++){ + r[++ri] = cs[j]; + } + for(j = i+1; cj = cs[j]; j++){ + if(cj._nodup != d){ + cj._nodup = d; + r[++ri] = cj; + } + } + return r; + } + } + return r; + } + + function quickDiffIEXml(c1, c2){ + var d = ++key, + r = []; + for(var i = 0, len = c1.length; i < len; i++){ + c1[i].setAttribute("_qdiff", d); + } + for(var i = 0, len = c2.length; i < len; i++){ + if(c2[i].getAttribute("_qdiff") != d){ + r[r.length] = c2[i]; + } + } + for(var i = 0, len = c1.length; i < len; i++){ + c1[i].removeAttribute("_qdiff"); + } + return r; + } + + function quickDiff(c1, c2){ + var len1 = c1.length, + d = ++key, + r = []; + if(!len1){ + return c2; + } + if(isIE && typeof c1[0].selectSingleNode != "undefined"){ + return quickDiffIEXml(c1, c2); + } + for(var i = 0; i < len1; i++){ + c1[i]._qdiff = d; + } + for(var i = 0, len = c2.length; i < len; i++){ + if(c2[i]._qdiff != d){ + r[r.length] = c2[i]; + } + } + return r; + } + + function quickId(ns, mode, root, id){ + if(ns == root){ + var d = root.ownerDocument || root; + return d.getElementById(id); + } + ns = getNodes(ns, mode, "*"); + return byId(ns, id); + } + + return { + getStyle : function(el, name){ + return Ext.fly(el).getStyle(name); + }, + + compile : function(path, type){ + type = type || "select"; + + + var fn = ["var f = function(root){\n var mode; ++batch; var n = root || document;\n"], + mode, + lastPath, + matchers = Ext.DomQuery.matchers, + matchersLn = matchers.length, + modeMatch, + + lmode = path.match(modeRe); + + if(lmode && lmode[1]){ + fn[fn.length] = 'mode="'+lmode[1].replace(trimRe, "")+'";'; + path = path.replace(lmode[1], ""); + } + + + while(path.substr(0, 1)=="/"){ + path = path.substr(1); + } + + while(path && lastPath != path){ + lastPath = path; + var tokenMatch = path.match(tagTokenRe); + if(type == "select"){ + if(tokenMatch){ + + if(tokenMatch[1] == "#"){ + fn[fn.length] = 'n = quickId(n, mode, root, "'+tokenMatch[2]+'");'; + }else{ + fn[fn.length] = 'n = getNodes(n, mode, "'+tokenMatch[2]+'");'; + } + path = path.replace(tokenMatch[0], ""); + }else if(path.substr(0, 1) != '@'){ + fn[fn.length] = 'n = getNodes(n, mode, "*");'; + } + + }else{ + if(tokenMatch){ + if(tokenMatch[1] == "#"){ + fn[fn.length] = 'n = byId(n, "'+tokenMatch[2]+'");'; + }else{ + fn[fn.length] = 'n = byTag(n, "'+tokenMatch[2]+'");'; + } + path = path.replace(tokenMatch[0], ""); + } + } + while(!(modeMatch = path.match(modeRe))){ + var matched = false; + for(var j = 0; j < matchersLn; j++){ + var t = matchers[j]; + var m = path.match(t.re); + if(m){ + fn[fn.length] = t.select.replace(tplRe, function(x, i){ + return m[i]; + }); + path = path.replace(m[0], ""); + matched = true; + break; + } + } + + if(!matched){ + Ext.Error.raise({ + sourceClass: 'Ext.DomQuery', + sourceMethod: 'compile', + msg: 'Error parsing selector. Parsing failed at "' + path + '"' + }); + } + } + if(modeMatch[1]){ + fn[fn.length] = 'mode="'+modeMatch[1].replace(trimRe, "")+'";'; + path = path.replace(modeMatch[1], ""); + } + } + + fn[fn.length] = "return nodup(n);\n}"; + + + eval(fn.join("")); + return f; + }, + + + jsSelect: function(path, root, type){ + + root = root || document; + + if(typeof root == "string"){ + root = document.getElementById(root); + } + var paths = path.split(","), + results = []; + + + for(var i = 0, len = paths.length; i < len; i++){ + var subPath = paths[i].replace(trimRe, ""); + + 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); + if(result && result != document){ + results = results.concat(result); + } + } + + + + if(paths.length > 1){ + return nodup(results); + } + return results; + }, + + isXml: function(el) { + 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) {} + } + return Ext.DomQuery.jsSelect.call(this, path, root, type); + } : function(path, root, type) { + return Ext.DomQuery.jsSelect.call(this, path, root, type); + }, + + + selectNode : function(path, root){ + return Ext.DomQuery.select(path, root)[0]; + }, + + + selectValue : function(path, root, defaultValue){ + path = path.replace(trimRe, ""); + if(!valueCache[path]){ + valueCache[path] = Ext.DomQuery.compile(path, "select"); + } + var n = valueCache[path](root), v; + n = n[0] ? n[0] : n; + + + + + + if (typeof n.normalize == 'function') n.normalize(); + + v = (n && n.firstChild ? n.firstChild.nodeValue : null); + return ((v === null||v === undefined||v==='') ? defaultValue : v); + }, + + + selectNumber : function(path, root, defaultValue){ + var v = Ext.DomQuery.selectValue(path, root, defaultValue || 0); + return parseFloat(v); + }, + + + is : function(el, ss){ + if(typeof el == "string"){ + el = document.getElementById(el); + } + var isArray = Ext.isArray(el), + result = Ext.DomQuery.filter(isArray ? el : [el], ss); + return isArray ? (result.length == el.length) : (result.length > 0); + }, + + + filter : function(els, ss, nonMatches){ + ss = ss.replace(trimRe, ""); + if(!simpleCache[ss]){ + simpleCache[ss] = Ext.DomQuery.compile(ss, "simple"); + } + var result = simpleCache[ss](els); + return nonMatches ? quickDiff(result, els) : result; + }, + + + matchers : [{ + re: /^\.([\w-]+)/, + select: 'n = byClassName(n, " {1} ");' + }, { + re: /^\:([\w-]+)(?:\(((?:[^\s>\/]*|.*?))\))?/, + select: 'n = byPseudo(n, "{1}", "{2}");' + },{ + re: /^(?:([\[\{])(?:@)?([\w-]+)\s?(?:(=|.=)\s?['"]?(.*?)["']?)?[\]\}])/, + select: 'n = byAttribute(n, "{2}", "{4}", "{3}", "{1}");' + }, { + re: /^#([\w-]+)/, + select: 'n = byId(n, "{1}");' + },{ + re: /^@([\w-]+)/, + select: 'return {firstChild:{nodeValue:attrValue(n, "{1}")}};' + } + ], + + + operators : { + "=" : function(a, v){ + return a == v; + }, + "!=" : function(a, v){ + return a != v; + }, + "^=" : function(a, v){ + return a && a.substr(0, v.length) == v; + }, + "$=" : function(a, v){ + return a && a.substr(a.length-v.length) == v; + }, + "*=" : function(a, v){ + return a && a.indexOf(v) !== -1; + }, + "%=" : function(a, v){ + return (a % v) == 0; + }, + "|=" : function(a, v){ + return a && (a == v || a.substr(0, v.length+1) == v+'-'); + }, + "~=" : function(a, v){ + return a && (' '+a+' ').indexOf(' '+v+' ') != -1; + } + }, + + + pseudos : { + "first-child" : function(c){ + var r = [], ri = -1, n; + for(var i = 0, ci; ci = n = c[i]; i++){ + while((n = n.previousSibling) && n.nodeType != 1); + if(!n){ + r[++ri] = ci; + } + } + return r; + }, + + "last-child" : function(c){ + var r = [], ri = -1, n; + for(var i = 0, ci; ci = n = c[i]; i++){ + while((n = n.nextSibling) && n.nodeType != 1); + if(!n){ + r[++ri] = ci; + } + } + return r; + }, + + "nth-child" : function(c, a) { + var r = [], ri = -1, + m = nthRe.exec(a == "even" && "2n" || a == "odd" && "2n+1" || !nthRe2.test(a) && "n+" + a || a), + f = (m[1] || 1) - 0, l = m[2] - 0; + for(var i = 0, n; n = c[i]; i++){ + var pn = n.parentNode; + if (batch != pn._batch) { + var j = 0; + for(var cn = pn.firstChild; cn; cn = cn.nextSibling){ + if(cn.nodeType == 1){ + cn.nodeIndex = ++j; + } + } + pn._batch = batch; + } + if (f == 1) { + if (l == 0 || n.nodeIndex == l){ + r[++ri] = n; + } + } else if ((n.nodeIndex + l) % f == 0){ + r[++ri] = n; + } + } + + return r; + }, + + "only-child" : function(c){ + var r = [], ri = -1;; + for(var i = 0, ci; ci = c[i]; i++){ + if(!prev(ci) && !next(ci)){ + r[++ri] = ci; + } + } + return r; + }, + + "empty" : function(c){ + var r = [], ri = -1; + for(var i = 0, ci; ci = c[i]; i++){ + var cns = ci.childNodes, j = 0, cn, empty = true; + while(cn = cns[j]){ + ++j; + if(cn.nodeType == 1 || cn.nodeType == 3){ + empty = false; + break; + } + } + if(empty){ + r[++ri] = ci; + } + } + return r; + }, + + "contains" : function(c, v){ + var r = [], ri = -1; + for(var i = 0, ci; ci = c[i]; i++){ + if((ci.textContent||ci.innerText||'').indexOf(v) != -1){ + r[++ri] = ci; + } + } + return r; + }, + + "nodeValue" : function(c, v){ + var r = [], ri = -1; + for(var i = 0, ci; ci = c[i]; i++){ + if(ci.firstChild && ci.firstChild.nodeValue == v){ + r[++ri] = ci; + } + } + return r; + }, + + "checked" : function(c){ + var r = [], ri = -1; + for(var i = 0, ci; ci = c[i]; i++){ + if(ci.checked == true){ + r[++ri] = ci; + } + } + return r; + }, + + "not" : function(c, ss){ + return Ext.DomQuery.filter(c, ss, true); + }, + + "any" : function(c, selectors){ + var ss = selectors.split('|'), + r = [], ri = -1, s; + for(var i = 0, ci; ci = c[i]; i++){ + for(var j = 0; s = ss[j]; j++){ + if(Ext.DomQuery.is(ci, s)){ + r[++ri] = ci; + break; + } + } + } + return r; + }, + + "odd" : function(c){ + return this["nth-child"](c, "odd"); + }, + + "even" : function(c){ + return this["nth-child"](c, "even"); + }, + + "nth" : function(c, a){ + return c[a-1] || []; + }, + + "first" : function(c){ + return c[0] || []; + }, + + "last" : function(c){ + return c[c.length-1] || []; + }, + + "has" : function(c, ss){ + var s = Ext.DomQuery.select, + r = [], ri = -1; + for(var i = 0, ci; ci = c[i]; i++){ + if(s(ss, ci).length > 0){ + r[++ri] = ci; + } + } + return r; + }, + + "next" : function(c, ss){ + var is = Ext.DomQuery.is, + r = [], ri = -1; + for(var i = 0, ci; ci = c[i]; i++){ + var n = next(ci); + if(n && is(n, ss)){ + r[++ri] = ci; + } + } + return r; + }, + + "prev" : function(c, ss){ + var is = Ext.DomQuery.is, + r = [], ri = -1; + for(var i = 0, ci; ci = c[i]; i++){ + var n = prev(ci); + if(n && is(n, ss)){ + r[++ri] = ci; + } + } + return r; + } + } + }; +}(); + + +Ext.query = Ext.DomQuery.select; + + + (function() { + var DOC = document, + EC = Ext.cache; + + Ext.Element = Ext.core.Element = function(element, forceNew) { + var dom = typeof element == "string" ? DOC.getElementById(element) : element, + id; + + if (!dom) { + return null; + } + + id = dom.id; + + if (!forceNew && id && EC[id]) { + + return EC[id].el; + } + + + this.dom = dom; + + + this.id = id || Ext.id(dom); + }; + + var DH = Ext.core.DomHelper, + El = Ext.core.Element; + + + El.prototype = { + + set: function(o, useSet) { + var el = this.dom, + attr, + val; + useSet = (useSet !== false) && !!el.setAttribute; + + for (attr in o) { + if (o.hasOwnProperty(attr)) { + val = o[attr]; + if (attr == 'style') { + DH.applyStyles(el, val); + } else if (attr == 'cls') { + el.className = val; + } else if (useSet) { + el.setAttribute(attr, val); + } else { + el[attr] = val; + } + } + } + return this; + }, + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + defaultUnit: "px", + + + is: function(simpleSelector) { + return Ext.DomQuery.is(this.dom, simpleSelector); + }, + + + focus: function(defer, + + dom) { + var me = this; + dom = dom || me.dom; + try { + if (Number(defer)) { + Ext.defer(me.focus, defer, null, [null, dom]); + } else { + dom.focus(); + } + } catch(e) {} + return me; + }, + + + blur: function() { + try { + this.dom.blur(); + } catch(e) {} + return this; + }, + + + getValue: function(asNumber) { + var val = this.dom.value; + return asNumber ? parseInt(val, 10) : val; + }, + + + addListener: function(eventName, fn, scope, options) { + Ext.EventManager.on(this.dom, eventName, fn, scope || this, options); + return this; + }, + + + removeListener: function(eventName, fn, scope) { + Ext.EventManager.un(this.dom, eventName, fn, scope || this); + return this; + }, + + + removeAllListeners: function() { + Ext.EventManager.removeAll(this.dom); + return this; + }, + + + purgeAllListeners: function() { + Ext.EventManager.purgeElement(this); + return this; + }, + + + addUnits: function(size, units) { + + + if (Ext.isNumber(size)) { + return size + (units || this.defaultUnit || 'px'); + } + + + if (size === "" || size == "auto" || size === undefined || 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; + }, + + + isBorderBox: function() { + return Ext.isBorderBox || noBoxAdjust[(this.dom.tagName || "").toLowerCase()]; + }, + + + remove: function() { + var me = this, + dom = me.dom; + + if (dom) { + delete me.dom; + Ext.removeNode(dom); + } + }, + + + hover: function(overFn, outFn, scope, options) { + var me = this; + me.on('mouseenter', overFn, scope || me.dom, options); + me.on('mouseleave', outFn, scope || me.dom, options); + return me; + }, + + + contains: function(el) { + return ! el ? false: Ext.core.Element.isAncestor(this.dom, el.dom ? el.dom: el); + }, + + + getAttributeNS: function(ns, name) { + return this.getAttribute(name, ns); + }, + + + getAttribute: (Ext.isIE && !(Ext.isIE9 && document.documentMode === 9)) ? + function(name, ns) { + var d = this.dom, + type; + if(ns) { + type = typeof d[ns + ":" + name]; + if (type != 'undefined' && type != 'unknown') { + return d[ns + ":" + name] || null; + } + return null; + } + if (name === "for") { + name = "htmlFor"; + } + return d[name] || null; + }: function(name, ns) { + var d = this.dom; + if (ns) { + return d.getAttributeNS(ns, name) || d.getAttribute(ns + ":" + name); + } + return d.getAttribute(name) || d[name] || null; + }, + + + update: function(html) { + if (this.dom) { + this.dom.innerHTML = html; + } + return this; + } + }; + + var ep = El.prototype; + + El.addMethods = function(o) { + Ext.apply(ep, o); + }; + + + ep.on = ep.addListener; + + + ep.un = ep.removeListener; + + + ep.clearListeners = ep.removeAllListeners; + + + ep.destroy = ep.remove; + + + ep.autoBoxAdjust = true; + + + var unitPattern = /\d+(px|em|%|en|ex|pt|in|cm|mm|pc)$/i, + docEl; + + + El.get = function(el) { + var ex, + elm, + id; + if (!el) { + return null; + } + if (typeof el == "string") { + + if (! (elm = DOC.getElementById(el))) { + return null; + } + if (EC[el] && EC[el].el) { + ex = EC[el].el; + ex.dom = elm; + } else { + ex = El.addToCache(new El(elm)); + } + return ex; + } else if (el.tagName) { + + if (! (id = el.id)) { + id = Ext.id(el); + } + if (EC[id] && EC[id].el) { + ex = EC[id].el; + ex.dom = el; + } else { + ex = El.addToCache(new El(el)); + } + return ex; + } else if (el instanceof El) { + if (el != docEl) { + + + + if (Ext.isIE && (el.id == undefined || el.id == '')) { + el.dom = el.dom; + } else { + el.dom = DOC.getElementById(el.id) || el.dom; + } + } + return el; + } else if (el.isComposite) { + return el; + } else if (Ext.isArray(el)) { + return El.select(el); + } else if (el == DOC) { + + if (!docEl) { + var f = function() {}; + f.prototype = El.prototype; + docEl = new f(); + docEl.dom = DOC; + } + return docEl; + } + return null; + }; + + El.addToCache = function(el, id) { + if (el) { + id = id || el.id; + EC[id] = { + el: el, + data: {}, + events: {} + }; + } + return el; + }; + + + El.data = function(el, key, value) { + el = El.get(el); + if (!el) { + return null; + } + var c = EC[el.id].data; + if (arguments.length == 2) { + return c[key]; + } else { + return (c[key] = value); + } + }; + + + + + function garbageCollect() { + if (!Ext.enableGarbageCollector) { + clearInterval(El.collectorThreadId); + } else { + var eid, + el, + d, + o; + + for (eid in EC) { + if (!EC.hasOwnProperty(eid)) { + continue; + } + o = EC[eid]; + if (o.skipGarbageCollection) { + continue; + } + el = o.el; + d = el.dom; + + + + + + + + + + + + + + + + + + if (!d || !d.parentNode || (!d.offsetParent && !DOC.getElementById(eid))) { + if (d && Ext.enableListenerCollection) { + Ext.EventManager.removeAll(d); + } + delete EC[eid]; + } + } + + if (Ext.isIE) { + var t = {}; + for (eid in EC) { + if (!EC.hasOwnProperty(eid)) { + continue; + } + t[eid] = EC[eid]; + } + EC = Ext.cache = t; + } + } + } + El.collectorThreadId = setInterval(garbageCollect, 30000); + + var flyFn = function() {}; + flyFn.prototype = El.prototype; + + + El.Flyweight = function(dom) { + this.dom = dom; + }; + + El.Flyweight.prototype = new flyFn(); + El.Flyweight.prototype.isFlyweight = true; + El._flyweights = {}; + + + El.fly = function(el, named) { + var ret = null; + named = named || '_global'; + el = Ext.getDom(el); + if (el) { + (El._flyweights[named] = El._flyweights[named] || new El.Flyweight()).dom = el; + ret = El._flyweights[named]; + } + return ret; + }; + + + Ext.get = El.get; + + + Ext.fly = El.fly; + + + var noBoxAdjust = Ext.isStrict ? { + select: 1 + }: { + input: 1, + select: 1, + textarea: 1 + }; + if (Ext.isIE || Ext.isGecko) { + noBoxAdjust['button'] = 1; + } +})(); + + +Ext.core.Element.addMethods({ + + findParent : function(simpleSelector, maxDepth, returnEl) { + var p = this.dom, + b = document.body, + depth = 0, + stopEl; + + maxDepth = maxDepth || 50; + if (isNaN(maxDepth)) { + stopEl = Ext.getDom(maxDepth); + maxDepth = Number.MAX_VALUE; + } + while (p && p.nodeType == 1 && depth < maxDepth && p != b && p != stopEl) { + if (Ext.DomQuery.is(p, simpleSelector)) { + return returnEl ? Ext.get(p) : p; + } + depth++; + p = p.parentNode; + } + return null; + }, + + + findParentNode : function(simpleSelector, maxDepth, returnEl) { + var p = Ext.fly(this.dom.parentNode, '_internal'); + return p ? p.findParent(simpleSelector, maxDepth, returnEl) : null; + }, + + + up : function(simpleSelector, maxDepth) { + return this.findParentNode(simpleSelector, maxDepth, true); + }, + + + select : function(selector) { + return Ext.core.Element.select(selector, false, this.dom); + }, + + + query : function(selector) { + return Ext.DomQuery.select(selector, this.dom); + }, + + + down : function(selector, returnDom) { + var n = Ext.DomQuery.selectNode(selector, this.dom); + return returnDom ? n : Ext.get(n); + }, + + + child : function(selector, returnDom) { + var node, + me = this, + id; + id = Ext.get(me).id; + + id = id.replace(/[\.:]/g, "\\$0"); + node = Ext.DomQuery.selectNode('#' + id + " > " + selector, me.dom); + return returnDom ? node : Ext.get(node); + }, + + + parent : function(selector, returnDom) { + return this.matchNode('parentNode', 'parentNode', selector, returnDom); + }, + + + next : function(selector, returnDom) { + return this.matchNode('nextSibling', 'nextSibling', selector, returnDom); + }, + + + prev : function(selector, returnDom) { + return this.matchNode('previousSibling', 'previousSibling', selector, returnDom); + }, + + + + first : function(selector, returnDom) { + return this.matchNode('nextSibling', 'firstChild', selector, returnDom); + }, + + + last : function(selector, returnDom) { + return this.matchNode('previousSibling', 'lastChild', selector, returnDom); + }, + + matchNode : function(dir, start, selector, returnDom) { + if (!this.dom) { + return null; + } + + var n = this.dom[start]; + while (n) { + if (n.nodeType == 1 && (!selector || Ext.DomQuery.is(n, selector))) { + return !returnDom ? Ext.get(n) : n; + } + n = n[dir]; + } + return null; + } +}); + + +Ext.core.Element.addMethods({ + + appendChild : function(el) { + return Ext.get(el).appendTo(this); + }, + + + appendTo : function(el) { + Ext.getDom(el).appendChild(this.dom); + return this; + }, + + + insertBefore : function(el) { + el = Ext.getDom(el); + el.parentNode.insertBefore(this.dom, el); + return this; + }, + + + insertAfter : function(el) { + el = Ext.getDom(el); + el.parentNode.insertBefore(this.dom, el.nextSibling); + return this; + }, + + + insertFirst : function(el, returnDom) { + el = el || {}; + if (el.nodeType || el.dom || typeof el == 'string') { + el = Ext.getDom(el); + this.dom.insertBefore(el, this.dom.firstChild); + return !returnDom ? Ext.get(el) : el; + } + else { + return this.createChild(el, this.dom.firstChild, returnDom); + } + }, + + + insertSibling: function(el, where, returnDom){ + var me = this, rt, + isAfter = (where || 'before').toLowerCase() == 'after', + insertEl; + + if(Ext.isArray(el)){ + insertEl = me; + Ext.each(el, function(e) { + rt = Ext.fly(insertEl, '_internal').insertSibling(e, where, returnDom); + if(isAfter){ + insertEl = rt; + } + }); + return rt; + } + + el = el || {}; + + if(el.nodeType || el.dom){ + rt = me.dom.parentNode.insertBefore(Ext.getDom(el), isAfter ? me.dom.nextSibling : me.dom); + if (!returnDom) { + rt = Ext.get(rt); + } + }else{ + if (isAfter && !me.dom.nextSibling) { + rt = Ext.core.DomHelper.append(me.dom.parentNode, el, !returnDom); + } else { + rt = Ext.core.DomHelper[isAfter ? 'insertAfter' : 'insertBefore'](me.dom, el, !returnDom); + } + } + return rt; + }, + + + replace : function(el) { + el = Ext.get(el); + this.insertBefore(el); + el.remove(); + return this; + }, + + + replaceWith: function(el){ + var me = this; + + if(el.nodeType || el.dom || typeof el == 'string'){ + el = Ext.get(el); + me.dom.parentNode.insertBefore(el, me.dom); + }else{ + el = Ext.core.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); + return me; + }, + + + createChild : function(config, insertBefore, returnDom) { + config = config || {tag:'div'}; + if (insertBefore) { + return Ext.core.DomHelper.insertBefore(insertBefore, config, returnDom !== true); + } + else { + return Ext.core.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), + d = newEl.dom || newEl; + + d.appendChild(this.dom); + return newEl; + }, + + + insertHtml : function(where, html, returnEl) { + var el = Ext.core.DomHelper.insertHtml(where, this.dom, html); + return returnEl ? Ext.get(el) : el; + } +}); + + +(function(){ + Ext.core.Element.boxMarkup = '
'; + + var supports = Ext.supports, + view = document.defaultView, + opacityRe = /alpha\(opacity=(.*)\)/i, + trimRe = /^\s+|\s+$/g, + spacesRe = /\s+/, + wordsRe = /\w/g, + adjustDirect2DTableRe = /table-row|table-.*-group/, + INTERNAL = '_internal', + PADDING = 'padding', + MARGIN = 'margin', + BORDER = 'border', + LEFT = '-left', + RIGHT = '-right', + TOP = '-top', + BOTTOM = '-bottom', + WIDTH = '-width', + MATH = Math, + HIDDEN = 'hidden', + ISCLIPPED = 'isClipped', + OVERFLOW = 'overflow', + OVERFLOWX = 'overflow-x', + OVERFLOWY = 'overflow-y', + ORIGINALCLIP = 'originalClip', + + 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; + + 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")); + } + return (isNum && width < 0) ? 0 : width; + }, + + + adjustHeight : function(height) { + var me = this, + isNum = (typeof height == "number"); + + if(isNum && me.autoBoxAdjust && !me.isBorderBox()){ + height -= (me.getBorderWidth("tb") + me.getPadding("tb")); + } + return (isNum && height < 0) ? 0 : height; + }, + + + + addCls : function(className){ + var me = this, + cls = [], + space = ((me.dom.className.replace(trimRe, '') == '') ? "" : " "), + i, len, v; + if (!Ext.isDefined(className)) { + return me; + } + + if (!Ext.isArray(className)) { + if (typeof className === 'string') { + className = className.replace(trimRe, '').split(spacesRe); + if (className.length === 1) { + className = className[0]; + if (!me.hasCls(className)) { + me.dom.className += space + className; + } + } else { + this.addCls(className); + } + } + } else { + for (i = 0, len = className.length; i < len; i++) { + v = className[i]; + if (typeof v == 'string' && (' ' + me.dom.className + ' ').indexOf(' ' + v + ' ') == -1) { + cls.push(v); + } + } + if (cls.length) { + me.dom.className += space + cls.join(" "); + } + } + return me; + }, + + + removeCls : function(className){ + var me = this, + i, idx, len, cls, elClasses; + if (!Ext.isDefined(className)) { + return me; + } + if (!Ext.isArray(className)){ + className = className.replace(trimRe, '').split(spacesRe); + } + if (me.dom && me.dom.className) { + elClasses = me.dom.className.replace(trimRe, '').split(spacesRe); + for (i = 0, len = className.length; i < len; i++) { + cls = className[i]; + if (typeof cls == 'string') { + cls = cls.replace(trimRe, ''); + idx = Ext.Array.indexOf(elClasses, cls); + if (idx != -1) { + elClasses.splice(idx, 1); + } + } + } + me.dom.className = elClasses.join(" "); + } + return me; + }, + + + radioCls : function(className){ + var cn = this.dom.parentNode.childNodes, + v, i, len; + className = Ext.isArray(className) ? className : [className]; + for (i = 0, len = cn.length; i < len; i++) { + v = cn[i]; + if (v && v.nodeType == 1) { + Ext.fly(v, '_internal').removeCls(className); + } + } + return this.addCls(className); + }, + + + toggleCls : Ext.supports.ClassList ? + function(className) { + this.dom.classList.toggle(Ext.String.trim(className)); + return this; + } : + function(className) { + return this.hasCls(className) ? this.removeCls(className) : this.addCls(className); + }, + + + hasCls : Ext.supports.ClassList ? + function(className) { + if (!className) { + return false; + } + className = className.split(spacesRe); + var ln = className.length, + i = 0; + for (; i < ln; i++) { + if (className[i] && this.dom.classList.contains(className[i])) { + return true; + } + } + return false; + } : + function(className){ + return className && (' ' + this.dom.className + ' ').indexOf(' ' + className + ' ') != -1; + }, + + + replaceCls : function(oldClassName, newClassName){ + return this.removeCls(oldClassName).addCls(newClassName); + }, + + isStyle : function(style, val) { + return this.getStyle(style) == val; + }, + + + getStyle : function(){ + return view && view.getComputedStyle ? + function(prop){ + var el = this.dom, + v, cs, out, display; + + if(el == document){ + return null; + } + prop = Ext.core.Element.normalize(prop); + out = (v = el.style[prop]) ? v : + (cs = view.getComputedStyle(el, "")) ? cs[prop] : null; + + + + if(prop == 'marginRight' && out != '0px' && !supports.RightMargin){ + display = this.getStyle('display'); + el.style.display = 'inline-block'; + out = view.getComputedStyle(el, '').marginRight; + el.style.display = display; + } + + if(prop == 'backgroundColor' && out == 'rgba(0, 0, 0, 0)' && !supports.TransparentColor){ + out = 'transparent'; + } + return out; + } : + 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; + } + } + } + return 1; + } + prop = Ext.core.Element.normalize(prop); + return el.style[prop] || ((cs = el.currentStyle) ? cs[prop] : null); + }; + }(), + + + getColor : function(attr, defaultValue, prefix){ + var v = this.getStyle(attr), + color = prefix || prefix === '' ? prefix : '#', + h; + + if(!v || (/transparent|inherit/.test(v))) { + return defaultValue; + } + if(/^r/.test(v)){ + Ext.each(v.slice(4, v.length -1).split(','), function(s){ + h = parseInt(s, 10); + color += (h < 16 ? '0' : '') + h.toString(16); + }); + }else{ + v = v.replace('#', ''); + color += v.length == 3 ? v.replace(/^(\w)(\w)(\w)$/, '$1$1$2$2$3$3') : v; + } + return(color.length > 5 ? color.toLowerCase() : defaultValue); + }, + + + setStyle : function(prop, value){ + var me = this, + tmp, style; + + if (!me.dom) { + return me; + } + + if (!Ext.isObject(prop)) { + tmp = {}; + tmp[prop] = value; + prop = tmp; + } + for (style in prop) { + if (prop.hasOwnProperty(style)) { + value = Ext.value(prop[style], ''); + if (style == 'opacity') { + me.setOpacity(value); + } + else { + me.dom.style[Ext.core.Element.normalize(style)] = value; + } + } + } + return me; + }, + + + setOpacity: function(opacity, animate) { + var me = this, + dom = me.dom, + val, + style; + + if (!me.dom) { + return me; + } + + style = me.dom.style; + + if (!animate || !me.anim) { + if (!Ext.supports.Opacity) { + opacity = opacity < 1 ? 'alpha(opacity=' + opacity * 100 + ')': ''; + val = style.filter.replace(opacityRe, '').replace(trimRe, ''); + + style.zoom = 1; + style.filter = val + (val.length > 0 ? ' ': '') + opacity; + } + else { + style.opacity = opacity; + } + } + else { + if (!Ext.isObject(animate)) { + animate = { + duration: 350, + easing: 'ease-in' + }; + } + me.animate(Ext.applyIf({ + to: { + opacity: opacity + } + }, + animate)); + } + return me; + }, + + + + clearOpacity : function(){ + var style = this.dom.style; + if(!Ext.supports.Opacity){ + if(!Ext.isEmpty(style.filter)){ + style.filter = style.filter.replace(opacityRe, '').replace(trimRe, ''); + } + }else{ + style.opacity = style['-moz-opacity'] = style['-khtml-opacity'] = ''; + } + return this; + }, + + + adjustDirect2DDimension: function(dimension) { + var me = this, + dom = me.dom, + display = me.getStyle('display'), + inlineDisplay = dom.style['display'], + inlinePosition = dom.style['position'], + originIndex = dimension === 'width' ? 0 : 1, + floating; + + if (display === 'inline') { + dom.style['display'] = 'inline-block'; + } + + dom.style['position'] = display.match(adjustDirect2DTableRe) ? 'absolute' : 'static'; + + + + 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, + dom = me.dom, + hidden = Ext.isIE && me.isStyle('display', 'none'), + height, overflow, style, floating; + + + + if (Ext.isIEQuirks) { + style = dom.style; + overflow = style.overflow; + me.setStyle({ overflow: 'hidden'}); + } + + height = dom.offsetHeight; + + height = MATH.max(height, hidden ? 0 : dom.clientHeight) || 0; + + + if (!hidden && Ext.supports.Direct2DBug) { + floating = me.adjustDirect2DDimension('height'); + if (preciseHeight) { + height += floating; + } + else if (floating > 0 && floating < 0.5) { + height++; + } + } + + if (contentHeight) { + height -= (me.getBorderWidth("tb") + me.getPadding("tb")); + } + + if (Ext.isIEQuirks) { + me.setStyle({ overflow: overflow}); + } + + if (height < 0) { + height = 0; + } + return height; + }, + + + getWidth: function(contentWidth, preciseWidth) { + var me = this, + dom = me.dom, + hidden = Ext.isIE && me.isStyle('display', 'none'), + rect, width, overflow, style, floating, parentPosition; + + + + if (Ext.isIEQuirks) { + style = dom.style; + overflow = style.overflow; + me.setStyle({overflow: 'hidden'}); + } + + + if (Ext.isOpera10_5) { + if (dom.parentNode.currentStyle.position === 'relative') { + parentPosition = dom.parentNode.style.position; + dom.parentNode.style.position = 'static'; + width = dom.offsetWidth; + dom.parentNode.style.position = parentPosition; + } + width = Math.max(width || 0, dom.offsetWidth); + + + + + + + } else if (Ext.supports.BoundingClientRect) { + rect = dom.getBoundingClientRect(); + width = rect.right - rect.left; + width = preciseWidth ? width : Math.ceil(width); + } else { + width = dom.offsetWidth; + } + + width = MATH.max(width, hidden ? 0 : dom.clientWidth) || 0; + + + if (!hidden && Ext.supports.Direct2DBug) { + floating = me.adjustDirect2DDimension('width'); + if (preciseWidth) { + width += floating; + } + else if (floating > 0 && floating < 0.5) { + width++; + } + } + + if (contentWidth) { + width -= (me.getBorderWidth("lr") + me.getPadding("lr")); + } + + if (Ext.isIEQuirks) { + me.setStyle({ overflow: overflow}); + } + + if (width < 0) { + width = 0; + } + return width; + }, + + + setWidth : function(width, animate){ + var me = this; + width = me.adjustWidth(width); + if (!animate || !me.anim) { + me.dom.style.width = me.addUnits(width); + } + else { + if (!Ext.isObject(animate)) { + animate = {}; + } + me.animate(Ext.applyIf({ + to: { + width: width + } + }, animate)); + } + return me; + }, + + + setHeight : function(height, animate){ + var me = this; + height = me.adjustHeight(height); + if (!animate || !me.anim) { + me.dom.style.height = me.addUnits(height); + } + else { + if (!Ext.isObject(animate)) { + animate = {}; + } + me.animate(Ext.applyIf({ + to: { + height: height + } + }, animate)); + } + return me; + }, + + + getBorderWidth : function(side){ + return this.addStyles(side, borders); + }, + + + getPadding : function(side){ + return this.addStyles(side, paddings); + }, + + + clip : function(){ + var me = this, + dom = me.dom; + + if(!data(dom, ISCLIPPED)){ + data(dom, ISCLIPPED, true); + data(dom, ORIGINALCLIP, { + o: me.getStyle(OVERFLOW), + x: me.getStyle(OVERFLOWX), + y: me.getStyle(OVERFLOWY) + }); + me.setStyle(OVERFLOW, HIDDEN); + me.setStyle(OVERFLOWX, HIDDEN); + me.setStyle(OVERFLOWY, HIDDEN); + } + return me; + }, + + + unclip : function(){ + var me = this, + dom = me.dom, + clip; + + if(data(dom, ISCLIPPED)){ + data(dom, ISCLIPPED, false); + clip = data(dom, ORIGINALCLIP); + if(o.o){ + me.setStyle(OVERFLOW, o.o); + } + if(o.x){ + me.setStyle(OVERFLOWX, o.x); + } + if(o.y){ + me.setStyle(OVERFLOWY, o.y); + } + } + return me; + }, + + + addStyles : function(sides, styles){ + var totalSize = 0, + sidesArr = sides.match(wordsRe), + i = 0, + len = sidesArr.length, + side, size; + for (; i < len; i++) { + side = sidesArr[i]; + size = side && parseInt(this.getStyle(styles[side]), 10); + if (size) { + totalSize += MATH.abs(size); + } + } + return totalSize; + }, + + margins : margins, + + + applyStyles : function(style){ + Ext.core.DomHelper.applyStyles(this.dom, style); + return this; + }, + + + getStyles : function(){ + var styles = {}, + len = arguments.length, + i = 0, style; + + for(; i < len; ++i) { + style = arguments[i]; + styles[style] = this.getStyle(style); + } + return styles; + }, + + + boxWrap : function(cls){ + cls = cls || Ext.baseCSSPrefix + 'box'; + var el = Ext.get(this.insertHtml("beforeBegin", "
" + Ext.String.format(Ext.core.Element.boxMarkup, cls) + "
")); + Ext.DomQuery.selectNode('.' + cls + '-mc', el.dom).appendChild(this.dom); + return el; + }, + + + setSize : function(width, height, animate){ + var me = this; + if (Ext.isObject(width)){ + height = width.height; + width = width.width; + } + width = me.adjustWidth(width); + height = me.adjustHeight(height); + if(!animate || !me.anim){ + me.dom.style.width = me.addUnits(width); + me.dom.style.height = me.addUnits(height); + } + else { + if (!Ext.isObject(animate)) { + animate = {}; + } + me.animate(Ext.applyIf({ + to: { + width: width, + height: height + } + }, animate)); + } + return me; + }, + + + getComputedHeight : function(){ + var me = this, + h = Math.max(me.dom.offsetHeight, me.dom.clientHeight); + if(!h){ + h = parseFloat(me.getStyle('height')) || 0; + if(!me.isBorderBox()){ + h += me.getFrameWidth('tb'); + } + } + return h; + }, + + + 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()){ + w += me.getFrameWidth('lr'); + } + } + return w; + }, + + + getFrameWidth : function(sides, onlyContentBox){ + return onlyContentBox && this.isBorderBox() ? 0 : (this.getPadding(sides) + this.getBorderWidth(sides)); + }, + + + addClsOnOver : function(className){ + var dom = this.dom; + this.hover( + function(){ + Ext.fly(dom, INTERNAL).addCls(className); + }, + function(){ + Ext.fly(dom, INTERNAL).removeCls(className); + } + ); + return this; + }, + + + addClsOnFocus : function(className){ + var me = this, + dom = me.dom; + me.on("focus", function(){ + Ext.fly(dom, INTERNAL).addCls(className); + }); + me.on("blur", function(){ + Ext.fly(dom, INTERNAL).removeCls(className); + }); + return me; + }, + + + addClsOnClick : function(className){ + var dom = this.dom; + this.on("mousedown", function(){ + Ext.fly(dom, INTERNAL).addCls(className); + var d = Ext.getDoc(), + fn = function(){ + Ext.fly(dom, INTERNAL).removeCls(className); + d.removeListener("mouseup", fn); + }; + d.on("mouseup", fn); + }); + return this; + }, + + + + getViewSize : function(){ + var me = this, + dom = me.dom, + isDoc = (dom == Ext.getDoc().dom || dom == Ext.getBody().dom), + style, overflow, ret; + + + if (isDoc) { + ret = { + width : Ext.core.Element.getViewWidth(), + height : Ext.core.Element.getViewHeight() + }; + + + } + else { + + + if (Ext.isIE6 || Ext.isIEQuirks) { + style = dom.style; + overflow = style.overflow; + me.setStyle({ overflow: 'hidden'}); + } + ret = { + width : dom.clientWidth, + height : dom.clientHeight + }; + if (Ext.isIE6 || Ext.isIEQuirks) { + me.setStyle({ overflow: overflow }); + } + } + return ret; + }, + + + + getStyleSize : function(){ + var me = this, + doc = document, + d = this.dom, + isDoc = (d == doc || d == doc.body), + s = d.style, + w, h; + + + if (isDoc) { + return { + width : Ext.core.Element.getViewWidth(), + height : Ext.core.Element.getViewHeight() + }; + } + + if(s.width && s.width != 'auto'){ + w = parseFloat(s.width); + if(me.isBorderBox()){ + w -= me.getFrameWidth('lr'); + } + } + + if(s.height && s.height != 'auto'){ + h = parseFloat(s.height); + if(me.isBorderBox()){ + h -= me.getFrameWidth('tb'); + } + } + + return {width: w || me.getWidth(true), height: h || me.getHeight(true)}; + }, + + + getSize : function(contentSize){ + return {width: this.getWidth(contentSize), height: this.getHeight(contentSize)}; + }, + + + repaint : function(){ + var dom = this.dom; + this.addCls(Ext.baseCSSPrefix + 'repaint'); + setTimeout(function(){ + Ext.fly(dom).removeCls(Ext.baseCSSPrefix + 'repaint'); + }, 1); + return this; + }, + + + unselectable : function(){ + var me = this; + me.dom.unselectable = "on"; + + me.swallowEvent("selectstart", true); + me.applyStyles("-moz-user-select:none;-khtml-user-select:none;"); + me.addCls(Ext.baseCSSPrefix + 'unselectable'); + + return me; + }, + + + getMargin : function(side){ + var me = this, + hash = {t:"top", l:"left", r:"right", b: "bottom"}, + o = {}, + key; + + if (!side) { + for (key in me.margins){ + o[hash[key]] = parseFloat(me.getStyle(me.margins[key])) || 0; + } + return o; + } else { + return me.addStyles.call(me, side, me.margins); + } + } + }); +})(); + + +Ext.core.Element.VISIBILITY = 1; + +Ext.core.Element.DISPLAY = 2; + + +Ext.core.Element.OFFSETS = 3; + + +Ext.core.Element.ASCLASS = 4; + + +Ext.core.Element.visibilityCls = Ext.baseCSSPrefix + 'hide-nosize'; + +Ext.core.Element.addMethods(function(){ + var El = Ext.core.Element, + OPACITY = "opacity", + VISIBILITY = "visibility", + DISPLAY = "display", + HIDDEN = "hidden", + OFFSETS = "offsets", + ASCLASS = "asclass", + NONE = "none", + NOSIZE = 'nosize', + ORIGINALDISPLAY = 'originalDisplay', + VISMODE = 'visibilityMode', + ISVISIBLE = 'isVisible', + data = El.data, + getDisplay = function(dom){ + var d = data(dom, ORIGINALDISPLAY); + if(d === undefined){ + data(dom, ORIGINALDISPLAY, d = ''); + } + return d; + }, + getVisMode = function(dom){ + var m = data(dom, VISMODE); + if(m === undefined){ + data(dom, VISMODE, m = 1); + } + return m; + }; + + return { + + originalDisplay : "", + visibilityMode : 1, + + + setVisibilityMode : function(visMode){ + data(this.dom, VISMODE, visMode); + return this; + }, + + + isVisible : function() { + var me = this, + dom = me.dom, + visible = data(dom, ISVISIBLE); + + if(typeof visible == 'boolean'){ + return visible; + } + + visible = !me.isStyle(VISIBILITY, HIDDEN) && + !me.isStyle(DISPLAY, NONE) && + !((getVisMode(dom) == El.ASCLASS) && me.hasCls(me.visibilityCls || El.visibilityCls)); + + data(dom, ISVISIBLE, visible); + return visible; + }, + + + setVisible : function(visible, animate){ + var me = this, isDisplay, isVisibility, isOffsets, isNosize, + dom = me.dom, + visMode = getVisMode(dom); + + + + if (typeof animate == 'string'){ + switch (animate) { + case DISPLAY: + visMode = El.DISPLAY; + break; + case VISIBILITY: + visMode = El.VISIBILITY; + break; + case OFFSETS: + visMode = El.OFFSETS; + break; + case NOSIZE: + case ASCLASS: + visMode = El.ASCLASS; + break; + } + me.setVisibilityMode(visMode); + animate = false; + } + + if (!animate || !me.anim) { + if(visMode == El.ASCLASS ){ + + me[visible?'removeCls':'addCls'](me.visibilityCls || El.visibilityCls); + + } else if (visMode == El.DISPLAY){ + + return me.setDisplayed(visible); + + } else if (visMode == El.OFFSETS){ + + if (!visible){ + + if (!me.hideModeStyles) { + me.hideModeStyles = { + position: me.getStyle('position'), + top: me.getStyle('top'), + left: me.getStyle('left') + }; + } + me.applyStyles({position: 'absolute', top: '-10000px', left: '-10000px'}); + } + + + + else if (me.hideModeStyles) { + me.applyStyles(me.hideModeStyles || {position: '', top: '', left: ''}); + delete me.hideModeStyles; + } + + }else{ + me.fixDisplay(); + + dom.style.visibility = visible ? '' : HIDDEN; + } + }else{ + + if(visible){ + me.setOpacity(0.01); + me.setVisible(true); + } + if (!Ext.isObject(animate)) { + animate = { + duration: 350, + easing: 'ease-in' + }; + } + me.animate(Ext.applyIf({ + callback: function() { + visible || me.setVisible(false).setOpacity(1); + }, + to: { + opacity: (visible) ? 1 : 0 + } + }, animate)); + } + data(dom, ISVISIBLE, visible); + return me; + }, + + + + hasMetrics : function(){ + var dom = this.dom; + return this.isVisible() || (getVisMode(dom) == El.OFFSETS) || (getVisMode(dom) == El.VISIBILITY); + }, + + + toggle : function(animate){ + var me = this; + me.setVisible(!me.isVisible(), me.anim(animate)); + return me; + }, + + + setDisplayed : function(value) { + if(typeof value == "boolean"){ + value = value ? getDisplay(this.dom) : NONE; + } + this.setStyle(DISPLAY, value); + return this; + }, + + + fixDisplay : function(){ + var me = this; + if (me.isStyle(DISPLAY, NONE)) { + me.setStyle(VISIBILITY, HIDDEN); + me.setStyle(DISPLAY, getDisplay(this.dom)); + if (me.isStyle(DISPLAY, NONE)) { + me.setStyle(DISPLAY, "block"); + } + } + }, + + + hide : function(animate){ + + if (typeof animate == 'string'){ + this.setVisible(false, animate); + return this; + } + this.setVisible(false, this.anim(animate)); + return this; + }, + + + show : function(animate){ + + if (typeof animate == 'string'){ + this.setVisible(true, animate); + return this; + } + this.setVisible(true, this.anim(animate)); + return this; + } + }; +}()); + +Ext.applyIf(Ext.core.Element.prototype, { + + animate: function(config) { + var me = this; + if (!me.id) { + me = Ext.get(me.dom); + } + if (Ext.fx.Manager.hasFxBlock(me.id)) { + return me; + } + Ext.fx.Manager.queueFx(Ext.create('Ext.fx.Anim', me.anim(config))); + return this; + }, + + + anim: function(config) { + if (!Ext.isObject(config)) { + return (config) ? {} : false; + } + + var me = this, + duration = config.duration || Ext.fx.Anim.prototype.duration, + easing = config.easing || 'ease', + animConfig; + + if (config.stopAnimation) { + me.stopAnimation(); + } + + Ext.applyIf(config, Ext.fx.Manager.getFxDefaults(me.id)); + + + Ext.fx.Manager.setFxDefaults(me.id, { + delay: 0 + }); + + animConfig = { + target: me, + remove: config.remove, + alternate: config.alternate || false, + duration: duration, + easing: easing, + callback: config.callback, + listeners: config.listeners, + iterations: config.iterations || 1, + scope: config.scope, + block: config.block, + concurrent: config.concurrent, + delay: config.delay || 0, + paused: true, + keyframes: config.keyframes, + from: config.from || {}, + to: Ext.apply({}, config) + }; + Ext.apply(animConfig.to, config.to); + + + delete animConfig.to.to; + delete animConfig.to.from; + delete animConfig.to.remove; + delete animConfig.to.alternate; + delete animConfig.to.keyframes; + delete animConfig.to.iterations; + delete animConfig.to.listeners; + delete animConfig.to.target; + delete animConfig.to.paused; + delete animConfig.to.callback; + delete animConfig.to.scope; + delete animConfig.to.duration; + delete animConfig.to.easing; + delete animConfig.to.concurrent; + delete animConfig.to.block; + delete animConfig.to.stopAnimation; + delete animConfig.to.delay; + return animConfig; + }, + + + slideIn: function(anchor, obj, slideOut) { + var me = this, + elStyle = me.dom.style, + beforeAnim, wrapAnim; + + anchor = anchor || "t"; + obj = obj || {}; + + beforeAnim = function() { + var animScope = this, + listeners = obj.listeners, + box, position, restoreSize, wrap, anim; + + if (!slideOut) { + me.fixDisplay(); + } + + box = me.getBox(); + if ((anchor == 't' || anchor == 'b') && box.height == 0) { + box.height = me.dom.scrollHeight; + } + else if ((anchor == 'l' || anchor == 'r') && box.width == 0) { + box.width = me.dom.scrollWidth; + } + + position = me.getPositioning(); + me.setSize(box.width, box.height); + + wrap = me.wrap({ + style: { + visibility: slideOut ? 'visible' : 'hidden' + } + }); + wrap.setPositioning(position); + if (wrap.isStyle('position', 'static')) { + wrap.position('relative'); + } + me.clearPositioning('auto'); + wrap.clip(); + + + + + me.setStyle({ + visibility: '', + position: 'absolute' + }); + if (slideOut) { + wrap.setSize(box.width, box.height); + } + + switch (anchor) { + case 't': + anim = { + from: { + width: box.width + 'px', + height: '0px' + }, + to: { + width: box.width + 'px', + height: box.height + 'px' + } + }; + elStyle.bottom = '0px'; + break; + case 'l': + anim = { + from: { + width: '0px', + height: box.height + 'px' + }, + to: { + width: box.width + 'px', + height: box.height + 'px' + } + }; + elStyle.right = '0px'; + break; + case 'r': + anim = { + from: { + x: box.x + box.width, + width: '0px', + height: box.height + 'px' + }, + to: { + x: box.x, + width: box.width + 'px', + height: box.height + 'px' + } + }; + break; + case 'b': + anim = { + from: { + y: box.y + box.height, + width: box.width + 'px', + height: '0px' + }, + to: { + y: box.y, + width: box.width + 'px', + height: box.height + 'px' + } + }; + break; + case 'tl': + anim = { + from: { + x: box.x, + y: box.y, + width: '0px', + height: '0px' + }, + to: { + width: box.width + 'px', + height: box.height + 'px' + } + }; + elStyle.bottom = '0px'; + elStyle.right = '0px'; + break; + case 'bl': + anim = { + from: { + x: box.x + box.width, + width: '0px', + height: '0px' + }, + to: { + x: box.x, + width: box.width + 'px', + height: box.height + 'px' + } + }; + elStyle.right = '0px'; + break; + case 'br': + anim = { + from: { + x: box.x + box.width, + y: box.y + box.height, + width: '0px', + height: '0px' + }, + to: { + x: box.x, + y: box.y, + width: box.width + 'px', + height: box.height + 'px' + } + }; + break; + case 'tr': + anim = { + from: { + y: box.y + box.height, + width: '0px', + height: '0px' + }, + to: { + y: box.y, + width: box.width + 'px', + height: box.height + 'px' + } + }; + elStyle.bottom = '0px'; + break; + } + + wrap.show(); + wrapAnim = Ext.apply({}, obj); + delete wrapAnim.listeners; + wrapAnim = Ext.create('Ext.fx.Anim', Ext.applyIf(wrapAnim, { + target: wrap, + duration: 500, + easing: 'ease-out', + from: slideOut ? anim.to : anim.from, + to: slideOut ? anim.from : anim.to + })); + + + wrapAnim.on('afteranimate', function() { + if (slideOut) { + me.setPositioning(position); + if (obj.useDisplay) { + me.setDisplayed(false); + } else { + me.hide(); + } + } + else { + me.clearPositioning(); + me.setPositioning(position); + } + if (wrap.dom) { + wrap.dom.parentNode.insertBefore(me.dom, wrap.dom); + wrap.remove(); + } + me.setSize(box.width, box.height); + animScope.end(); + }); + + if (listeners) { + wrapAnim.on(listeners); + } + }; + + me.animate({ + duration: obj.duration ? obj.duration * 2 : 1000, + listeners: { + beforeanimate: { + fn: beforeAnim + }, + afteranimate: { + fn: function() { + if (wrapAnim && wrapAnim.running) { + wrapAnim.end(); + } + } + } + } + }); + return me; + }, + + + + slideOut: function(anchor, o) { + return this.slideIn(anchor, o, true); + }, + + + + puff: function(obj) { + var me = this, + beforeAnim; + obj = Ext.applyIf(obj || {}, { + easing: 'ease-out', + duration: 500, + useDisplay: false + }); + + beforeAnim = function() { + me.clearOpacity(); + me.show(); + + var box = me.getBox(), + fontSize = me.getStyle('fontSize'), + position = me.getPositioning(); + this.to = { + width: box.width * 2, + height: box.height * 2, + x: box.x - (box.width / 2), + y: box.y - (box.height /2), + opacity: 0, + fontSize: '200%' + }; + this.on('afteranimate',function() { + if (me.dom) { + if (obj.useDisplay) { + me.setDisplayed(false); + } else { + me.hide(); + } + me.clearOpacity(); + me.setPositioning(position); + me.setStyle({fontSize: fontSize}); + } + }); + }; + + me.animate({ + duration: obj.duration, + easing: obj.easing, + listeners: { + beforeanimate: { + fn: beforeAnim + } + } + }); + return me; + }, + + + switchOff: function(obj) { + var me = this, + beforeAnim; + + obj = Ext.applyIf(obj || {}, { + easing: 'ease-in', + duration: 500, + remove: false, + useDisplay: false + }); + + beforeAnim = function() { + var animScope = this, + size = me.getSize(), + xy = me.getXY(), + keyframe, position; + me.clearOpacity(); + me.clip(); + position = me.getPositioning(); + + keyframe = Ext.create('Ext.fx.Animator', { + target: me, + duration: obj.duration, + easing: obj.easing, + keyframes: { + 33: { + opacity: 0.3 + }, + 66: { + height: 1, + y: xy[1] + size.height / 2 + }, + 100: { + width: 1, + x: xy[0] + size.width / 2 + } + } + }); + keyframe.on('afteranimate', function() { + if (obj.useDisplay) { + me.setDisplayed(false); + } else { + me.hide(); + } + me.clearOpacity(); + me.setPositioning(position); + me.setSize(size); + animScope.end(); + }); + }; + me.animate({ + duration: (obj.duration * 2), + listeners: { + beforeanimate: { + fn: beforeAnim + } + } + }); + return me; + }, + + + frame : function(color, count, obj){ + var me = this, + beforeAnim; + + color = color || '#C3DAF9'; + count = count || 1; + obj = obj || {}; + + beforeAnim = function() { + me.show(); + var animScope = this, + box = me.getBox(), + proxy = Ext.getBody().createChild({ + style: { + position : 'absolute', + 'pointer-events': 'none', + 'z-index': 35000, + border : '0px solid ' + color + } + }), + proxyAnim; + proxyAnim = Ext.create('Ext.fx.Anim', { + target: proxy, + duration: obj.duration || 1000, + iterations: count, + from: { + top: box.y, + left: box.x, + borderWidth: 0, + opacity: 1, + height: box.height, + width: box.width + }, + to: { + top: box.y - 20, + left: box.x - 20, + borderWidth: 10, + opacity: 0, + height: box.height + 40, + width: box.width + 40 + } + }); + proxyAnim.on('afteranimate', function() { + proxy.remove(); + animScope.end(); + }); + }; + + me.animate({ + duration: (obj.duration * 2) || 2000, + listeners: { + beforeanimate: { + fn: beforeAnim + } + } + }); + return me; + }, + + + ghost: function(anchor, obj) { + var me = this, + beforeAnim; + + anchor = anchor || "b"; + beforeAnim = function() { + var width = me.getWidth(), + height = me.getHeight(), + xy = me.getXY(), + position = me.getPositioning(), + to = { + opacity: 0 + }; + switch (anchor) { + case 't': + to.y = xy[1] - height; + break; + case 'l': + to.x = xy[0] - width; + break; + case 'r': + to.x = xy[0] + width; + break; + case 'b': + to.y = xy[1] + height; + break; + case 'tl': + to.x = xy[0] - width; + to.y = xy[1] - height; + break; + case 'bl': + to.x = xy[0] - width; + to.y = xy[1] + height; + break; + case 'br': + to.x = xy[0] + width; + to.y = xy[1] + height; + break; + case 'tr': + to.x = xy[0] + width; + to.y = xy[1] - height; + break; + } + this.to = to; + this.on('afteranimate', function () { + if (me.dom) { + me.hide(); + me.clearOpacity(); + me.setPositioning(position); + } + }); + }; + + me.animate(Ext.applyIf(obj || {}, { + duration: 500, + easing: 'ease-out', + listeners: { + beforeanimate: { + fn: beforeAnim + } + } + })); + return me; + }, + + + highlight: function(color, o) { + var me = this, + dom = me.dom, + from = {}, + restore, to, attr, lns, event, fn; + + o = o || {}; + lns = o.listeners || {}; + attr = o.attr || 'backgroundColor'; + from[attr] = color || 'ffff9c'; + + if (!o.to) { + to = {}; + to[attr] = o.endColor || me.getColor(attr, 'ffffff', ''); + } + 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; + return fn.apply(event.scope || lns.scope || window, arguments); + } + }, + afteranimate: function() { + if (dom) { + dom.style[attr] = restore; + } + + event = lns.afteranimate; + if (event) { + fn = event.fn || event; + fn.apply(event.scope || lns.scope || window, arguments); + } + } + }); + + me.animate(Ext.apply({}, o, { + duration: 1000, + easing: 'ease-in', + from: from, + to: to + })); + return me; + }, + + + pause: function(ms) { + var me = this; + Ext.fx.Manager.setFxDefaults(me.id, { + delay: ms + }); + return me; + }, + + + fadeIn: function(o) { + this.animate(Ext.apply({}, o, { + opacity: 1 + })); + return this; + }, + + + fadeOut: function(o) { + this.animate(Ext.apply({}, o, { + opacity: 0 + })); + return this; + }, + + + scale: function(w, h, o) { + this.animate(Ext.apply({}, o, { + width: w, + height: h + })); + return this; + }, + + + shift: function(config) { + this.animate(config); + return this; + } +}); + + +Ext.applyIf(Ext.core.Element, { + unitRe: /\d+(px|em|%|en|ex|pt|in|cm|mm|pc)$/i, + camelRe: /(-[a-z])/gi, + opacityRe: /alpha\(opacity=(.*)\)/i, + cssRe: /([a-z0-9-]+)\s*:\s*([^;\s]+(?:\s*[^;\s]+)*);?/gi, + propertyCache: {}, + defaultUnit : "px", + 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'}, + + + addUnits : Ext.core.Element.prototype.addUnits, + + + parseBox : function(box) { + if (Ext.isObject(box)) { + return { + top: box.top || 0, + right: box.right || 0, + bottom: box.bottom || 0, + left: box.left || 0 + }; + } else { + if (typeof box != 'string') { + box = box.toString(); + } + var parts = box.split(' '), + ln = parts.length; + + if (ln == 1) { + parts[1] = parts[2] = parts[3] = parts[0]; + } + else if (ln == 2) { + parts[2] = parts[0]; + parts[3] = parts[1]; + } + else if (ln == 3) { + parts[3] = parts[1]; + } + + return { + top :parseFloat(parts[0]) || 0, + right :parseFloat(parts[1]) || 0, + bottom:parseFloat(parts[2]) || 0, + left :parseFloat(parts[3]) || 0 + }; + } + + }, + + + unitizeBox : function(box, units) { + var A = this.addUnits, + B = this.parseBox(box); + + return A(B.top, units) + ' ' + + A(B.right, units) + ' ' + + A(B.bottom, units) + ' ' + + A(B.left, units); + + }, + + + camelReplaceFn : function(m, a) { + return a.charAt(1).toUpperCase(); + }, + + + normalize : function(prop) { + if (prop == 'float') { + prop = Ext.supports.Float ? 'cssFloat' : 'styleFloat'; + } + return this.propertyCache[prop] || (this.propertyCache[prop] = prop.replace(this.camelRe, this.camelReplaceFn)); + }, + + + getDocumentHeight: function() { + return Math.max(!Ext.isStrict ? document.body.scrollHeight : document.documentElement.scrollHeight, this.getViewportHeight()); + }, + + + getDocumentWidth: function() { + return Math.max(!Ext.isStrict ? document.body.scrollWidth : document.documentElement.scrollWidth, this.getViewportWidth()); + }, + + + getViewportHeight: function(){ + return window.innerHeight; + }, + + + getViewportWidth : function() { + return window.innerWidth; + }, + + + getViewSize : function() { + return { + width: window.innerWidth, + height: window.innerHeight + }; + }, + + + getOrientation : function() { + if (Ext.supports.OrientationChange) { + return (window.orientation == 0) ? 'portrait' : 'landscape'; + } + + return (window.innerHeight > window.innerWidth) ? 'portrait' : 'landscape'; + }, + + + fromPoint: function(x, y) { + return Ext.get(document.elementFromPoint(x, y)); + }, + + + parseStyles: function(styles){ + var out = {}, + cssRe = this.cssRe, + matches; + + if (styles) { + + + + + cssRe.lastIndex = 0; + while ((matches = cssRe.exec(styles))) { + out[matches[1]] = matches[2]; + } + } + return out; + } +}); + + +Ext.CompositeElementLite = function(els, root){ + + this.elements = []; + this.add(els, root); + this.el = new Ext.core.Element.Flyweight(); +}; + +Ext.CompositeElementLite.prototype = { + isComposite: true, + + + getElement : function(el){ + + var e = this.el; + e.dom = el; + e.id = el.id; + return e; + }, + + + transformElement : function(el){ + return Ext.getDom(el); + }, + + + getCount : function(){ + return this.elements.length; + }, + + add : function(els, root){ + var me = this, + elements = me.elements; + if(!els){ + return this; + } + if(typeof els == "string"){ + els = Ext.core.Element.selectorFunction(els, root); + }else if(els.isComposite){ + els = els.elements; + }else if(!Ext.isIterable(els)){ + els = [els]; + } + + for(var i = 0, len = els.length; i < len; ++i){ + elements.push(me.transformElement(els[i])); + } + return me; + }, + + invoke : function(fn, args){ + var me = this, + els = me.elements, + len = els.length, + e, + i; + + for(i = 0; i < len; i++) { + e = els[i]; + if(e){ + Ext.core.Element.prototype[fn].apply(me.getElement(e), args); + } + } + return me; + }, + + item : function(index){ + var me = this, + el = me.elements[index], + out = null; + + if(el){ + out = me.getElement(el); + } + return out; + }, + + + addListener : function(eventName, handler, scope, opt){ + var els = this.elements, + len = els.length, + i, e; + + for(i = 0; i -1){ + replacement = Ext.getDom(replacement); + if(domReplace){ + d = this.elements[index]; + d.parentNode.insertBefore(replacement, d); + Ext.removeNode(d); + } + this.elements.splice(index, 1, replacement); + } + return this; + }, + + + clear : function(){ + this.elements = []; + } +}; + +Ext.CompositeElementLite.prototype.on = Ext.CompositeElementLite.prototype.addListener; + + +Ext.CompositeElementLite.importElementMethods = function() { + var fnName, + ElProto = Ext.core.Element.prototype, + CelProto = Ext.CompositeElementLite.prototype; + + for (fnName in ElProto) { + if (typeof ElProto[fnName] == 'function'){ + (function(fnName) { + CelProto[fnName] = CelProto[fnName] || function() { + return this.invoke(fnName, arguments); + }; + }).call(CelProto, fnName); + + } + } +}; + +Ext.CompositeElementLite.importElementMethods(); + +if(Ext.DomQuery){ + Ext.core.Element.selectorFunction = Ext.DomQuery.select; +} + + +Ext.core.Element.select = function(selector, root){ + var els; + if(typeof selector == "string"){ + els = Ext.core.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.util.DelayedTask = function(fn, scope, args) { + var me = this, + id, + call = function() { + clearInterval(id); + id = null; + fn.apply(scope, args || []); + }; + + + this.delay = function(delay, newFn, newScope, newArgs) { + me.cancel(); + fn = newFn || fn; + scope = newScope || scope; + args = newArgs || args; + id = setInterval(call, delay); + }; + + + this.cancel = function(){ + if (id) { + clearInterval(id); + id = null; + } + }; +}; +Ext.require('Ext.util.DelayedTask', function() { + + Ext.util.Event = Ext.extend(Object, (function() { + function createBuffered(handler, listener, o, scope) { + listener.task = new Ext.util.DelayedTask(); + return function() { + listener.task.delay(o.buffer, handler, scope, Ext.Array.toArray(arguments)); + }; + } + + function createDelayed(handler, listener, o, scope) { + return function() { + var task = new Ext.util.DelayedTask(); + if (!listener.tasks) { + listener.tasks = []; + } + listener.tasks.push(task); + task.delay(o.delay || 10, handler, scope, Ext.Array.toArray(arguments)); + }; + } + + function createSingle(handler, listener, o, scope) { + return function() { + listener.ev.removeListener(listener.fn, scope); + return handler.apply(scope, arguments); + }; + } + + return { + isEvent: true, + + constructor: function(observable, name) { + this.name = name; + this.observable = observable; + this.listeners = []; + }, + + addListener: function(fn, scope, options) { + var me = this, + 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); + if (me.firing) { + + me.listeners = me.listeners.slice(0); + } + me.listeners.push(listener); + } + }, + + createListener: function(fn, scope, o) { + o = o || {}; + scope = scope || this.observable; + + var listener = { + fn: fn, + scope: scope, + o: o, + ev: this + }, + handler = fn; + + + + if (o.single) { + handler = createSingle(handler, listener, o, scope); + } + if (o.delay) { + handler = createDelayed(handler, listener, o, scope); + } + if (o.buffer) { + handler = createBuffered(handler, listener, o, scope); + } + + listener.fireFn = handler; + return listener; + }, + + findListener: function(fn, scope) { + var listeners = this.listeners, + i = listeners.length, + listener, + s; + + while (i--) { + listener = listeners[i]; + if (listener) { + s = listener.scope; + if (listener.fn == fn && (s == scope || s == this.observable)) { + return i; + } + } + } + + return - 1; + }, + + isListening: function(fn, scope) { + return this.findListener(fn, scope) !== -1; + }, + + removeListener: function(fn, scope) { + var me = this, + index, + listener, + k; + index = me.findListener(fn, scope); + if (index != -1) { + listener = me.listeners[index]; + + if (me.firing) { + me.listeners = me.listeners.slice(0); + } + + + if (listener.task) { + listener.task.cancel(); + delete listener.task; + } + + + k = listener.tasks && listener.tasks.length; + if (k) { + while (k--) { + listener.tasks[k].cancel(); + } + delete listener.tasks; + } + + + me.listeners.splice(index, 1); + return true; + } + + return false; + }, + + + clearListeners: function() { + var listeners = this.listeners, + i = listeners.length; + + while (i--) { + this.removeListener(listeners[i].fn, listeners[i].scope); + } + }, + + fire: function() { + var me = this, + listeners = me.listeners, + count = listeners.length, + i, + args, + listener; + + if (count > 0) { + me.firing = true; + for (i = 0; i < count; i++) { + listener = listeners[i]; + args = arguments.length ? Array.prototype.slice.call(arguments, 0) : []; + if (listener.o) { + args.push(listener.o); + } + if (listener && listener.fireFn.apply(listener.scope || me.observable, args) === false) { + return (me.firing = false); + } + } + } + me.firing = false; + return true; + } + }; + })()); +}); + + +Ext.EventManager = { + + + + + hasBoundOnReady: false, + + + hasFiredReady: false, + + + readyTimeout: null, + + + hasOnReadyStateChange: false, + + + readyEvent: new Ext.util.Event(), + + + checkReadyState: function(){ + var me = Ext.EventManager; + + if(window.attachEvent){ + + if (window != top) { + return false; + } + try{ + document.documentElement.doScroll('left'); + }catch(e){ + return false; + } + me.fireDocReady(); + return true; + } + if (document.readyState == 'complete') { + me.fireDocReady(); + return true; + } + me.readyTimeout = setTimeout(arguments.callee, 2); + return false; + }, + + + bindReadyEvent: function(){ + var me = Ext.EventManager; + if (me.hasBoundOnReady) { + return; + } + + if (document.addEventListener) { + document.addEventListener('DOMContentLoaded', me.fireDocReady, false); + + window.addEventListener('load', me.fireDocReady, false); + } else { + + if (!me.checkReadyState()) { + document.attachEvent('onreadystatechange', me.checkReadyState); + me.hasOnReadyStateChange = true; + } + + window.attachEvent('onload', me.fireDocReady, false); + } + me.hasBoundOnReady = true; + }, + + + fireDocReady: function(){ + var me = Ext.EventManager; + + + if (!me.hasFiredReady) { + me.hasFiredReady = true; + + if (document.addEventListener) { + document.removeEventListener('DOMContentLoaded', me.fireDocReady, false); + window.removeEventListener('load', me.fireDocReady, false); + } else { + if (me.readyTimeout !== null) { + clearTimeout(me.readyTimeout); + } + if (me.hasOnReadyStateChange) { + document.detachEvent('onreadystatechange', me.checkReadyState); + } + window.detachEvent('onload', me.fireDocReady); + } + Ext.supports.init(); + } + if (!Ext.isReady) { + Ext.isReady = true; + me.onWindowUnload(); + me.readyEvent.fire(); + } + }, + + + onDocumentReady: function(fn, scope, options){ + options = options || {}; + var me = Ext.EventManager, + readyEvent = me.readyEvent; + + + options.single = true; + + + if (Ext.isReady) { + readyEvent.addListener(fn, scope, options); + readyEvent.fire(); + } else { + options.delay = options.delay || 1; + readyEvent.addListener(fn, scope, options); + me.bindReadyEvent(); + } + }, + + + + + + stoppedMouseDownEvent: new Ext.util.Event(), + + + propRe: /^(?:scope|delay|buffer|single|stopEvent|preventDefault|stopPropagation|normalized|args|delegate|freezeEvent)$/, + + + getId : function(element) { + var skipGarbageCollection = false, + id; + + element = Ext.getDom(element); + + if (element === document || element === window) { + id = element === document ? Ext.documentId : Ext.windowId; + } + else { + id = Ext.id(element); + } + + if (element && (element.getElementById || element.navigator)) { + skipGarbageCollection = true; + } + + if (!Ext.cache[id]){ + Ext.core.Element.addToCache(new Ext.core.Element(element), id); + if (skipGarbageCollection) { + Ext.cache[id].skipGarbageCollection = true; + } + } + return id; + }, + + + prepareListenerConfig: function(element, config, isRemove){ + var me = this, + propRe = me.propRe, + key, value, args; + + + for (key in config) { + if (config.hasOwnProperty(key)) { + + if (!propRe.test(key)) { + value = config[key]; + + + if (Ext.isFunction(value)) { + + args = [element, key, value, config.scope, config]; + } else { + + args = [element, key, value.fn, value.scope, value]; + } + + if (isRemove === true) { + me.removeListener.apply(this, args); + } else { + me.addListener.apply(me, args); + } + } + } + } + }, + + + normalizeEvent: function(eventName, fn){ + if (/mouseenter|mouseleave/.test(eventName) && !Ext.supports.MouseEnterLeave) { + if (fn) { + fn = Ext.Function.createInterceptor(fn, this.contains, this); + } + eventName = eventName == 'mouseenter' ? 'mouseover' : 'mouseout'; + } else if (eventName == 'mousewheel' && !Ext.supports.MouseWheel && !Ext.isOpera){ + eventName = 'DOMMouseScroll'; + } + return { + eventName: eventName, + fn: fn + }; + }, + + + contains: function(event){ + var parent = event.browserEvent.currentTarget, + child = this.getRelatedTarget(event); + + if (parent && parent.firstChild) { + while (child) { + if (child === parent) { + return false; + } + child = child.parentNode; + if (child && (child.nodeType != 1)) { + child = null; + } + } + } + return true; + }, + + + addListener: function(element, eventName, fn, scope, options){ + + if (Ext.isObject(eventName)) { + this.prepareListenerConfig(element, eventName); + return; + } + + var dom = Ext.getDom(element), + 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 || {}; + + bind = this.normalizeEvent(eventName, fn); + wrap = this.createListenerWrap(dom, eventName, bind.fn, scope, options); + + + if (dom.attachEvent) { + dom.attachEvent('on' + bind.eventName, wrap); + } else { + dom.addEventListener(bind.eventName, wrap, options.capture || false); + } + + if (dom == document && eventName == 'mousedown') { + this.stoppedMouseDownEvent.addListener(wrap); + } + + + this.getEventListenerCache(dom, eventName).push({ + fn: fn, + wrap: wrap, + scope: scope + }); + }, + + + removeListener : function(element, eventName, fn, scope) { + + if (Ext.isObject(eventName)) { + this.prepareListenerConfig(element, eventName, true); + return; + } + + var dom = Ext.getDom(element), + cache = this.getEventListenerCache(dom, eventName), + bindName = this.normalizeEvent(eventName).eventName, + i = cache.length, j, + listener, wrap, tasks; + + + while (i--) { + listener = cache[i]; + + if (listener && (!fn || listener.fn == fn) && (!scope || listener.scope === scope)) { + wrap = listener.wrap; + + + if (wrap.task) { + clearTimeout(wrap.task); + delete wrap.task; + } + + + j = wrap.tasks && wrap.tasks.length; + if (j) { + while (j--) { + clearTimeout(wrap.tasks[j]); + } + delete wrap.tasks; + } + + if (dom.detachEvent) { + dom.detachEvent('on' + bindName, wrap); + } else { + dom.removeEventListener(bindName, wrap, false); + } + + if (wrap && dom == document && eventName == 'mousedown') { + this.stoppedMouseDownEvent.removeListener(wrap); + } + + + cache.splice(i, 1); + } + } + }, + + + removeAll : function(element){ + var dom = Ext.getDom(element), + cache, ev; + if (!dom) { + return; + } + cache = this.getElementEventCache(dom); + + for (ev in cache) { + if (cache.hasOwnProperty(ev)) { + this.removeListener(dom, ev); + } + } + Ext.cache[dom.id].events = {}; + }, + + + purgeElement : function(element, eventName) { + var dom = Ext.getDom(element), + i = 0, len; + + if(eventName) { + this.removeListener(dom, eventName); + } + else { + this.removeAll(dom); + } + + if(dom && dom.childNodes) { + for(len = element.childNodes.length; i < len; i++) { + this.purgeElement(element.childNodes[i], eventName); + } + } + }, + + + createListenerWrap : function(dom, ename, fn, scope, options) { + options = !Ext.isObject(options) ? {} : options; + + var f = ['if(!Ext) {return;}'], + 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);'); + } + + 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.target) { + f.push('if(e.target !== options.target) {return;}'); + } + + if(options.stopEvent) { + f.push('e.stopEvent();'); + } else { + if(options.preventDefault) { + f.push('e.preventDefault();'); + } + if(options.stopPropagation) { + f.push('e.stopPropagation();'); + } + } + + if(options.normalized === false) { + f.push('e = e.browserEvent;'); + } + + if(options.buffer) { + f.push('(wrap.task && clearTimeout(wrap.task));'); + f.push('wrap.task = setTimeout(function(){'); + } + + if(options.delay) { + f.push('wrap.tasks = wrap.tasks || [];'); + f.push('wrap.tasks.push(setTimeout(function(){'); + } + + + f.push('fn.call(scope || dom, e, t, options);'); + + if(options.single) { + f.push('Ext.EventManager.removeListener(dom, ename, fn, scope);'); + } + + if(options.delay) { + f.push('}, ' + options.delay + '));'); + } + + 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) { + var eventCache = this.getElementEventCache(element); + return eventCache[eventName] || (eventCache[eventName] = []); + }, + + + getElementEventCache : function(element) { + var elementCache = Ext.cache[this.getId(element)]; + return elementCache.events || (elementCache.events = {}); + }, + + + mouseLeaveRe: /(mouseout|mouseleave)/, + mouseEnterRe: /(mouseover|mouseenter)/, + + + stopEvent: function(event) { + this.stopPropagation(event); + this.preventDefault(event); + }, + + + stopPropagation: function(event) { + event = event.browserEvent || event; + if (event.stopPropagation) { + event.stopPropagation(); + } else { + event.cancelBubble = true; + } + }, + + + preventDefault: function(event) { + event = event.browserEvent || event; + if (event.preventDefault) { + event.preventDefault(); + } else { + event.returnValue = false; + + try { + + if (event.ctrlKey || event.keyCode > 111 && event.keyCode < 124) { + event.keyCode = -1; + } + } catch (e) { + + } + } + }, + + + getRelatedTarget: function(event) { + event = event.browserEvent || event; + var target = event.relatedTarget; + if (!target) { + if (this.mouseLeaveRe.test(event.type)) { + target = event.toElement; + } else if (this.mouseEnterRe.test(event.type)) { + target = event.fromElement; + } + } + return this.resolveTextNode(target); + }, + + + getPageX: function(event) { + return this.getXY(event)[0]; + }, + + + getPageY: function(event) { + return this.getXY(event)[1]; + }, + + + getPageXY: function(event) { + event = event.browserEvent || event; + var x = event.pageX, + y = event.pageY, + doc = document.documentElement, + body = document.body; + + + if (!x && x !== 0) { + x = event.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc && doc.clientLeft || body && body.clientLeft || 0); + y = event.clientY + (doc && doc.scrollTop || body && body.scrollTop || 0) - (doc && doc.clientTop || body && body.clientTop || 0); + } + return [x, y]; + }, + + + getTarget: function(event) { + event = event.browserEvent || event; + return this.resolveTextNode(event.target || event.srcElement); + }, + + + + resolveTextNode: Ext.isGecko ? + function(node) { + if (!node) { + return; + } + + var s = HTMLElement.prototype.toString.call(node); + if (s == '[xpconnect wrapped native prototype]' || s == '[object XULElement]') { + return; + } + return node.nodeType == 3 ? node.parentNode: node; + }: function(node) { + return node && node.nodeType == 3 ? node.parentNode: node; + }, + + + + + curWidth: 0, + curHeight: 0, + + + onWindowResize: function(fn, scope, options){ + var resize = this.resizeEvent; + if(!resize){ + this.resizeEvent = resize = new Ext.util.Event(); + this.on(window, 'resize', this.fireResize, this, {buffer: 100}); + } + resize.addListener(fn, scope, options); + }, + + + fireResize: function(){ + var me = this, + w = Ext.core.Element.getViewWidth(), + h = Ext.core.Element.getViewHeight(); + + + if(me.curHeight != h || me.curWidth != w){ + me.curHeight = h; + me.curWidth = w; + me.resizeEvent.fire(w, h); + } + }, + + + removeResizeListener: function(fn, scope){ + if (this.resizeEvent) { + this.resizeEvent.removeListener(fn, scope); + } + }, + + onWindowUnload: function() { + var unload = this.unloadEvent; + if (!unload) { + this.unloadEvent = unload = new Ext.util.Event(); + this.addListener(window, 'unload', this.fireUnload, this); + } + }, + + + fireUnload: function() { + + try { + this.removeUnloadListener(); + + if (Ext.isGecko3) { + var gridviews = Ext.ComponentQuery.query('gridview'), + i = 0, + ln = gridviews.length; + for (; i < ln; i++) { + gridviews[i].scrollToTop(); + } + } + + var el, + cache = Ext.cache; + for (el in cache) { + if (cache.hasOwnProperty(el)) { + Ext.EventManager.removeAll(el); + } + } + } catch(e) { + } + }, + + + removeUnloadListener: function(){ + if (this.unloadEvent) { + this.removeListener(window, 'unload', this.fireUnload); + } + }, + + + useKeyDown: Ext.isWebKit ? + parseInt(navigator.userAgent.match(/AppleWebKit\/(\d+)/)[1], 10) >= 525 : + !((Ext.isGecko && !Ext.isWindows) || Ext.isOpera), + + + getKeyEvent: function(){ + return this.useKeyDown ? 'keydown' : 'keypress'; + } +}; + + +Ext.onReady = function(fn, scope, options) { + Ext.Loader.onReady(fn, scope, true, options); +}; + + +Ext.onDocumentReady = Ext.EventManager.onDocumentReady; + + +Ext.EventManager.on = Ext.EventManager.addListener; + + +Ext.EventManager.un = Ext.EventManager.removeListener; + +(function(){ + var initExtCss = function() { + + var bd = document.body || document.getElementsByTagName('body')[0], + baseCSSPrefix = Ext.baseCSSPrefix, + cls = [], + htmlCls = [], + html; + + if (!bd) { + return false; + } + + html = bd.parentNode; + + + 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'); + } + if (Ext.isGecko) { + cls.push(baseCSSPrefix + 'gecko'); + } + if (Ext.isGecko3) { + cls.push(baseCSSPrefix + 'gecko3'); + } + if (Ext.isGecko4) { + cls.push(baseCSSPrefix + 'gecko4'); + } + if (Ext.isOpera) { + cls.push(baseCSSPrefix + 'opera'); + } + if (Ext.isWebKit) { + cls.push(baseCSSPrefix + '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'); + } + if (Ext.isChrome) { + cls.push(baseCSSPrefix + 'chrome'); + } + if (Ext.isMac) { + cls.push(baseCSSPrefix + 'mac'); + } + if (Ext.isLinux) { + cls.push(baseCSSPrefix + 'linux'); + } + if (!Ext.supports.CSS3BorderRadius) { + cls.push(baseCSSPrefix + 'nbr'); + } + if (!Ext.supports.CSS3LinearGradient) { + cls.push(baseCSSPrefix + 'nlg'); + } + if (!Ext.scopeResetCSS) { + cls.push(baseCSSPrefix + 'reset'); + } + + + if (html) { + if (Ext.isStrict && (Ext.isIE6 || Ext.isIE7)) { + Ext.isBorderBox = false; + } + else { + Ext.isBorderBox = true; + } + + 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); + } + + Ext.fly(bd, '_internal').addCls(cls); + return true; + }; + + Ext.onReady(initExtCss); +})(); + + +Ext.define('Ext.EventObjectImpl', { + uses: ['Ext.util.Point'], + + + BACKSPACE: 8, + + TAB: 9, + + NUM_CENTER: 12, + + ENTER: 13, + + RETURN: 13, + + SHIFT: 16, + + CTRL: 17, + + ALT: 18, + + PAUSE: 19, + + CAPS_LOCK: 20, + + ESC: 27, + + SPACE: 32, + + PAGE_UP: 33, + + PAGE_DOWN: 34, + + END: 35, + + HOME: 36, + + LEFT: 37, + + UP: 38, + + RIGHT: 39, + + DOWN: 40, + + PRINT_SCREEN: 44, + + INSERT: 45, + + DELETE: 46, + + ZERO: 48, + + ONE: 49, + + TWO: 50, + + THREE: 51, + + FOUR: 52, + + FIVE: 53, + + SIX: 54, + + SEVEN: 55, + + EIGHT: 56, + + NINE: 57, + + A: 65, + + B: 66, + + C: 67, + + D: 68, + + E: 69, + + F: 70, + + G: 71, + + H: 72, + + I: 73, + + J: 74, + + K: 75, + + L: 76, + + M: 77, + + N: 78, + + O: 79, + + P: 80, + + Q: 81, + + R: 82, + + S: 83, + + T: 84, + + U: 85, + + V: 86, + + W: 87, + + X: 88, + + Y: 89, + + Z: 90, + + CONTEXT_MENU: 93, + + NUM_ZERO: 96, + + NUM_ONE: 97, + + NUM_TWO: 98, + + NUM_THREE: 99, + + NUM_FOUR: 100, + + NUM_FIVE: 101, + + NUM_SIX: 102, + + NUM_SEVEN: 103, + + NUM_EIGHT: 104, + + NUM_NINE: 105, + + NUM_MULTIPLY: 106, + + NUM_PLUS: 107, + + NUM_MINUS: 109, + + NUM_PERIOD: 110, + + NUM_DIVISION: 111, + + F1: 112, + + F2: 113, + + F3: 114, + + F4: 115, + + F5: 116, + + F6: 117, + + F7: 118, + + F8: 119, + + F9: 120, + + F10: 121, + + F11: 122, + + F12: 123, + + + clickRe: /(dbl)?click/, + + safariKeys: { + 3: 13, + 63234: 37, + 63235: 39, + 63232: 38, + 63233: 40, + 63276: 33, + 63277: 34, + 63272: 46, + 63273: 36, + 63275: 35 + }, + + btnMap: Ext.isIE ? { + 1: 0, + 4: 1, + 2: 2 + } : { + 0: 0, + 1: 1, + 2: 2 + }, + + constructor: function(event, freezeEvent){ + if (event) { + this.setEvent(event.browserEvent || event, freezeEvent); + } + }, + + setEvent: function(event, freezeEvent){ + var me = this, button, options; + + if (event == me || (event && event.browserEvent)) { + return event; + } + me.browserEvent = event; + if (event) { + + button = event.button ? me.btnMap[event.button] : (event.which ? event.which - 1 : -1); + if (me.clickRe.test(event.type) && button == -1) { + button = 0; + } + options = { + type: event.type, + button: button, + shiftKey: event.shiftKey, + + ctrlKey: event.ctrlKey || event.metaKey || false, + altKey: event.altKey, + + keyCode: event.keyCode, + charCode: event.charCode, + + target: Ext.EventManager.getTarget(event), + relatedTarget: Ext.EventManager.getRelatedTarget(event), + currentTarget: event.currentTarget, + xy: (freezeEvent ? me.getXY() : null) + }; + } else { + options = { + button: -1, + shiftKey: false, + ctrlKey: false, + altKey: false, + keyCode: 0, + charCode: 0, + target: null, + xy: [0, 0] + }; + } + Ext.apply(me, options); + return me; + }, + + + stopEvent: function(){ + this.stopPropagation(); + this.preventDefault(); + }, + + + preventDefault: function(){ + if (this.browserEvent) { + Ext.EventManager.preventDefault(this.browserEvent); + } + }, + + + stopPropagation: function(){ + var browserEvent = this.browserEvent; + + if (browserEvent) { + if (browserEvent.type == 'mousedown') { + Ext.EventManager.stoppedMouseDownEvent.fire(this); + } + Ext.EventManager.stopPropagation(browserEvent); + } + }, + + + getCharCode: function(){ + return this.charCode || this.keyCode; + }, + + + getKey: function(){ + return this.normalizeKey(this.keyCode || this.charCode); + }, + + + normalizeKey: function(key){ + + return Ext.isWebKit ? (this.safariKeys[key] || key) : key; + }, + + + getPageX: function(){ + return this.getX(); + }, + + + getPageY: function(){ + return this.getY(); + }, + + + getX: function() { + return this.getXY()[0]; + }, + + + getY: function() { + return this.getXY()[1]; + }, + + + getXY: function() { + if (!this.xy) { + + this.xy = Ext.EventManager.getPageXY(this.browserEvent); + } + return this.xy; + }, + + + getTarget : function(selector, maxDepth, returnEl){ + if (selector) { + return Ext.fly(this.target).findParent(selector, maxDepth, returnEl); + } + return returnEl ? Ext.get(this.target) : this.target; + }, + + + getRelatedTarget : function(selector, maxDepth, returnEl){ + if (selector) { + return Ext.fly(this.relatedTarget).findParent(selector, maxDepth, returnEl); + } + return returnEl ? Ext.get(this.relatedTarget) : this.relatedTarget; + }, + + + getWheelDelta : function(){ + var event = this.browserEvent, + delta = 0; + + if (event.wheelDelta) { + delta = event.wheelDelta / 120; + } else if (event.detail){ + delta = -event.detail / 3; + } + return delta; + }, + + + within : function(el, related, allowEl){ + if(el){ + var t = related ? this.getRelatedTarget() : this.getTarget(), + result; + + if (t) { + result = Ext.fly(el).contains(t); + if (!result && allowEl) { + result = t == Ext.getDom(el); + } + return result; + } + } + return false; + }, + + + isNavKeyPress : function(){ + var me = this, + k = this.normalizeKey(me.keyCode); + + return (k >= 33 && k <= 40) || + k == me.RETURN || + k == me.TAB || + k == me.ESC; + }, + + + isSpecialKey : function(){ + var k = this.normalizeKey(this.keyCode); + return (this.type == 'keypress' && this.ctrlKey) || + this.isNavKeyPress() || + (k == this.BACKSPACE) || + (k >= 16 && k <= 20) || + (k >= 44 && k <= 46); + }, + + + getPoint : function(){ + var xy = this.getXY(); + return Ext.create('Ext.util.Point', xy[0], xy[1]); + }, + + + hasModifier : function(){ + return this.ctrlKey || this.altKey || this.shiftKey || this.metaKey; + }, + + + injectEvent: function () { + var API, + dispatchers = {}; + + + + + + + if (!Ext.isIE && document.createEvent) { + API = { + createHtmlEvent: function (doc, type, bubbles, cancelable) { + var event = doc.createEvent('HTMLEvents'); + + event.initEvent(type, bubbles, cancelable); + return event; + }, + + createMouseEvent: function (doc, type, bubbles, cancelable, detail, + clientX, clientY, ctrlKey, altKey, shiftKey, metaKey, + button, relatedTarget) { + var event = doc.createEvent('MouseEvents'), + view = doc.defaultView || window; + + if (event.initMouseEvent) { + event.initMouseEvent(type, bubbles, cancelable, view, detail, + clientX, clientY, clientX, clientY, ctrlKey, altKey, + shiftKey, metaKey, button, relatedTarget); + } else { + event = doc.createEvent('UIEvents'); + event.initEvent(type, bubbles, cancelable); + event.view = view; + event.detail = detail; + event.screenX = clientX; + event.screenY = clientY; + event.clientX = clientX; + event.clientY = clientY; + event.ctrlKey = ctrlKey; + event.altKey = altKey; + event.metaKey = metaKey; + event.shiftKey = shiftKey; + event.button = button; + event.relatedTarget = relatedTarget; + } + + return event; + }, + + createUIEvent: function (doc, type, bubbles, cancelable, detail) { + var event = doc.createEvent('UIEvents'), + view = doc.defaultView || window; + + event.initUIEvent(type, bubbles, cancelable, view, detail); + return event; + }, + + fireEvent: function (target, type, event) { + target.dispatchEvent(event); + }, + + fixTarget: function (target) { + + if (target == window && !target.dispatchEvent) { + return document; + } + + return target; + } + } + } else if (document.createEventObject) { + var crazyIEButtons = { 0: 1, 1: 4, 2: 2 }; + + API = { + createHtmlEvent: function (doc, type, bubbles, cancelable) { + var event = doc.createEventObject(); + event.bubbles = bubbles; + event.cancelable = cancelable; + return event; + }, + + createMouseEvent: function (doc, type, bubbles, cancelable, detail, + clientX, clientY, ctrlKey, altKey, shiftKey, metaKey, + button, relatedTarget) { + var event = doc.createEventObject(); + event.bubbles = bubbles; + event.cancelable = cancelable; + event.detail = detail; + event.screenX = clientX; + event.screenY = clientY; + event.clientX = clientX; + event.clientY = clientY; + event.ctrlKey = ctrlKey; + event.altKey = altKey; + event.shiftKey = shiftKey; + event.metaKey = metaKey; + event.button = crazyIEButtons[button] || button; + event.relatedTarget = relatedTarget; + return event; + }, + + createUIEvent: function (doc, type, bubbles, cancelable, detail) { + var event = doc.createEventObject(); + event.bubbles = bubbles; + event.cancelable = cancelable; + return event; + }, + + fireEvent: function (target, type, event) { + target.fireEvent('on' + type, event); + }, + + fixTarget: function (target) { + if (target == document) { + + + return document.documentElement; + } + + return target; + } + }; + } + + + + + Ext.Object.each({ + load: [false, false], + unload: [false, false], + select: [true, false], + change: [true, false], + submit: [true, true], + reset: [true, false], + resize: [true, false], + scroll: [true, false] + }, + function (name, value) { + var bubbles = value[0], cancelable = value[1]; + dispatchers[name] = function (targetEl, srcEvent) { + var e = API.createHtmlEvent(name, bubbles, cancelable); + API.fireEvent(targetEl, name, e); + }; + }); + + + + + function createMouseEventDispatcher (type, detail) { + var cancelable = (type != 'mousemove'); + return function (targetEl, srcEvent) { + var xy = srcEvent.getXY(), + e = API.createMouseEvent(targetEl.ownerDocument, type, true, cancelable, + detail, xy[0], xy[1], srcEvent.ctrlKey, srcEvent.altKey, + srcEvent.shiftKey, srcEvent.metaKey, srcEvent.button, + srcEvent.relatedTarget); + API.fireEvent(targetEl, type, e); + }; + } + + Ext.each(['click', 'dblclick', 'mousedown', 'mouseup', 'mouseover', 'mousemove', 'mouseout'], + function (eventName) { + dispatchers[eventName] = createMouseEventDispatcher(eventName, 1); + }); + + + + + Ext.Object.each({ + focusin: [true, false], + focusout: [true, false], + activate: [true, true], + focus: [false, false], + blur: [false, false] + }, + function (name, value) { + var bubbles = value[0], cancelable = value[1]; + dispatchers[name] = function (targetEl, srcEvent) { + var e = API.createUIEvent(targetEl.ownerDocument, name, bubbles, cancelable, 1); + API.fireEvent(targetEl, name, e); + }; + }); + + + if (!API) { + + + dispatchers = {}; + + API = { + fixTarget: function (t) { + return t; + } + }; + } + + function cannotInject (target, srcEvent) { + + } + + return function (target) { + var me = this, + dispatcher = dispatchers[me.type] || cannotInject, + t = target ? (target.dom || target) : me.getTarget(); + + t = API.fixTarget(t); + dispatcher(t, me); + }; + }() + +}, function() { + +Ext.EventObject = new Ext.EventObjectImpl(); + +}); + + + +(function(){ + var doc = document, + isCSS1 = doc.compatMode == "CSS1Compat", + ELEMENT = Ext.core.Element, + fly = function(el){ + if (!_fly) { + _fly = new Ext.core.Element.Flyweight(); + } + _fly.dom = el; + return _fly; + }, _fly; + + Ext.apply(ELEMENT, { + isAncestor : function(p, c) { + var ret = false; + + p = Ext.getDom(p); + c = Ext.getDom(c); + if (p && c) { + if (p.contains) { + return p.contains(c); + } else if (p.compareDocumentPosition) { + return !!(p.compareDocumentPosition(c) & 16); + } else { + while ((c = c.parentNode)) { + ret = c == p || ret; + } + } + } + return ret; + }, + + getViewWidth : function(full) { + return full ? ELEMENT.getDocumentWidth() : ELEMENT.getViewportWidth(); + }, + + getViewHeight : function(full) { + return full ? ELEMENT.getDocumentHeight() : ELEMENT.getViewportHeight(); + }, + + getDocumentHeight: function() { + return Math.max(!isCSS1 ? doc.body.scrollHeight : doc.documentElement.scrollHeight, ELEMENT.getViewportHeight()); + }, + + getDocumentWidth: function() { + return Math.max(!isCSS1 ? doc.body.scrollWidth : doc.documentElement.scrollWidth, ELEMENT.getViewportWidth()); + }, + + getViewportHeight: function(){ + return Ext.isIE ? + (Ext.isStrict ? doc.documentElement.clientHeight : doc.body.clientHeight) : + self.innerHeight; + }, + + getViewportWidth : function() { + return (!Ext.isStrict && !Ext.isOpera) ? doc.body.clientWidth : + Ext.isIE ? doc.documentElement.clientWidth : self.innerWidth; + }, + + getY : function(el) { + return ELEMENT.getXY(el)[1]; + }, + + getX : function(el) { + return ELEMENT.getXY(el)[0]; + }, + + getXY : function(el) { + var p, + pe, + b, + bt, + bl, + dbd, + x = 0, + y = 0, + scroll, + hasAbsolute, + bd = (doc.body || doc.documentElement), + ret = [0,0]; + + el = Ext.getDom(el); + + if(el != bd){ + 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; + + while (p) { + pe = fly(p); + x += p.offsetLeft; + y += p.offsetTop; + + hasAbsolute = hasAbsolute || pe.isStyle("position", "absolute"); + + if (Ext.isGecko) { + y += bt = parseInt(pe.getStyle("borderTopWidth"), 10) || 0; + x += bl = parseInt(pe.getStyle("borderLeftWidth"), 10) || 0; + + if (p != el && !pe.isStyle('overflow','visible')) { + x += bl; + y += bt; + } + } + p = p.offsetParent; + } + + if (Ext.isSafari && hasAbsolute) { + x -= bd.offsetLeft; + y -= bd.offsetTop; + } + + if (Ext.isGecko && !hasAbsolute) { + dbd = fly(bd); + x += parseInt(dbd.getStyle("borderLeftWidth"), 10) || 0; + y += parseInt(dbd.getStyle("borderTopWidth"), 10) || 0; + } + + p = el.parentNode; + while (p && p != bd) { + if (!Ext.isOpera || (p.tagName != 'TR' && !fly(p).isStyle("display", "inline"))) { + x -= p.scrollLeft; + y -= p.scrollTop; + } + p = p.parentNode; + } + ret = [x,y]; + } + } + return ret; + }, + + setXY : function(el, xy) { + (el = Ext.fly(el, '_setXY')).position(); + + var pts = el.translatePoints(xy), + style = el.dom.style, + pos; + + for (pos in pts) { + if (!isNaN(pts[pos])) { + style[pos] = pts[pos] + "px"; + } + } + }, + + setX : function(el, x) { + ELEMENT.setXY(el, [x, false]); + }, + + setY : function(el, y) { + ELEMENT.setXY(el, [false, y]); + }, + + + serializeForm: function(form) { + var fElements = form.elements || (document.forms[form] || Ext.getDom(form)).elements, + hasSubmit = false, + encoder = encodeURIComponent, + name, + data = '', + type, + hasValue; + + Ext.each(fElements, function(element){ + name = element.name; + type = element.type; + + if (!element.disabled && name) { + if (/select-(one|multiple)/i.test(type)) { + 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)); + } + }); + } else if (!(/file|undefined|reset|button/i.test(type))) { + if (!(/radio|checkbox/i.test(type) && !element.checked) && !(type == 'submit' && hasSubmit)) { + data += encoder(name) + '=' + encoder(element.value) + '&'; + hasSubmit = /submit/i.test(type); + } + } + } + }); + return data.substr(0, data.length - 1); + } + }); +})(); + + + +Ext.core.Element.addMethods({ + + + 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; + }, + + + 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; + } + me.on(eventName, fn); + return me; + }, + + + 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; + + if (Ext.core.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; + n.nodeIndex = ++ni; + } + } else { + + Ext.fly(n).clean(); + n.nodeIndex = ++ni; + } + n = nx; + } + + Ext.core.Element.data(dom, 'isCleaned', true); + return me; + }, + + + load : function(options) { + this.getLoader().load(options); + return this; + }, + + + 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; + }, + + + update : function(html, loadScripts, callback) { + var me = this, + id, + dom, + interval; + + if (!me.dom) { + return me; + } + html = html || ''; + dom = me.dom; + + if (loadScripts !== true) { + dom.innerHTML = html; + Ext.callback(callback, me); + return me; + } + + 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; + }, + + + createProxy : function(config, renderTo, matchBox) { + config = (typeof config == 'object') ? config : {tag : "div", cls: config}; + + var me = this, + proxy = renderTo ? Ext.core.DomHelper.append(renderTo, config, true) : + Ext.core.DomHelper.insertBefore(me.dom, config, true); + + 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; + + +Ext.core.Element.addMethods({ + + getAnchorXY : function(anchor, local, s){ + + + anchor = (anchor || "tl").toLowerCase(); + s = s || {}; + + 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(), + xy, + r = Math.round, + o = me.getXY(), + scroll = me.getScroll(), + extraX = vp ? scroll.left : !local ? o[0] : 0, + extraY = vp ? scroll.top : !local ? o[1] : 0, + hash = { + c : [r(w * 0.5), r(h * 0.5)], + t : [r(w * 0.5), 0], + l : [0, r(h * 0.5)], + r : [w, r(h * 0.5)], + b : [r(w * 0.5), h], + tl : [0, 0], + bl : [0, h], + br : [w, h], + tr : [w, 0] + }; + + xy = hash[anchor]; + return [xy[0] + extraX, xy[1] + extraY]; + }, + + + anchorTo : function(el, alignment, offsets, animate, monitorScroll, callback){ + var me = this, + dom = me.dom, + scroll = !Ext.isEmpty(monitorScroll), + action = function(){ + Ext.fly(dom).alignTo(el, alignment, offsets, animate); + Ext.callback(callback, Ext.fly(dom)); + }, + anchor = this.getAnchor(); + + + this.removeAnchor(); + Ext.apply(anchor, { + fn: action, + scroll: scroll + }); + + Ext.EventManager.onWindowResize(action, null); + + if(scroll){ + Ext.EventManager.on(window, 'scroll', action, null, + {buffer: !isNaN(monitorScroll) ? monitorScroll : 50}); + } + action.call(me); + return me; + }, + + + removeAnchor : function(){ + var me = this, + anchor = this.getAnchor(); + + if(anchor && anchor.fn){ + Ext.EventManager.removeResizeListener(anchor.fn); + if(anchor.scroll){ + Ext.EventManager.un(window, 'scroll', anchor.fn); + } + delete anchor.fn; + } + return me; + }, + + + getAnchor : function(){ + var data = Ext.core.Element.data, + dom = this.dom; + if (!dom) { + return; + } + var anchor = data(dom, '_anchor'); + + if(!anchor){ + anchor = data(dom, '_anchor', {}); + } + return anchor; + }, + + getAlignVector: function(el, spec, offset) { + var me = this, + side = {t:"top", l:"left", r:"right", b: "bottom"}, + thisRegion = me.getRegion(), + elRegion; + + 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(); + }, + + + getAlignToXY : function(el, p, o){ + 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]; + p = (!p || p == "?" ? "tl-bl?" : (!(/-/).test(p) && p !== "" ? "tl-" + p : p || "tl-bl")).toLowerCase(); + + var me = this, + d = me.dom, + a1, + a2, + x, + y, + + w, + h, + r, + dw = Ext.core.Element.getViewWidth() -10, + dh = Ext.core.Element.getViewHeight()-10, + p1y, + p1x, + p2y, + p2x, + swapY, + swapX, + doc = document, + docElement = doc.documentElement, + docBody = doc.body, + scrollX = (docElement.scrollLeft || docBody.scrollLeft || 0)+5, + scrollY = (docElement.scrollTop || docBody.scrollTop || 0)+5, + c = false, + p1 = "", + p2 = "", + 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]; + p2 = m[2]; + c = !!m[3]; + + + + a1 = me.getAnchorXY(p1, true); + a2 = el.getAnchorXY(p2, false); + + x = a2[0] - a1[0] + o[0]; + y = a2[1] - a1[1] + o[1]; + + if(c){ + w = me.getWidth(); + h = me.getHeight(); + r = el.getRegion(); + + + + p1y = p1.charAt(0); + p1x = p1.charAt(p1.length-1); + p2y = p2.charAt(0); + p2x = p2.charAt(p2.length-1); + swapY = ((p1y=="t" && p2y=="b") || (p1y=="b" && p2y=="t")); + swapX = ((p1x=="r" && p2x=="l") || (p1x=="l" && p2x=="r")); + + + if (x + w > dw + scrollX) { + x = swapX ? r.left-w : dw+scrollX-w; + } + if (x < scrollX) { + x = swapX ? r.right : scrollX; + } + if (y + h > dh + scrollY) { + y = swapY ? r.top-h : dh+scrollY-h; + } + if (y < scrollY){ + y = swapY ? r.bottom : scrollY; + } + } + return [x,y]; + }, + + + alignTo : function(element, position, offsets, animate){ + var me = this; + return me.setXY(me.getAlignToXY(element, position, offsets), + me.anim && !!animate ? me.anim(animate) : false); + }, + + + adjustForConstraints : function(xy, parent) { + var vector = this.getConstrainVector(parent, xy); + if (vector) { + xy[0] += vector[0]; + xy[1] += vector[1]; + } + return xy; + }, + + + getConstrainVector: function(constrainTo, proposedPosition) { + if (!(constrainTo instanceof Ext.util.Region)) { + constrainTo = Ext.get(constrainTo).getViewRegion(); + } + var thisRegion = this.getRegion(), + vector = [0, 0], + shadowSize = this.shadow && this.shadow.offset, + overflowed = false; + + + if (proposedPosition) { + thisRegion.translateBy(proposedPosition[0] - thisRegion.x, proposedPosition[1] - thisRegion.y); + } + + + + if (shadowSize) { + constrainTo.adjust(0, -shadowSize, -shadowSize, shadowSize); + } + + + if (thisRegion.right > constrainTo.right) { + overflowed = true; + vector[0] = (constrainTo.right - thisRegion.right); + } + if (thisRegion.left + vector[0] < constrainTo.left) { + overflowed = true; + vector[0] = (constrainTo.left - thisRegion.left); + } + + + if (thisRegion.bottom > constrainTo.bottom) { + overflowed = true; + vector[1] = (constrainTo.bottom - thisRegion.bottom); + } + if (thisRegion.top + vector[1] < constrainTo.top) { + overflowed = true; + vector[1] = (constrainTo.top - thisRegion.top); + } + return overflowed ? vector : false; + }, + + + getCenterXY : function(){ + return this.getAlignToXY(document, 'c-c'); + }, + + + center : function(centerIn){ + return this.alignTo(centerIn || document, 'c-c'); + } +}); + + +(function(){ + +var ELEMENT = Ext.core.Element, + LEFT = "left", + RIGHT = "right", + TOP = "top", + BOTTOM = "bottom", + POSITION = "position", + STATIC = "static", + RELATIVE = "relative", + AUTO = "auto", + ZINDEX = "z-index"; + +Ext.override(Ext.core.Element, { + + getX : function(){ + return ELEMENT.getX(this.dom); + }, + + + getY : function(){ + return ELEMENT.getY(this.dom); + }, + + + getXY : function(){ + return ELEMENT.getXY(this.dom); + }, + + + getOffsetsTo : function(el){ + var o = this.getXY(), + e = Ext.fly(el, '_internal').getXY(); + return [o[0]-e[0],o[1]-e[1]]; + }, + + + setX : function(x, animate){ + return this.setXY([x, this.getY()], animate); + }, + + + setY : function(y, animate){ + return this.setXY([this.getX(), y], animate); + }, + + + setLeft : function(left){ + this.setStyle(LEFT, this.addUnits(left)); + return this; + }, + + + setTop : function(top){ + this.setStyle(TOP, this.addUnits(top)); + return this; + }, + + + setRight : function(right){ + this.setStyle(RIGHT, this.addUnits(right)); + return this; + }, + + + setBottom : function(bottom){ + this.setStyle(BOTTOM, this.addUnits(bottom)); + return this; + }, + + + setXY: function(pos, animate) { + var me = this; + if (!animate || !me.anim) { + ELEMENT.setXY(me.dom, pos); + } + else { + if (!Ext.isObject(animate)) { + animate = {}; + } + me.animate(Ext.applyIf({ to: { x: pos[0], y: pos[1] } }, animate)); + } + return me; + }, + + + setLocation : function(x, y, animate){ + return this.setXY([x, y], animate); + }, + + + moveTo : function(x, y, animate){ + return this.setXY([x, y], animate); + }, + + + getLeft : function(local){ + return !local ? this.getX() : parseInt(this.getStyle(LEFT), 10) || 0; + }, + + + getRight : function(local){ + var me = this; + return !local ? me.getX() + me.getWidth() : (me.getLeft(true) + me.getWidth()) || 0; + }, + + + getTop : function(local) { + return !local ? this.getY() : parseInt(this.getStyle(TOP), 10) || 0; + }, + + + getBottom : function(local){ + var me = this; + return !local ? me.getY() + me.getHeight() : (me.getTop(true) + me.getHeight()) || 0; + }, + + + position : function(pos, zIndex, x, y) { + var me = this; + + if (!pos && me.isStyle(POSITION, STATIC)){ + me.setStyle(POSITION, RELATIVE); + } else if(pos) { + me.setStyle(POSITION, pos); + } + if (zIndex){ + me.setStyle(ZINDEX, zIndex); + } + if (x || y) { + me.setXY([x || false, y || false]); + } + }, + + + clearPositioning : function(value){ + value = value || ''; + this.setStyle({ + left : value, + right : value, + top : value, + bottom : value, + "z-index" : "", + position : STATIC + }); + return this; + }, + + + getPositioning : function(){ + var l = this.getStyle(LEFT); + var t = this.getStyle(TOP); + return { + "position" : this.getStyle(POSITION), + "left" : l, + "right" : l ? "" : this.getStyle(RIGHT), + "top" : t, + "bottom" : t ? "" : this.getStyle(BOTTOM), + "z-index" : this.getStyle(ZINDEX) + }; + }, + + + setPositioning : function(pc){ + var me = this, + style = me.dom.style; + + me.setStyle(pc); + + if(pc.right == AUTO){ + style.right = ""; + } + if(pc.bottom == AUTO){ + style.bottom = ""; + } + + return me; + }, + + + translatePoints: function(x, y) { + if (Ext.isArray(x)) { + y = x[1]; + x = x[0]; + } + var me = this, + relative = me.isStyle(POSITION, RELATIVE), + o = me.getXY(), + left = parseInt(me.getStyle(LEFT), 10), + top = parseInt(me.getStyle(TOP), 10); + + if (!Ext.isNumber(left)) { + left = relative ? 0 : me.dom.offsetLeft; + } + if (!Ext.isNumber(top)) { + top = relative ? 0 : me.dom.offsetTop; + } + left = (Ext.isNumber(x)) ? x - o[0] + left : undefined; + top = (Ext.isNumber(y)) ? y - o[1] + top : undefined; + return { + left: left, + top: top + }; + }, + + + setBox: function(box, adjust, animate) { + var me = this, + w = box.width, + h = box.height; + if ((adjust && !me.autoBoxAdjust) && !me.isBorderBox()) { + w -= (me.getBorderWidth("lr") + me.getPadding("lr")); + h -= (me.getBorderWidth("tb") + me.getPadding("tb")); + } + me.setBounds(box.x, box.y, w, h, animate); + return me; + }, + + + getBox: function(contentBox, local) { + var me = this, + xy, + left, + top, + getBorderWidth = me.getBorderWidth, + getPadding = me.getPadding, + l, r, t, b, w, h, bx; + if (!local) { + xy = me.getXY(); + } else { + left = parseInt(me.getStyle("left"), 10) || 0; + top = parseInt(me.getStyle("top"), 10) || 0; + xy = [left, top]; + } + w = me.getWidth(); + h = me.getHeight(); + if (!contentBox) { + bx = { + x: xy[0], + y: xy[1], + 0: xy[0], + 1: xy[1], + width: w, + height: h + }; + } else { + l = getBorderWidth.call(me, "l") + getPadding.call(me, "l"); + r = getBorderWidth.call(me, "r") + getPadding.call(me, "r"); + t = getBorderWidth.call(me, "t") + getPadding.call(me, "t"); + b = getBorderWidth.call(me, "b") + getPadding.call(me, "b"); + bx = { + x: xy[0] + l, + y: xy[1] + t, + 0: xy[0] + l, + 1: xy[1] + t, + width: w - (l + r), + height: h - (t + b) + }; + } + bx.right = bx.x + bx.width; + bx.bottom = bx.y + bx.height; + return bx; + }, + + + move: function(direction, distance, animate) { + var me = this, + xy = me.getXY(), + x = xy[0], + y = xy[1], + left = [x - distance, y], + right = [x + distance, y], + top = [x, y - distance], + bottom = [x, y + distance], + hash = { + l: left, + left: left, + r: right, + right: right, + t: top, + top: top, + up: top, + b: bottom, + bottom: bottom, + down: bottom + }; + + direction = direction.toLowerCase(); + me.moveTo(hash[direction][0], hash[direction][1], animate); + }, + + + setLeftTop: function(left, top) { + var me = this, + style = me.dom.style; + style.left = me.addUnits(left); + style.top = me.addUnits(top); + return me; + }, + + + getRegion: function() { + return this.getPageBox(true); + }, + + + getViewRegion: function() { + 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(); + } + else { + pos = me.getXY(); + left = pos[0] + me.getBorderWidth('l') + me.getPadding('l'); + top = pos[1] + me.getBorderWidth('t') + me.getPadding('t'); + width = me.getWidth(true); + height = me.getHeight(true); + } + + return Ext.create('Ext.util.Region', top, left + width, top + height, left); + }, + + + getPageBox : function(getRegion) { + 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, + xy = me.getXY(), + t = xy[1], + r = xy[0] + w, + b = xy[1] + h, + l = xy[0]; + + if (getRegion) { + return Ext.create('Ext.util.Region', t, r, b, l); + } + else { + return { + left: l, + top: t, + width: w, + height: h, + right: r, + bottom: b + }; + } + }, + + + setBounds: function(x, y, width, height, animate) { + var me = this; + if (!animate || !me.anim) { + me.setSize(width, height); + me.setLocation(x, y); + } else { + if (!Ext.isObject(animate)) { + animate = {}; + } + me.animate(Ext.applyIf({ + to: { + x: x, + y: y, + width: me.adjustWidth(width), + height: me.adjustHeight(height) + } + }, animate)); + } + return me; + }, + + + setRegion: function(region, animate) { + return this.setBounds(region.left, region.top, region.right - region.left, region.bottom - region.top, animate); + } +}); +})(); + + +Ext.override(Ext.core.Element, { + + isScrollable : function(){ + var dom = this.dom; + return dom.scrollHeight > dom.clientHeight || dom.scrollWidth > dom.clientWidth; + }, + + + getScroll : function() { + var d = this.dom, + doc = document, + body = doc.body, + docElement = doc.documentElement, + l, + t, + ret; + + if (d == doc || d == body) { + if (Ext.isIE && Ext.isStrict) { + l = docElement.scrollLeft; + t = docElement.scrollTop; + } else { + l = window.pageXOffset; + t = window.pageYOffset; + } + ret = { + left: l || (body ? body.scrollLeft : 0), + top : t || (body ? body.scrollTop : 0) + }; + } else { + ret = { + left: d.scrollLeft, + top : d.scrollTop + }; + } + + return ret; + }, + + + scrollTo : function(side, value, animate) { + + var top = /top/i.test(side), + me = this, + dom = me.dom, + obj = {}, + prop; + if (!animate || !me.anim) { + + prop = 'scroll' + (top ? 'Top' : 'Left'); + dom[prop] = value; + } + else { + if (!Ext.isObject(animate)) { + animate = {}; + } + obj['scroll' + (top ? 'Top' : 'Left')] = value; + me.animate(Ext.applyIf({ + to: obj + }, animate)); + } + return me; + }, + + + scrollIntoView : function(container, hscroll) { + container = Ext.getDom(container) || Ext.getBody().dom; + var el = this.dom, + offsets = this.getOffsetsTo(container), + + left = offsets[0] + container.scrollLeft, + top = offsets[1] + container.scrollTop, + bottom = top + el.offsetHeight, + right = left + el.offsetWidth, + + ctClientHeight = container.clientHeight, + ctScrollTop = parseInt(container.scrollTop, 10), + ctScrollLeft = parseInt(container.scrollLeft, 10), + ctBottom = ctScrollTop + ctClientHeight, + ctRight = ctScrollLeft + container.clientWidth; + + if (el.offsetHeight > ctClientHeight || top < ctScrollTop) { + container.scrollTop = top; + } else if (bottom > ctBottom) { + container.scrollTop = bottom - ctClientHeight; + } + + container.scrollTop = container.scrollTop; + + if (hscroll !== false) { + if (el.offsetWidth > container.clientWidth || left < ctScrollLeft) { + container.scrollLeft = left; + } + else if (right > ctRight) { + container.scrollLeft = right - container.clientWidth; + } + container.scrollLeft = container.scrollLeft; + } + return this; + }, + + + scrollChildIntoView : function(child, hscroll) { + Ext.fly(child, '_scrollChildIntoView').scrollIntoView(this, hscroll); + }, + + + scroll : function(direction, distance, animate) { + if (!this.isScrollable()) { + return false; + } + var el = this.dom, + l = el.scrollLeft, t = el.scrollTop, + w = el.scrollWidth, h = el.scrollHeight, + cw = el.clientWidth, ch = el.clientHeight, + scrolled = false, v, + hash = { + l: Math.min(l + distance, w-cw), + r: v = Math.max(l - distance, 0), + t: Math.max(t - distance, 0), + b: Math.min(t + distance, h-ch) + }; + hash.d = hash.b; + hash.u = hash.t; + + direction = direction.substr(0, 1); + if ((v = hash[direction]) > -1) { + scrolled = true; + this.scrollTo(direction == 'l' || direction == 'r' ? 'left' : 'top', v, this.anim(animate)); + } + return scrolled; + } +}); + +Ext.core.Element.addMethods( + function() { + var VISIBILITY = "visibility", + DISPLAY = "display", + HIDDEN = "hidden", + NONE = "none", + XMASKED = Ext.baseCSSPrefix + "masked", + XMASKEDRELATIVE = Ext.baseCSSPrefix + "masked-relative", + data = Ext.core.Element.data; + + return { + + isVisible : function(deep) { + var vis = !this.isStyle(VISIBILITY, HIDDEN) && !this.isStyle(DISPLAY, NONE), + p = this.dom.parentNode; + + if (deep !== true || !vis) { + return vis; + } + + while (p && !(/^body/i.test(p.tagName))) { + if (!Ext.fly(p, '_isVisible').isVisible()) { + return false; + } + p = p.parentNode; + } + return true; + }, + + + isDisplayed : function() { + return !this.isStyle(DISPLAY, NONE); + }, + + + enableDisplayMode : function(display) { + this.setVisibilityMode(Ext.core.Element.DISPLAY); + + if (!Ext.isEmpty(display)) { + data(this.dom, 'originalDisplay', display); + } + + return this; + }, + + + mask : function(msg, msgCls) { + var me = this, + dom = me.dom, + setExpression = dom.style.setExpression, + dh = Ext.core.DomHelper, + EXTELMASKMSG = Ext.baseCSSPrefix + "mask-msg", + el, + mask; + + if (!(/^body/i.test(dom.tagName) && me.getStyle('position') == 'static')) { + me.addCls(XMASKEDRELATIVE); + } + el = data(dom, 'maskMsg'); + if (el) { + el.remove(); + } + el = data(dom, 'mask'); + if (el) { + el.remove(); + } + + mask = dh.append(dom, {cls : Ext.baseCSSPrefix + "mask"}, true); + data(dom, 'mask', mask); + + me.addCls(XMASKED); + mask.setDisplayed(true); + + if (typeof msg == 'string') { + var mm = dh.append(dom, {cls : EXTELMASKMSG, cn:{tag:'div'}}, true); + data(dom, 'maskMsg', mm); + mm.dom.className = msgCls ? EXTELMASKMSG + " " + msgCls : EXTELMASKMSG; + mm.dom.firstChild.innerHTML = msg; + mm.setDisplayed(true); + mm.center(me); + } + + + + + + if (!Ext.supports.IncludePaddingInWidthCalculation && setExpression) { + mask.dom.style.setExpression('width', 'this.parentNode.offsetWidth + "px"'); + } + + + + if (!Ext.supports.IncludePaddingInHeightCalculation && setExpression) { + mask.dom.style.setExpression('height', 'this.parentNode.offsetHeight + "px"'); + } + + else if (Ext.isIE && !(Ext.isIE7 && Ext.isStrict) && me.getStyle('height') == 'auto') { + mask.setSize(undefined, me.getHeight()); + } + return mask; + }, + + + unmask : function() { + var me = this, + dom = me.dom, + mask = data(dom, 'mask'), + maskMsg = data(dom, 'maskMsg'); + + if (mask) { + + if (mask.dom.style.clearExpression) { + mask.dom.style.clearExpression('width'); + mask.dom.style.clearExpression('height'); + } + if (maskMsg) { + maskMsg.remove(); + data(dom, 'maskMsg', undefined); + } + + mask.remove(); + data(dom, 'mask', undefined); + me.removeCls([XMASKED, XMASKEDRELATIVE]); + } + }, + + isMasked : function() { + var me = this, + mask = data(me.dom, 'mask'), + maskMsg = data(me.dom, 'maskMsg'); + + if (mask && mask.isVisible()) { + if (maskMsg) { + maskMsg.center(me); + } + return true; + } + return false; + }, + + + createShim : function() { + var el = document.createElement('iframe'), + shim; + + el.frameBorder = '0'; + el.className = Ext.baseCSSPrefix + 'shim'; + el.src = Ext.SSL_SECURE_URL; + shim = Ext.get(this.dom.parentNode.insertBefore(el, this.dom)); + shim.autoBoxAdjust = false; + return shim; + } + }; + }() +); + +Ext.core.Element.addMethods({ + + addKeyListener : function(key, fn, scope){ + var config; + if(typeof key != 'object' || Ext.isArray(key)){ + config = { + key: key, + fn: fn, + scope: scope + }; + }else{ + config = { + key : key.key, + shift : key.shift, + ctrl : key.ctrl, + alt : key.alt, + fn: fn, + scope: scope + }; + } + return Ext.create('Ext.util.KeyMap', this, config); + }, + + + addKeyMap : function(config){ + return Ext.create('Ext.util.KeyMap', this, config); + } +}); + + + +Ext.CompositeElementLite.importElementMethods(); + + +Ext.apply(Ext.CompositeElementLite.prototype, { + addElements : function(els, root){ + if(!els){ + return this; + } + if(typeof els == "string"){ + els = Ext.core.Element.selectorFunction(els, root); + } + var yels = this.elements; + Ext.each(els, function(e) { + yels.push(Ext.get(e)); + }); + return this; + }, + + + first : function(){ + return this.item(0); + }, + + + last : function(){ + return this.item(this.getCount()-1); + }, + + + contains : function(el){ + return this.indexOf(el) != -1; + }, + + + removeElement : function(keys, removeDom){ + var me = this, + els = this.elements, + el; + Ext.each(keys, function(val){ + if ((el = (els[val] || els[val = me.indexOf(val)]))) { + if(removeDom){ + if(el.dom){ + el.remove(); + }else{ + Ext.removeNode(el); + } + } + els.splice(val, 1); + } + }); + return this; + } +}); + + +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){ + var els; + if(typeof selector == "string"){ + els = Ext.core.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.define('Ext.util.Observable', { + + + + requires: ['Ext.util.Event'], + + statics: { + + releaseCapture: function(o) { + o.fireEvent = this.prototype.fireEvent; + }, + + + capture: function(o, fn, scope) { + o.fireEvent = Ext.Function.createInterceptor(o.fireEvent, fn, scope); + }, + + + observe: function(cls, listeners) { + if (cls) { + if (!cls.isObservable) { + Ext.applyIf(cls, new this()); + this.capture(cls.prototype, cls.fireEvent, cls); + } + if (Ext.isObject(listeners)) { + cls.on(listeners); + } + return cls; + } + } + }, + + + + + + isObservable: true, + + constructor: function(config) { + var me = this; + + Ext.apply(me, config); + if (me.listeners) { + me.on(me.listeners); + delete me.listeners; + } + me.events = me.events || {}; + + if (me.bubbleEvents) { + me.enableBubble(me.bubbleEvents); + } + }, + + + eventOptionsRe : /^(?:scope|delay|buffer|single|stopEvent|preventDefault|stopPropagation|normalized|args|delegate|element|vertical|horizontal)$/, + + + addManagedListener : function(item, ename, fn, scope, options) { + var me = this, + managedListeners = me.managedListeners = me.managedListeners || [], + config; + + if (Ext.isObject(ename)) { + options = ename; + for (ename in options) { + if (options.hasOwnProperty(ename)) { + config = options[ename]; + if (!me.eventOptionsRe.test(ename)) { + me.addManagedListener(item, ename, config.fn || config, config.scope || options.scope, config.fn ? config : options); + } + } + } + } + else { + managedListeners.push({ + item: item, + ename: ename, + fn: fn, + scope: scope, + options: options + }); + + item.on(ename, fn, scope, options); + } + }, + + + removeManagedListener : function(item, ename, fn, scope) { + var me = this, + options, + config, + managedListeners, + managedListener, + length, + i; + + if (Ext.isObject(ename)) { + options = ename; + for (ename in options) { + if (options.hasOwnProperty(ename)) { + config = options[ename]; + if (!me.eventOptionsRe.test(ename)) { + me.removeManagedListener(item, ename, config.fn || config, config.scope || options.scope); + } + } + } + } + + 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); + } + } + }, + + + fireEvent: function() { + var me = this, + args = Ext.Array.toArray(arguments), + ename = args[0].toLowerCase(), + ret = true, + event = me.events[ename], + queue = me.eventQueue, + parent; + + 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 parent.fireEvent.apply(parent, args); + } + } else if (event && Ext.isObject(event)) { + args.shift(); + ret = event.fire.apply(event, args); + } + return ret; + }, + + + addListener: function(ename, fn, scope, options) { + var me = this, + config, + event; + + if (Ext.isObject(ename)) { + options = ename; + for (ename in options) { + if (options.hasOwnProperty(ename)) { + config = options[ename]; + if (!me.eventOptionsRe.test(ename)) { + me.addListener(ename, config.fn || config, config.scope || options.scope, config.fn ? config : options); + } + } + } + } + else { + ename = ename.toLowerCase(); + me.events[ename] = me.events[ename] || true; + event = me.events[ename] || true; + if (Ext.isBoolean(event)) { + me.events[ename] = event = new Ext.util.Event(me, ename); + } + event.addListener(fn, scope, Ext.isObject(options) ? options : {}); + } + }, + + + removeListener: function(ename, fn, scope) { + var me = this, + config, + event, + options; + + if (Ext.isObject(ename)) { + options = ename; + for (ename in options) { + if (options.hasOwnProperty(ename)) { + config = options[ename]; + if (!me.eventOptionsRe.test(ename)) { + me.removeListener(ename, config.fn || config, config.scope || options.scope); + } + } + } + } else { + ename = ename.toLowerCase(); + event = me.events[ename]; + if (event.isEvent) { + event.removeListener(fn, scope); + } + } + }, + + + clearListeners: function() { + var events = this.events, + event, + key; + + for (key in events) { + if (events.hasOwnProperty(key)) { + event = events[key]; + if (event.isEvent) { + event.clearListeners(); + } + } + } + + 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; + + for (; i < len; i++) { + managedListener = managedListeners[i]; + managedListener.item.un(managedListener.ename, managedListener.fn, managedListener.scope); + } + + this.managedListeners = []; + }, + + purgeManagedListeners : function() { + console.warn('Observable: purgeManagedListeners has been deprecated. Please use clearManagedListeners.'); + return this.clearManagedListeners.apply(this, arguments); + }, + + + 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; + } + } else { + Ext.applyIf(me.events, o); + } + }, + + + hasListener: function(ename) { + var event = this.events[ename.toLowerCase()]; + return event && event.isEvent === true && event.listeners.length > 0; + }, + + + suspendEvents: function(queueSuspended) { + this.eventsSuspended = true; + if (queueSuspended && !this.eventQueue) { + this.eventQueue = []; + } + }, + + + resumeEvents: function() { + var me = this, + queued = me.eventQueue || []; + + me.eventsSuspended = false; + delete me.eventQueue; + + Ext.each(queued, + function(e) { + me.fireEvent.apply(me, e); + }); + }, + + + relayEvents : function(origin, events, prefix) { + prefix = prefix || ''; + var me = this, + len = events.length, + i = 0, + oldName, + newName; + + for (; i < len; i++) { + oldName = events[i].substr(prefix.length); + newName = prefix + oldName; + me.events[newName] = me.events[newName] || true; + origin.on(oldName, me.createRelayer(newName)); + } + }, + + + createRelayer: function(newName){ + var me = this; + return function(){ + return me.fireEvent.apply(me, [newName].concat(Array.prototype.slice.call(arguments, 0, -1))); + }; + }, + + + enableBubble: function(events) { + var me = this; + if (!Ext.isEmpty(events)) { + events = Ext.isArray(events) ? events: Ext.Array.toArray(arguments); + Ext.each(events, + function(ename) { + ename = ename.toLowerCase(); + var ce = me.events[ename] || true; + if (Ext.isBoolean(ce)) { + ce = new Ext.util.Event(me, ename); + me.events[ename] = ce; + } + ce.bubble = true; + }); + } + } +}, function() { + + + + + this.createAlias({ + on: 'addListener', + un: 'removeListener', + mon: 'addManagedListener', + mun: 'removeManagedListener' + }); + + + this.observeClass = this.observe; + + Ext.apply(Ext.util.Observable.prototype, function(){ + + + + function getMethodEvent(method){ + var e = (this.methodEvents = this.methodEvents || {})[method], + returnValue, + v, + cancel, + obj = this; + + if (!e) { + this.methodEvents[method] = e = {}; + e.originalFn = this[method]; + e.methodName = method; + e.before = []; + e.after = []; + + var makeCall = function(fn, scope, args){ + if((v = fn.apply(scope || obj, args)) !== undefined){ + if (typeof v == 'object') { + if(v.returnValue !== undefined){ + returnValue = v.returnValue; + }else{ + returnValue = v; + } + cancel = !!v.cancel; + } + else + if (v === false) { + cancel = true; + } + else { + returnValue = v; + } + } + }; + + this[method] = function(){ + var args = Array.prototype.slice.call(arguments, 0), + b, i, len; + returnValue = v = undefined; + cancel = false; + + for(i = 0, len = e.before.length; i < len; i++){ + b = e.before[i]; + makeCall(b.fn, b.scope, args); + if (cancel) { + return returnValue; + } + } + + if((v = e.originalFn.apply(obj, args)) !== undefined){ + returnValue = v; + } + + for(i = 0, len = e.after.length; i < len; i++){ + b = e.after[i]; + makeCall(b.fn, b.scope, args); + if (cancel) { + return returnValue; + } + } + return returnValue; + }; + } + return e; + } + + return { + + + + beforeMethod : function(method, fn, scope){ + getMethodEvent.call(this, method).before.push({ + fn: fn, + scope: scope + }); + }, + + + afterMethod : function(method, fn, scope){ + getMethodEvent.call(this, method).after.push({ + fn: fn, + scope: scope + }); + }, + + removeMethodListener: function(method, fn, scope){ + var e = this.getMethodEvent(method), + 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); + 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); + return; + } + } + }, + + toggleEventLogging: function(toggle) { + Ext.util.Observable[toggle ? 'capture' : 'releaseCapture'](this, function(en) { + if (Ext.isDefined(Ext.global.console)) { + Ext.global.console.log(en, arguments); + } + }); + } + }; + }()); +}); + + +Ext.define('Ext.util.Animate', { + + uses: ['Ext.fx.Manager', 'Ext.fx.Anim'], + + + animate: function(animObj) { + var me = this; + if (Ext.fx.Manager.hasFxBlock(me.id)) { + return me; + } + Ext.fx.Manager.queueFx(Ext.create('Ext.fx.Anim', me.anim(animObj))); + return this; + }, + + + anim: function(config) { + if (!Ext.isObject(config)) { + return (config) ? {} : false; + } + + var me = this; + + if (config.stopAnimation) { + me.stopAnimation(); + } + + Ext.applyIf(config, Ext.fx.Manager.getFxDefaults(me.id)); + + return Ext.apply({ + target: me, + paused: true + }, config); + }, + + + stopFx: Ext.Function.alias(Ext.util.Animate, 'stopAnimation'), + + + stopAnimation: function() { + Ext.fx.Manager.stopAnimation(this.id); + }, + + + syncFx: function() { + Ext.fx.Manager.setFxDefaults(this.id, { + concurrent: true + }); + }, + + + sequenceFx: function() { + Ext.fx.Manager.setFxDefaults(this.id, { + concurrent: false + }); + }, + + + hasActiveFx: Ext.Function.alias(Ext.util.Animate, 'getActiveAnimation'), + + + getActiveAnimation: function() { + return Ext.fx.Manager.getActiveAnimation(this.id); + } +}); + + +Ext.applyIf(Ext.core.Element.prototype, Ext.util.Animate.prototype); + +Ext.define('Ext.state.Provider', { + mixins: { + observable: 'Ext.util.Observable' + }, + + + prefix: 'ext-', + + constructor : function(config){ + config = config || {}; + var me = this; + Ext.apply(me, config); + + me.addEvents("statechange"); + me.state = {}; + me.mixins.observable.constructor.call(me); + }, + + + get : function(name, defaultValue){ + return typeof this.state[name] == "undefined" ? + defaultValue : this.state[name]; + }, + + + clear : function(name){ + var me = this; + delete me.state[name]; + me.fireEvent("statechange", me, name, null); + }, + + + set : function(name, value){ + var me = this; + me.state[name] = value; + me.fireEvent("statechange", me, name, value); + }, + + + decodeValue : function(value){ + + + + + + + + + + var me = this, + re = /^(a|n|d|b|s|o|e)\:(.*)$/, + matches = re.exec(unescape(value)), + all, + type, + value, + keyValue; + + if(!matches || !matches[1]){ + return; + } + + type = matches[1]; + value = matches[2]; + switch (type) { + case 'e': + return null; + case 'n': + return parseFloat(value); + case 'd': + return new Date(Date.parse(value)); + case 'b': + return (value == '1'); + case 'a': + all = []; + if(value != ''){ + Ext.each(value.split('^'), function(val){ + all.push(me.decodeValue(val)); + }, me); + } + return all; + case 'o': + all = {}; + if(value != ''){ + Ext.each(value.split('^'), function(val){ + keyValue = val.split('='); + all[keyValue[0]] = me.decodeValue(keyValue[1]); + }, me); + } + return all; + default: + return value; + } + }, + + + encodeValue : function(value){ + var flat = '', + i = 0, + enc, + len, + key; + + if (value == null) { + return 'e:1'; + } else if(typeof value == 'number') { + enc = 'n:' + value; + } else if(typeof value == 'boolean') { + enc = 'b:' + (value ? '1' : '0'); + } else if(Ext.isDate(value)) { + enc = 'd:' + value.toGMTString(); + } else if(Ext.isArray(value)) { + for (len = value.length; i < len; i++) { + flat += this.encodeValue(value[i]); + if (i != len - 1) { + flat += '^'; + } + } + enc = 'a:' + flat; + } else if (typeof value == 'object') { + for (key in value) { + if (typeof value[key] != 'function' && value[key] !== undefined) { + flat += key + '=' + this.encodeValue(value[key]) + '^'; + } + } + enc = 'o:' + flat.substring(0, flat.length-1); + } else { + enc = 's:' + value; + } + return escape(enc); + } +}); + +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'] +}, function() { + + 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,', + 'it = items,', + 'l = it.length,', + 'c;', + 'for (; i < l; i++) {', + 'c = it[i];', + 'if (c.{0}) {', + 'r.push(c);', + '}', + '}', + 'return r;' + ].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)); + }, + + getItems = function(items, mode) { + var result = [], + i = 0, + length = items.length, + candidate, + deep = mode !== '>'; + + for (; i < length; i++) { + candidate = items[i]; + if (candidate.getRefItems) { + result = result.concat(candidate.getRefItems(deep)); + } + } + return result; + }, + + getAncestors = function(items) { + var result = [], + i = 0, + length = items.length, + candidate; + for (; i < length; i++) { + candidate = items[i]; + while (!!(candidate = (candidate.ownerCt || candidate.floatParent))) { + result.push(candidate); + } + } + 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(); + } + else { + var result = [], + i = 0, + length = items.length, + candidate; + for (; i < length; i++) { + candidate = items[i]; + if (candidate.isXType(xtype, shallow)) { + result.push(candidate); + } + } + return result; + } + }, + + // Filters the passed candidate array and returns only items which have the passed className + filterByClassName = function(items, className) { + var EA = Ext.Array, + result = [], + i = 0, + length = items.length, + candidate; + for (; i < length; i++) { + candidate = items[i]; + if (candidate.el ? candidate.el.hasCls(className) : EA.contains(candidate.initCls(), className)) { + result.push(candidate); + } + } + 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, + length = items.length, + candidate; + for (; i < length; i++) { + candidate = items[i]; + if (!value ? !!candidate[property] : (String(candidate[property]) === value)) { + result.push(candidate); + } + } + 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, + length = items.length, + candidate; + for (; i < length; i++) { + candidate = items[i]; + if (candidate.getItemId() === id) { + result.push(candidate); + } + } + 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, + length = operations.length, + 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]); + } + else if (operation.mode) { + workingItems = getItems(workingItems || [root], operation.mode); + } + else { + 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; + } + } + return []; + }, + + is: function(component) { + var operations = this.operations, + components = Ext.isArray(component) ? component : [component], + originalLength = components.length, + lastOperation = operations[operations.length-1], + ln, i; + + components = filterItems(components, lastOperation); + if (components.length === originalLength) { + if (operations.length > 1) { + for (i = 0, ln = components.length; i < ln; i++) { + if (Ext.Array.indexOf(this.execute(), components[i]) === -1) { + return false; + } + } + } + return true; + } + return false; + } + }); + + 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, + i = 0, + length = components.length, + results = [], + index = -1, + component; + + for(; i < length; ++i) { + component = components[i]; + if (!CQ.is(component, selector)) { + results[++index] = component; + } + } + return results; + } + }, + + /** + *

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, + i = 0, + results = [], + noDupResults = [], + dupMatcher = {}, + query, resultsLn, cmp; + + for (; i < length; i++) { + selector = Ext.String.trim(selectors[i]); + query = this.cache[selector]; + if (!query) { + this.cache[selector] = query = this.parse(selector); + } + 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++) { + cmp = results[i]; + if (!dupMatcher[cmp.id]) { + noDupResults.push(cmp); + dupMatcher[cmp.id] = true; + } + } + results = noDupResults; + } + 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; + } + var query = this.cache[selector]; + if (!query) { + this.cache[selector] = query = this.parse(selector); + } + return query.is(component); + }, + + parse: function(selector) { + var operations = [], + length = matchers.length, + lastSelector, + tokenMatch, + matchedChar, + modeMatch, + 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, + args: [Ext.String.trim(tokenMatch[2]), Boolean(tokenMatch[3])] + }); + } + + // 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] + '"'); + } + } + } + + // 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! + operations.push({ + mode: modeMatch[2]||modeMatch[1] + }); + selector = selector.replace(modeMatch[0], ''); + } + } + + // 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 */ + + /* 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; + + 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(); + } + + this.filterFn = this.filter; + } + }, + + /** + * @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; + + return function(item) { + return matcher.test(me.getRoot.call(me, item)[property]); + }; + }, + + /** + * @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]; + }, + + /** + * @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); + + 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', { + + /** + * @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} + */ + + /** + * @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 + */ + + /** + * @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. + */ + + /** + * @cfg {String} direction The direction to sort by. Defaults to ASC + */ + direction: "ASC", + + constructor: function(config) { + 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.updateSortFunction(); + }, + + /** + * @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); + }; + }, + + /** + * @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); + } + + return v1 > v2 ? 1 : (v1 < v2 ? -1 : 0); + }, + + /** + * @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]; + }, + + // @TODO: Add docs for these three methods + setDirection: function(direction) { + var me = this; + me.direction = direction; + me.updateSortFunction(); + }, + + toggle: function() { + var me = this; + me.direction = Ext.String.toggle(me.direction, "ASC", "DESC"); + me.updateSortFunction(); + }, + + 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
+    }
+});
+ * 
+ *

+ * 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' + }, + + uses: [ + 'Ext.data.Connection', + 'Ext.Ajax' + ], + + statics: { + Renderer: { + Html: function(loader, response, active){ + loader.getTarget().update(response.responseText, active.scripts === true); + return true; + } + } + }, + + /* End Definitions */ + + /** + * @cfg {String} url The url to retrieve the content from. Defaults to null. + */ + url: null, + + /** + * @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, + + /** + * @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, + + /** + * @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, + + /** + * @cfg {Mixed} loadMask True or a string to show when the element is loading. + */ + loadMask: false, + + /** + * @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. + */ + + /** + * @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, + + constructor: function(config) { + var me = this, + autoLoad; + + 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', + + /** + * @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', + + /** + * @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' + ); + + // don't pass config because we have already applied it. + me.mixins.observable.constructor.call(me); + + if (me.autoLoad) { + autoLoad = me.autoLoad; + if (autoLoad === true) { + autoLoad = {}; + } + me.load(autoLoad); + } + }, + + /** + * 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; + }, + + /** + * Get the target of this loader. + * @return {Ext.Component} target The target, null if none exists. + */ + getTarget: function(){ + return this.target || null; + }, + + /** + * Aborts the active load request + */ + abort: function(){ + var active = this.active; + if (active !== undefined) { + Ext.Ajax.abort(active.request); + if (active.mask) { + this.removeMask(); + } + delete this.active; + } + }, + + /** + * Remove the mask on the target + * @private + */ + removeMask: function(){ + this.target.unmask(); + }, + + /** + * Add the mask on the target + * @private + * @param {Mixed} mask The mask configuration + */ + addMask: function(mask){ + this.target.mask(mask === true ? null : mask); + }, + + /** + * 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'); + } + + options = Ext.apply({}, options); + + 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; + + 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 + }); + + if (!options.url) { + Ext.Error.raise('You must specify the URL from which content should be loaded'); + } + + 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); + }, + + /** + * 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); + + + 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; + }, + + /** + * 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); + }, + + /** + * Clears any auto refresh. See {@link #startAutoRefresh}. + */ + stopAutoRefresh: function(){ + clearInterval(this.autoRefresh); + delete this.autoRefresh; + }, + + /** + * 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); + }, + + /** + * 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 + */ + +Ext.define('Ext.layout.Layout', { + + /* Begin Definitions */ + + /* End Definitions */ + + isLayout: true, + initialized: false, + + 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 = {}; + } + return Ext.createByAlias('layout.' + type, layout || {}); + } + } + }, + + constructor : function(config) { + this.id = Ext.id(null, this.type + '-'); + Ext.apply(this, config); + }, + + /** + * @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); + } + else { + me.layoutCancelled = true; + } + me.layoutBusy = false; + me.doOwnerCtLayouts(); + }, + + beforeLayout : function() { + this.renderItems(this.getLayoutItems(), this.getRenderTarget()); + return true; + }, + + /** + * @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; + + 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); + } + } + }, + + // @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; + }, + + /** + * @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; + } + }, + + /** + * @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; + }, + + /** + * @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; + }, + + // @private - Returns empty array + getLayoutItems : function() { + return []; + }, + + /** + * @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 */ + + 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); + } + }, + + /** + * Returns the owner component's resize element. + * @return {Ext.core.Element} + */ + getTarget : function() { + return this.owner.el; + }, + + /** + *

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 + ); + } + + me.autoSized = { + width: !Ext.isNumber(width), + height: !Ext.isNumber(height) + }; + + me.lastComponentSize = { + width: width, + height: height + }; + }, + + getTargetInfo : function() { + if (!this.targetInfo) { + var target = this.getTarget(), + body = this.owner.getTargetEl(); + + this.targetInfo = { + padding: { + top: target.getPadding('t'), + right: target.getPadding('r'), + bottom: target.getPadding('b'), + left: target.getPadding('l') + }, + border: { + top: target.getBorderWidth('t'), + right: target.getBorderWidth('r'), + bottom: target.getBorderWidth('b'), + left: target.getBorderWidth('l') + }, + bodyMargin: { + top: body.getMargin('t'), + right: body.getMargin('r'), + bottom: body.getMargin('b'), + left: body.getMargin('l') + } + }; + } + return this.targetInfo; + }, + + // 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; + + // 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(); + } + + // 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); + } +}); + +/** + * @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'); + }, + + + /** + * Configures the default state provider for your application + * @param {Provider} stateProvider The state provider to set + */ + setProvider : function(stateProvider){ + this.provider = stateProvider; + }, + + /** + * 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); + }, + + /** + * 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' + }, + + 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, + + autoGenIdRe: /^((\w+-)|(ext-comp-))\d{4,}$/i, + + constructor: function(config) { + var me = this; + + config = config || {}; + if (Ext.isDefined(config.stateful)) { + me.stateful = config.stateful; + } + if (Ext.isDefined(config.saveDelay)) { + me.saveDelay = config.saveDelay; + } + me.stateId = config.stateId; + + if (!me.stateEvents) { + me.stateEvents = []; + } + if (config.stateEvents) { + me.stateEvents.concat(config.stateEvents); + } + 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', + + /** + * @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]; + } + + var me = this, + i = 0, + len = events.length; + + for (; i < len; ++i) { + me.on(events[i], me.onStateChange, me); + } + }, + + /** + * This method is called when any of the {@link #stateEvents} are fired. + * @private + */ + onStateChange: function(){ + var me = this, + delay = me.saveDelay; + + if (delay > 0) { + if (!me.stateTask) { + me.stateTask = Ext.create('Ext.util.DelayedTask', me.saveState, me); + } + 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); + } + } + } + }, + + /** + * 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); + } + } + } + } + }, + + /** + * 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 + */ + +Ext.define('Ext.AbstractManager', { + + /* Begin Definitions */ + + requires: ['Ext.util.HashMap'], + + /* End Definitions */ + + typeName: 'type', + + constructor: function(config) { + Ext.apply(this, config || {}); + + /** + * Contains all of the items currently managed + * @property all + * @type Ext.util.MixedCollection + */ + this.all = Ext.create('Ext.util.HashMap'); + + this.types = {}; + }, + + /** + * 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; + }, + + /** + * 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; + }, + + /** + * 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"); + } + + 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); + } + }); + } + }, + + /** + * Executes the specified function once for each item in the collection. + * Returning false from the function will cease iteration. + * + * The paramaters passed to the function are: + *

    + *
  • key : String

    The key of the item

  • + *
  • value : Number

    The value of the item

  • + *
  • length : Number

    The total number of items in the collection

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

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

+ *

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

+ *

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

+ * @singleton + */ +Ext.define('Ext.PluginManager', { + extend: 'Ext.AbstractManager', + alternateClassName: 'Ext.PluginMgr', + singleton: true, + typeName: 'ptype', + + /** + * Creates a new Plugin from the specified config object using the + * config object's ptype to determine the class to instantiate. + * @param {Object} config A configuration object for the Plugin you wish to create. + * @param {Constructor} defaultType The constructor to provide the default Plugin type if + * the config object does not contain a ptype. (Optional if the config contains a ptype). + * @return {Ext.Component} The newly instantiated Plugin. + */ + //create: function(plugin, defaultType) { + // if (plugin instanceof this) { + // return plugin; + // } else { + // var type, config = {}; + // + // if (Ext.isString(plugin)) { + // type = plugin; + // } + // else { + // type = plugin[this.typeName] || defaultType; + // config = plugin; + // } + // + // return Ext.createByAlias('plugin.' + type, config); + // } + //}, + + create : function(config, defaultType){ + if (config.init) { + return config; + } else { + return Ext.createByAlias('plugin.' + (config.ptype || defaultType), config); + } + + // Prior system supported Singleton plugins. + //var PluginCls = this.types[config.ptype || defaultType]; + //if (PluginCls.init) { + // return PluginCls; + //} else { + // return new PluginCls(config); + //} + }, + + /** + * 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); + } + } + + return matches; + } +}, function() { + /** + * Shorthand for {@link Ext.PluginManager#registerType} + * @param {String} ptype The ptype mnemonic string by which the Plugin class + * may be looked up. + * @param {Constructor} cls The new Plugin class. + * @member Ext + * @method preg + */ + Ext.preg = function() { + return Ext.PluginManager.registerType.apply(Ext.PluginManager, arguments); + }; +}); + +/** + * @class Ext.ComponentManager + * @extends Ext.AbstractManager + *

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

+ *

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

+ *

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

+ *

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

+ * @singleton + */ +Ext.define('Ext.ComponentManager', { + extend: 'Ext.AbstractManager', + alternateClassName: 'Ext.ComponentMgr', + + singleton: true, + + typeName: 'xtype', + + /** + * Creates a new Component from the specified config object using the + * config object's xtype to determine the class to instantiate. + * @param {Object} config A configuration object for the Component you wish to create. + * @param {Constructor} defaultType The constructor to provide the default Component type if + * the config object does not contain a xtype. (Optional if the config contains a xtype). + * @return {Ext.Component} The newly instantiated Component. + */ + create: function(component, defaultType){ + if (component instanceof Ext.AbstractComponent) { + return component; + } + else if (Ext.isString(component)) { + return Ext.createByAlias('widget.' + component); + } + else { + 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 + */ + +Ext.define('Ext.XTemplate', { + + /* Begin Definitions */ + + extend: 'Ext.Template', + + 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 || {}); + } + }, + + + + argsRe: /]*>((?:(?=([^<]+))\2|<(?!tpl\b[^>]*>))*?)<\/tpl>/, + nameRe: /^]*?for="(.*?)"/, + ifRe: /^]*?if="(.*?)"/, + execRe: /^]*?exec="(.*?)"/, + constructor: function() { + this.callParent(arguments); + + var me = this, + html = me.html, + argsRe = me.argsRe, + nameRe = me.nameRe, + ifRe = me.ifRe, + execRe = me.execRe, + id = 0, + tpls = [], + VALUES = 'values', + PARENT = 'parent', + XINDEX = 'xindex', + XCOUNT = 'xcount', + RETURN = 'return ', + WITHVALUES = 'with(values){ ', + m, matchName, matchIf, matchExec, exp, fn, exec, name, i; + + html = ['', html, ''].join(''); + + while ((m = html.match(argsRe))) { + exp = null; + fn = null; + exec = null; + matchName = m[0].match(nameRe); + matchIf = m[0].match(ifRe); + matchExec = m[0].match(execRe); + + exp = matchIf ? matchIf[1] : null; + if (exp) { + fn = Ext.functionFactory(VALUES, PARENT, XINDEX, XCOUNT, WITHVALUES + 'try{' + RETURN + Ext.String.htmlDecode(exp) + ';}catch(e){return;}}'); + } + + exp = matchExec ? matchExec[1] : null; + if (exp) { + exec = Ext.functionFactory(VALUES, PARENT, XINDEX, XCOUNT, WITHVALUES + Ext.String.htmlDecode(exp) + ';}'); + } + + 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; + } + + for (i = tpls.length - 1; i >= 0; --i) { + me.compileTpl(tpls[i]); + } + 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); + }, + + 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; + + 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 : ""'; + } + + + else if (name == '#') { + v = 'xindex'; + } + else if (name.substr(0, 7) == "parent.") { + v = name; + } + + else if (name.indexOf('.') != -1) { + v = "values." + name; + } + + + 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 + "),'"; + } + + 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); + + tpl.compiled = function(values, parent, xindex, xcount) { + var vs, + length, + buffer, + i; + + 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 ''; + } + + 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(''); + } + + if (tpl.exec) { + tpl.exec.call(me, vs, parent, xindex, xcount); + } + return evaluatedFn.call(me, vs, parent, xindex, xcount); + }; + + return this; + }, + + + applyTemplate: function(values) { + return this.master.compiled.call(this, values, {}, 1, 1); + }, + + + 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; + + me.items = []; + me.map = {}; + me.keys = []; + me.length = 0; + + me.addEvents( + + 'clear', + + + 'add', + + + 'replace', + + + 'remove' + ); + + me.allowFunctions = allowFunctions === true; + + if (keyFn) { + me.getKey = keyFn; + } + + me.mixins.observable.constructor.call(me); + }, + + + allowFunctions : false, + + + 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; + }, + + + getKey : function(o){ + return o.id; + }, + + + replace : function(key, o){ + var me = this, + old, + index; + + 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; + }, + + + addAll : function(objs){ + var me = this, + i = 0, + args, + len, + key; + + if (arguments.length > 1 || Ext.isArray(objs)) { + args = arguments.length > 1 ? arguments : objs; + for (len = args.length; i < len; i++) { + me.add(args[i]); + } + } else { + for (key in objs) { + if (objs.hasOwnProperty(key)) { + if (me.allowFunctions || typeof objs[key] != 'function') { + me.add(key, objs[key]); + } + } + } + } + }, + + + each : function(fn, scope){ + var items = [].concat(this.items), + i = 0, + len = items.length, + item; + + for (; i < len; i++) { + item = items[i]; + if (fn.call(scope || item, item, i, len) === false) { + break; + } + } + }, + + + 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); + } + }, + + + 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; + }, + + 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); + }, + + + insert : function(index, key, obj){ + var me = this, + myKey = key, + myObj = obj; + + if (arguments.length == 2) { + myObj = myKey; + myKey = me.getKey(myObj); + } + if (me.containsKey(myKey)) { + me.suspendEvents(); + me.removeAtKey(myKey); + me.resumeEvents(); + } + if (index >= me.length) { + return me.add(myKey, myObj); + } + me.length++; + me.items.splice(index, 0, myObj); + if (typeof myKey != 'undefined' && myKey !== null) { + me.map[myKey] = myObj; + } + me.keys.splice(index, 0, myKey); + me.fireEvent('add', index, myObj, myKey); + return myObj; + }, + + + remove : function(o){ + return this.removeAt(this.indexOf(o)); + }, + + + removeAll : function(items){ + Ext.each(items || [], function(item) { + this.remove(item); + }, this); + + return this; + }, + + + removeAt : function(index){ + var me = this, + o, + key; + + 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; + }, + + + removeAtKey : function(key){ + return this.removeAt(this.indexOfKey(key)); + }, + + + getCount : function(){ + return this.length; + }, + + + indexOf : function(o){ + return Ext.Array.indexOf(this.items, o); + }, + + + indexOfKey : function(key){ + return Ext.Array.indexOf(this.keys, key); + }, + + + get : function(key) { + var me = this, + mk = me.map[key], + item = mk !== undefined ? mk : (typeof key == 'number') ? me.items[key] : undefined; + return typeof item != 'function' || me.allowFunctions ? item : null; + }, + + + getAt : function(index) { + return this.items[index]; + }, + + + getByKey : function(key) { + return this.map[key]; + }, + + + contains : function(o){ + return Ext.Array.contains(this.items, o); + }, + + + containsKey : function(key){ + return typeof this.map[key] != 'undefined'; + }, + + + clear : function(){ + var me = this; + + me.length = 0; + me.items = []; + me.keys = []; + me.map = {}; + me.fireEvent('clear'); + }, + + + first : function() { + return this.items[0]; + }, + + + last : function() { + return this.items[this.length - 1]; + }, + + + sum: function(property, root, start, end) { + var values = this.extractValues(property, root), + length = values.length, + sum = 0, + i; + + start = start || 0; + end = (end || end === 0) ? end : length - 1; + + for (i = start; i <= end; i++) { + sum += values[i]; + } + + return sum; + }, + + + 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); + } + } + + return unique; + }, + + + extractValues: function(property, root) { + var values = this.items; + + if (root) { + values = Ext.Array.pluck(values, root); + } + + return Ext.Array.pluck(values, property); + }, + + + getRange : function(start, end){ + var me = this, + items = me.items, + range = [], + i; + + if (items.length < 1) { + return range; + } + + 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]; + } + } + return range; + }, + + + filter : function(property, value, anyMatch, caseSensitive) { + var filters = [], + filterFn; + + + 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); + } + + + + filterFn = function(record) { + var isMatch = true, + length = filters.length, + i; + + for (i = 0; i < length; i++) { + var filter = filters[i], + fn = filter.filterFn, + scope = filter.scope; + + isMatch = isMatch && fn.call(scope, record); + } + + return isMatch; + }; + + return this.filterBy(filterFn); + }, + + + filterBy : function(fn, scope) { + var me = this, + newMC = new this.self(), + keys = me.keys, + items = me.items, + length = items.length, + i; + + newMC.getKey = me.getKey; + + for (i = 0; i < length; i++) { + if (fn.call(scope || me, items[i], keys[i])) { + newMC.add(keys[i], items[i]); + } + } + + return newMC; + }, + + + 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); + }, + + + findIndexBy : function(fn, scope, start){ + var me = this, + keys = me.keys, + items = me.items, + i = start || 0, + len = items.length; + + for (; i < len; i++) { + if (fn.call(scope || me, items[i], keys[i])) { + return i; + } + } + return -1; + }, + + + createValueMatcher : function(value, anyMatch, caseSensitive, exactMatch) { + if (!value.exec) { + var er = Ext.String.escapeRegex; + value = String(value); + + if (anyMatch === true) { + value = er(value); + } else { + value = '^' + er(value); + if (exactMatch === true) { + value += '$'; + } + } + value = new RegExp(value, caseSensitive ? '' : 'i'); + } + return value; + }, + + + clone : function() { + var me = this, + copy = new this.self(), + keys = me.keys, + items = me.items, + i = 0, + len = items.length; + + for(; i < len; i++){ + copy.add(keys[i], items[i]); + } + copy.getKey = me.getKey; + return copy; + } +}); + + +Ext.define("Ext.util.Sortable", { + + isSortable: true, + + + defaultSortDirection: "ASC", + + requires: [ + 'Ext.util.Sorter' + ], + + + sortRoot: null, + + + initSortable: function() { + var me = this, + sorters = me.sorters; + + + me.sorters = Ext.create('Ext.util.AbstractMixedCollection', false, function(item) { + return item.id || item.property; + }); + + if (sorters) { + me.sorters.addAll(me.decodeSorters(sorters)); + } + }, + + + sort: function(sorters, direction, where, doSort) { + var me = this, + sorter, sorterFn, + newSorters; + + if (Ext.isArray(sorters)) { + doSort = where; + where = direction; + newSorters = sorters; + } + else if (Ext.isObject(sorters)) { + doSort = where; + where = direction; + newSorters = [sorters]; + } + else if (Ext.isString(sorters)) { + sorter = me.sorters.get(sorters); + + if (!sorter) { + sorter = { + property : sorters, + direction: direction + }; + newSorters = [sorter]; + } + else if (direction === undefined) { + sorter.toggle(); + } + else { + sorter.setDirection(direction); + } + } + + if (newSorters && newSorters.length) { + newSorters = me.decodeSorters(newSorters); + if (Ext.isString(where)) { + if (where === 'prepend') { + sorters = me.sorters.clone().items; + + me.sorters.clear(); + me.sorters.addAll(newSorters); + me.sorters.addAll(sorters); + } + else { + me.sorters.addAll(newSorters); + } + } + else { + me.sorters.clear(); + me.sorters.addAll(newSorters); + } + + if (doSort !== false) { + me.onBeforeSort(newSorters); + } + } + + 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 result; + }; + + me.doSort(sorterFn); + } + } + + return sorters; + }, + + onBeforeSort: Ext.emptyFn, + + + decodeSorters: function(sorters) { + if (!Ext.isArray(sorters)) { + if (sorters === undefined) { + sorters = []; + } else { + sorters = [sorters]; + } + } + + var length = sorters.length, + Sorter = Ext.util.Sorter, + fields = this.model ? this.model.prototype.fields : null, + field, + config, i; + + for (i = 0; i < length; i++) { + config = sorters[i]; + + if (!(config instanceof Sorter)) { + if (Ext.isString(config)) { + config = { + property: config + }; + } + + Ext.applyIf(config, { + root : this.sortRoot, + direction: "ASC" + }); + + + if (config.fn) { + config.sorterFn = config.fn; + } + + + if (typeof config == 'function') { + config = { + sorterFn: config + }; + } + + + if (fields && !config.transform) { + field = fields.get(config.property); + config.transform = field ? field.sortType : undefined; + } + sorters[i] = Ext.create('Ext.util.Sorter', config); + } + } + + return sorters; + }, + + getSorters: function() { + return this.sorters.items; + }, + + + getSortState : function() { + return this.sortInfo; + } +}); + +Ext.define('Ext.util.MixedCollection', { + extend: 'Ext.util.AbstractMixedCollection', + mixins: { + sortable: 'Ext.util.Sortable' + }, + + constructor: function() { + var me = this; + me.callParent(arguments); + me.addEvents('sort'); + me.mixins.sortable.initSortable.call(me); + }, + + doSort: function(sorterFn) { + this.sortBy(sorterFn); + }, + + + _sort : function(property, dir, fn){ + var me = this, + i, len, + dsc = String(dir).toUpperCase() == 'DESC' ? -1 : 1, + + + c = [], + keys = me.keys, + items = me.items; + + + fn = fn || function(a, b) { + return a - b; + }; + + + for(i = 0, len = items.length; i < len; i++){ + c[c.length] = { + key : keys[i], + value: items[i], + index: i + }; + } + + + Ext.Array.sort(c, function(a, b){ + var v = fn(a[property], b[property]) * dsc; + if(v === 0){ + v = (a.index < b.index ? -1 : 1); + } + return v; + }); + + + for(i = 0, len = c.length; i < len; i++){ + items[i] = c[i].value; + keys[i] = c[i].key; + } + + me.fireEvent('sort', me); + }, + + + sortBy: function(sorterFn) { + var me = this, + items = me.items, + keys = me.keys, + length = items.length, + temp = [], + i; + + + for (i = 0; i < length; i++) { + temp[i] = { + key : keys[i], + value: items[i], + index: i + }; + } + + Ext.Array.sort(temp, function(a, b) { + var v = sorterFn(a.value, b.value); + if (v === 0) { + v = (a.index < b.index ? -1 : 1); + } + + return v; + }); + + + for (i = 0; i < length; i++) { + items[i] = temp[i].value; + keys[i] = temp[i].key; + } + + me.fireEvent('sort', me, items, keys); + }, + + + reorder: function(mapping) { + var me = this, + items = me.items, + index = 0, + length = items.length, + order = [], + remaining = [], + oldIndex; + + me.suspendEvents(); + + + for (oldIndex in mapping) { + order[mapping[oldIndex]] = items[oldIndex]; + } + + for (index = 0; index < length; index++) { + if (mapping[index] == undefined) { + remaining.push(items[index]); + } + } + + for (index = 0; index < length; index++) { + if (order[index] == undefined) { + order[index] = remaining.shift(); + } + } + + me.clear(); + me.addAll(order); + + me.resumeEvents(); + me.fireEvent('sort', me); + }, + + + sortByKey : function(dir, fn){ + this._sort('key', dir, fn || function(a, b){ + var v1 = String(a).toUpperCase(), v2 = String(b).toUpperCase(); + return v1 > v2 ? 1 : (v1 < v2 ? -1 : 0); + }); + } +}); + + +Ext.define('Ext.data.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.LoadMask', { + + + + mixins: { + observable: 'Ext.util.Observable' + }, + + requires: ['Ext.data.StoreManager'], + + + + + + + msg : 'Loading...', + + msgCls : Ext.baseCSSPrefix + 'mask-loading', + + + useMsg: true, + + + disabled: false, + + constructor : function(el, config) { + var me = this; + + if (el.isComponent) { + me.bindComponent(el); + } else { + me.el = Ext.get(el); + } + Ext.apply(me, config); + + me.addEvents('beforeshow', 'show', 'hide'); + if (me.store) { + me.bindStore(me.store, true); + } + me.mixins.observable.constructor.call(me, config); + }, + + bindComponent: function(comp) { + var me = this, + listeners = { + resize: me.onComponentResize, + scope: me + }; + + if (comp.el) { + me.onComponentRender(comp); + } else { + listeners.render = { + fn: me.onComponentRender, + scope: me, + single: true + }; + } + me.mon(comp, listeners); + }, + + + onComponentRender: function(comp) { + this.el = comp.getContentTarget(); + }, + + + onComponentResize: function(comp, w, h) { + this.el.isMasked(); + }, + + + 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(); + } + }, + + + disable : function() { + var me = this; + + me.disabled = true; + if (me.loading) { + me.onLoad(); + } + }, + + + enable : function() { + this.disabled = false; + }, + + + isDisabled : function() { + return this.disabled; + }, + + + onLoad : function() { + var me = this; + + me.loading = false; + me.el.unmask(); + me.fireEvent('hide', me, me.el, me.store); + }, + + + onBeforeLoad : function() { + var me = this; + + if (!me.disabled && !me.loading && me.fireEvent('beforeshow', me, me.el, me.store) !== false) { + if (me.useMsg) { + me.el.mask(me.msg, me.msgCls, false); + } else { + me.el.mask(); + } + + me.fireEvent('show', me, me.el, me.store); + me.loading = true; + } + }, + + + show: function() { + this.onBeforeLoad(); + }, + + + hide: function() { + this.onLoad(); + }, + + + destroy : function() { + this.hide(); + this.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 = []; + + if (!target.isContainer) { + Ext.Error.raise({ + target: target, + msg: 'Components can only be loaded into a container' + }); + } + + try { + items = Ext.decode(response.responseText); + } catch (e) { + success = false; + } + + if (success) { + if (active.removeAll) { + target.removeAll(); + } + target.add(items); + } + return success; + } + } + }, + + + + + target: null, + + + loadMask: false, + + + + + renderer: 'html', + + + setTarget: function(target){ + var me = this; + + if (Ext.isString(target)) { + target = Ext.getCmp(target); + } + + if (me.target && me.target != target) { + me.abort(); + } + me.target = target; + }, + + + removeMask: function(){ + this.target.setLoading(false); + }, + + + addMask: function(mask){ + this.target.setLoading(mask); + }, + + + + setOptions: function(active, options){ + active.removeAll = Ext.isDefined(options.removeAll) ? options.removeAll : this.removeAll; + }, + + + getRenderer: function(renderer){ + if (Ext.isFunction(renderer)) { + return renderer; + } + + var renderers = this.statics().Renderer; + switch (renderer) { + case 'component': + return renderers.Component; + case 'data': + return renderers.Data; + default: + return Ext.ElementLoader.Renderer.Html; + } + } +}); + + + +Ext.define('Ext.layout.component.Auto', { + + + + alias: 'layout.autocomponent', + + extend: 'Ext.layout.component.Component', + + + + type: 'autocomponent', + + onLayout : function(width, height) { + this.setTargetSize(width, height); + } +}); + + +Ext.define('Ext.AbstractComponent', { + + + + mixins: { + observable: 'Ext.util.Observable', + animate: 'Ext.util.Animate', + state: 'Ext.state.Stateful' + }, + + requires: [ + 'Ext.PluginManager', + 'Ext.ComponentManager', + 'Ext.core.Element', + 'Ext.core.DomHelper', + 'Ext.XTemplate', + 'Ext.ComponentQuery', + 'Ext.LoadMask', + 'Ext.ComponentLoader', + 'Ext.EventManager', + 'Ext.layout.Layout', + 'Ext.layout.component.Auto' + ], + + + + uses: [ + 'Ext.ZIndexManager' + ], + + statics: { + AUTO_ID: 1000 + }, + + + + isComponent: true, + + getAutoId: function() { + return ++Ext.AbstractComponent.AUTO_ID; + }, + + + + + + + + + + + renderTpl: null, + + + + + + + + + + + + + + + + + tplWriteMode: 'overwrite', + + + baseCls: Ext.baseCSSPrefix + 'component', + + + + + + + + + disabledCls: Ext.baseCSSPrefix + 'item-disabled', + + + ui: 'default', + + + uiCls: [], + + + + + + + + + + + + + + + hidden: false, + + + disabled: false, + + + + + draggable: false, + + + floating: false, + + + hideMode: 'display', + + + + + + + styleHtmlContent: false, + + + styleHtmlCls: Ext.baseCSSPrefix + 'html', + + + + + + + + + + allowDomMove: true, + + + autoShow: false, + + + autoRender: false, + + needsLayout: false, + + + + + rendered: false, + + weight: 0, + + trimRe: /^\s+|\s+$/g, + spacesRe: /\s+/, + + + + maskOnDisable: true, + + constructor : function(config) { + var me = this, + i, len; + + config = config || {}; + 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); + for (i = 0, len = me.plugins.length; i < len; i++) { + me.plugins[i] = me.constructPlugin(me.plugins[i]); + } + } + + me.initComponent(); + + + Ext.ComponentManager.register(me); + + + me.mixins.observable.constructor.call(me); + me.mixins.state.constructor.call(me, config); + + + if (me.plugins) { + me.plugins = [].concat(me.plugins); + for (i = 0, len = me.plugins.length; i < len; i++) { + me.plugins[i] = me.initPlugin(me.plugins[i]); + } + } + + me.loader = me.getLoader(); + + if (me.renderTo) { + me.render(me.renderTo); + } + + 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.'); + } + me.disabledCls = me.disabledClass; + delete me.disabledClass; + } + }, + + initComponent: Ext.emptyFn, + + show: Ext.emptyFn, + + animate: function(animObj) { + var me = this, + to; + + animObj = animObj || {}; + to = animObj.to || {}; + + 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; + + if (to.height && to.height > curHeight) { + h = to.height; + needsResize = true; + } + if (to.width && to.width > curWidth) { + w = to.width; + needsResize = true; + } + + + + + if (needsResize) { + var clearWidth = !Ext.isNumber(me.width), + clearHeight = !Ext.isNumber(me.height); + + me.componentLayout.childrenChanged = true; + me.setSize(w, h, me.ownerCt); + me.el.setSize(curWidth, curHeight); + if (clearWidth) { + delete me.width; + } + if (clearHeight) { + delete me.height; + } + } + } + return me.mixins.animate.animate.apply(me, arguments); + }, + + + findLayoutController: function() { + return this.findParentBy(function(c) { + + + return !c.ownerCt || (c.layout.layoutBusy && !c.ownerCt.layout.layoutBusy); + }); + }, + + onShow : function() { + + var needsLayout = this.needsLayout; + if (Ext.isObject(needsLayout)) { + this.doComponentLayout(needsLayout.width, needsLayout.height, needsLayout.isSetSize, needsLayout.ownerCt); + } + }, + + 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; + }, + + + + initPlugin : function(plugin) { + plugin.init(this); + + return plugin; + }, + + + doAutoRender: function() { + var me = this; + if (me.floating) { + me.render(document.body); + } else { + me.render(Ext.isBoolean(me.autoRender) ? Ext.getBody() : me.autoRender); + } + }, + + + render : function(container, position) { + var me = this; + + if (!me.rendered && me.fireEvent('beforerender', me) !== false) { + + + if (me.el) { + me.el = Ext.get(me.el); + } + + + if (me.floating) { + me.onFloatRender(); + } + + container = me.initContainer(container); + + me.onRender(container, position); + + + + me.el.setVisibilityMode(Ext.core.Element[me.hideMode.toUpperCase()]); + + if (me.overCls) { + me.el.hover(me.addOverCls, me.removeOverCls, me); + } + + me.fireEvent('render', me); + + me.initContent(); + + me.afterRender(container); + me.fireEvent('afterrender', me); + + me.initEvents(); + + if (me.hidden) { + + + + me.el.hide(); + } + + if (me.disabled) { + + me.disable(true); + } + } + return me; + }, + + + onRender : function(container, position) { + var me = this, + el = me.el, + cls = me.initCls(), + styles = me.initStyles(), + renderTpl, renderData, i; + + position = me.getInsertPosition(position); + + if (!el) { + if (position) { + el = Ext.core.DomHelper.insertBefore(position, me.getElConfig(), true); + } + else { + el = Ext.core.DomHelper.append(container, me.getElConfig(), true); + } + } + else if (me.allowDomMove !== false) { + if (position) { + container.dom.insertBefore(el.dom, position); + } else { + container.dom.appendChild(el.dom); + } + } + + 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' + }); + } + } + + el.addCls(cls); + el.setStyle(styles); + + + + + + + + + + + + + me.el = el; + + me.rendered = true; + me.addUIToElement(true); + + for (i = 0; i < me.uiCls.length; i++) { + me.addUIClsToElement(me.uiCls[i], true); + } + me.rendered = false; + me.initFrame(); + + renderTpl = me.initRenderTpl(); + if (renderTpl) { + renderData = me.initRenderData(); + renderTpl.append(me.getTargetEl(), renderData); + } + + me.applyRenderSelectors(); + + me.rendered = true; + + me.setUI(me.ui); + }, + + + afterRender : function() { + var me = this, + pos, + xy; + + me.getComponentLayout(); + + + if (!me.ownerCt || (me.height || me.width)) { + me.setSize(me.width, me.height); + } + + + + 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 (Ext.isDefined(me.x) || Ext.isDefined(me.y)) { + me.setPosition(me.x, me.y); + } + + if (me.styleHtmlContent) { + me.getTargetEl().addCls(me.styleHtmlCls); + } + }, + + frameCls: Ext.baseCSSPrefix + 'frame', + + frameTpl: [ + '', + '
{parent.baseCls}-{parent.ui}-{.}-tl" style="background-position: {tl}; padding-left: {frameWidth}px" role="presentation">', + '
{parent.baseCls}-{parent.ui}-{.}-tr" style="background-position: {tr}; padding-right: {frameWidth}px" role="presentation">', + '
{parent.baseCls}-{parent.ui}-{.}-tc" style="background-position: {tc}; height: {frameWidth}px" role="presentation">
', + '
', + '
', + '
', + '
{parent.baseCls}-{parent.ui}-{.}-ml" style="background-position: {ml}; padding-left: {frameWidth}px" role="presentation">', + '
{parent.baseCls}-{parent.ui}-{.}-mr" style="background-position: {mr}; padding-right: {frameWidth}px" role="presentation">', + '
{parent.baseCls}-{parent.ui}-{.}-mc" role="presentation">
', + '
', + '
', + '', + '
{parent.baseCls}-{parent.ui}-{.}-bl" style="background-position: {bl}; padding-left: {frameWidth}px" role="presentation">', + '
{parent.baseCls}-{parent.ui}-{.}-br" style="background-position: {br}; padding-right: {frameWidth}px" role="presentation">', + '
{parent.baseCls}-{parent.ui}-{.}-bc" style="background-position: {bc}; height: {frameWidth}px" role="presentation">
', + '
', + '
', + '
' + ], + + 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">
' + ], + + + initFrame : function() { + if (Ext.supports.CSS3BorderRadius) { + return false; + } + + 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))); + + + me.frameBody = me.el.down('.' + me.frameCls + '-mc'); + + + Ext.apply(me.renderSelectors, { + frameTL: '.' + me.baseCls + '-tl', + frameTC: '.' + me.baseCls + '-tc', + frameTR: '.' + me.baseCls + '-tr', + frameML: '.' + me.baseCls + '-ml', + frameMC: '.' + me.baseCls + '-mc', + frameMR: '.' + me.baseCls + '-mr', + frameBL: '.' + me.baseCls + '-bl', + frameBC: '.' + me.baseCls + '-bc', + frameBR: '.' + me.baseCls + '-br' + }); + } + }, + + updateFrame: function() { + if (Ext.supports.CSS3BorderRadius) { + return false; + } + + var me = this, + wasTable = this.frameSize && this.frameSize.table, + oldFrameTL = this.frameTL, + oldFrameBL = this.frameBL, + oldFrameML = this.frameML, + oldFrameMC = this.frameMC, + newMCClassName; + + this.initFrame(); + + if (oldFrameMC) { + if (me.frame) { + + delete me.frameTL; + delete me.frameTC; + delete me.frameTR; + delete me.frameML; + delete me.frameMC; + delete me.frameMR; + delete me.frameBL; + delete me.frameBC; + delete me.frameBR; + this.applyRenderSelectors(); + + + newMCClassName = this.frameMC.dom.className; + + + oldFrameMC.insertAfter(this.frameMC); + this.frameMC.remove(); + + + this.frameBody = this.frameMC = oldFrameMC; + + + oldFrameMC.dom.className = newMCClassName; + + + if (wasTable) { + me.el.query('> table')[1].remove(); + } + else { + if (oldFrameTL) { + oldFrameTL.remove(); + } + if (oldFrameBL) { + oldFrameBL.remove(); + } + oldFrameML.remove(); + } + } + else { + + + } + } + else if (me.frame) { + this.applyRenderSelectors(); + } + }, + + getFrameInfo: function() { + if (Ext.supports.CSS3BorderRadius) { + return false; + } + + var me = this, + left = me.el.getStyle('background-position-x'), + top = me.el.getStyle('background-position-y'), + info, frameInfo = false, max; + + + + if (!left && !top) { + info = me.el.getStyle('background-position').split(' '); + left = info[0]; + top = info[1]; + } + + + + + if (parseInt(left, 10) >= 1000000 && parseInt(top, 10) >= 1000000) { + max = Math.max; + + frameInfo = { + + table: left.substr(0, 3) == '110', + + + vertical: top.substr(0, 3) == '110', + + + top: max(left.substr(3, 2), left.substr(5, 2)), + right: max(left.substr(5, 2), top.substr(3, 2)), + bottom: max(top.substr(3, 2), top.substr(5, 2)), + left: max(top.substr(5, 2), left.substr(3, 2)) + }; + + frameInfo.width = max(frameInfo.top, frameInfo.right, frameInfo.bottom, frameInfo.left); + + + 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."); + } + + me.frame = me.frame || !!frameInfo; + me.frameSize = frameInfo || false; + + return frameInfo; + }, + + getFramePositions: function(frameInfo) { + var me = this, + frameWidth = frameInfo.width, + dock = me.dock, + positions, tc, bc, ml, mr; + + if (frameInfo.vertical) { + tc = '0 -' + (frameWidth * 0) + 'px'; + bc = '0 -' + (frameWidth * 1) + 'px'; + + if (dock && dock == "right") { + tc = 'right -' + (frameWidth * 0) + 'px'; + bc = 'right -' + (frameWidth * 1) + 'px'; + } + + positions = { + tl: '0 -' + (frameWidth * 0) + 'px', + tr: '0 -' + (frameWidth * 1) + 'px', + bl: '0 -' + (frameWidth * 2) + 'px', + br: '0 -' + (frameWidth * 3) + 'px', + + ml: '-' + (frameWidth * 1) + 'px 0', + mr: 'right 0', + + tc: tc, + bc: bc + }; + } else { + ml = '-' + (frameWidth * 0) + 'px 0'; + mr = 'right 0'; + + if (dock && dock == "bottom") { + ml = 'left bottom'; + mr = 'right bottom'; + } + + positions = { + tl: '0 -' + (frameWidth * 2) + 'px', + tr: 'right -' + (frameWidth * 3) + 'px', + bl: '0 -' + (frameWidth * 4) + 'px', + br: 'right -' + (frameWidth * 5) + 'px', + + ml: ml, + mr: mr, + + tc: '0 -' + (frameWidth * 0) + 'px', + bc: '0 -' + (frameWidth * 1) + 'px' + }; + } + + return positions; + }, + + + 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); + } else { + me.componentCls = me.baseCls; + } + if (me.cls) { + cls.push(me.cls); + delete me.cls; + } + + return cls.concat(me.additionalCls); + }, + + + setUI: function(ui) { + var me = this, + oldUICls = Ext.Array.clone(me.uiCls), + newUICls = [], + cls, + i; + + + for (i = 0; i < oldUICls.length; i++) { + cls = oldUICls[i]; + + me.removeClsWithUI(cls); + newUICls.push(cls); + } + + + me.removeUIFromElement(); + + + me.ui = ui; + + + me.addUIToElement(); + + + for (i = 0; i < newUICls.length; i++) { + cls = newUICls[i]; + + me.addClsWithUI(cls); + } + }, + + + addClsWithUI: function(cls) { + var me = this, + i; + + if (!Ext.isArray(cls)) { + cls = [cls]; + } + + for (i = 0; i < cls.length; i++) { + if (cls[i] && !me.hasUICls(cls[i])) { + me.uiCls = Ext.Array.clone(me.uiCls); + me.uiCls.push(cls[i]); + me.addUIClsToElement(cls[i]); + } + } + }, + + + removeClsWithUI: function(cls) { + var me = this, + i; + + if (!Ext.isArray(cls)) { + cls = [cls]; + } + + for (i = 0; i < cls.length; i++) { + if (cls[i] && me.hasUICls(cls[i])) { + me.uiCls = Ext.Array.remove(me.uiCls, cls[i]); + me.removeUIClsFromElement(cls[i]); + } + } + }, + + + hasUICls: function(cls) { + var me = this, + uiCls = me.uiCls || []; + + return Ext.Array.contains(uiCls, cls); + }, + + + addUIClsToElement: function(cls, force) { + var me = this; + + me.addCls(Ext.baseCSSPrefix + cls); + me.addCls(me.baseCls + '-' + cls); + me.addCls(me.baseCls + '-' + me.ui + '-' + cls); + + if (!force && me.rendered && me.frame && !Ext.supports.CSS3BorderRadius) { + + var els = ['tl', 'tc', 'tr', 'ml', 'mc', 'mr', 'bl', 'bc', 'br'], + i, el; + + + for (i = 0; i < els.length; i++) { + el = me['frame' + els[i].toUpperCase()]; + + if (el && el.dom) { + el.addCls(me.baseCls + '-' + me.ui + '-' + els[i]); + el.addCls(me.baseCls + '-' + me.ui + '-' + cls + '-' + els[i]); + } + } + } + }, + + + removeUIClsFromElement: function(cls, force) { + var me = this; + + me.removeCls(Ext.baseCSSPrefix + cls); + me.removeCls(me.baseCls + '-' + cls); + me.removeCls(me.baseCls + '-' + me.ui + '-' + cls); + + if (!force &&me.rendered && me.frame && !Ext.supports.CSS3BorderRadius) { + + var els = ['tl', 'tc', 'tr', 'ml', 'mc', 'mr', 'bl', 'bc', 'br'], + i, el; + + + for (i = 0; i < els.length; i++) { + el = me['frame' + els[i].toUpperCase()]; + if (el && el.dom) { + el.removeCls(me.baseCls + '-' + me.ui + '-' + cls + '-' + els[i]); + } + } + } + }, + + + addUIToElement: function(force) { + var me = this; + + me.addCls(me.baseCls + '-' + me.ui); + + if (me.rendered && me.frame && !Ext.supports.CSS3BorderRadius) { + + var els = ['tl', 'tc', 'tr', 'ml', 'mc', 'mr', 'bl', 'bc', 'br'], + i, el; + + + for (i = 0; i < els.length; i++) { + el = me['frame' + els[i].toUpperCase()]; + + if (el) { + el.addCls(me.baseCls + '-' + me.ui + '-' + els[i]); + } + } + } + }, + + + 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]); + } + } + } + }, + + getElConfig : function() { + var result = this.autoEl || {tag: 'div'}; + result.id = this.id; + return result; + }, + + + getInsertPosition: function(position) { + + if (position !== undefined) { + if (Ext.isNumber(position)) { + position = this.container.dom.childNodes[position]; + } + else { + position = Ext.getDom(position); + } + } + + return position; + }, + + + initContainer: function(container) { + var me = this; + + + + + if (!container && me.el) { + container = me.el.dom.parentNode; + me.allowDomMove = false; + } + + me.container = Ext.get(container); + + if (me.ctCls) { + me.container.addCls(me.ctCls); + } + + return me.container; + }, + + + initRenderData: function() { + var me = this; + + return Ext.applyIf(me.renderData, { + ui: me.ui, + uiCls: me.uiCls, + baseCls: me.baseCls, + componentCls: me.componentCls, + frame: me.frame + }); + }, + + + getTpl: function(name) { + var prototype = this.self.prototype, + ownerPrototype; + + if (this.hasOwnProperty(name)) { + if (!(this[name] instanceof Ext.XTemplate)) { + this[name] = Ext.ClassManager.dynInstantiate('Ext.XTemplate', this[name]); + } + + return this[name]; + } + + if (!(prototype[name] instanceof Ext.XTemplate)) { + ownerPrototype = prototype; + + do { + if (ownerPrototype.hasOwnProperty(name)) { + ownerPrototype[name] = Ext.ClassManager.dynInstantiate('Ext.XTemplate', ownerPrototype[name]); + break; + } + + ownerPrototype = ownerPrototype.superclass; + } while (ownerPrototype); + } + + return prototype[name]; + }, + + + initRenderTpl: function() { + return this.getTpl('renderTpl'); + }, + + + initStyles: function() { + var style = {}, + me = this, + Element = Ext.core.Element; + + if (Ext.isString(me.style)) { + style = Element.parseStyles(me.style); + } else { + style = Ext.apply({}, me.style); + } + + + + if (me.padding !== undefined) { + style.padding = Element.unitizeBox((me.padding === true) ? 5 : me.padding); + } + + if (me.margin !== undefined) { + style.margin = Element.unitizeBox((me.margin === true) ? 5 : me.margin); + } + + delete me.style; + return style; + }, + + + initContent: function() { + var me = this, + target = me.getTargetEl(), + contentEl, + pre; + + if (me.html) { + target.update(Ext.core.DomHelper.markup(me.html)); + delete me.html; + } + + 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); + } + + if (me.data) { + me.tpl[me.tplWriteMode](target, me.data); + delete me.data; + } + } + }, + + + 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); + } + } + } + } + }, + + + 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)); + } + } + }, + + + is: function(selector) { + return Ext.ComponentQuery.is(this, selector); + }, + + + up: function(selector) { + var result = this.ownerCt; + if (selector) { + for (; result; result = result.ownerCt) { + if (Ext.ComponentQuery.is(result, selector)) { + return result; + } + } + } + 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); + } + } + } + } + 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; + } + } + } else { + if (idx) { + return it.getAt(--idx); + } + } + } + } + return null; + }, + + + previousNode: function(selector, includeSelf) { + var node = this, + result, + it, len, i; + + + if (includeSelf && node.is(selector)) { + return node; + } + + result = this.prev(selector); + if (result) { + return result; + } + + 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); + } + }, + + + 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; + } + + 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); + } + }, + + + 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; + }, + + + update : function(htmlOrData, loadScripts, cb) { + var me = this; + + if (me.tpl && !Ext.isString(htmlOrData)) { + me.data = htmlOrData; + if (me.rendered) { + me.tpl[me.tplWriteMode](me.getTargetEl(), htmlOrData || {}); + } + } else { + me.html = Ext.isObject(htmlOrData) ? Ext.core.DomHelper.markup(htmlOrData) : htmlOrData; + if (me.rendered) { + me.getTargetEl().update(me.html, loadScripts, cb); + } + } + + if (me.rendered) { + me.doComponentLayout(); + } + }, + + + setVisible : function(visible) { + return this[visible ? 'show': 'hide'](); + }, + + + isVisible: function(deep) { + var me = this, + child = me, + visible = !me.hidden, + ancestor = me.ownerCt; + + + me.hiddenAncestor = false; + if (me.destroyed) { + return false; + } + + 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; + }, + + + 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); + } + + 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; + + if (silent !== true) { + me.fireEvent('disable', me); + } + + return me; + }, + + + onEnable: function() { + if (this.maskOnDisable) { + this.el.unmask(); + } + }, + + + onDisable : function() { + if (this.maskOnDisable) { + this.el.mask(); + } + }, + + + 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; + }, + + + addClass : function() { + return this.addCls.apply(this, arguments); + }, + + + removeCls : function(className) { + var me = this; + + if (!className) { + return me; + } + if (!Ext.isArray(className)){ + className = className.replace(me.trimRe, '').split(me.spacesRe); + } + if (me.rendered) { + me.el.removeCls(className); + } + else if (me.additionalCls.length) { + Ext.each(className, function(cls) { + Ext.Array.remove(me.additionalCls, cls); + }); + } + return me; + }, + + removeClass : function() { + if (Ext.isDefined(Ext.global.console)) { + Ext.global.console.warn('Ext.Component: removeClass has been deprecated. Please use removeCls.'); + } + return this.removeCls.apply(this, arguments); + }, + + addOverCls: function() { + var me = this; + if (!me.disabled) { + me.el.addCls(me.overCls); + } + }, + + removeOverCls: function() { + this.el.removeCls(this.overCls); + }, + + addListener : function(element, listeners, scope, options) { + var me = this, + fn, + option; + + if (Ext.isString(element) && (Ext.isObject(listeners) || options && options.element)) { + if (options.element) { + fn = listeners; + + listeners = {}; + listeners[element] = fn; + element = options.element; + if (scope) { + listeners.scope = scope; + } + + for (option in options) { + if (options.hasOwnProperty(option)) { + if (me.eventOptionsRe.test(option)) { + listeners[option] = options[option]; + } + } + } + } + + + + if (me[element] && me[element].on) { + me.mon(me[element], listeners); + } else { + me.afterRenderEvents = me.afterRenderEvents || {}; + me.afterRenderEvents[element] = listeners; + } + } + + return me.mixins.observable.addListener.apply(me, arguments); + }, + + + + + getBubbleTarget : function() { + return this.ownerCt; + }, + + + isFloating : function() { + return this.floating; + }, + + + isDraggable : function() { + return !!this.draggable; + }, + + + isDroppable : function() { + return !!this.droppable; + }, + + + onAdded : function(container, pos) { + this.ownerCt = container; + this.fireEvent('added', this, container, pos); + }, + + + onRemoved : function() { + var me = this; + + me.fireEvent('removed', me, me.ownerCt); + delete me.ownerCt; + }, + + + beforeDestroy : Ext.emptyFn, + + + onResize : Ext.emptyFn, + + + setSize : function(width, height) { + var me = this, + layoutCollection; + + + if (Ext.isObject(width)) { + height = width.height; + width = width.width; + } + + + if (Ext.isNumber(width)) { + width = Ext.Number.constrain(width, me.minWidth, me.maxWidth); + } + if (Ext.isNumber(height)) { + height = Ext.Number.constrain(height, me.minHeight, me.maxHeight); + } + + if (!me.rendered || !me.isVisible()) { + + if (me.hiddenAncestor) { + layoutCollection = me.hiddenAncestor.layoutOnShow; + layoutCollection.remove(me); + layoutCollection.add(me); + } + me.needsLayout = { + width: width, + height: height, + isSetSize: true + }; + if (!me.rendered) { + me.width = (width !== undefined) ? width : me.width; + me.height = (height !== undefined) ? height : me.height; + } + return me; + } + me.doComponentLayout(width, height, true); + + return me; + }, + + setCalculatedSize : function(width, height, ownerCt) { + var me = this, + layoutCollection; + + + if (Ext.isObject(width)) { + ownerCt = width.ownerCt; + height = width.height; + width = width.width; + } + + + 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: 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; + } + + componentLayout.layout(width, height, isSetSize, ownerCt); + } + return me; + }, + + + setComponentLayout : function(layout) { + var currentLayout = this.componentLayout; + if (currentLayout && currentLayout.isLayout && currentLayout != layout) { + currentLayout.setOwner(null); + } + this.componentLayout = layout; + layout.setOwner(this); + }, + + getComponentLayout : function() { + var me = this; + + if (!me.componentLayout || !me.componentLayout.isLayout) { + me.setComponentLayout(Ext.layout.Layout.create(me.componentLayout, 'autocomponent')); + } + return me.componentLayout; + }, + + + afterComponentLayout: function(width, height, isSetSize, layoutOwner) { + this.fireEvent('resize', this, width, height); + }, + + + beforeComponentLayout: function(width, height, isSetSize, layoutOwner) { + return true; + }, + + + setPosition : function(x, y) { + var me = this; + + 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(); + }, + + + 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; + + 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; + + if (me.rendered) { + if (load !== false && !me.collapsed) { + if (Ext.isObject(load)) { + config = load; + } + else if (Ext.isString(load)) { + config = {msg: load}; + } + else { + config = {}; + } + me.loadMask = me.loadMask || Ext.create('Ext.LoadMask', targetEl ? me.getTargetEl() : me.el, config); + me.loadMask.show(); + } else if (me.loadMask) { + Ext.destroy(me.loadMask); + me.loadMask = null; + } + } + + return me.loadMask; + }, + + + 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); + }, + + + destroy : function() { + 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; + } + } + }, + + + 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) { + if (!config.cmp && Ext.global.console) { + Ext.global.console.warn("Attempted to attach a plugin "); + } + 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; + } +}); + + +Ext.define('Ext.data.Connection', { + mixins: { + observable: 'Ext.util.Observable' + }, + + statics: { + requestId: 0 + }, + + url: null, + async: true, + method: null, + username: '', + password: '', + + + disableCaching: true, + + + disableCachingParam: '_dc', + + + timeout : 30000, + + + + useDefaultHeader : true, + defaultPostHeader : 'application/x-www-form-urlencoded; charset=UTF-8', + useDefaultXhrHeader : true, + defaultXhrHeader : 'XMLHttpRequest', + + constructor : function(config) { + config = config || {}; + Ext.apply(this, config); + + this.addEvents( + + 'beforerequest', + + 'requestcomplete', + + 'requestexception' + ); + this.requests = {}; + this.mixins.observable.constructor.call(this); + }, + + + 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; + + 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; + } + + + if (options.autoAbort === true || me.autoAbort) { + me.abort(); + } + + + xhr = this.getXhrInstance(); + + async = options.async !== false ? (options.async || me.async) : false; + + + 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); + + + request = { + id: ++Ext.data.Connection.requestId, + xhr: xhr, + headers: headers, + options: options, + async: async, + timeout: setTimeout(function() { + request.timedout = true; + me.abort(request); + }, options.timeout || me.timeout) + }; + me.requests[request.id] = request; + + + if (async) { + xhr.onreadystatechange = Ext.Function.bind(me.onStateChange, me, [request]); + } + + + xhr.send(requestOptions.data); + if (!async) { + return this.onComplete(request); + } + 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); + + + 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 (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); + }); + } + + 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, + + response = { + responseText: '', + responseXML: null + }, doc, firstChild; + + 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) { + } + + 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); + }, + + + isFormUpload: function(options){ + var form = this.getForm(options); + if (form) { + return (options.isUpload || (/multipart\/form-data/i).test(form.getAttribute('enctype'))); + } + return false; + }, + + + getForm: function(options){ + return Ext.getDom(options.form) || null; + }, + + + setOptions: function(options, scope){ + var me = this, + params = options.params || {}, + extraParams = me.extraParams, + urlParams = options.urlParams, + url = options.url || me.url, + jsonData = options.jsonData, + method, + disableCache, + data; + + + + if (Ext.isFunction(params)) { + params = params.call(scope, options); + } + + + if (Ext.isFunction(url)) { + url = url.call(scope, options); + } + + 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); + } + + + if (Ext.isObject(params)) { + params = Ext.Object.toQueryString(params); + } + + if (Ext.isObject(extraParams)) { + extraParams = Ext.Object.toQueryString(extraParams); + } + + params = params + ((extraParams) ? ((params) ? '&' : '') + extraParams : ''); + + urlParams = Ext.isObject(urlParams) ? Ext.Object.toQueryString(urlParams) : urlParams; + + params = this.setupParams(options, params); + + + method = (options.method || me.method || ((params || data) ? 'POST' : 'GET')).toUpperCase(); + this.setupMethod(options, method); + + + disableCache = options.disableCaching !== false ? (options.disableCaching || me.disableCaching) : false; + + if (method === 'GET' && disableCache) { + url = Ext.urlAppend(url, (options.disableCachingParam || me.disableCachingParam) + '=' + (new Date().getTime())); + } + + + if ((method == 'GET' || data) && params) { + url = Ext.urlAppend(url, params); + params = null; + } + + + if (urlParams) { + url = Ext.urlAppend(url, urlParams); + } + + return { + url: url, + method: method, + data: data || params || null + }; + }, + + + setupUrl: function(options, url){ + var form = this.getForm(options); + if (form) { + url = url || form.action; + } + return url; + }, + + + + setupParams: function(options, params) { + var form = this.getForm(options), + serializedForm; + if (form && !this.isFormUpload(options)) { + serializedForm = Ext.core.Element.serializeForm(form); + params = params ? (params + '&' + serializedForm) : serializedForm; + } + return params; + }, + + + setupMethod: function(options, method){ + if (this.isFormUpload(options)) { + return 'POST'; + } + 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; + + if (!headers['Content-Type'] && (data || params)) { + if (data) { + if (options.rawData) { + contentType = 'text/plain'; + } else { + if (xmlData && Ext.isDefined(xmlData)) { + contentType = 'text/xml'; + } else if (jsonData && Ext.isDefined(jsonData)) { + contentType = 'application/json'; + } + } + } + headers['Content-Type'] = contentType; + } + + if (me.useDefaultXhrHeader && !headers['X-Requested-With']) { + headers['X-Requested-With'] = me.defaultXhrHeader; + } + + try{ + for (key in headers) { + if (headers.hasOwnProperty(key)) { + header = headers[key]; + xhr.setRequestHeader(key, header); + } + + } + } catch(e) { + me.fireEvent('exception', key, header); + } + 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){} + } + return xhr; + })(), + + + isLoading : function(request) { + if (!(request && request.xhr)) { + return false; + } + + var state = request.xhr.readyState; + return !(state === 0 || state == 4); + }, + + + abort : function(request) { + var me = this, + requests = me.requests, + id; + + if (request && me.isLoading(request)) { + + request.xhr.onreadystatechange = null; + request.xhr.abort(); + me.clearTimeout(request); + if (!request.timedout) { + request.aborted = true; + } + me.onComplete(request); + me.cleanup(request); + } else if (!request) { + for(id in requests) { + if (requests.hasOwnProperty(id)) { + me.abort(requests[id]); + } + } + } + }, + + + onStateChange : function(request) { + if (request.xhr.readyState == 4) { + this.clearTimeout(request); + this.onComplete(request); + this.cleanup(request); + } + }, + + + clearTimeout: function(request){ + clearTimeout(request.timeout); + delete request.timeout; + }, + + + cleanup: function(request){ + request.xhr = null; + delete request.xhr; + }, + + + onComplete : function(request) { + var me = this, + options = request.options, + result = me.parseStatus(request.xhr.status), + success = result.success, + response; + + if (success) { + response = me.createResponse(request); + me.fireEvent('requestcomplete', me, response, options); + Ext.callback(options.success, options.scope, [response, options]); + } else { + if (result.isException || request.aborted || request.timedout) { + response = me.createException(request); + } else { + response = me.createResponse(request); + } + me.fireEvent('requestexception', me, response, options); + Ext.callback(options.failure, options.scope, [response, options]); + } + Ext.callback(options.callback, options.scope, [options, success, response]); + delete me.requests[request.id]; + return response; + }, + + + 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 + }; + }, + + + 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.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: + Ext.Error.raise('Unknown Association type: "' + association.type + '"'); + } + } + 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; + + if (ownerModel === undefined) { + Ext.Error.raise("The configured ownerModel was not valid (you tried " + ownerName + ")"); + } + if (associatedModel === undefined) { + Ext.Error.raise("The configured associatedModel was not valid (you tried " + associatedName + ")"); + } + + this.ownerModel = ownerModel; + this.associatedModel = associatedModel; + + + + + + Ext.applyIf(this, { + ownerName : ownerName, + associatedName: associatedName + }); + }, + + + getReader: function(){ + var me = this, + reader = me.reader, + model = me.associatedModel; + + if (reader) { + if (Ext.isString(reader)) { + reader = { + type: reader + }; + } + if (reader.isReader) { + reader.setModel(model); + } else { + Ext.applyIf(reader, { + model: model, + type : me.defaultReaderType + }); + } + me.reader = Ext.createByAlias('reader.' + reader.type, reader); + } + return me.reader || null; + } +}); + + +Ext.define('Ext.ModelManager', { + extend: 'Ext.AbstractManager', + alternateClassName: 'Ext.ModelMgr', + requires: ['Ext.data.Association'], + + singleton: true, + + typeName: 'mtype', + + + associationStack: [], + + + registerType: function(name, config) { + var proto = config.prototype, + model; + if (proto && proto.isModel) { + + model = config; + } else { + + if (!config.extend) { + config.extend = 'Ext.data.Model'; + } + model = Ext.define(name, config); + } + this.types[name] = model; + return model; + }, + + + onModelDefined: function(model) { + var stack = this.associationStack, + length = stack.length, + create = [], + association, i, created; + + for (i = 0; i < length; i++) { + association = stack[i]; + + if (association.associatedModel == model.modelName) { + create.push(association); + } + } + + 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() { + if (Ext.isDefined(Ext.global.console)) { + Ext.global.console.warn('Ext.regModel has been deprecated. Models can now be created by extending Ext.data.Model: Ext.define("MyModel", {extend: "Ext.data.Model", fields: []});.'); + } + return this.ModelManager.registerType.apply(this.ModelManager, arguments); + }; +}); + + +Ext.define('Ext.app.Controller', { + + + mixins: { + observable: 'Ext.util.Observable' + }, + + onClassExtended: function(cls, data) { + var className = Ext.getClassName(cls), + match = className.match(/^(.*)\.controller\./); + + if (match !== null) { + var namespace = Ext.Loader.getPrefix(className) || match[1], + onBeforeClassCreated = data.onBeforeClassCreated, + requires = [], + modules = ['model', 'view', 'store'], + prefix; + + data.onBeforeClassCreated = function(cls, data) { + var i, ln, module, + items, j, subLn, item; + + for (i = 0,ln = modules.length; i < ln; i++) { + module = modules[i]; + + items = Ext.Array.from(data[module + 's']); + + for (j = 0,subLn = items.length; j < subLn; j++) { + item = items[j]; + + prefix = Ext.Loader.getPrefix(item); + + if (prefix === '' || prefix === item) { + requires.push(namespace + '.' + module + '.' + item); + } + else { + requires.push(item); + } + } + } + + Ext.require(requires, Ext.Function.pass(onBeforeClassCreated, arguments, this)); + }; + } + }, + + constructor: function(config) { + this.mixins.observable.constructor.call(this, config); + + Ext.apply(this, config || {}); + + this.createGetters('model', this.models); + this.createGetters('store', this.stores); + this.createGetters('view', this.views); + + if (this.refs) { + this.ref(this.refs); + } + }, + + + init: function(application) {}, + + onLaunch: function(application) {}, + + createGetters: function(type, refs) { + type = Ext.String.capitalize(type); + Ext.Array.each(refs, function(ref) { + var fn = 'get', + parts = ref.split('.'); + + + Ext.Array.each(parts, function(part) { + fn += Ext.String.capitalize(part); + }); + fn += type; + + if (!this[fn]) { + this[fn] = Ext.Function.pass(this['get' + type], [ref], this); + } + + this[fn](ref); + }, + this); + }, + + ref: function(refs) { + var me = this; + refs = Ext.Array.from(refs); + Ext.Array.each(refs, function(info) { + var ref = info.ref, + fn = 'get' + Ext.String.capitalize(ref); + if (!me[fn]) { + me[fn] = Ext.Function.pass(me.getRef, [ref, info], me); + } + }); + }, + + getRef: function(ref, info, config) { + this.refCache = this.refCache || {}; + info = info || {}; + config = config || {}; + + Ext.apply(info, config); + + if (info.forceCreate) { + return Ext.ComponentManager.create(info, 'component'); + } + + var me = this, + selector = info.selector, + cached = me.refCache[ref]; + + if (!cached) { + me.refCache[ref] = cached = Ext.ComponentQuery.query(info.selector)[0]; + if (!cached && info.autoCreate) { + me.refCache[ref] = cached = Ext.ComponentManager.create(info, 'component'); + } + if (cached) { + cached.on('beforedestroy', function() { + me.refCache[ref] = null; + }); + } + } + + return cached; + }, + + control: function(selectors, listeners) { + this.application.control(selectors, listeners, this); + }, + + getController: function(name) { + return this.application.getController(name); + }, + + getStore: function(name) { + return this.application.getStore(name); + }, + + getModel: function(model) { + return this.application.getModel(model); + }, + + getView: function(view) { + return this.application.getView(view); + } +}); + + +Ext.define('Ext.data.SortTypes', { + + singleton: true, + + + none : function(s) { + return s; + }, + + + stripTagsRE : /<\/?[^>]+>/gi, + + + asText : function(s) { + return String(s).replace(this.stripTagsRE, ""); + }, + + + asUCText : function(s) { + return String(s).toUpperCase().replace(this.stripTagsRE, ""); + }, + + + asUCString : function(s) { + return String(s).toUpperCase(); + }, + + + asDate : function(s) { + if(!s){ + return 0; + } + if(Ext.isDate(s)){ + return s.getTime(); + } + return Date.parse(String(s)); + }, + + + asFloat : function(s) { + var val = parseFloat(String(s).replace(/,/g, "")); + return isNaN(val) ? 0 : val; + }, + + + asInt : function(s) { + var val = parseInt(String(s).replace(/,/g, ""), 10); + return isNaN(val) ? 0 : val; + } +}); + +Ext.define('Ext.data.Errors', { + extend: 'Ext.util.MixedCollection', + + + isValid: function() { + return this.length === 0; + }, + + + getByField: function(fieldName) { + var errors = [], + error, field, i; + + for (i = 0; i < this.length; i++) { + error = this.items[i]; + + if (error.field == fieldName) { + errors.push(error); + } + } + + return errors; + } +}); + + +Ext.define('Ext.data.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, + + + error: undefined, + + constructor: function(config) { + Ext.apply(this, config || {}); + }, + + + setStarted: function() { + this.started = true; + this.running = true; + }, + + + setCompleted: function() { + this.complete = true; + this.running = false; + }, + + + setSuccessful: function() { + this.success = true; + }, + + + setException: function(error) { + this.exception = true; + this.success = false; + this.running = false; + this.error = error; + }, + + + hasException: function() { + return this.exception === true; + }, + + + getError: function() { + return this.error; + }, + + + getRecords: function() { + var resultSet = this.getResultSet(); + + return (resultSet === undefined ? this.records : resultSet.records); + }, + + + getResultSet: function() { + return this.resultSet; + }, + + + isStarted: function() { + return this.started === true; + }, + + + isRunning: function() { + return this.running === true; + }, + + + isComplete: function() { + return this.complete === true; + }, + + + wasSuccessful: function() { + return this.isComplete() && this.success === true; + }, + + + setBatch: function(batch) { + this.batch = batch; + }, + + + allowWrite: function() { + return this.action != 'read'; + } +}); + +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', + + + presence: function(config, value) { + if (value === undefined) { + value = config; + } + + return !!value; + }, + + + length: function(config, value) { + if (value === undefined) { + return false; + } + + var length = value.length, + min = config.min, + max = config.max; + + if ((min && length < min) || (max && length > max)) { + return false; + } else { + return true; + } + }, + + + 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; + } +}); + +Ext.define('Ext.data.ResultSet', { + + loaded: true, + + + count: 0, + + + total: 0, + + + success: false, + + + + constructor: function(config) { + Ext.apply(this, config); + + + this.totalRecords = this.total; + + if (config.count === undefined) { + this.count = this.records.length; + } + } +}); + +Ext.define('Ext.data.writer.Writer', { + alias: 'writer.base', + alternateClassName: ['Ext.data.DataWriter', 'Ext.data.Writer'], + + + writeAllFields: true, + + + nameProperty: 'name', + + constructor: function(config) { + Ext.apply(this, config); + }, + + + 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 this.writeRecords(request, data); + }, + + + 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 data; + } +}); + + +Ext.define('Ext.util.Floating', { + + uses: ['Ext.Layer', 'Ext.window.Window'], + + + focusOnToFront: true, + + + 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); + }, + + 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); + } + }, + + setFloatParent: function(floatParent) { + var me = this; + + + 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.constrain || me.constrainHeader) && !me.constrainTo) { + me.constrainTo = floatParent ? floatParent.getTargetEl() : me.container; + } + }, + + onFloatParentHide: function() { + this.showOnParentShow = this.isVisible(); + this.hide(); + }, + + onFloatParentShow: function() { + if (this.showOnParentShow) { + delete this.showOnParentShow; + this.show(); + } + }, + + + getZIndexParent: function() { + var p = this.ownerCt, + c; + + if (p) { + while (p) { + c = p; + p = p.ownerCt; + } + if (c.floating) { + return c; + } + } + }, + + + + + + + setZIndex: function(index) { + var me = this; + this.el.setZIndex(index); + + + index += 10; + + + + if (me.floatingItems) { + index = Math.floor(me.floatingItems.setBase(index) / 100) * 100 + 10000; + } + return index; + }, + + + doConstrain: function(constrainTo) { + var me = this, + constrainEl, + vector, + xy; + + 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); + } + } + }, + + + alignTo: function(element, position, offsets) { + if (element.isComponent) { + element = element.getEl(); + } + var xy = this.el.getAlignToXY(element, position, offsets); + this.setPagePosition(xy); + return this; + }, + + + toFront: function(preventFocus) { + var me = this; + + + + 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; + }, + + + 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(); + } + this.fireEvent('deactivate', this); + } + }, + + + toBack: function() { + this.zIndexManager.sendToBack(this); + return this; + }, + + + center: function() { + var xy = this.el.getAlignToXY(this.container, 'c-c'); + this.setPagePosition(xy); + return this; + }, + + + 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); + + this.setSize(size); + } +}); + + +Ext.define('Ext.layout.container.AbstractContainer', { + + + + extend: 'Ext.layout.Layout', + + + + type: 'container', + + fixedLayout: true, + + + managedHeight: true, + + managedWidth: true, + + + bindToOwnerCtComponent: false, + + + bindToOwnerCtContainer: false, + + + + isManaged: function(dimension) { + dimension = Ext.String.capitalize(dimension); + var me = this, + child = me, + managed = me['managed' + dimension], + ancestor = me.owner.ownerCt; + + if (ancestor && ancestor.layout) { + while (ancestor && ancestor.layout) { + if (managed === false || ancestor.layout['managed' + dimension] === false) { + managed = false; + break; + } + ancestor = ancestor.ownerCt; + } + } + return managed; + }, + + layout: function() { + var me = this, + owner = me.owner; + if (Ext.isNumber(owner.height) || owner.isViewport) { + me.managedHeight = false; + } + if (Ext.isNumber(owner.width) || owner.isViewport) { + me.managedWidth = false; + } + me.callParent(arguments); + }, + + + 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 || []; + }, + + 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', + + statics: { + zBase : 9000 + }, + + constructor: function(container) { + var me = this; + + me.list = {}; + me.zIndexStack = []; + me.front = null; + + if (container) { + + + 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(); + }); + } + }, + + getNextZSeed: function() { + return (Ext.ZIndexManager.zBase += 10000); + }, + + setBase: function(baseZIndex) { + this.zseed = baseZIndex; + return this.assignZIndices(); + }, + + + 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; + }, + + + _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.el.getStyle('zIndex') - 4); + } + } + } + }, + + + _activateLast: function(justHidden) { + var comp, + lastActivated = false, + i; + + + + + for (i = this.zIndexStack.length-1; i >= 0; --i) { + comp = this.zIndexStack[i]; + if (!comp.hidden) { + if (!lastActivated) { + this._setActiveChild(comp); + lastActivated = true; + } + + + if (comp.modal) { + this._showModalMask(comp.el.getStyle('zIndex') - 4); + return; + } + } + } + + + + this._hideModalMask(); + if (!lastActivated) { + this._setActiveChild(null); + } + }, + + _showModalMask: function(zIndex) { + if (!this.mask) { + this.mask = this.targetEl.createChild({ + cls: Ext.baseCSSPrefix + 'mask' + }); + this.mask.setVisibilityMode(Ext.core.Element.DISPLAY); + this.mask.on('click', this._onMaskClick, this); + } + 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(); + } + }, + + _onMaskClick: function() { + if (this.front) { + this.front.focus(); + } + }, + + _onContainerResize: function() { + if (this.mask && this.mask.isVisible()) { + this.mask.setSize(this.targetEl.getViewSize(true)); + } + }, + + + 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); + }, + + + 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); + } + }, + + + get : function(id) { + return typeof id == "object" ? id : this.list[id]; + }, + + + 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; + }, + + + sendToBack : function(comp) { + comp = this.get(comp); + Ext.Array.remove(this.zIndexStack, comp); + this.zIndexStack.unshift(comp); + this.assignZIndices(); + return comp; + }, + + + hideAll : function() { + for (var id in this.list) { + if (this.list[id].isComponent && this.list[id].isVisible()) { + this.list[id].hide(); + } + } + }, + + + 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(); + } + } + }, + + + 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); + } + delete this.tempHidden; + }, + + + getActive : function() { + return this.front; + }, + + + 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; + }, + + + 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; + } + } + }, + + + 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; + } + } + }, + + destroy: function() { + delete this.zIndexStack; + delete this.list; + delete this.container; + delete this.targetEl; + } +}, function() { + + Ext.WindowManager = Ext.WindowMgr = new this(); +}); + + +Ext.define('Ext.layout.container.boxOverflow.None', { + + alternateClassName: 'Ext.layout.boxOverflow.None', + + constructor: function(layout, config) { + this.layout = layout; + Ext.apply(this, config || {}); + }, + + handleOverflow: Ext.emptyFn, + + clearOverflow: Ext.emptyFn, + + + getItem: function(item) { + return this.layout.owner.getComponent(item); + } +}); + +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(); + }, + + 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; + } + + if (!Ext.isArray(keyCode)) { + keyCode = [keyCode]; + } + + if (!processed) { + for (i = 0, len = keyCode.length; i < len; ++i) { + key = keyCode[i]; + if (Ext.isString(key)) { + keyCode[i] = key.toLowerCase().charCodeAt(0); + } + } + } + + this.bindings.push(Ext.apply({ + keyCode: keyCode + }, binding)); + }, + + + handleKeyDown: function(event) { + if (this.enabled) { + var bindings = this.bindings, + i = 0, + len = bindings.length; + + event = this.processEvent(event); + for(; i < len; ++i){ + this.processBinding(bindings[i], event); + } + } + }, + + + processEvent: function(event){ + return event; + }, + + + processBinding: function(binding, event){ + if (this.checkModifiers(binding, event)) { + 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; + } + } + } + }, + + + 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; + }, + + + 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; + }, + + + enable: function(){ + if(!this.enabled){ + this.el.on(this.eventName, this.handleKeyDown, this); + this.enabled = true; + } + }, + + + disable: function(){ + if(this.enabled){ + this.el.removeListener(this.eventName, this.handleKeyDown, this); + this.enabled = false; + } + }, + + + setDisabled : function(disabled){ + if (disabled) { + this.disable(); + } else { + this.enable(); + } + }, + + + destroy: function(removeEl){ + var me = this; + + me.bindings = []; + me.disable(); + if (removeEl === true) { + me.el.remove(); + } + delete me.el; + } +}); + + +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(); + } + + + if(this.handler){ + this.on("click", this.handler, this.scope || this); + } + + this.callParent(); + }, + + + + + + + + + interval : 20, + + + delay: 250, + + + preventDefault : true, + + stopDefault : false, + + timer : 0, + + + 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); + } + } + 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; + }, + + + setDisabled: function(disabled){ + this[disabled ? 'disable' : 'enable'](); + }, + + eventOptions: function(e){ + if(this.preventDefault){ + e.preventDefault(); + } + if(this.stopDefault){ + e.stopEvent(); + } + }, + + + destroy : function() { + this.disable(true); + Ext.destroy(this.el); + this.clearListeners(); + }, + + handleDblClick : function(e){ + clearTimeout(this.timer); + this.el.blur(); + + this.fireEvent("mousedown", this, e); + this.fireEvent("click", this, e); + }, + + + 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); + + + if (this.accelerate) { + this.delay = 400; + } + + + + e = new Ext.EventObjectImpl(e); + + this.timer = Ext.defer(this.click, this.delay || this.interval, this, [e]); + }, + + + 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; + }, + + + handleMouseOut : function(){ + clearTimeout(this.timer); + if(this.pressedCls){ + this.el.removeCls(this.pressedCls); + } + this.el.on("mouseover", this.handleMouseReturn, this); + }, + + + handleMouseReturn : function(){ + this.el.un("mouseover", this.handleMouseReturn, this); + if(this.pressedCls){ + this.el.addCls(this.pressedCls); + } + this.click(); + }, + + + 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); + } + this.fireEvent("mouseup", this, e); + } +}); + + +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, + 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.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 (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 (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); + } + }, + + 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.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); + } + }, + + + getSize: function(text){ + var measure = this.measure, + size; + + measure.update(text); + size = measure.getSize(); + measure.update(''); + return size; + }, + + + 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') + ); + }, + + + 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({ + + 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.boxOverflow.Scroller', { + + + + extend: 'Ext.layout.container.boxOverflow.None', + requires: ['Ext.util.ClickRepeater', 'Ext.core.Element'], + alternateClassName: 'Ext.layout.boxOverflow.Scroller', + mixins: { + observable: 'Ext.util.Observable' + }, + + + + + animateScroll: false, + + + scrollIncrement: 20, + + + wheelIncrement: 10, + + + scrollRepeatInterval: 60, + + + scrollDuration: 400, + + + + + + + scrollerCls: Ext.baseCSSPrefix + 'box-scroller', + + + + + + constructor: function(layout, config) { + this.layout = layout; + Ext.apply(this, config || {}); + + this.addEvents( + + 'scroll' + ); + }, + + initCSSClasses: function() { + var me = this, + layout = me.layout; + + 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; + } + }, + + handleOverflow: function(calculations, targetSize) { + var me = this, + layout = me.layout, + methodName = 'get' + layout.parallelPrefixCap, + newSize = {}; + + 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 }; + }, + + + createInnerElements: function() { + var me = this, + target = me.layout.getRenderTarget(); + + + + 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(); + } + }, + + + createWheelListener: function() { + this.layout.innerCt.on({ + scope : this, + mousewheel: function(e) { + e.stopEvent(); + + this.scrollBy(e.getWheelDelta() * this.wheelIncrement * -1, false); + } + }); + }, + + + clearOverflow: function() { + this.hideScrollers(); + }, + + + showScrollers: function() { + this.createScrollers(); + this.beforeScroller.show(); + this.afterScroller.show(); + this.updateScrollButtons(); + + this.layout.owner.addClsWithUI('scroller'); + }, + + + hideScrollers: function() { + if (this.beforeScroller != undefined) { + this.beforeScroller.hide(); + this.afterScroller.hide(); + + this.layout.owner.removeClsWithUI('scroller'); + } + }, + + + 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) + }); + + before.addClsOnOver(this.beforeScrollerCls + '-hover'); + after.addClsOnOver(this.afterScrollerCls + '-hover'); + + before.setVisibilityMode(Ext.core.Element.DISPLAY); + after.setVisibilityMode(Ext.core.Element.DISPLAY); + + this.beforeRepeater = Ext.create('Ext.util.ClickRepeater', before, { + interval: this.scrollRepeatInterval, + handler : this.scrollLeft, + scope : this + }); + + this.afterRepeater = Ext.create('Ext.util.ClickRepeater', after, { + interval: this.scrollRepeatInterval, + handler : this.scrollRight, + scope : this + }); + + + this.beforeScroller = before; + + + this.afterScroller = after; + } + }, + + + destroy: function() { + Ext.destroy(this.beforeRepeater, this.afterRepeater, this.beforeScroller, this.afterScroller, this.beforeCt, this.afterCt); + }, + + + scrollBy: function(delta, animate) { + this.scrollTo(this.getScrollPosition() + delta, animate); + }, + + + getScrollAnim: function() { + return { + duration: this.scrollDuration, + callback: this.updateScrollButtons, + scope : this + }; + }, + + + updateScrollButtons: function() { + if (this.beforeScroller == undefined || this.afterScroller == undefined) { + return; + } + + 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; + }, + + + atExtremeBefore: function() { + return this.getScrollPosition() === 0; + }, + + + scrollLeft: function() { + this.scrollBy(-this.scrollIncrement, false); + }, + + + scrollRight: function() { + this.scrollBy(this.scrollIncrement, false); + }, + + + getScrollPosition: function(){ + var layout = this.layout; + return parseInt(layout.innerCt.dom['scroll' + layout.parallelBeforeCap], 10) || 0; + }, + + + getMaxScrollPosition: function() { + var layout = this.layout; + return layout.innerCt.dom['scroll' + layout.parallelPrefixCap] - this.layout.innerCt['get' + layout.parallelPrefixCap](); + }, + + + atExtremeAfter: function() { + return this.getScrollPosition() >= this.getMaxScrollPosition(); + }, + + + scrollTo: function(position, animate) { + var me = this, + layout = me.layout, + oldPosition = me.getScrollPosition(), + newPosition = Ext.Number.constrain(position, 0, me.getMaxScrollPosition()); + + 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); + } + }, + + + scrollToItem: function(item, animate) { + var me = this, + layout = me.layout, + visibility, + box, + newPos; + + 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); + } + } + }, + + + 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', { + + + + statics: { + fromObject: function(obj) { + return new this(obj.x, obj.y); + } + }, + + + + constructor: function(x, y) { + this.x = (x != null && !isNaN(x)) ? x : 0; + this.y = (y != null && !isNaN(y)) ? y : 0; + + return this; + }, + + copy: function() { + return new Ext.util.Offset(this.x, this.y); + }, + + copyFrom: function(p) { + this.x = p.x; + this.y = p.y; + }, + + toString: function() { + return "Offset[" + this.x + "," + this.y + "]"; + }, + + equals: function(offset) { + if(!(offset instanceof this.statics())) { + Ext.Error.raise('Offset must be an instance of Ext.util.Offset'); + } + + return (this.x == offset.x && this.y == offset.y); + }, + + 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); + } + }, + + isZero: function() { + return this.x == 0 && this.y == 0; + } +}); + + +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 + } + }, + + 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; + + 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 + }); + } + } + } + + map.disable(); + if (!config.disabled) { + map.enable(); + } + }, + + + 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; + }, + + + disable: function() { + this.map.disable(); + this.disabled = true; + }, + + + setDisabled : function(disabled){ + this.map.setDisabled(disabled); + this.disabled = disabled; + }, + + + getKeyEvent: function(forceKeyDown){ + return (forceKeyDown || Ext.EventManager.useKeyDown) ? 'keydown' : 'keypress'; + } +}); + + + +Ext.define('Ext.fx.Queue', { + + requires: ['Ext.util.HashMap'], + + 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--; + } + }, + + + 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; + }, + + + getFxQueue: function(targetId) { + if (!targetId) { + return false; + } + var me = this, + queue = me.fxQueue[targetId], + target = me.targets.get(targetId); + + if (!target) { + return false; + } + + if (!queue) { + me.fxQueue[targetId] = []; + + if (target.type != 'element') { + target.target.on('destroy', function() { + me.fxQueue[targetId] = []; + }); + } + } + return me.fxQueue[targetId]; + }, + + + queueFx: function(anim) { + var me = this, + target = anim.target, + queue, ln; + + if (!target) { + return; + } + + queue = me.getFxQueue(target.getId()); + ln = queue.length; + + if (ln) { + if (anim.concurrent) { + anim.paused = false; + } + else { + queue[ln - 1].on('afteranimate', function() { + anim.paused = false; + }); + } + } + 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', { + + isAnimTarget: true, + + constructor: function(target) { + this.target = target; + this.id = this.getId(); + }, + + getId: function() { + return this.target.id; + } +}); + + + +Ext.define('Ext.fx.target.Sprite', { + + + + extend: 'Ext.fx.target.Target', + + + + 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; + }, + + getAttr: function(attr, val) { + return [[this.target, val != undefined ? val : this.getFromPrim(this.target, attr)]]; + }, + + 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; + } + } + } + ln = spriteArr.length; + for (i = 0; i < ln; i++) { + spritePtr = spriteArr[i]; + spritePtr[0].setAttributes(spritePtr[1]); + } + this.target.redraw(); + } +}); + + + +Ext.define('Ext.fx.target.CompositeSprite', { + + + + extend: 'Ext.fx.target.Sprite', + + + + 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: 'component', + + + 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'); + } + }, + + compMethod: { + top: 'setPosition', + left: 'setPosition', + x: 'setPagePosition', + y: 'setPagePosition', + height: 'setSize', + width: 'setSize', + opacity: 'setOpacity' + }, + + + getAttr: function(attr, val) { + return [[this.target, val !== undefined ? val : this.getPropMethod[attr].call(this.target)]]; + }, + + 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) { + 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); + } + } + else { + o.target.el.setSize(w, h); + } + } + if (meth.setOpacity.target) { + o = meth.setOpacity; + o.target.el.setStyle('opacity', o.opacity); + } + } + } + } +}); + + +Ext.define('Ext.fx.CubicBezier', { + + + + singleton: true, + + + + 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)); + }, + + 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', { + + + + + + 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; + }, + + + getGreen: function() { + return this.g; + }, + + + getBlue: function() { + return this.b; + }, + + + getRGB: function() { + 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); + + + 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; + } + } + return [h, s, l]; + }, + + + 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]); + }, + + + getDarker: function(factor) { + factor = factor || this.lightnessFactor; + return this.getLighter(-factor); + }, + + + 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(''); + }, + + + 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); + + 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 ''; + } + }, + + + 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; + + + 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(); + + this.ghost = Ext.get(this.el.dom.childNodes[1]); + this.dropStatus = this.dropNotAllowed; + }, + + 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; + } + }, + + + reset : function(clearGhost){ + this.el.dom.className = Ext.baseCSSPrefix + 'dd-drag-proxy ' + this.dropNotAllowed; + this.dropStatus = this.dropNotAllowed; + if(clearGhost){ + this.ghost.update(""); + } + }, + + + 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'); + } + }, + + + getEl : function(){ + return this.el; + }, + + + getGhost : function(){ + return this.ghost; + }, + + + hide : function(clear) { + this.proxy.hide(); + if (clear) { + this.reset(true); + } + }, + + + stop : function(){ + if(this.anim && this.anim.isAnimated && this.anim.isAnimated()){ + this.anim.stop(); + } + }, + + + show : function() { + this.proxy.show(); + this.proxy.toFront(); + }, + + + sync : function(){ + this.proxy.el.sync(); + }, + + + 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(); + } + }, + + + afterRepair : function(){ + this.hide(true); + if(typeof this.callback == "function"){ + this.callback.call(this.scope || this); + } + this.callback = null; + this.scope = null; + }, + + 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); + }, + + + insertProxy: true, + + + setStatus: Ext.emptyFn, + reset: Ext.emptyFn, + update: Ext.emptyFn, + stop: Ext.emptyFn, + sync: Ext.emptyFn, + + + getEl: function(){ + return this.ghost.el; + }, + + + getGhost: function(){ + return this.ghost; + }, + + + getProxy: function(){ + return this.proxy; + }, + + + hide : function(){ + if (this.ghost) { + if (this.proxy) { + this.proxy.remove(); + delete this.proxy; + } + + + this.panel.unghost(null, false); + delete this.ghost; + } + }, + + + 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); + } + } + }, + + + repair: function(xy, callback, scope) { + this.hide(); + if (typeof callback == "function") { + callback.call(scope || this); + } + }, + + + 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', + + + 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; + }, + + + onLayout: function(width, height) { + 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: {} + }; + + 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; + } + } + + + if (height === undefined || height === null || width === undefined || width === null) { + padding = info.padding; + border = info.border; + frameSize = me.frameSize; + + + 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}); + } + + + if (layout && layout.isLayout) { + + layout.bindToOwnerCtComponent = true; + layout.layout(); + + + + + + + + + + + + + + info.autoSizedCtLayout = layout.autoSize === true; + } + + + + + + + me.dockItems(autoWidth, autoHeight); + me.setTargetSize(info.size.width, info.size.height); + } + else { + me.setTargetSize(width, height); + me.dockItems(); + } + me.callParent(arguments); + }, + + + dockItems : function(autoWidth, autoHeight) { + this.calculateDockBoxes(autoWidth, autoHeight); + + + + + var info = this.info, + boxes = info.boxes, + ln = boxes.length, + dock, i; + + + + 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; + } + } + + + + if (!info.autoSizedCtLayout) { + if (autoWidth) { + info.bodyBox.width = null; + } + if (autoHeight) { + info.bodyBox.height = null; + } + } + + + + this.setBodyBox(info.bodyBox); + }, + + + calculateDockBoxes : function(autoWidth, autoHeight) { + + + + 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; + + + + 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 + }; + + + 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); + } + + + + + info.boxes.push(box); + } + }, + + + adjustSizedBox : function(box, index) { + var bodyBox = this.info.bodyBox, + frameSize = this.frameSize, + info = this.info, + padding = info.padding, + pos = box.type, + border = info.border; + + switch (pos) { + case 'top': + box.y = bodyBox.y; + break; + + case 'left': + box.x = bodyBox.x; + break; + + case 'bottom': + box.y = (bodyBox.y + bodyBox.height) - box.height; + break; + + case 'right': + box.x = (bodyBox.x + bodyBox.width) - box.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); + } + 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; + }, + + + 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; + + 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; + } + } + } + + switch (pos) { + case 'top': + box.y = bodyBox.y; + if (!box.overlay) { + bodyBox.y += box.height; + } + size.height += box.height; + break; + + case 'bottom': + box.y = (bodyBox.y + bodyBox.height); + size.height += box.height; + break; + + case 'left': + box.x = bodyBox.x; + if (!box.overlay) { + bodyBox.x += box.width; + if (autoSizedCtLayout) { + size.width += box.width; + } else { + bodyBox.width -= box.width; + } + } + break; + + case 'right': + if (!box.overlay) { + if (autoSizedCtLayout) { + size.width += box.width; + } else { + bodyBox.width -= box.width; + } + } + 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); + } + else { + box.x -= (frameSize.left + padding.left + border.left); + } + } + return box; + }, + + + 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); + } + 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; + } + } + + + + 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 box; + }, + + + 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; + }, + + + renderItems: function(items, target) { + var cns = target.dom.childNodes, + cnsLn = cns.length, + ln = items.length, + domLn = 0, + i, j, cn, item; + + + 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; + } + } + + if (j === ln) { + domLn++; + } + } + + + for (i = 0, j = 0; i < ln; i++, j++) { + item = items[i]; + + + + + + + + + + if (i === j && (item.dock === 'right' || item.dock === 'bottom')) { + j += domLn; + } + + + if (item && !item.rendered) { + this.renderItem(item, target, j); + } + else if (!this.isValidParent(item, target, j)) { + this.moveItem(item, target, j); + } + } + }, + + + 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; + } + + 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); + } + }, + + + configureItem : function(item, pos) { + this.callParent(arguments); + + item.addCls(Ext.baseCSSPrefix + 'docked'); + item.addClsWithUI('docked-' + item.dock); + }, + + afterRemove : function(item) { + this.callParent(arguments); + if (this.itemCls) { + item.el.removeCls(this.itemCls + '-' + item.dock); + } + var dom = item.el.dom; + + if (!item.destroying && dom) { + dom.parentNode.removeChild(dom); + } + 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; + } + }); + }, + + 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)); + } + } + } + } + } + }, + + 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); + }); + }); + } +}); + +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' + }, + + + 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 + }); +}); + + +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; + + if (this.type) { + if (Ext.isString(this.type)) { + this.type = types[this.type.toUpperCase()] || types.AUTO; + } + } else { + this.type = types.AUTO; + } + + + 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; + } + }, + + + + + + + + dateFormat: null, + + + useNull: false, + + + defaultValue: "", + + mapping: null, + + sortType : null, + + sortDir : "ASC", + + allowBlank : true, + + + persist: true +}); + + +Ext.define('Ext.data.reader.Reader', { + requires: ['Ext.data.ResultSet'], + alternateClassName: ['Ext.data.Reader', 'Ext.data.DataReader'], + + + + + totalProperty: 'total', + + + successProperty: 'success', + + + root: '', + + + + + implicitIncludes: true, + + isReader: true, + + constructor: function(config) { + var me = this; + + Ext.apply(me, config || {}); + me.fieldCount = 0; + me.model = Ext.ModelManager.getModel(config.model); + if (me.model) { + me.buildExtractors(); + } + }, + + + setModel: function(model, setOnProxy) { + var me = this; + + me.model = Ext.ModelManager.getModel(model); + me.buildExtractors(true); + + if (setOnProxy && me.proxy) { + me.proxy.setModel(me.model, true); + } + }, + + + read: function(response) { + var data = response; + + if (response && response.responseText) { + data = this.getResponseData(response); + } + + if (data) { + return this.readRecords(data); + } else { + return this.nullResultSet; + } + }, + + + readRecords: function(data) { + var me = this; + + + if (me.fieldCount !== me.getFields().length) { + me.buildExtractors(true); + } + + + me.rawData = data; + + data = me.getData(data); + + + + var root = Ext.isArray(data) ? data : me.getRoot(data), + success = true, + recordCount = 0, + total, value, records, message; + + if (root) { + total = root.length; + } + + if (me.totalProperty) { + value = parseInt(me.getTotal(data), 10); + if (!isNaN(value)) { + total = value; + } + } + + if (me.successProperty) { + value = me.getSuccess(data); + if (value === false || value === 'false') { + success = false; + } + } + + if (me.messageProperty) { + message = me.getMessage(data); + } + + if (root) { + records = me.extractData(root); + recordCount = records.length; + } else { + recordCount = 0; + records = []; + } + + return Ext.create('Ext.data.ResultSet', { + total : total || recordCount, + count : recordCount, + records: records, + success: success, + message: message + }); + }, + + + extractData : function(root) { + var me = this, + values = [], + records = [], + Model = me.model, + i = 0, + length = root.length, + idProp = me.getIdProperty(), + node, id, record; + + if (!root.length && Ext.isObject(root)) { + root = [root]; + length = 1; + } + + for (; i < length; i++) { + node = root[i]; + values = me.extractValues(node); + id = me.getId(node); + + + record = new Model(values, id); + record.raw = node; + records.push(record); + + if (me.implicitIncludes) { + me.readAssociated(record, node); + } + } + + return records; + }, + + + readAssociated: function(record, data) { + var associations = record.associations.items, + i = 0, + length = associations.length, + association, associationData, proxy, reader; + + for (; i < length; i++) { + association = associations[i]; + associationData = this.getAssociatedDataRoot(data, association.associationKey || association.name); + + if (associationData) { + reader = association.getReader(); + if (!reader) { + proxy = association.associatedModel.proxy; + + if (proxy) { + reader = proxy.getReader(); + } else { + reader = new this.constructor({ + model: association.associatedName + }); + } + } + association.read(record, reader, associationData); + } + } + }, + + + getAssociatedDataRoot: function(data, associationName) { + return data[associationName]; + }, + + getFields: function() { + return this.model.prototype.fields.items; + }, + + + extractValues: function(data) { + var fields = this.getFields(), + i = 0, + length = fields.length, + output = {}, + field, value; + + for (; i < length; i++) { + field = fields[i]; + value = this.extractorFunctions[i](data); + + output[field.name] = value; + } + + return output; + }, + + + getData: function(data) { + return data; + }, + + + getRoot: function(data) { + return data; + }, + + + getResponseData: function(response) { + Ext.Error.raise("getResponseData must be implemented in the Ext.data.reader.Reader subclass"); + }, + + + onMetaChange : function(meta) { + var fields = meta.fields, + newModel; + + Ext.apply(this, meta); + + if (fields) { + newModel = Ext.define("Ext.data.reader.Json-Model" + Ext.id(), { + extend: 'Ext.data.Model', + fields: fields + }); + this.setModel(newModel, true); + } else { + this.buildExtractors(true); + } + }, + + + getIdProperty: function(){ + var prop = this.idProperty; + if (Ext.isEmpty(prop)) { + prop = this.model.prototype.idProperty; + } + return prop; + }, + + + buildExtractors: function(force) { + var me = this, + idProp = me.getIdProperty(), + totalProp = me.totalProperty, + successProp = me.successProperty, + messageProp = me.messageProperty, + accessor; + + if (force === true) { + delete me.extractorFunctions; + } + + if (me.extractorFunctions) { + return; + } + + + if (totalProp) { + me.getTotal = me.createAccessor(totalProp); + } + + if (successProp) { + me.getSuccess = me.createAccessor(successProp); + } + + if (messageProp) { + me.getMessage = me.createAccessor(messageProp); + } + + if (idProp) { + accessor = me.createAccessor(idProp); + + me.getId = function(record) { + var id = accessor.call(me, record); + return (id === undefined || id === '') ? null : id; + }; + } else { + me.getId = function() { + return null; + }; + } + me.buildFieldExtractors(); + }, + + + buildFieldExtractors: function() { + + var me = this, + fields = me.getFields(), + ln = fields.length, + i = 0, + extractorFunctions = [], + field, map; + + for (; i < ln; i++) { + field = fields[i]; + map = (field.mapping !== undefined && field.mapping !== null) ? field.mapping : field.name; + + extractorFunctions.push(me.createAccessor(map)); + } + me.fieldCount = ln; + + me.extractorFunctions = extractorFunctions; + } +}, function() { + Ext.apply(this, { + + nullResultSet: Ext.create('Ext.data.ResultSet', { + total : 0, + count : 0, + records: [], + success: true + }) + }); +}); + +Ext.define('Ext.data.reader.Json', { + extend: 'Ext.data.reader.Reader', + alternateClassName: 'Ext.data.JsonReader', + alias : 'reader.json', + + root: '', + + + + + useSimpleAccessors: false, + + + readRecords: function(data) { + + if (data.metaData) { + this.onMetaChange(data.metaData); + } + + + this.jsonData = data; + return this.callParent([data]); + }, + + + getResponseData: function(response) { + try { + var data = Ext.decode(response.responseText); + } + catch (ex) { + Ext.Error.raise({ + response: response, + json: response.responseText, + parseError: ex, + msg: 'Unable to parse the JSON returned by the server: ' + ex.toString() + }); + } + if (!data) { + Ext.Error.raise('JSON object not found'); + } + + return data; + }, + + + buildExtractors : function() { + var me = this; + + me.callParent(arguments); + + if (me.root) { + me.getRoot = me.createAccessor(me.root); + } else { + me.getRoot = function(root) { + return root; + }; + } + }, + + + extractData: function(root) { + var recordName = this.record, + data = [], + length, i; + + if (recordName) { + length = root.length; + + for (i = 0; i < length; i++) { + data[i] = root[i][recordName]; + } + } else { + data = root; + } + return this.callParent([data]); + }, + + + createAccessor: function() { + var re = /[\[\.]/; + + return function(expr) { + if (Ext.isEmpty(expr)) { + return Ext.emptyFn; + } + if (Ext.isFunction(expr)) { + return expr; + } + if (this.useSimpleAccessors !== true) { + var i = String(expr).search(re); + if (i >= 0) { + return Ext.functionFactory('obj', 'return obj' + (i > 0 ? '.' : '') + expr); + } + } + return function(obj) { + return obj[expr]; + }; + }; + }() +}); + +Ext.define('Ext.data.writer.Json', { + extend: 'Ext.data.writer.Writer', + alternateClassName: 'Ext.data.JsonWriter', + alias: 'writer.json', + + + root: undefined, + + + encode: false, + + + allowSingle: true, + + + writeRecords: function(request, data) { + var root = this.root; + + if (this.allowSingle && data.length == 1) { + + data = data[0]; + } + + if (this.encode) { + if (root) { + + request.params[root] = Ext.encode(data); + } else { + Ext.Error.raise('Must specify a root when using encode'); + } + } else { + + request.jsonData = request.jsonData || {}; + if (root) { + request.jsonData[root] = data; + } else { + request.jsonData = data; + } + } + return request; + } +}); + + +Ext.define('Ext.data.proxy.Proxy', { + alias: 'proxy.proxy', + alternateClassName: ['Ext.data.DataProxy', 'Ext.data.Proxy'], + requires: [ + 'Ext.data.reader.Json', + 'Ext.data.writer.Json' + ], + uses: [ + 'Ext.data.Batch', + 'Ext.data.Operation', + 'Ext.data.Model' + ], + mixins: { + observable: 'Ext.util.Observable' + }, + + + batchOrder: 'create,update,destroy', + + + batchActions: true, + + + defaultReaderType: 'json', + + + defaultWriterType: 'json', + + + + isProxy: true, + + constructor: function(config) { + config = config || {}; + + if (config.model === undefined) { + delete config.model; + } + + this.mixins.observable.constructor.call(this, config); + + if (this.model !== undefined && !(this.model instanceof Ext.data.Model)) { + this.setModel(this.model); + } + }, + + + setModel: function(model, setOnStore) { + this.model = Ext.ModelManager.getModel(model); + + var reader = this.reader, + writer = this.writer; + + this.setReader(reader); + this.setWriter(writer); + + if (setOnStore && this.store) { + this.store.setModel(this.model); + } + }, + + + getModel: function() { + return this.model; + }, + + + setReader: function(reader) { + var me = this; + + if (reader === undefined || typeof reader == 'string') { + reader = { + type: reader + }; + } + + if (reader.isReader) { + reader.setModel(me.model); + } else { + Ext.applyIf(reader, { + proxy: me, + model: me.model, + type : me.defaultReaderType + }); + + reader = Ext.createByAlias('reader.' + reader.type, reader); + } + + me.reader = reader; + return me.reader; + }, + + + getReader: function() { + return this.reader; + }, + + + setWriter: function(writer) { + if (writer === undefined || typeof writer == 'string') { + writer = { + type: writer + }; + } + + if (!(writer instanceof Ext.data.writer.Writer)) { + Ext.applyIf(writer, { + model: this.model, + type : this.defaultWriterType + }); + + writer = Ext.createByAlias('writer.' + writer.type, writer); + } + + this.writer = writer; + + return this.writer; + }, + + + getWriter: function() { + return this.writer; + }, + + + create: Ext.emptyFn, + + + read: Ext.emptyFn, + + + update: Ext.emptyFn, + + + destroy: Ext.emptyFn, + + + batch: function(operations, listeners) { + var me = this, + batch = Ext.create('Ext.data.Batch', { + proxy: me, + listeners: listeners || {} + }), + useBatch = me.batchActions, + records; + + Ext.each(me.batchOrder.split(','), function(action) { + records = operations[action]; + if (records) { + if (useBatch) { + batch.add(Ext.create('Ext.data.Operation', { + action: action, + records: records + })); + } else { + Ext.each(records, function(record){ + batch.add(Ext.create('Ext.data.Operation', { + action : action, + records: [record] + })); + }); + } + } + }, me); + + batch.start(); + return batch; + } +}, function() { + + + + Ext.data.DataProxy = this; + + + +}); + + +Ext.define('Ext.data.proxy.Server', { + extend: 'Ext.data.proxy.Proxy', + 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)); + + if (operation.id && !params.id) { + params.id = operation.id; + } + + request = Ext.create('Ext.data.Request', { + params : params, + action : operation.action, + records : operation.records, + 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; + + 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.setCompleted(); + operation.setSuccessful(); + } else { + operation.setException(result.message); + me.fireEvent('exception', this, response, operation); + } + } else { + me.setException(operation, response); + 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; + }, + + + 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, + direction: sorters[i].direction + }; + } + return this.applyEncoding(min); + + }, + + + encodeFilters: function(filters) { + var min = [], + length = filters.length, + i = 0; + + for (; i < length; i++) { + min[i] = { + property: filters[i].property, + value : filters[i].value + }; + } + return this.applyEncoding(min); + }, + + + getParams: function(params, operation) { + params = params || {}; + + var me = this, + isDef = Ext.isDefined, + groupers = operation.groupers, + sorters = operation.sorters, + filters = operation.filters, + 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; + + 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; + params[directionParam] = sorters[0].direction; + } 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); + } +}); + + +Ext.define('Ext.data.proxy.Ajax', { + requires: ['Ext.util.MixedCollection', 'Ext.Ajax'], + extend: 'Ext.data.proxy.Server', + alias: 'proxy.ajax', + alternateClassName: ['Ext.data.HttpProxy', 'Ext.data.AjaxProxy'], + + + actionMethods: { + create : 'POST', + read : 'GET', + update : 'POST', + destroy: 'POST' + }, + + + + + doRequest: function(operation, callback, scope) { + var writer = this.getWriter(), + request = this.buildRequest(operation, callback, scope); + + if (operation.allowWrite()) { + request = writer.write(request); + } + + Ext.apply(request, { + headers : this.headers, + timeout : this.timeout, + scope : this, + callback : this.createRequestCallback(request, operation, callback, scope), + method : this.getMethod(request), + disableCaching: false + }); + + Ext.Ajax.request(request); + + return request; + }, + + + getMethod: function(request) { + return this.actionMethods[request.action]; + }, + + + createRequestCallback: function(request, operation, callback, scope) { + var me = this; + + return function(options, success, response) { + me.processResponse(success, operation, request, response, callback, scope); + }; + } +}, function() { + + Ext.data.HttpProxy = this; +}); + + +Ext.define('Ext.data.Model', { + alternateClassName: 'Ext.data.Record', + + mixins: { + observable: 'Ext.util.Observable' + }, + + requires: [ + 'Ext.ModelManager', + 'Ext.data.Field', + 'Ext.data.Errors', + 'Ext.data.Operation', + 'Ext.data.validations', + 'Ext.data.proxy.Ajax', + 'Ext.util.MixedCollection' + ], + + onClassExtended: function(cls, data) { + var onBeforeClassCreated = data.onBeforeClassCreated; + + data.onBeforeClassCreated = function(cls, data) { + var me = this, + name = Ext.getClassName(cls), + prototype = cls.prototype, + superCls = cls.prototype.superclass, + + validations = data.validations || [], + fields = data.fields || [], + associations = data.associations || [], + belongsTo = data.belongsTo, + hasMany = data.hasMany, + + fieldsMixedCollection = new Ext.util.MixedCollection(false, function(field) { + return field.name; + }), + + associationsMixedCollection = new Ext.util.MixedCollection(false, function(association) { + return association.name; + }), + + superValidations = superCls.validations, + superFields = superCls.fields, + superAssociations = superCls.associations, + + association, i, ln, + dependencies = []; + + + cls.modelName = name; + prototype.modelName = name; + + + if (superValidations) { + validations = superValidations.concat(validations); + } + + data.validations = validations; + + + if (superFields) { + fields = superFields.items.concat(fields); + } + + for (i = 0, ln = fields.length; i < ln; ++i) { + fieldsMixedCollection.add(new Ext.data.Field(fields[i])); + } + + data.fields = fieldsMixedCollection; + + + + if (belongsTo) { + belongsTo = Ext.Array.from(belongsTo); + + for (i = 0, ln = belongsTo.length; i < ln; ++i) { + association = belongsTo[i]; + + if (!Ext.isObject(association)) { + association = {model: association}; + } + + association.type = 'belongsTo'; + associations.push(association); + } + + delete data.belongsTo; + } + + if (hasMany) { + hasMany = Ext.Array.from(hasMany); + for (i = 0, ln = hasMany.length; i < ln; ++i) { + association = hasMany[i]; + + if (!Ext.isObject(association)) { + association = {model: association}; + } + + association.type = 'hasMany'; + associations.push(association); + } + + delete data.hasMany; + } + + if (superAssociations) { + associations = superAssociations.items.concat(associations); + } + + for (i = 0, ln = associations.length; i < ln; ++i) { + dependencies.push('association.' + associations[i].type.toLowerCase()); + } + + if (data.proxy) { + if (typeof data.proxy === 'string') { + dependencies.push('proxy.' + data.proxy); + } + else if (typeof data.proxy.type === 'string') { + dependencies.push('proxy.' + data.proxy.type); + } + } + + Ext.require(dependencies, function() { + Ext.ModelManager.registerType(name, cls); + + for (i = 0, ln = associations.length; i < ln; ++i) { + association = associations[i]; + + Ext.apply(association, { + ownerModel: name, + associatedModel: association.model + }); + + if (Ext.ModelManager.getModel(association.model) === undefined) { + Ext.ModelManager.registerDeferredAssociation(association); + } else { + associationsMixedCollection.add(Ext.data.Association.create(association)); + } + } + + data.associations = associationsMixedCollection; + + onBeforeClassCreated.call(me, cls, data); + + cls.setProxy(cls.prototype.proxy || cls.prototype.defaultProxyType); + + + Ext.ModelManager.onModelDefined(cls); + }); + } + }, + + inheritableStatics: { + + setProxy: function(proxy) { + + if (!proxy.isProxy) { + if (typeof proxy == "string") { + proxy = { + type: proxy + }; + } + proxy = Ext.createByAlias("proxy." + proxy.type, proxy); + } + proxy.setModel(this); + this.proxy = this.prototype.proxy = proxy; + + return proxy; + }, + + + getProxy: function() { + return this.proxy; + }, + + + load: function(id, config) { + config = Ext.apply({}, config); + config = Ext.applyIf(config, { + action: 'read', + id : id + }); + + var operation = Ext.create('Ext.data.Operation', config), + scope = config.scope || this, + record = null, + callback; + + callback = function(operation) { + if (operation.wasSuccessful()) { + record = operation.getRecords()[0]; + Ext.callback(config.success, scope, [record, operation]); + } else { + Ext.callback(config.failure, scope, [record, operation]); + } + Ext.callback(config.callback, scope, [record, operation]); + }; + + this.proxy.read(operation, callback, this); + } + }, + + statics: { + PREFIX : 'ext-record', + AUTO_ID: 1, + EDIT : 'edit', + REJECT : 'reject', + COMMIT : 'commit', + + + id: function(rec) { + var id = [this.PREFIX, '-', this.AUTO_ID++].join(''); + rec.phantom = true; + rec.internalId = id; + return id; + } + }, + + + editing : false, + + + dirty : false, + + + persistanceProperty: 'data', + + evented: false, + isModel: true, + + + phantom : false, + + + idProperty: 'id', + + + defaultProxyType: 'ajax', + + + + constructor: function(data, id) { + data = data || {}; + + var me = this, + fields, + length, + field, + name, + i, + isArray = Ext.isArray(data), + newData = isArray ? {} : null; + + + me.internalId = (id || id === 0) ? id : Ext.data.Model.id(me); + + Ext.applyIf(me, { + data: {} + }); + + + me.modified = {}; + + me[me.persistanceProperty] = {}; + + me.mixins.observable.constructor.call(me); + + + fields = me.fields.items; + length = fields.length; + + for (i = 0; i < length; i++) { + field = fields[i]; + name = field.name; + + if (isArray){ + + + newData[name] = data[i]; + } + else if (data[name] === undefined) { + data[name] = field.defaultValue; + } + } + + me.set(newData || data); + + me.dirty = false; + me.modified = {}; + + if (me.getId()) { + me.phantom = false; + } + + if (typeof me.init == 'function') { + me.init(); + } + + me.id = me.modelName + '-' + me.internalId; + + Ext.ModelManager.register(me); + }, + + + get: function(field) { + return this[this.persistanceProperty][field]; + }, + + + set: function(fieldName, value) { + var me = this, + fields = me.fields, + modified = me.modified, + convertFields = [], + field, key, i, currentValue; + + + if (arguments.length == 1 && Ext.isObject(fieldName)) { + for (key in fieldName) { + if (fieldName.hasOwnProperty(key)) { + + + + field = fields.get(key); + if (field && field.convert !== field.type.convert) { + convertFields.push(key); + continue; + } + + me.set(key, fieldName[key]); + } + } + + for (i = 0; i < convertFields.length; i++) { + field = convertFields[i]; + me.set(field, fieldName[field]); + } + + } else { + if (fields) { + field = fields.get(fieldName); + + if (field && field.convert) { + value = field.convert(value, me); + } + } + currentValue = me.get(fieldName); + me[me.persistanceProperty][fieldName] = value; + + if (field && field.persist && !me.isEqual(currentValue, value)) { + me.dirty = true; + me.modified[fieldName] = currentValue; + } + + if (!me.editing) { + me.afterEdit(); + } + } + }, + + + isEqual: function(a, b){ + if (Ext.isDate(a) && Ext.isDate(b)) { + return a.getTime() === b.getTime(); + } + 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.modifiedSave = Ext.apply({}, me.modified); + } + }, + + + cancelEdit : function(){ + var me = this; + if (me.editing) { + me.editing = false; + + me.modified = me.modifiedSave; + me[me.persistanceProperty] = me.dataSave; + me.dirty = me.dirtySave; + delete me.modifiedSave; + delete me.dataSave; + delete me.dirtySave; + } + }, + + + endEdit : function(silent){ + var me = this; + if (me.editing) { + me.editing = false; + delete me.modifiedSave; + delete me.dataSave; + delete me.dirtySave; + if (silent !== true && me.dirty) { + me.afterEdit(); + } + } + }, + + + getChanges : function(){ + var modified = this.modified, + changes = {}, + field; + + for (field in modified) { + if (modified.hasOwnProperty(field)){ + changes[field] = this.get(field); + } + } + + return changes; + }, + + + isModified : function(fieldName) { + return this.modified.hasOwnProperty(fieldName); + }, + + + setDirty : function() { + var me = this, + name; + + me.dirty = true; + + me.fields.each(function(field) { + if (field.persist) { + name = field.name; + me.modified[name] = me.get(name); + } + }, 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, + modified = me.modified, + field; + + for (field in modified) { + if (modified.hasOwnProperty(field)) { + if (typeof modified[field] != "function") { + me[me.persistanceProperty][field] = modified[field]; + } + } + } + + me.dirty = false; + me.editing = false; + me.modified = {}; + + if (silent !== true) { + me.afterReject(); + } + }, + + + commit : function(silent) { + var me = this; + + me.dirty = false; + me.editing = false; + + me.modified = {}; + + if (silent !== true) { + me.afterCommit(); + } + }, + + + copy : function(newId) { + var me = this; + + return new me.self(Ext.apply({}, me[me.persistanceProperty]), newId || me.internalId); + }, + + + setProxy: function(proxy) { + + if (!proxy.isProxy) { + if (typeof proxy === "string") { + proxy = { + type: proxy + }; + } + proxy = Ext.createByAlias("proxy." + proxy.type, proxy); + } + proxy.setModel(this.self); + this.proxy = proxy; + + return proxy; + }, + + + getProxy: function() { + return this.proxy; + }, + + + validate: function() { + var errors = Ext.create('Ext.data.Errors'), + validations = this.validations, + validators = Ext.data.validations, + length, validation, field, valid, type, i; + + if (validations) { + length = validations.length; + + for (i = 0; i < length; i++) { + validation = validations[i]; + field = validation.field || validation.name; + type = validation.type; + valid = validators[type](validation, this.get(field)); + + if (!valid) { + errors.add({ + field : field, + message: validation.message || validators[type + 'Message'] + }); + } + } + } + + return errors; + }, + + + isValid: function(){ + return this.validate().isValid(); + }, + + + save: function(options) { + options = Ext.apply({}, options); + + var me = this, + action = me.phantom ? 'create' : 'update', + record = null, + scope = options.scope || me, + operation, + callback; + + Ext.apply(options, { + records: [me], + action : action + }); + + operation = Ext.create('Ext.data.Operation', options); + + callback = function(operation) { + if (operation.wasSuccessful()) { + record = operation.getRecords()[0]; + + + me.set(record.data); + record.dirty = false; + + Ext.callback(options.success, scope, [record, operation]); + } else { + Ext.callback(options.failure, scope, [record, operation]); + } + + Ext.callback(options.callback, scope, [record, operation]); + }; + + me.getProxy()[action](operation, callback, me); + + return me; + }, + + + destroy: function(options){ + options = Ext.apply({}, options); + + var me = this, + record = null, + scope = options.scope || me, + operation, + callback; + + Ext.apply(options, { + records: [me], + action : 'destroy' + }); + + operation = Ext.create('Ext.data.Operation', options); + callback = function(operation) { + if (operation.wasSuccessful()) { + Ext.callback(options.success, scope, [record, operation]); + } else { + Ext.callback(options.failure, scope, [record, operation]); + } + Ext.callback(options.callback, scope, [record, operation]); + }; + + me.getProxy().destroy(operation, callback, me); + return me; + }, + + + getId: function() { + return this.get(this.idProperty); + }, + + + setId: function(id) { + this.set(this.idProperty, id); + }, + + + join : function(store) { + + this.store = store; + }, + + + unjoin: function() { + delete this.store; + }, + + + afterEdit : function() { + this.callStore('afterEdit'); + }, + + + afterReject : function() { + this.callStore("afterReject"); + }, + + + afterCommit: function() { + this.callStore('afterCommit'); + }, + + + callStore: function(fn) { + var store = this.store; + + if (store !== undefined && typeof store[fn] == "function") { + store[fn](this); + } + }, + + + getAssociatedData: function(){ + return this.prepareAssociatedData(this, [], null); + }, + + + prepareAssociatedData: function(record, ids, associationType) { + + var associations = record.associations.items, + associationCount = associations.length, + associationData = {}, + associatedStore, associatedName, associatedRecords, associatedRecord, + associatedRecordCount, association, id, i, j, type, allow; + + for (i = 0; i < associationCount; i++) { + association = associations[i]; + type = association.type; + allow = true; + if (associationType) { + allow = type == associationType; + } + if (allow && type == 'hasMany') { + + + associatedStore = record[association.storeName]; + + + associationData[association.name] = []; + + + if (associatedStore && associatedStore.data.length > 0) { + associatedRecords = associatedStore.data.items; + associatedRecordCount = associatedRecords.length; + + + for (j = 0; j < associatedRecordCount; j++) { + associatedRecord = associatedRecords[j]; + + id = associatedRecord.id; + + + + if (Ext.Array.indexOf(ids, id) == -1) { + ids.push(id); + + associationData[association.name][j] = associatedRecord.data; + Ext.apply(associationData[association.name][j], this.prepareAssociatedData(associatedRecord, ids, type)); + } + } + } + } else if (allow && type == 'belongsTo') { + associatedRecord = record[association.instanceName]; + if (associatedRecord !== undefined) { + id = associatedRecord.id; + if (Ext.Array.indexOf(ids, id) == -1) { + ids.push(id); + associationData[association.name] = associatedRecord.data; + Ext.apply(associationData[association.name], this.prepareAssociatedData(associatedRecord, ids, type)); + } + } + } + } + + return associationData; + } +}); + + + +Ext.define('Ext.Component', { + + + + alias: ['widget.component', 'widget.box'], + + extend: 'Ext.AbstractComponent', + + requires: [ + 'Ext.util.DelayedTask' + ], + + uses: [ + 'Ext.Layer', + 'Ext.resizer.Resizer', + 'Ext.util.ComponentDragger' + ], + + mixins: { + floating: 'Ext.util.Floating' + }, + + statics: { + + DIRECTION_TOP: 'top', + DIRECTION_RIGHT: 'right', + DIRECTION_BOTTOM: 'bottom', + DIRECTION_LEFT: 'left' + }, + + + + + + + resizeHandles: 'all', + + + + + floating: false, + + + toFrontOnShow: true, + + + + + + + + + + hideMode: 'display', + + hideParent: false, + + ariaRole: 'presentation', + + bubbleEvents: [], + + actionMode: 'el', + monPropRe: /^(?:scope|delay|buffer|single|stopEvent|preventDefault|stopPropagation|normalized|args|delegate)$/, + + + + + + + + constructor: function(config) { + config = config || {}; + if (config.initialConfig) { + + + if (config.isAction) { + this.baseAction = config; + } + config = config.initialConfig; + + } + else if (config.tagName || config.dom || Ext.isString(config)) { + + config = { + applyTo: config, + id: config.id || config + }; + } + + this.callParent([config]); + + + + if (this.baseAction){ + this.baseAction.addComponent(this); + } + }, + + initComponent: function() { + var me = this; + + if (me.listeners) { + me.on(me.listeners); + delete me.listeners; + } + me.enableBubble(me.bubbleEvents); + me.mons = []; + }, + + + afterRender: function() { + var me = this, + resizable = me.resizable; + + if (me.floating) { + me.makeFloating(me.floating); + } else { + me.el.setVisibilityMode(Ext.core.Element[me.hideMode.toUpperCase()]); + } + + me.setAutoScroll(me.autoScroll); + me.callParent(); + + if (!(me.x && me.y) && (me.pageX || me.pageY)) { + me.setPagePosition(me.pageX, me.pageY); + } + + if (resizable) { + me.initResizable(resizable); + } + + if (me.draggable) { + me.initDraggable(); + } + + me.initAria(); + }, + + initAria: function() { + var actionEl = this.getActionEl(), + role = this.ariaRole; + if (role) { + actionEl.dom.setAttribute('role', role); + } + }, + + + setAutoScroll : function(scroll){ + var me = this, + targetEl; + scroll = !!scroll; + if (me.rendered) { + targetEl = me.getTargetEl(); + targetEl.setStyle('overflow', scroll ? 'auto' : ''); + if (scroll && (Ext.isIE6 || Ext.isIE7)) { + + + targetEl.position(); + } + } + me.autoScroll = scroll; + return me; + }, + + + makeFloating : function(cfg){ + this.mixins.floating.constructor.call(this, cfg); + }, + + initResizable: function(resizable) { + resizable = Ext.apply({ + target: this, + dynamic: false, + constrainTo: this.constrainTo, + handles: this.resizeHandles + }, resizable); + resizable.target = this; + this.resizer = Ext.create('Ext.resizer.Resizer', resizable); + }, + + getDragEl: function() { + return this.el; + }, + + 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); + + + if (me.constrain || me.constrainDelegate) { + ddConfig.constrain = me.constrain; + ddConfig.constrainDelegate = me.constrainDelegate; + } + + this.dd = Ext.create('Ext.util.ComponentDragger', this, ddConfig); + }, + + + setPosition: function(x, y, animate) { + var me = this, + el = me.el, + to = {}, + adj, adjX, adjY, xIsNumber, yIsNumber; + + if (Ext.isArray(x)) { + animate = y; + y = x[1]; + x = x[0]; + } + me.x = x; + me.y = y; + + if (!me.rendered) { + return me; + } + + adj = me.adjustPosition(x, y); + adjX = adj.x; + adjY = adj.y; + xIsNumber = Ext.isNumber(adjX); + yIsNumber = Ext.isNumber(adjY); + + if (xIsNumber || yIsNumber) { + if (animate) { + if (xIsNumber) { + to.left = adjX; + } + if (yIsNumber) { + to.top = adjY; + } + + me.stopAnimation(); + me.animate(Ext.apply({ + duration: 1000, + listeners: { + afteranimate: Ext.Function.bind(me.afterSetPosition, me, [adjX, adjY]) + }, + to: to + }, animate)); + } + else { + if (!xIsNumber) { + el.setTop(adjY); + } + else if (!yIsNumber) { + el.setLeft(adjX); + } + else { + el.setLeftTop(adjX, adjY); + } + me.afterSetPosition(adjX, adjY); + } + } + return me; + }, + + + afterSetPosition: function(ax, ay) { + this.onPosition(ax, ay); + this.fireEvent('move', this, ax, ay); + }, + + showAt: function(x, y, animate) { + + if (this.floating) { + this.setPosition(x, y, animate); + } else { + this.setPagePosition(x, y, animate); + } + this.show(); + }, + + + setPagePosition: function(x, y, animate) { + var me = this, + p; + + if (Ext.isArray(x)) { + y = x[1]; + x = x[0]; + } + me.pageX = x; + me.pageY = y; + if (me.floating && me.floatParent) { + + p = me.floatParent.getTargetEl().getViewRegion(); + if (Ext.isNumber(x) && Ext.isNumber(p.left)) { + x -= p.left; + } + if (Ext.isNumber(y) && Ext.isNumber(p.top)) { + y -= p.top; + } + me.setPosition(x, y, animate); + } + else { + p = me.el.translatePoints(x, y); + me.setPosition(p.left, p.top, animate); + } + return me; + }, + + + getBox : function(local){ + var pos = this.getPosition(local); + var s = this.getSize(); + s.x = pos[0]; + s.y = pos[1]; + return s; + }, + + + updateBox : function(box){ + this.setSize(box.width, box.height); + this.setPagePosition(box.x, box.y); + return this; + }, + + + getOuterSize: function() { + var el = this.el; + return { + width: el.getWidth() + el.getMargin('lr'), + height: el.getHeight() + el.getMargin('tb') + }; + }, + + + adjustSize: function(w, h) { + if (this.autoWidth) { + w = 'auto'; + } + + if (this.autoHeight) { + h = 'auto'; + } + + return { + width: w, + height: h + }; + }, + + + adjustPosition: function(x, y) { + + + if (this.floating && this.floatParent) { + var o = this.floatParent.getTargetEl().getViewRegion(); + x += o.left; + y += o.top; + } + + return { + x: x, + y: y + }; + }, + + + getPosition: function(local) { + var el = this.el, + xy; + + if (local === true) { + return [el.getLeft(true), el.getTop(true)]; + } + xy = this.xy || el.getXY(); + + + if (this.floating && this.floatParent) { + var o = this.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()); + }, + + onEnable: function() { + var actionEl = this.getActionEl(); + actionEl.dom.removeAttribute('aria-disabled'); + actionEl.dom.disabled = false; + this.callParent(); + }, + + onDisable: function() { + var actionEl = this.getActionEl(); + actionEl.dom.setAttribute('aria-disabled', true); + actionEl.dom.disabled = true; + this.callParent(); + }, + + + show: function(animateTarget, cb, scope) { + if (this.rendered && this.isVisible()) { + if (this.toFrontOnShow && this.floating) { + this.toFront(); + } + } else if (this.fireEvent('beforeshow', this) !== false) { + this.hidden = false; + + + if (!this.rendered && (this.autoRender || this.floating)) { + this.doAutoRender(); + } + if (this.rendered) { + this.beforeShow(); + this.onShow.apply(this, arguments); + + + + if (this.ownerCt && !this.floating && !(this.ownerCt.suspendLayout || this.ownerCt.layout.layoutBusy)) { + this.ownerCt.doLayout(); + } + this.afterShow.apply(this, arguments); + } + } + return this; + }, + + beforeShow: Ext.emptyFn, + + + onShow: function() { + var me = this; + + me.el.show(); + if (this.floating && this.constrain) { + this.doConstrain(); + } + me.callParent(arguments); + }, + + afterShow: function(animateTarget, cb, scope) { + var me = this, + fromBox, + toBox, + ghostPanel; + + + animateTarget = animateTarget || me.animateTarget; + + + if (!me.ghost) { + animateTarget = null; + } + + if (animateTarget) { + 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.animate({ + from: fromBox, + to: toBox, + listeners: { + afteranimate: function() { + delete ghostPanel.componentLayout.lastComponentSize; + me.unghost(); + me.el.removeCls(Ext.baseCSSPrefix + 'hide-offsets'); + if (me.floating) { + me.toFront(); + } + Ext.callback(cb, scope || me); + } + } + }); + } + else { + if (me.floating) { + me.toFront(); + } + Ext.callback(cb, scope || me); + } + me.fireEvent('show', me); + }, + + + hide: function() { + + + + this.showOnParentShow = false; + + if (!(this.rendered && !this.isVisible()) && this.fireEvent('beforehide', this) !== false) { + this.hidden = true; + if (this.rendered) { + this.onHide.apply(this, arguments); + + + + if (this.ownerCt && !this.floating && !(this.ownerCt.suspendLayout || this.ownerCt.layout.layoutBusy)) { + this.ownerCt.doLayout(); + } + } + } + return this; + }, + + + onHide: function(animateTarget, cb, scope) { + var me = this, + ghostPanel, + toBox; + + + animateTarget = animateTarget || me.animateTarget; + + + if (!me.ghost) { + animateTarget = null; + } + + if (animateTarget) { + animateTarget = animateTarget.el ? animateTarget.el : Ext.get(animateTarget); + ghostPanel = me.ghost(); + ghostPanel.el.stopAnimation(); + toBox = animateTarget.getBox(); + toBox.width += 'px'; + toBox.height += 'px'; + ghostPanel.el.animate({ + to: toBox, + listeners: { + afteranimate: function() { + delete ghostPanel.componentLayout.lastComponentSize; + ghostPanel.el.hide(); + me.afterHide(cb, scope); + } + } + }); + } + me.el.hide(); + if (!animateTarget) { + me.afterHide(cb, scope); + } + }, + + afterHide: function(cb, scope) { + Ext.callback(cb, scope || this); + this.fireEvent('hide', this); + }, + + + onDestroy: function() { + var me = this; + + + if (me.rendered) { + Ext.destroy( + me.proxy, + me.resizer + ); + + if (me.actionMode == 'container' || me.removeMode == 'container') { + me.container.remove(); + } + } + me.callParent(); + }, + + deleteMembers: function() { + var args = arguments, + len = args.length, + i = 0; + for (; i < len; ++i) { + delete this[args[i]]; + } + }, + + + focus: function(selectText, delay) { + var me = this, + focusEl; + + if (delay) { + me.focusTask.delay(Ext.isNumber(delay) ? delay: 10, null, me, [selectText, false]); + return me; + } + + if (me.rendered && !me.isDestroyed) { + + focusEl = me.getFocusEl(); + focusEl.focus(); + if (focusEl.dom && selectText === true) { + focusEl.dom.select(); + } + + + + if (me.floating) { + me.toFront(true); + } + } + return me; + }, + + + getFocusEl: function() { + return this.el; + }, + + + blur: function() { + if (this.rendered) { + this.getFocusEl().blur(); + } + return this; + }, + + getEl: function() { + return this.el; + }, + + + getResizeEl: function() { + return this.el; + }, + + + getPositionEl: function() { + return this.el; + }, + + + getActionEl: function() { + return this.el; + }, + + + getVisibilityEl: function() { + return this.el; + }, + + + onResize: Ext.emptyFn, + + + getBubbleTarget: function() { + return this.ownerCt; + }, + + + getContentTarget: function() { + return this.el; + }, + + + cloneConfig: function(overrides) { + overrides = overrides || {}; + var id = overrides.id || Ext.id(); + var cfg = Ext.applyIf(overrides, this.initialConfig); + cfg.id = id; + + var self = Ext.getClass(this); + + + return new self(cfg); + }, + + + getXType: function() { + return this.self.xtype; + }, + + + findParentBy: function(fn) { + var p; + + + for (p = this.ownerCt; p && !fn(p, this); p = p.ownerCt); + return p || null; + }, + + + findParentByType: function(xtype) { + return Ext.isFunction(xtype) ? + this.findParentBy(function(p) { + return p.constructor === xtype; + }) + : + this.up(xtype); + }, + + + bubble: function(fn, scope, args) { + var p = this; + while (p) { + if (fn.apply(scope || p, args || [p]) === false) { + break; + } + p = p.ownerCt; + } + return this; + }, + + getProxy: function() { + if (!this.proxy) { + this.proxy = this.el.createProxy(Ext.baseCSSPrefix + 'proxy-el', Ext.getBody(), true); + } + return this.proxy; + } + +}, function() { + + + this.prototype.focusTask = Ext.create('Ext.util.DelayedTask', this.prototype.focus); + +}); + + +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); + + } + }, + + getLayoutTargetSize : function() { + var target = this.getTarget(), + ret; + + if (target) { + ret = target.getViewSize(); + + + + + if (Ext.isIE && ret.width == 0){ + ret = target.getStyleSize(); + } + + ret.width -= target.getPadding('lr'); + ret.height -= target.getPadding('tb'); + } + return ret; + }, + + beforeLayout: function() { + if (this.owner.beforeLayout(arguments) !== false) { + return this.callParent(arguments); + } + else { + return false; + } + }, + + afterLayout: function() { + this.owner.afterLayout(arguments); + this.callParent(arguments); + }, + + + getRenderedItems: function() { + var me = this, + target = me.getTarget(), + items = me.getLayoutItems(), + ln = items.length, + renderedItems = [], + i, item; + + for (i = 0; i < ln; i++) { + item = items[i]; + if (item.rendered && me.isValidParent(item, target, i)) { + renderedItems.push(item); + } + } + + return renderedItems; + }, + + + getVisibleItems: function() { + var target = this.getTarget(), + items = this.getLayoutItems(), + ln = items.length, + visibleItems = [], + i, item; + + for (i = 0; i < ln; i++) { + item = items[i]; + if (item.rendered && this.isValidParent(item, target, i) && item.hidden !== true) { + visibleItems.push(item); + } + } + + return visibleItems; + } +}); + + +Ext.define('Ext.layout.container.Auto', { + + + + alias: ['layout.auto', 'layout.autocontainer'], + + extend: 'Ext.layout.container.Container', + + + + type: 'autocontainer', + + fixedLayout: false, + + bindToOwnerCtComponent: true, + + + onLayout : function(owner, target) { + var me = this, + items = me.getLayoutItems(), + ln = items.length, + i; + + + if (ln) { + + + + if (!me.clearEl) { + me.clearEl = me.getRenderTarget().createChild({ + cls: Ext.baseCSSPrefix + 'clear', + role: 'presentation' + }); + } + + + for (i = 0; i < ln; i++) { + me.setItemSize(items[i]); + } + } + } +}); + +Ext.define('Ext.container.AbstractContainer', { + + + + extend: 'Ext.Component', + + requires: [ + 'Ext.util.MixedCollection', + 'Ext.layout.container.Auto', + 'Ext.ZIndexManager' + ], + + + + + + + + + + suspendLayout : false, + + + autoDestroy : true, + + + defaultType: 'panel', + + isContainer : true, + + baseCls: Ext.baseCSSPrefix + 'container', + + + bubbleEvents: ['add', 'remove'], + + + initComponent : function(){ + var me = this; + me.addEvents( + + 'afterlayout', + + 'beforeadd', + + 'beforeremove', + + 'add', + + 'remove', + + 'beforecardswitch', + + 'cardswitch' + ); + + + me.layoutOnShow = Ext.create('Ext.util.MixedCollection'); + me.callParent(); + me.initItems(); + }, + + + initItems : function() { + var me = this, + items = me.items; + + + me.items = Ext.create('Ext.util.MixedCollection', false, me.getComponentId); + + if (items) { + if (!Ext.isArray(items)) { + items = [items]; + } + + me.add(items); + } + }, + + + afterRender : function() { + this.getLayout(); + this.callParent(); + }, + + + setLayout : function(layout) { + var currentLayout = this.layout; + + if (currentLayout && currentLayout.isLayout && currentLayout != layout) { + currentLayout.setOwner(null); + } + + this.layout = layout; + layout.setOwner(this); + }, + + + getLayout : function() { + var me = this; + if (!me.layout || !me.layout.isLayout) { + me.setLayout(Ext.layout.Layout.create(me.layout, 'autocontainer')); + } + + return me.layout; + }, + + + doLayout : function() { + var me = this, + layout = me.getLayout(); + + if (me.rendered && layout && !me.suspendLayout) { + + if ((!Ext.isNumber(me.width) || !Ext.isNumber(me.height)) && me.componentLayout.type !== 'autocomponent') { + + if (me.componentLayout.layoutBusy !== true) { + me.doComponentLayout(); + if (me.componentLayout.layoutCancelled === true) { + layout.layout(); + } + } + } + + else { + + if (layout.layoutBusy !== true) { + layout.layout(); + } + } + } + + return me; + }, + + + afterLayout : function(layout) { + this.fireEvent('afterlayout', this, layout); + }, + + + prepareItems : function(items, applyDefaults) { + if (!Ext.isArray(items)) { + items = [items]; + } + + + var i = 0, + len = items.length, + item; + + for (; i < len; i++) { + item = items[i]; + if (applyDefaults) { + item = this.applyDefaults(item); + } + items[i] = this.lookupComponent(item); + } + return items; + }, + + + applyDefaults : function(config) { + var defaults = this.defaults; + + if (defaults) { + if (Ext.isFunction(defaults)) { + defaults = defaults.call(this, config); + } + + if (Ext.isString(config)) { + config = Ext.ComponentManager.get(config); + Ext.applyIf(config, defaults); + } else if (!config.isComponent) { + Ext.applyIf(config, defaults); + } else { + Ext.applyIf(config, defaults); + } + } + + return config; + }, + + + lookupComponent : function(comp) { + return Ext.isString(comp) ? Ext.ComponentManager.get(comp) : this.createComponent(comp); + }, + + + createComponent : function(config, defaultType) { + + + + + + + + return Ext.ComponentManager.create(config, defaultType || this.defaultType); + }, + + + getComponentId : function(comp) { + return comp.getItemId(); + }, + + + add : function() { + var me = this, + args = Array.prototype.slice.call(arguments), + hasMultipleArgs, + items, + results = [], + i, + ln, + item, + index = -1, + cmp; + + if (typeof args[0] == 'number') { + index = args.shift(); + } + + hasMultipleArgs = args.length > 1; + if (hasMultipleArgs || Ext.isArray(args[0])) { + + items = hasMultipleArgs ? args : args[0]; + + 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 { + item = me.add(item); + } + results.push(item); + } + + me.suspendLayout = false; + me.doLayout(); + return results; + } + + cmp = me.prepareItems(args[0], true)[0]; + + + + + if (cmp.floating) { + cmp.onAdded(me, index); + } else { + index = (index !== -1) ? index : me.items.length; + if (me.fireEvent('beforeadd', me, cmp, index) !== false && me.onBeforeAdd(cmp) !== false) { + me.items.insert(index, cmp); + cmp.onAdded(me, index); + me.onAdd(cmp, index); + me.fireEvent('add', me, cmp, index); + } + me.doLayout(); + } + 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, + + + insert : function(index, comp) { + return this.add(index, comp); + }, + + + move : function(fromIdx, toIdx) { + var items = this.items, + item; + item = items.removeAt(fromIdx); + if (item === false) { + return false; + } + items.insert(toIdx, item); + this.doLayout(); + return item; + }, + + + onBeforeAdd : function(item) { + var me = this; + + if (item.ownerCt) { + item.ownerCt.remove(item, false); + } + + if (me.border === false || me.border === 0) { + item.border = (item.border === true); + } + }, + + + 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); + me.fireEvent('remove', me, c); + } + + return c; + }, + + + doRemove : function(component, autoDestroy) { + var me = this, + layout = me.layout, + hasLayout = layout && me.rendered; + + me.items.remove(component); + component.onRemoved(); + + if (hasLayout) { + layout.onRemove(component); + } + + me.onRemove(component, autoDestroy); + + if (autoDestroy === true || (autoDestroy !== false && me.autoDestroy)) { + component.destroy(); + } + + if (hasLayout && !autoDestroy) { + layout.afterRemove(component); + } + + if (!me.destroying) { + me.doLayout(); + } + }, + + + removeAll : function(autoDestroy) { + var me = this, + removeItems = me.items.items.slice(), + items = [], + i = 0, + len = removeItems.length, + item; + + + me.suspendLayout = true; + for (; i < len; i++) { + item = removeItems[i]; + me.remove(item, autoDestroy); + + if (item.ownerCt !== me) { + items.push(item); + } + } + + + me.suspendLayout = false; + me.doLayout(); + return items; + }, + + + + + + + + + + getRefItems : function(deep) { + var me = this, + items = me.items.items, + len = items.length, + i = 0, + item, + result = []; + + for (; i < len; i++) { + item = items[i]; + result.push(item); + if (deep && item.getRefItems) { + result.push.apply(result, item.getRefItems(true)); + } + } + + + + if (me.floatingItems && me.floatingItems.accessList) { + result.push.apply(result, me.floatingItems.accessList); + } + + return result; + }, + + + cascade : function(fn, scope, origArgs){ + var me = this, + cs = me.items ? me.items.items : [], + len = cs.length, + i = 0, + c, + args = origArgs ? origArgs.concat(me) : [me], + componentIndex = args.length - 1; + + if (fn.apply(scope || me, args) !== false) { + for(; i < len; i++){ + c = cs[i]; + if (c.cascade) { + c.cascade(fn, scope, origArgs); + } else { + args[componentIndex] = c; + fn.apply(scope || cs, args); + } + } + } + return this; + }, + + + getComponent : function(comp) { + if (Ext.isObject(comp)) { + comp = comp.getItemId(); + } + + return this.items.get(comp); + }, + + + query : function(selector) { + return Ext.ComponentQuery.query(selector, this); + }, + + + child : function(selector) { + return this.query('> ' + selector)[0] || null; + }, + + + down : function(selector) { + return this.query(selector)[0] || null; + }, + + + show : function() { + this.callParent(arguments); + this.performDeferredLayouts(); + return this; + }, + + + + performDeferredLayouts: function() { + var layoutCollection = this.layoutOnShow, + ln = layoutCollection.getCount(), + i = 0, + needsLayout, + item; + + for (; i < ln; i++) { + item = layoutCollection.get(i); + needsLayout = item.needsLayout; + + if (Ext.isObject(needsLayout)) { + item.doComponentLayout(needsLayout.width, needsLayout.height, needsLayout.isSetSize, needsLayout.ownerCt); + } + } + layoutCollection.clear(); + }, + + //@private + + + onEnable: function() { + Ext.Array.each(this.query('[isFormField]'), function(item) { + if (item.resetDisable) { + item.enable(); + delete item.resetDisable; + } + }); + this.callParent(); + }, + + + + onDisable: function() { + Ext.Array.each(this.query('[isFormField]'), function(item) { + if (item.resetDisable !== false && !item.disabled) { + item.disable(); + item.resetDisable = true; + } + }); + this.callParent(); + }, + + + beforeLayout: function() { + return true; + }, + + + beforeDestroy : function() { + var me = this, + items = me.items, + c; + + if (items) { + while ((c = items.first())) { + me.doRemove(c, true); + } + } + + Ext.destroy( + me.layout, + me.floatingItems + ); + me.callParent(); + } +}); + +Ext.define('Ext.container.Container', { + extend: 'Ext.container.AbstractContainer', + alias: 'widget.container', + alternateClassName: 'Ext.Container', + + + getChildByElement: function(el) { + var item, + itemEl, + i = 0, + it = this.items.items, + ln = it.length; + + el = Ext.getDom(el); + for (; i < ln; i++) { + item = it[i]; + itemEl = item.getEl(); + if ((itemEl.dom === el) || itemEl.contains(el)) { + return item; + } + } + return null; + } +}); + + +Ext.define('Ext.toolbar.Fill', { + extend: 'Ext.Component', + alias: 'widget.tbfill', + alternateClassName: 'Ext.Toolbar.Fill', + isFill : true, + flex: 1 +}); + +Ext.define('Ext.toolbar.Item', { + extend: 'Ext.Component', + alias: 'widget.tbitem', + alternateClassName: 'Ext.Toolbar.Item', + enable:Ext.emptyFn, + disable:Ext.emptyFn, + focus:Ext.emptyFn + +}); + +Ext.define('Ext.toolbar.Separator', { + extend: 'Ext.toolbar.Item', + alias: 'widget.tbseparator', + alternateClassName: 'Ext.Toolbar.Separator', + baseCls: Ext.baseCSSPrefix + 'toolbar-separator', + focusable: false +}); + +Ext.define('Ext.menu.Manager', { + singleton: true, + requires: [ + 'Ext.util.MixedCollection', + 'Ext.util.KeyMap' + ], + alternateClassName: 'Ext.menu.MenuMgr', + + uses: ['Ext.menu.Menu'], + + menus: {}, + groups: {}, + attached: false, + lastShow: new Date(), + + init: function() { + var me = this; + + me.active = Ext.create('Ext.util.MixedCollection'); + Ext.getDoc().addKeyListener(27, function() { + if (me.active.length > 0) { + me.hideAll(); + } + }, me); + }, + + + hideAll: function() { + var active = this.active, + c; + if (active && active.length > 0) { + c = active.clone(); + c.each(function(m) { + m.hide(); + }); + return true; + } + return false; + }, + + onHide: function(m) { + var me = this, + active = me.active; + active.remove(m); + if (active.length < 1) { + Ext.getDoc().un('mousedown', me.onMouseDown, me); + me.attached = false; + } + }, + + onShow: function(m) { + var me = this, + active = me.active, + last = active.last(), + attached = me.attached, + menuEl = m.getEl(), + zIndex; + + me.lastShow = new Date(); + active.add(m); + if (!attached) { + Ext.getDoc().on('mousedown', me.onMouseDown, me); + me.attached = true; + } + m.toFront(); + }, + + onBeforeHide: function(m) { + if (m.activeChild) { + m.activeChild.hide(); + } + if (m.autoHideTimer) { + clearTimeout(m.autoHideTimer); + delete m.autoHideTimer; + } + }, + + onBeforeShow: function(m) { + var active = this.active, + parentMenu = m.parentMenu; + + active.remove(m); + if (!parentMenu && !m.allowOtherMenus) { + this.hideAll(); + } + else if (parentMenu && parentMenu.activeChild && m != parentMenu.activeChild) { + parentMenu.activeChild.hide(); + } + }, + + + onMouseDown: function(e) { + var me = this, + active = me.active, + lastShow = me.lastShow; + + if (Ext.Date.getElapsed(lastShow) > 50 && active.length > 0 && !e.getTarget('.' + Ext.baseCSSPrefix + 'menu')) { + me.hideAll(); + } + }, + + + register: function(menu) { + var me = this; + + if (!me.active) { + me.init(); + } + + if (menu.floating) { + me.menus[menu.id] = menu; + menu.on({ + beforehide: me.onBeforeHide, + hide: me.onHide, + beforeshow: me.onBeforeShow, + show: me.onShow, + scope: me + }); + } + }, + + + get: function(menu) { + var menus = this.menus; + + if (typeof menu == 'string') { + if (!menus) { + return null; + } + return menus[menu]; + } else if (menu.isMenu) { + return menu; + } else if (Ext.isArray(menu)) { + return Ext.create('Ext.menu.Menu', {items:menu}); + } else { + return Ext.ComponentManager.create(menu, 'menu'); + } + }, + + + unregister: function(menu) { + var me = this, + menus = me.menus, + active = me.active; + + delete menus[menu.id]; + active.remove(menu); + menu.un({ + beforehide: me.onBeforeHide, + hide: me.onHide, + beforeshow: me.onBeforeShow, + show: me.onShow, + scope: me + }); + }, + + + registerCheckable: function(menuItem) { + var groups = this.groups, + groupId = menuItem.group; + + if (groupId) { + if (!groups[groupId]) { + groups[groupId] = []; + } + + groups[groupId].push(menuItem); + } + }, + + + unregisterCheckable: function(menuItem) { + var groups = this.groups, + groupId = menuItem.group; + + if (groupId) { + Ext.Array.remove(groups[groupId], menuItem); + } + }, + + onCheckChange: function(menuItem, state) { + var groups = this.groups, + groupId = menuItem.group, + i = 0, + group, ln, curr; + + if (groupId && state) { + group = groups[groupId]; + ln = group.length; + for (; i < ln; i++) { + curr = group[i]; + if (curr != menuItem) { + curr.setChecked(false); + } + } + } + } +}); + +Ext.define('Ext.button.Button', { + + + alias: 'widget.button', + extend: 'Ext.Component', + + requires: [ + 'Ext.menu.Manager', + 'Ext.util.ClickRepeater', + 'Ext.layout.component.Button', + 'Ext.util.TextMetrics', + 'Ext.util.KeyMap' + ], + + alternateClassName: 'Ext.Button', + + + isButton: true, + componentLayout: 'button', + + + hidden: false, + + + disabled: false, + + + pressed: false, + + + + + + + + + + + + + + + + + + + + + + + + + + + enableToggle: false, + + + + + + + menuAlign: 'tl-bl?', + + + + + + + type: 'button', + + + clickEvent: 'click', + + + preventDefault: true, + + + handleMouseEvents: true, + + + tooltipType: 'qtip', + + + baseCls: Ext.baseCSSPrefix + 'btn', + + + pressedCls: 'pressed', + + + overCls: 'over', + + + focusCls: 'focus', + + + menuActiveCls: 'menu-active', + + ariaRole: 'button', + + + renderTpl: + '' + + '' + + ' tabIndex="{tabIndex}" role="link">' + + '{text}' + + '' + + '' + + '' + + '' + + '' + + '' , + + + scale: 'small', + + + allowedScales: ['small', 'medium', 'large'], + + + + + iconAlign: 'left', + + + arrowAlign: 'right', + + + arrowCls: 'arrow', + + + + + + + + + + maskOnDisable: false, + + + initComponent: function() { + var me = this; + me.callParent(arguments); + + me.addEvents( + + 'click', + + + 'toggle', + + + 'mouseover', + + + 'mouseout', + + + 'menushow', + + + 'menuhide', + + + 'menutriggerover', + + + 'menutriggerout' + ); + + if (me.menu) { + + me.split = true; + + + me.menu = Ext.menu.Manager.get(me.menu); + me.menu.ownerCt = me; + } + + + if (me.url) { + me.href = me.url; + } + + + if (me.href && !me.hasOwnProperty('preventDefault')) { + me.preventDefault = false; + } + + if (Ext.isString(me.toggleGroup)) { + me.enableToggle = true; + } + + }, + + + initAria: function() { + this.callParent(); + var actionEl = this.getActionEl(); + if (this.menu) { + actionEl.dom.setAttribute('aria-haspopup', true); + } + }, + + + getActionEl: function() { + return this.btnEl; + }, + + + getFocusEl: function() { + return this.btnEl; + }, + + + setButtonCls: function() { + var me = this, + el = me.el, + cls = []; + + if (me.useSetClass) { + if (!Ext.isEmpty(me.oldCls)) { + me.removeClsWithUI(me.oldCls); + me.removeClsWithUI(me.pressedCls); + } + + + if (me.iconCls || me.icon) { + if (me.text) { + cls.push('icon-text-' + me.iconAlign); + } else { + cls.push('icon'); + } + } else if (me.text) { + cls.push('noicon'); + } + + 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' + }); + + if (me.scale) { + me.ui = me.ui + '-' + me.scale; + } + + + me.callParent(arguments); + + + if (me.split && me.arrowTooltip) { + me.arrowEl.dom[me.tooltipType] = me.arrowTooltip; + } + + + me.mon(me.btnEl, { + scope: me, + focus: me.onFocus, + blur : me.onBlur + }); + + + btn = me.el; + + if (me.icon) { + me.setIcon(me.icon); + } + + if (me.iconCls) { + me.setIconCls(me.iconCls); + } + + if (me.tooltip) { + me.setTooltip(me.tooltip, true); + } + + + if (me.handleMouseEvents) { + me.mon(btn, { + scope: me, + mouseover: me.onMouseOver, + mouseout: me.onMouseOut, + mousedown: me.onMouseDown + }); + + if (me.split) { + me.mon(btn, { + mousemove: me.onMouseMove, + scope: me + }); + } + } + + + if (me.menu) { + me.mon(me.menu, { + scope: me, + show: me.onMenuShow, + hide: me.onMenuHide + }); + + me.keyMap = Ext.create('Ext.util.KeyMap', me.el, { + key: Ext.EventObject.DOWN, + handler: me.onDownKey, + scope: me + }); + } + + + if (me.repeat) { + repeater = Ext.create('Ext.util.ClickRepeater', btn, Ext.isObject(me.repeat) ? me.repeat: {}); + me.mon(repeater, 'click', me.onRepeatClick, me); + } else { + me.mon(btn, me.clickEvent, me.onClick, me); + } + + + Ext.ButtonToggleManager.register(me); + }, + + + getTemplateArgs: function() { + var me = this, + persistentPadding = me.getPersistentBtnPadding(), + innerSpanStyle = ''; + + + if (Math.max.apply(Math, persistentPadding) > 0) { + innerSpanStyle = 'margin:' + Ext.Array.map(persistentPadding, function(pad) { + return -pad + 'px'; + }).join(' '); + } + + return { + href : me.getHref(), + target : me.target || '_blank', + type : me.type, + splitCls : me.getSplitCls(), + cls : me.cls, + text : me.text || ' ', + tabIndex : me.tabIndex, + innerSpanStyle: innerSpanStyle + }; + }, + + + getHref: function() { + var me = this; + return me.href ? Ext.urlAppend(me.href, me.params + Ext.Object.toQueryString(Ext.apply(Ext.apply({}, me.baseParams)))) : false; + }, + + + setParams: function(p) { + this.params = p; + this.btnEl.dom.href = this.getHref(); + }, + + getSplitCls: function() { + var me = this; + return me.split ? (me.baseCls + '-' + me.arrowCls) + ' ' + (me.baseCls + '-' + me.arrowCls + '-' + me.arrowAlign) : ''; + }, + + + afterRender: function() { + var me = this; + me.useSetClass = true; + me.setButtonCls(); + me.doc = Ext.getDoc(); + this.callParent(arguments); + }, + + + setIconCls: function(cls) { + var me = this, + btnInnerEl = me.btnInnerEl; + if (btnInnerEl) { + + btnInnerEl.removeCls(me.iconCls); + btnInnerEl.addCls(cls || ''); + me.setButtonCls(); + } + me.iconCls = cls; + return me; + }, + + + setTooltip: function(tooltip, initial) { + var me = this; + + if (me.rendered) { + if (!initial) { + me.clearTip(); + } + if (Ext.isObject(tooltip)) { + Ext.tip.QuickTipManager.register(Ext.apply({ + target: me.btnEl.id + }, + tooltip)); + me.tooltip = tooltip; + } else { + me.btnEl.dom.setAttribute('data-' + this.tooltipType, tooltip); + } + } else { + me.tooltip = tooltip; + } + return me; + }, + + + getRefItems: function(deep){ + var menu = this.menu, + items; + + if (menu) { + items = menu.getRefItems(deep); + items.unshift(menu); + } + return items || []; + }, + + + clearTip: function() { + if (Ext.isObject(this.tooltip)) { + Ext.tip.QuickTipManager.unregister(this.btnEl); + } + }, + + + beforeDestroy: function() { + var me = this; + if (me.rendered) { + me.clearTip(); + } + if (me.menu && me.destroyMenu !== false) { + Ext.destroy(me.btnEl, me.btnInnerEl, me.menu); + } + Ext.destroy(me.repeater); + }, + + + onDestroy: function() { + var me = this; + if (me.rendered) { + 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; + } + me.callParent(); + }, + + + setHandler: function(handler, scope) { + this.handler = handler; + this.scope = scope; + return this; + }, + + + setText: function(text) { + var me = this; + me.text = text; + if (me.el) { + me.btnInnerEl.update(text || ' '); + me.setButtonCls(); + } + me.doComponentLayout(); + return me; + }, + + + setIcon: function(icon) { + var me = this, + btnInnerEl = me.btnInnerEl; + me.icon = icon; + if (btnInnerEl) { + btnInnerEl.setStyle('background-image', icon ? 'url(' + icon + ')': ''); + me.setButtonCls(); + } + return me; + }, + + + getText: function() { + return this.text; + }, + + + toggle: function(state, suppressEvent) { + var me = this; + state = state === undefined ? !me.pressed: !!state; + if (state !== me.pressed) { + if (me.rendered) { + me[state ? 'addClsWithUI': 'removeClsWithUI'](me.pressedCls); + } + me.btnEl.dom.setAttribute('aria-pressed', state); + me.pressed = state; + if (!suppressEvent) { + me.fireEvent('toggle', me, state); + Ext.callback(me.toggleHandler, me.scope || me, [me, state]); + } + } + return me; + }, + + + showMenu: function() { + var me = this; + if (me.rendered && me.menu) { + if (me.tooltip) { + Ext.tip.QuickTipManager.getQuickTip().cancelShow(me.btnEl); + } + if (me.menu.isVisible()) { + me.menu.hide(); + } + + me.menu.showBy(me.el, me.menuAlign); + } + return me; + }, + + + hideMenu: function() { + if (this.hasVisibleMenu()) { + this.menu.hide(); + } + return this; + }, + + + hasVisibleMenu: function() { + var menu = this.menu; + return menu && menu.rendered && menu.isVisible(); + }, + + + onRepeatClick: function(repeat, e) { + this.onClick(e); + }, + + + onClick: function(e) { + var me = this; + if (me.preventDefault || (me.disabled && me.getHref()) && e) { + e.preventDefault(); + } + if (e.button !== 0) { + 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(); + } + }, + + + onMouseOver: function(e) { + var me = this; + if (!me.disabled && !e.within(me.el, true, true)) { + me.onMouseEnter(e); + } + }, + + + onMouseOut: function(e) { + var me = this; + if (!e.within(me.el, true, true)) { + if (me.overMenuTrigger) { + me.onMenuTriggerOut(e); + } + me.onMouseLeave(e); + } + }, + + + onMouseMove: function(e) { + var me = this, + el = me.el, + over = me.overMenuTrigger, + overlap, btnSize; + + if (me.split) { + if (me.arrowAlign === 'right') { + overlap = e.getX() - el.getX(); + btnSize = el.getWidth(); + } else { + overlap = e.getY() - el.getY(); + btnSize = el.getHeight(); + } + + if (overlap > (btnSize - me.getTriggerSize())) { + if (!over) { + me.onMenuTriggerOver(e); + } + } else { + if (over) { + me.onMenuTriggerOut(e); + } + } + } + }, + + + getTriggerSize: function() { + var me = this, + size = me.triggerSize, + side, sideFirstLetter, undef; + + if (size === undef) { + side = me.arrowAlign; + sideFirstLetter = side.charAt(0); + size = me.triggerSize = me.el.getFrameWidth(sideFirstLetter) + me.btnWrap.getFrameWidth(sideFirstLetter) + (me.frameSize && me.frameSize[side] || 0); + } + return size; + }, + + + onMouseEnter: function(e) { + var me = this; + me.addClsWithUI(me.overCls); + me.fireEvent('mouseover', me, e); + }, + + + onMouseLeave: function(e) { + var me = this; + me.removeClsWithUI(me.overCls); + me.fireEvent('mouseout', me, e); + }, + + + onMenuTriggerOver: function(e) { + var me = this; + me.overMenuTrigger = true; + me.fireEvent('menutriggerover', me, me.menu, e); + }, + + + onMenuTriggerOut: function(e) { + var me = this; + delete me.overMenuTrigger; + me.fireEvent('menutriggerout', me, me.menu, e); + }, + + + enable : function(silent) { + var me = this; + + me.callParent(arguments); + + me.removeClsWithUI('disabled'); + + return me; + }, + + + disable : function(silent) { + var me = this; + + me.callParent(arguments); + + me.addClsWithUI('disabled'); + + 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; + if (!me.disabled) { + me.addClsWithUI(me.focusCls); + } + }, + + + onBlur: function(e) { + var me = this; + me.removeClsWithUI(me.focusCls); + }, + + + onMouseDown: function(e) { + var me = this; + if (!me.disabled && e.button === 0) { + me.addClsWithUI(me.pressedCls); + me.doc.on('mouseup', me.onMouseUp, me); + } + }, + + onMouseUp: function(e) { + var me = this; + if (e.button === 0) { + if (!me.pressed) { + me.removeClsWithUI(me.pressedCls); + } + me.doc.un('mouseup', me.onMouseUp, me); + } + }, + + onMenuShow: function(e) { + var me = this; + me.ignoreNextClick = 0; + me.addClsWithUI(me.menuActiveCls); + me.fireEvent('menushow', me, me.menu); + }, + + + onMenuHide: function(e) { + var me = this; + me.removeClsWithUI(me.menuActiveCls); + me.ignoreNextClick = Ext.defer(me.restoreClick, 250, me); + me.fireEvent('menuhide', me, me.menu); + }, + + + restoreClick: function() { + this.ignoreNextClick = 0; + }, + + + onDownKey: function() { + var me = this; + + if (!me.disabled) { + if (me.menu) { + me.showMenu(); + } + } + }, + + + getPersistentBtnPadding: function() { + var cls = Ext.button.Button, + padding = cls.persistentPadding, + btn, leftTop, btnEl, btnInnerEl; + + if (!padding) { + padding = cls.persistentPadding = [0, 0, 0, 0]; + + if (!Ext.isIE) { + + btn = Ext.create('Ext.button.Button', { + renderTo: Ext.getBody(), + text: 'test', + style: 'position:absolute;top:-999px;' + }); + btnEl = btn.btnEl; + btnInnerEl = btn.btnInnerEl; + btnEl.setSize(null, null); + + leftTop = btnInnerEl.getOffsetsTo(btnEl); + padding[0] = leftTop[1]; + padding[1] = btnEl.getWidth() - btnInnerEl.getWidth() - leftTop[0]; + padding[2] = btnEl.getHeight() - btnInnerEl.getHeight() - leftTop[1]; + padding[3] = leftTop[0]; + + btn.destroy(); + } + } + + return padding; + } + +}, function() { + var groups = {}, + g, i, l; + + function toggleGroup(btn, state) { + if (state) { + g = groups[btn.toggleGroup]; + for (i = 0, l = g.length; i < l; i++) { + if (g[i] !== btn) { + g[i].toggle(false); + } + } + } + } + + Ext.ButtonToggleManager = { + register: function(btn) { + if (!btn.toggleGroup) { + return; + } + var group = groups[btn.toggleGroup]; + if (!group) { + group = groups[btn.toggleGroup] = []; + } + group.push(btn); + btn.on('toggle', toggleGroup); + }, + + unregister: function(btn) { + if (!btn.toggleGroup) { + return; + } + var group = groups[btn.toggleGroup]; + if (group) { + Ext.Array.remove(group, btn); + btn.un('toggle', toggleGroup); + } + }, + + + getPressed: function(group) { + var g = groups[group], + i = 0, + len; + if (g) { + for (len = g.length; i < len; i++) { + if (g[i].pressed === true) { + return g[i]; + } + } + } + return null; + } + }; +}); + + +Ext.define('Ext.layout.container.boxOverflow.Menu', { + + + + extend: 'Ext.layout.container.boxOverflow.None', + requires: ['Ext.toolbar.Separator', 'Ext.button.Button'], + alternateClassName: 'Ext.layout.boxOverflow.Menu', + + + + + + + noItemsMenuText : '
(None)
', + + constructor: function(layout) { + var me = this; + + me.callParent(arguments); + + + layout.beforeLayout = Ext.Function.createInterceptor(layout.beforeLayout, this.clearOverflow, this); + + me.afterCtCls = me.afterCtCls || Ext.baseCSSPrefix + 'box-menu-' + layout.parallelAfter; + + me.menuItems = []; + }, + + handleOverflow: function(calculations, targetSize) { + var me = this, + layout = me.layout, + methodName = 'get' + layout.parallelPrefixCap, + newSize = {}, + posArgs = [null, null]; + + me.callParent(arguments); + this.createMenu(calculations, targetSize); + newSize[layout.perpendicularPrefix] = targetSize[layout.perpendicularPrefix]; + newSize[layout.parallelPrefix] = targetSize[layout.parallelPrefix] - me.afterCt[methodName](); + + + + posArgs[layout.perpendicularSizeIndex] = (calculations.meta.maxSize - me.menuTrigger['get' + layout.perpendicularPrefixCap]()) / 2; + me.menuTrigger.setPosition.apply(me.menuTrigger, posArgs); + + return { targetSize: newSize }; + }, + + + clearOverflow: function(calculations, targetSize) { + var me = this, + newWidth = targetSize ? targetSize.width + (me.afterCt ? me.afterCt.getWidth() : 0) : 0, + items = me.menuItems, + i = 0, + length = items.length, + item; + + me.hideTrigger(); + for (; i < length; i++) { + items[i].show(); + } + items.length = 0; + + return targetSize ? { + targetSize: { + height: targetSize.height, + width : newWidth + } + } : null; + }, + + + showTrigger: function() { + this.menuTrigger.show(); + }, + + + hideTrigger: function() { + if (this.menuTrigger != undefined) { + this.menuTrigger.hide(); + } + }, + + + beforeMenuShow: function(menu) { + var me = this, + items = me.menuItems, + i = 0, + len = items.length, + item, + prev; + + var needsSep = function(group, prev){ + return group.isXType('buttongroup') && !(prev instanceof Ext.toolbar.Separator); + }; + + me.clearMenu(); + menu.removeAll(); + + for (; i < len; i++) { + item = items[i]; + + + if (!i && (item instanceof Ext.toolbar.Separator)) { + continue; + } + if (prev && (needsSep(item, prev) || needsSep(prev, item))) { + menu.add('-'); + } + + me.addComponentToMenu(menu, item); + prev = item; + } + + + if (menu.items.length < 1) { + menu.add(me.noItemsMenuText); + } + }, + + + createMenuConfig : function(component, hideOnClick) { + var config = Ext.apply({}, component.initialConfig), + group = component.toggleGroup; + + Ext.copyTo(config, component, [ + 'iconCls', 'icon', 'itemId', 'disabled', 'handler', 'scope', 'menu' + ]); + + Ext.apply(config, { + text : component.overflowText || component.text, + hideOnClick: hideOnClick, + destroyMenu: false + }); + + if (group || component.enableToggle) { + Ext.apply(config, { + group : group, + checked: component.pressed, + listeners: { + checkchange: function(item, checked){ + component.toggle(checked); + } + } + }); + } + + delete config.ownerCt; + delete config.xtype; + delete config.id; + return config; + }, + + + addComponentToMenu : function(menu, component) { + var me = this; + if (component instanceof Ext.toolbar.Separator) { + menu.add('-'); + } else if (component.isComponent) { + if (component.isXType('splitbutton')) { + menu.add(me.createMenuConfig(component, true)); + + } else if (component.isXType('button')) { + menu.add(me.createMenuConfig(component, !component.menu)); + + } else if (component.isXType('buttongroup')) { + component.items.each(function(item){ + me.addComponentToMenu(menu, item); + }); + } else { + menu.add(Ext.create(Ext.getClassName(component), me.createMenuConfig(component))); + } + } + }, + + + clearMenu : function() { + var menu = this.moreMenu; + if (menu && menu.items) { + menu.items.each(function(item) { + if (item.menu) { + delete item.menu; + } + }); + } + }, + + + createMenu: function(calculations, targetSize) { + var me = this, + layout = me.layout, + startProp = layout.parallelBefore, + sizeProp = layout.parallelPrefix, + available = targetSize[sizeProp], + boxes = calculations.boxes, + i = 0, + len = boxes.length, + box; + + if (!me.menuTrigger) { + me.createInnerElements(); + + + me.menu = Ext.create('Ext.menu.Menu', { + hideMode: 'offsets', + listeners: { + scope: me, + beforeshow: me.beforeMenuShow + } + }); + + + me.menuTrigger = Ext.create('Ext.button.Button', { + ownerCt : me.layout.owner, + iconCls : Ext.baseCSSPrefix + layout.owner.getXType() + '-more-icon', + ui : layout.owner instanceof Ext.toolbar.Toolbar ? 'default-toolbar' : 'default', + menu : me.menu, + getSplitCls: function() { return '';}, + renderTo: me.afterCt + }); + } + me.showTrigger(); + available -= me.afterCt.getWidth(); + + + + me.menuItems.length = 0; + for (; i < len; i++) { + box = boxes[i]; + if (box[startProp] + box[sizeProp] > available) { + me.menuItems.push(box.component); + box.component.hide(); + } + } + }, + + + createInnerElements: function() { + var me = this, + target = me.layout.getRenderTarget(); + + if (!this.afterCt) { + target.addCls(Ext.baseCSSPrefix + me.layout.direction + '-box-overflow-body'); + this.afterCt = target.insertSibling({cls: Ext.layout.container.Box.prototype.innerCls + ' ' + this.afterCtCls}, 'before'); + } + }, + + + destroy: function() { + Ext.destroy(this.menu, this.menuTrigger); + } +}); + + +Ext.define('Ext.util.Region', { + + + + requires: ['Ext.util.Offset'], + + statics: { + + getRegion: function(el) { + return Ext.fly(el).getPageBox(true); + }, + + + from: function(o) { + return new this(o.top, o.right, o.bottom, o.left); + } + }, + + + + + constructor : function(t, r, b, l) { + var me = this; + me.y = me.top = me[1] = t; + me.right = r; + me.bottom = b; + me.x = me.left = me[0] = l; + }, + + + contains : function(region) { + var me = this; + return (region.x >= me.x && + region.right <= me.right && + region.y >= me.y && + region.bottom <= me.bottom); + + }, + + + intersect : function(region) { + var me = this, + t = Math.max(me.y, region.y), + r = Math.min(me.right, region.right), + b = Math.min(me.bottom, region.bottom), + l = Math.max(me.x, region.x); + + if (b > t && r > l) { + return new this.self(t, r, b, l); + } + else { + return false; + } + }, + + + union : function(region) { + var me = this, + t = Math.min(me.y, region.y), + r = Math.max(me.right, region.right), + b = Math.max(me.bottom, region.bottom), + l = Math.min(me.x, region.x); + + return new this.self(t, r, b, l); + }, + + + constrainTo : function(r) { + var me = this, + constrain = Ext.Number.constrain; + me.top = me.y = constrain(me.top, r.y, r.bottom); + me.bottom = constrain(me.bottom, r.y, r.bottom); + me.left = me.x = constrain(me.left, r.x, r.right); + me.right = constrain(me.right, r.x, r.right); + return me; + }, + + + adjust : function(t, r, b, l) { + var me = this; + me.top = me.y += t; + me.left = me.x += l; + me.right += r; + me.bottom += b; + return me; + }, + + + getOutOfBoundOffset: function(axis, p) { + if (!Ext.isObject(axis)) { + if (axis == 'x') { + return this.getOutOfBoundOffsetX(p); + } else { + return this.getOutOfBoundOffsetY(p); + } + } else { + p = axis; + var d = Ext.create('Ext.util.Offset'); + d.x = this.getOutOfBoundOffsetX(p.x); + d.y = this.getOutOfBoundOffsetY(p.y); + return d; + } + + }, + + + getOutOfBoundOffsetX: function(p) { + if (p <= this.x) { + return this.x - p; + } else if (p >= this.right) { + return this.right - p; + } + + return 0; + }, + + + getOutOfBoundOffsetY: function(p) { + if (p <= this.y) { + return this.y - p; + } else if (p >= this.bottom) { + return this.bottom - p; + } + + return 0; + }, + + + isOutOfBound: function(axis, p) { + if (!Ext.isObject(axis)) { + if (axis == 'x') { + return this.isOutOfBoundX(p); + } else { + return this.isOutOfBoundY(p); + } + } else { + p = axis; + return (this.isOutOfBoundX(p.x) || this.isOutOfBoundY(p.y)); + } + }, + + + isOutOfBoundX: function(p) { + return (p < this.x || p > this.right); + }, + + + isOutOfBoundY: function(p) { + return (p < this.y || p > this.bottom); + }, + + + restrict: function(axis, p, factor) { + if (Ext.isObject(axis)) { + var newP; + + factor = p; + p = axis; + + if (p.copy) { + newP = p.copy(); + } + else { + newP = { + x: p.x, + y: p.y + }; + } + + newP.x = this.restrictX(p.x, factor); + newP.y = this.restrictY(p.y, factor); + return newP; + } else { + if (axis == 'x') { + return this.restrictX(p, factor); + } else { + return this.restrictY(p, factor); + } + } + }, + + + restrictX : function(p, factor) { + if (!factor) { + factor = 1; + } + + if (p <= this.x) { + p -= (p - this.x) * factor; + } + else if (p >= this.right) { + p -= (p - this.right) * factor; + } + return p; + }, + + + restrictY : function(p, factor) { + if (!factor) { + factor = 1; + } + + if (p <= this.y) { + p -= (p - this.y) * factor; + } + else if (p >= this.bottom) { + p -= (p - this.bottom) * factor; + } + return p; + }, + + + getSize: function() { + return { + width: this.right - this.x, + height: this.bottom - this.y + }; + }, + + + copy: function() { + return new this.self(this.y, this.right, this.bottom, this.x); + }, + + + copyFrom: function(p) { + var me = this; + me.top = me.y = me[1] = p.y; + me.right = p.right; + me.bottom = p.bottom; + me.left = me.x = me[0] = p.x; + + return this; + }, + + + toString: function() { + return "Region[" + this.top + "," + this.right + "," + this.bottom + "," + this.left + "]"; + }, + + + + translateBy: function(x, y) { + if (arguments.length == 1) { + y = x.y; + x = x.x; + } + var me = this; + me.top = me.y += y; + me.right += x; + me.bottom += y; + me.left = me.x += x; + + return me; + }, + + + round: function() { + var me = this; + me.top = me.y = Math.round(me.y); + me.right = Math.round(me.right); + me.bottom = Math.round(me.bottom); + me.left = me.x = Math.round(me.x); + + return me; + }, + + + equals: function(region) { + return (this.top == region.top && this.right == region.right && this.bottom == region.bottom && this.left == region.left); + } +}); + + + + + +Ext.define('Ext.dd.DragDropManager', { + singleton: true, + + requires: ['Ext.util.Region'], + + uses: ['Ext.tip.QuickTipManager'], + + + alternateClassName: ['Ext.dd.DragDropMgr', 'Ext.dd.DDM'], + + + ids: {}, + + + handleIds: {}, + + + dragCurrent: null, + + + dragOvers: {}, + + + deltaX: 0, + + + deltaY: 0, + + + preventDefault: true, + + + stopPropagation: true, + + + initialized: false, + + + locked: false, + + + init: function() { + this.initialized = true; + }, + + + POINT: 0, + + + INTERSECT: 1, + + + mode: 0, + + + _execOnAll: function(sMethod, args) { + for (var i in this.ids) { + for (var j in this.ids[i]) { + var oDD = this.ids[i][j]; + if (! this.isTypeOfDD(oDD)) { + continue; + } + oDD[sMethod].apply(oDD, args); + } + } + }, + + + _onLoad: function() { + + this.init(); + + var Event = Ext.EventManager; + Event.on(document, "mouseup", this.handleMouseUp, this, true); + Event.on(document, "mousemove", this.handleMouseMove, this, true); + Event.on(window, "unload", this._onUnload, this, true); + Event.on(window, "resize", this._onResize, this, true); + + + }, + + + _onResize: function(e) { + this._execOnAll("resetConstraints", []); + }, + + + lock: function() { this.locked = true; }, + + + unlock: function() { this.locked = false; }, + + + isLocked: function() { return this.locked; }, + + + locationCache: {}, + + + useCache: true, + + + clickPixelThresh: 3, + + + clickTimeThresh: 350, + + + dragThreshMet: false, + + + clickTimeout: null, + + + startX: 0, + + + startY: 0, + + + regDragDrop: function(oDD, sGroup) { + if (!this.initialized) { this.init(); } + + if (!this.ids[sGroup]) { + this.ids[sGroup] = {}; + } + this.ids[sGroup][oDD.id] = oDD; + }, + + + removeDDFromGroup: function(oDD, sGroup) { + if (!this.ids[sGroup]) { + this.ids[sGroup] = {}; + } + + var obj = this.ids[sGroup]; + if (obj && obj[oDD.id]) { + delete obj[oDD.id]; + } + }, + + + _remove: function(oDD) { + for (var g in oDD.groups) { + if (g && this.ids[g] && this.ids[g][oDD.id]) { + delete this.ids[g][oDD.id]; + } + } + delete this.handleIds[oDD.id]; + }, + + + regHandle: function(sDDId, sHandleId) { + if (!this.handleIds[sDDId]) { + this.handleIds[sDDId] = {}; + } + this.handleIds[sDDId][sHandleId] = sHandleId; + }, + + + isDragDrop: function(id) { + return ( this.getDDById(id) ) ? true : false; + }, + + + getRelated: function(p_oDD, bTargetsOnly) { + var oDDs = []; + for (var i in p_oDD.groups) { + for (var j in this.ids[i]) { + var dd = this.ids[i][j]; + if (! this.isTypeOfDD(dd)) { + continue; + } + if (!bTargetsOnly || dd.isTarget) { + oDDs[oDDs.length] = dd; + } + } + } + + return oDDs; + }, + + + isLegalTarget: function (oDD, oTargetDD) { + var targets = this.getRelated(oDD, true); + for (var i=0, len=targets.length;i this.clickPixelThresh || + diffY > this.clickPixelThresh) { + this.startDrag(this.startX, this.startY); + } + } + + if (this.dragThreshMet) { + this.dragCurrent.b4Drag(e); + this.dragCurrent.onDrag(e); + if(!this.dragCurrent.moveOnly){ + this.fireEvents(e, false); + } + } + + this.stopEvent(e); + + return true; + }, + + + fireEvents: function(e, isDrop) { + var dc = this.dragCurrent; + + + + if (!dc || dc.isLocked()) { + return; + } + + var pt = e.getPoint(); + + + var oldOvers = []; + + var outEvts = []; + var overEvts = []; + var dropEvts = []; + var enterEvts = []; + + + + for (var i in this.dragOvers) { + + var ddo = this.dragOvers[i]; + + if (! this.isTypeOfDD(ddo)) { + continue; + } + + if (! this.isOverTarget(pt, ddo, this.mode)) { + outEvts.push( ddo ); + } + + oldOvers[i] = true; + delete this.dragOvers[i]; + } + + for (var sGroup in dc.groups) { + + if ("string" != typeof sGroup) { + continue; + } + + for (i in this.ids[sGroup]) { + var oDD = this.ids[sGroup][i]; + if (! this.isTypeOfDD(oDD)) { + continue; + } + + if (oDD.isTarget && !oDD.isLocked() && ((oDD != dc) || (dc.ignoreSelf === false))) { + if (this.isOverTarget(pt, oDD, this.mode)) { + + if (isDrop) { + dropEvts.push( oDD ); + + } else { + + + if (!oldOvers[oDD.id]) { + enterEvts.push( oDD ); + + } else { + overEvts.push( oDD ); + } + + this.dragOvers[oDD.id] = oDD; + } + } + } + } + } + + if (this.mode) { + if (outEvts.length) { + dc.b4DragOut(e, outEvts); + dc.onDragOut(e, outEvts); + } + + if (enterEvts.length) { + dc.onDragEnter(e, enterEvts); + } + + if (overEvts.length) { + dc.b4DragOver(e, overEvts); + dc.onDragOver(e, overEvts); + } + + if (dropEvts.length) { + dc.b4DragDrop(e, dropEvts); + dc.onDragDrop(e, dropEvts); + } + + } else { + + var len = 0; + for (i=0, len=outEvts.length; i 2000) { + } else { + setTimeout(this._addListeners, 10); + if (document && document.body) { + this._timeoutCount += 1; + } + } + } + }, + + + handleWasClicked: function(node, id) { + if (this.isHandle(id, node.id)) { + return true; + } else { + + var p = node.parentNode; + + while (p) { + if (this.isHandle(id, p.id)) { + return true; + } else { + p = p.parentNode; + } + } + } + + return false; + } +}, function() { + this._addListeners(); +}); + + + +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', + 'Ext.layout.container.boxOverflow.Scroller', + 'Ext.util.Format', + 'Ext.dd.DragDropManager' + ], + + + + + + + defaultMargins: { + top: 0, + right: 0, + bottom: 0, + left: 0 + }, + + + padding: '0', + + pack: 'start', + + + + + type: 'box', + scrollOffset: 0, + itemCls: Ext.baseCSSPrefix + 'box-item', + targetCls: Ext.baseCSSPrefix + 'box-layout-ct', + innerCls: Ext.baseCSSPrefix + 'box-inner', + + bindToOwnerCtContainer: true, + + fixedLayout: false, + + + + availableSpaceOffset: 0, + + + reserveOffset: true, + + + clearInnerCtOnLayout: false, + + flexSortFn: function (a, b) { + var maxParallelPrefix = 'max' + this.parallelPrefixCap, + infiniteValue = Infinity; + a = a.component[maxParallelPrefix] || infiniteValue; + b = b.component[maxParallelPrefix] || infiniteValue; + + if (!isFinite(a) && !isFinite(b)) { + return false; + } + return a - b; + }, + + + minSizeSortFn: function(a, b) { + return b.available - a.available; + }, + + constructor: function(config) { + var me = this; + + me.callParent(arguments); + + + me.flexSortFn = Ext.Function.bind(me.flexSortFn, me); + + me.initOverflowHandler(); + }, + + + getChildBox: function(child) { + child = child.el || this.owner.getComponent(child).el; + return { + left: child.getLeft(true), + top: child.getTop(true), + width: child.getWidth(), + height: child.getHeight() + }; + }, + + + calculateChildBox: function(child) { + var me = this, + boxes = me.calculateChildBoxes(me.getVisibleItems(), me.getLayoutTargetSize()).boxes, + ln = boxes.length, + i = 0; + + child = me.owner.getComponent(child); + for (; i < ln; i++) { + if (boxes[i].component === child) { + return boxes[i]; + } + } + }, + + + calculateChildBoxes: function(visibleItems, targetSize) { + var me = this, + math = Math, + mmax = math.max, + infiniteValue = Infinity, + undefinedValue, + + parallelPrefix = me.parallelPrefix, + parallelPrefixCap = me.parallelPrefixCap, + perpendicularPrefix = me.perpendicularPrefix, + perpendicularPrefixCap = me.perpendicularPrefixCap, + parallelMinString = 'min' + parallelPrefixCap, + perpendicularMinString = 'min' + perpendicularPrefixCap, + perpendicularMaxString = 'max' + perpendicularPrefixCap, + + parallelSize = targetSize[parallelPrefix] - me.scrollOffset, + perpendicularSize = targetSize[perpendicularPrefix], + padding = me.padding, + parallelOffset = padding[me.parallelBefore], + paddingParallel = parallelOffset + padding[me.parallelAfter], + perpendicularOffset = padding[me.perpendicularLeftTop], + paddingPerpendicular = perpendicularOffset + padding[me.perpendicularRightBottom], + availPerpendicularSize = mmax(0, perpendicularSize - paddingPerpendicular), + + isStart = me.pack == 'start', + isCenter = me.pack == 'center', + isEnd = me.pack == 'end', + + constrain = Ext.Number.constrain, + visibleCount = visibleItems.length, + nonFlexSize = 0, + totalFlex = 0, + desiredSize = 0, + minimumSize = 0, + maxSize = 0, + boxes = [], + 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, + perpendicularMargins, stretchSize; + + + for (i = 0; i < visibleCount; i++) { + child = visibleItems[i]; + childPerpendicular = child[perpendicularPrefix]; + me.layoutItem(child); + childMargins = child.margins; + parallelMargins = childMargins[me.parallelBefore] + childMargins[me.parallelAfter]; + + + tmpObj = { + component: child, + margins: childMargins + }; + + + if (child.flex) { + totalFlex += child.flex; + childParallel = undefinedValue; + } + + else { + if (!(child[parallelPrefix] && childPerpendicular)) { + childSize = child.getSize(); + } + childParallel = child[parallelPrefix] || childSize[parallelPrefix]; + childPerpendicular = childPerpendicular || childSize[perpendicularPrefix]; + } + + nonFlexSize += parallelMargins + (childParallel || 0); + desiredSize += parallelMargins + (child.flex ? child[parallelMinString] || 0 : childParallel); + minimumSize += parallelMargins + (child[parallelMinString] || childParallel || 0); + + + if (typeof childPerpendicular != 'number') { + + + childPerpendicular = child['get' + perpendicularPrefixCap](); + } + + + maxSize = mmax(maxSize, childPerpendicular + childMargins[me.perpendicularLeftTop] + childMargins[me.perpendicularRightBottom]); + + tmpObj[parallelPrefix] = childParallel || undefinedValue; + tmpObj[perpendicularPrefix] = childPerpendicular || undefinedValue; + boxes.push(tmpObj); + } + shortfall = desiredSize - parallelSize; + tooNarrow = minimumSize > parallelSize; + + + availableSpace = mmax(0, parallelSize - nonFlexSize - paddingParallel - (me.reserveOffset ? me.availableSpaceOffset : 0)); + + if (tooNarrow) { + for (i = 0; i < visibleCount; i++) { + box = boxes[i]; + minSize = visibleItems[i][parallelMinString] || visibleItems[i][parallelPrefix] || box[parallelPrefix]; + box.dirtySize = box.dirtySize || box[parallelPrefix] != minSize; + box[parallelPrefix] = minSize; + } + } + else { + + + if (shortfall > 0) { + + for (i = 0; i < visibleCount; i++) { + item = visibleItems[i]; + minSize = item[parallelMinString] || 0; + + + + if (item.flex) { + box = boxes[i]; + box.dirtySize = box.dirtySize || box[parallelPrefix] != minSize; + box[parallelPrefix] = minSize; + } + else { + minSizes.push({ + minSize: minSize, + available: boxes[i][parallelPrefix] - minSize, + index: i + }); + } + } + + + Ext.Array.sort(minSizes, me.minSizeSortFn); + + + for (i = 0, length = minSizes.length; i < length; i++) { + itemIndex = minSizes[i].index; + + if (itemIndex == undefinedValue) { + continue; + } + item = visibleItems[itemIndex]; + minSize = minSizes[i].minSize; + + box = boxes[itemIndex]; + oldSize = box[parallelPrefix]; + newSize = mmax(minSize, oldSize - math.ceil(shortfall / (length - i))); + reduction = oldSize - newSize; + + box.dirtySize = box.dirtySize || box[parallelPrefix] != newSize; + box[parallelPrefix] = newSize; + shortfall -= reduction; + } + } + else { + remainingSpace = availableSpace; + remainingFlex = totalFlex; + flexedBoxes = []; + + + for (i = 0; i < visibleCount; i++) { + child = visibleItems[i]; + if (isStart && child.flex) { + flexedBoxes.push(boxes[Ext.Array.indexOf(visibleItems, child)]); + } + } + + + + Ext.Array.sort(flexedBoxes, me.flexSortFn); + + + for (i = 0; i < flexedBoxes.length; i++) { + calcs = flexedBoxes[i]; + child = calcs.component; + childMargins = calcs.margins; + + flexedSize = math.ceil((child.flex / remainingFlex) * remainingSpace); + + + flexedSize = Math.max(child['min' + parallelPrefixCap] || 0, math.min(child['max' + parallelPrefixCap] || infiniteValue, flexedSize)); + + + remainingSpace -= flexedSize; + remainingFlex -= child.flex; + + calcs.dirtySize = calcs.dirtySize || calcs[parallelPrefix] != flexedSize; + calcs[parallelPrefix] = flexedSize; + } + } + } + + if (isCenter) { + parallelOffset += availableSpace / 2; + } + else if (isEnd) { + parallelOffset += availableSpace; + } + + + + + + if (me.owner.dock && (Ext.isIE6 || Ext.isIE7 || Ext.isIEQuirks) && !me.owner.width && me.direction == 'vertical') { + + calculatedWidth = maxSize + me.owner.el.getPadding('lr') + me.owner.el.getBorderWidth('lr'); + if (me.owner.frameSize) { + calculatedWidth += me.owner.frameSize.left + me.owner.frameSize.right; + } + + availPerpendicularSize = Math.min(availPerpendicularSize, targetSize.width = maxSize + padding.left + padding.right); + } + + + for (i = 0; i < visibleCount; i++) { + child = visibleItems[i]; + calcs = boxes[i]; + + childMargins = calcs.margins; + + perpendicularMargins = childMargins[me.perpendicularLeftTop] + childMargins[me.perpendicularRightBottom]; + + + parallelOffset += childMargins[me.parallelBefore]; + + calcs[me.parallelBefore] = parallelOffset; + calcs[me.perpendicularLeftTop] = perpendicularOffset + childMargins[me.perpendicularLeftTop]; + + if (me.align == 'stretch') { + stretchSize = constrain(availPerpendicularSize - perpendicularMargins, child[perpendicularMinString] || 0, child[perpendicularMaxString] || infiniteValue); + calcs.dirtySize = calcs.dirtySize || calcs[perpendicularPrefix] != stretchSize; + calcs[perpendicularPrefix] = stretchSize; + } + else if (me.align == 'stretchmax') { + stretchSize = constrain(maxSize - perpendicularMargins, child[perpendicularMinString] || 0, child[perpendicularMaxString] || infiniteValue); + calcs.dirtySize = calcs.dirtySize || calcs[perpendicularPrefix] != stretchSize; + calcs[perpendicularPrefix] = stretchSize; + } + else if (me.align == me.alignCenteringString) { + + + + diff = mmax(availPerpendicularSize, maxSize) - me.innerCt.getBorderWidth(me.perpendicularLT + me.perpendicularRB) - calcs[perpendicularPrefix]; + if (diff > 0) { + calcs[me.perpendicularLeftTop] = perpendicularOffset + Math.round(diff / 2); + } + } + + + parallelOffset += (calcs[parallelPrefix] || 0) + childMargins[me.parallelAfter]; + } + + return { + boxes: boxes, + meta : { + calculatedWidth: calculatedWidth, + maxSize: maxSize, + nonFlexSize: nonFlexSize, + desiredSize: desiredSize, + minimumSize: minimumSize, + shortfall: shortfall, + tooNarrow: tooNarrow + } + }; + }, + + + initOverflowHandler: function() { + var handler = this.overflowHandler; + + if (typeof handler == 'string') { + handler = { + type: handler + }; + } + + var handlerType = 'None'; + if (handler && handler.type != undefined) { + handlerType = handler.type; + } + + var constructor = Ext.layout.container.boxOverflow[handlerType]; + if (constructor[this.type]) { + constructor = constructor[this.type]; + } + + this.overflowHandler = Ext.create('Ext.layout.container.boxOverflow.' + handlerType, this, handler); + }, + + + onLayout: function() { + this.callParent(); + + if (this.clearInnerCtOnLayout === true && this.adjustmentPass !== true) { + this.innerCt.setSize(null, null); + } + + var me = this, + targetSize = me.getLayoutTargetSize(), + items = me.getVisibleItems(), + calcs = me.calculateChildBoxes(items, targetSize), + boxes = calcs.boxes, + meta = calcs.meta, + handler, method, results; + + if (me.autoSize && calcs.meta.desiredSize) { + targetSize[me.parallelPrefix] = calcs.meta.desiredSize; + } + + + if (meta.shortfall > 0) { + handler = me.overflowHandler; + method = meta.tooNarrow ? 'handleOverflow': 'clearOverflow'; + + results = handler[method](calcs, targetSize); + + if (results) { + if (results.targetSize) { + targetSize = results.targetSize; + } + + if (results.recalculate) { + items = me.getVisibleItems(owner); + calcs = me.calculateChildBoxes(items, targetSize); + boxes = calcs.boxes; + } + } + } else { + me.overflowHandler.clearOverflow(); + } + + + me.layoutTargetLastSize = targetSize; + + + me.childBoxCache = calcs; + + me.updateInnerCtSize(targetSize, calcs); + me.updateChildBoxes(boxes); + me.handleTargetOverflow(targetSize); + }, + + + updateChildBoxes: function(boxes) { + var me = this, + i = 0, + length = boxes.length, + animQueue = [], + dd = Ext.dd.DDM.getDDById(me.innerCt.id), + oldBox, newBox, changed, comp, boxAnim, animCallback; + + for (; i < length; i++) { + newBox = boxes[i]; + comp = newBox.component; + + + + if (dd && (dd.getDragEl() === comp.el.dom)) { + continue; + } + + changed = false; + + oldBox = me.getChildBox(comp); + + + + + if (me.animate) { + + animCallback = me.animate.callback || me.animate; + boxAnim = { + layoutAnimation: true, + target: comp, + from: {}, + to: {}, + listeners: {} + }; + + + + + if (!isNaN(newBox.width) && (newBox.width != oldBox.width)) { + changed = true; + + boxAnim.to.width = newBox.width; + } + if (!isNaN(newBox.height) && (newBox.height != oldBox.height)) { + changed = true; + + boxAnim.to.height = newBox.height; + } + if (!isNaN(newBox.left) && (newBox.left != oldBox.left)) { + changed = true; + + boxAnim.to.left = newBox.left; + } + if (!isNaN(newBox.top) && (newBox.top != oldBox.top)) { + changed = true; + + boxAnim.to.top = newBox.top; + } + if (changed) { + animQueue.push(boxAnim); + } + } else { + if (newBox.dirtySize) { + if (newBox.width !== oldBox.width || newBox.height !== oldBox.height) { + me.setItemSize(comp, newBox.width, newBox.height); + } + } + + if (isNaN(newBox.left) || isNaN(newBox.top)) { + continue; + } + comp.setPosition(newBox.left, newBox.top); + } + } + + + length = animQueue.length; + if (length) { + + + + var afterAnimate = function(anim) { + + length -= 1; + if (!length) { + me.layoutBusy = false; + if (Ext.isFunction(animCallback)) { + animCallback(); + } + } + }; + + var beforeAnimate = function() { + me.layoutBusy = true; + }; + + + for (i = 0, length = animQueue.length; i < length; i++) { + boxAnim = animQueue[i]; + + + boxAnim.listeners.afteranimate = afterAnimate; + + + if (!i) { + boxAnim.listeners.beforeanimate = beforeAnimate; + } + if (me.animate.duration) { + boxAnim.duration = me.animate.duration; + } + comp = boxAnim.target; + delete boxAnim.target; + + comp.stopAnimation(); + comp.animate(boxAnim); + } + } + }, + + + updateInnerCtSize: function(tSize, calcs) { + var me = this, + mmax = Math.max, + align = me.align, + padding = me.padding, + width = tSize.width, + height = tSize.height, + meta = calcs.meta, + innerCtWidth, + innerCtHeight; + + if (me.direction == 'horizontal') { + innerCtWidth = width; + innerCtHeight = meta.maxSize + padding.top + padding.bottom + me.innerCt.getBorderWidth('tb'); + + if (align == 'stretch') { + innerCtHeight = height; + } + else if (align == 'middle') { + innerCtHeight = mmax(height, innerCtHeight); + } + } else { + innerCtHeight = height; + innerCtWidth = meta.maxSize + padding.left + padding.right + me.innerCt.getBorderWidth('lr'); + + if (align == 'stretch') { + innerCtWidth = width; + } + else if (align == 'center') { + innerCtWidth = mmax(width, innerCtWidth); + } + } + me.getRenderTarget().setSize(innerCtWidth || undefined, innerCtHeight || undefined); + + + + if (meta.calculatedWidth && me.owner.el.getWidth() > meta.calculatedWidth) { + me.owner.el.setWidth(meta.calculatedWidth); + } + + if (me.innerCt.dom.scrollTop) { + me.innerCt.dom.scrollTop = 0; + } + }, + + + handleTargetOverflow: function(previousTargetSize) { + var target = this.getTarget(), + overflow = target.getStyle('overflow'), + newTargetSize; + + if (overflow && overflow != 'hidden' && !this.adjustmentPass) { + newTargetSize = this.getLayoutTargetSize(); + if (newTargetSize.width != previousTargetSize.width || newTargetSize.height != previousTargetSize.height) { + this.adjustmentPass = true; + this.onLayout(); + return true; + } + } + + delete this.adjustmentPass; + }, + + + isValidParent : function(item, target, position) { + + + var itemEl = item.el ? item.el.dom : Ext.getDom(item); + return (itemEl && this.innerCt && itemEl.parentNode === this.innerCt.dom) || false; + }, + + + + getRenderTarget: function() { + if (!this.innerCt) { + + this.innerCt = this.getTarget().createChild({ + cls: this.innerCls, + role: 'presentation' + }); + this.padding = Ext.util.Format.parseBox(this.padding); + } + return this.innerCt; + }, + + + renderItem: function(item, target) { + this.callParent(arguments); + var me = this, + itemEl = item.getEl(), + style = itemEl.dom.style, + margins = item.margins || item.margin; + + + if (margins) { + if (Ext.isString(margins) || Ext.isNumber(margins)) { + margins = Ext.util.Format.parseBox(margins); + } else { + Ext.applyIf(margins, {top: 0, right: 0, bottom: 0, left: 0}); + } + } else { + margins = Ext.apply({}, me.defaultMargins); + } + + + margins.top += itemEl.getMargin('t'); + margins.right += itemEl.getMargin('r'); + margins.bottom += itemEl.getMargin('b'); + margins.left += itemEl.getMargin('l'); + style.marginTop = style.marginRight = style.marginBottom = style.marginLeft = '0'; + + + item.margins = margins; + }, + + + destroy: function() { + Ext.destroy(this.overflowHandler); + this.callParent(arguments); + } +}); + +Ext.define('Ext.layout.container.HBox', { + + + + alias: ['layout.hbox'], + extend: 'Ext.layout.container.Box', + alternateClassName: 'Ext.layout.HBoxLayout', + + + + + align: 'top', + + //@private + + alignCenteringString: 'middle', + + type : 'hbox', + + direction: 'horizontal', + + + parallelSizeIndex: 0, + perpendicularSizeIndex: 1, + + parallelPrefix: 'width', + parallelPrefixCap: 'Width', + parallelLT: 'l', + parallelRB: 'r', + parallelBefore: 'left', + parallelBeforeCap: 'Left', + parallelAfter: 'right', + parallelPosition: 'x', + + perpendicularPrefix: 'height', + perpendicularPrefixCap: 'Height', + perpendicularLT: 't', + perpendicularRB: 'b', + perpendicularLeftTop: 'top', + perpendicularRightBottom: 'bottom', + perpendicularPosition: 'y' +}); + +Ext.define('Ext.layout.container.VBox', { + + + + alias: ['layout.vbox'], + extend: 'Ext.layout.container.Box', + alternateClassName: 'Ext.layout.VBoxLayout', + + + + + align : 'left', + + //@private + + alignCenteringString: 'center', + + type: 'vbox', + + direction: 'vertical', + + + parallelSizeIndex: 1, + perpendicularSizeIndex: 0, + + parallelPrefix: 'height', + parallelPrefixCap: 'Height', + parallelLT: 't', + parallelRB: 'b', + parallelBefore: 'top', + parallelBeforeCap: 'Top', + parallelAfter: 'bottom', + parallelPosition: 'y', + + perpendicularPrefix: 'width', + perpendicularPrefixCap: 'Width', + perpendicularLT: 'l', + perpendicularRB: 'r', + perpendicularLeftTop: 'left', + perpendicularRightBottom: 'right', + perpendicularPosition: 'x' +}); + +Ext.define('Ext.FocusManager', { + singleton: true, + alternateClassName: 'Ext.FocusMgr', + + mixins: { + observable: 'Ext.util.Observable' + }, + + requires: [ + 'Ext.ComponentManager', + 'Ext.ComponentQuery', + 'Ext.util.HashMap', + 'Ext.util.KeyNav' + ], + + + enabled: false, + + + + focusElementCls: Ext.baseCSSPrefix + 'focus-element', + + focusFrameCls: Ext.baseCSSPrefix + 'focus-frame', + + + whitelist: [ + 'textfield' + ], + + tabIndexWhitelist: [ + 'a', + 'button', + 'embed', + 'frame', + 'iframe', + 'img', + 'input', + 'object', + 'select', + 'textarea' + ], + + constructor: function() { + var me = this, + CQ = Ext.ComponentQuery; + + me.addEvents( + + 'beforecomponentfocus', + + + 'componentfocus', + + + 'disable', + + + 'enable' + ); + + + + me.keyNav = Ext.create('Ext.util.KeyNav', Ext.getDoc(), { + disabled: true, + scope: me, + + backspace: me.focusLast, + enter: me.navigateIn, + esc: me.navigateOut, + tab: me.navigateSiblings + + + + + + + + }); + + me.focusData = {}; + me.subscribers = Ext.create('Ext.util.HashMap'); + me.focusChain = {}; + + + Ext.apply(CQ.pseudos, { + focusable: function(cmps) { + var len = cmps.length, + results = [], + i = 0, + c, + + isFocusable = function(x) { + return x && x.focusable !== false && CQ.is(x, '[rendered]:not([destroying]):not([isDestroyed]):not([disabled]){isVisible(true)}{el && c.el.dom && c.el.isVisible()}'); + }; + + for (; i < len; i++) { + c = cmps[i]; + if (isFocusable(c)) { + results.push(c); + } + } + + return results; + }, + + nextFocus: function(cmps, idx, step) { + step = step || 1; + idx = parseInt(idx, 10); + + var len = cmps.length, + i = idx + step, + c; + + for (; i != idx; i += step) { + if (i >= len) { + i = 0; + } else if (i < 0) { + i = len - 1; + } + + c = cmps[i]; + if (CQ.is(c, ':focusable')) { + return [c]; + } else if (c.placeholder && CQ.is(c.placeholder, ':focusable')) { + return [c.placeholder]; + } + } + + return []; + }, + + prevFocus: function(cmps, idx) { + return this.nextFocus(cmps, idx, -1); + }, + + root: function(cmps) { + var len = cmps.length, + results = [], + i = 0, + c; + + for (; i < len; i++) { + c = cmps[i]; + if (!c.ownerCt) { + results.push(c); + } + } + + return results; + } + }); + }, + + + addXTypeToWhitelist: function(xtype) { + var me = this; + + if (Ext.isArray(xtype)) { + Ext.Array.forEach(xtype, me.addXTypeToWhitelist, me); + return; + } + + if (!Ext.Array.contains(me.whitelist, xtype)) { + me.whitelist.push(xtype); + } + }, + + clearComponent: function(cmp) { + clearTimeout(this.cmpFocusDelay); + if (!cmp.isDestroyed) { + cmp.blur(); + } + }, + + + disable: function() { + var me = this; + + if (!me.enabled) { + return; + } + + delete me.options; + me.enabled = false; + + Ext.ComponentManager.all.un('add', me.onComponentCreated, me); + + me.removeDOM(); + + + me.keyNav.disable(); + + + me.setFocusAll(false); + + me.fireEvent('disable', me); + }, + + + enable: function(options) { + var me = this; + + if (options === true) { + options = { focusFrame: true }; + } + me.options = options = options || {}; + + if (me.enabled) { + return; + } + + + Ext.ComponentManager.all.on('add', me.onComponentCreated, me); + + me.initDOM(options); + + + me.keyNav.enable(); + + + me.setFocusAll(true, options); + + + me.focusEl.focus(); + delete me.focusedCmp; + + me.enabled = true; + me.fireEvent('enable', me); + }, + + focusLast: function(e) { + var me = this; + + if (me.isWhitelisted(me.focusedCmp)) { + return true; + } + + + if (me.previousFocusedCmp) { + me.previousFocusedCmp.focus(); + } + }, + + getRootComponents: function() { + var me = this, + CQ = Ext.ComponentQuery, + inline = CQ.query(':focusable:root:not([floating])'), + floating = CQ.query(':focusable:root[floating]'); + + + + floating.sort(function(a, b) { + return a.el.getZIndex() > b.el.getZIndex(); + }); + + return floating.concat(inline); + }, + + initDOM: function(options) { + var me = this, + sp = ' ', + cls = me.focusFrameCls; + + if (!Ext.isReady) { + Ext.onReady(me.initDOM, me); + return; + } + + + if (!me.focusEl) { + me.focusEl = Ext.getBody().createChild({ + tabIndex: '-1', + cls: me.focusElementCls, + html: sp + }); + } + + + if (!me.focusFrame && options.focusFrame) { + me.focusFrame = Ext.getBody().createChild({ + cls: cls, + children: [ + { cls: cls + '-top' }, + { cls: cls + '-bottom' }, + { cls: cls + '-left' }, + { cls: cls + '-right' } + ], + style: 'top: -100px; left: -100px;' + }); + me.focusFrame.setVisibilityMode(Ext.core.Element.DISPLAY); + me.focusFrameWidth = me.focusFrame.child('.' + cls + '-top').getHeight(); + me.focusFrame.hide().setLeftTop(0, 0); + } + }, + + isWhitelisted: function(cmp) { + return cmp && Ext.Array.some(this.whitelist, function(x) { + return cmp.isXType(x); + }); + }, + + navigateIn: function(e) { + var me = this, + focusedCmp = me.focusedCmp, + rootCmps, + firstChild; + + if (!focusedCmp) { + + rootCmps = me.getRootComponents(); + if (rootCmps.length) { + rootCmps[0].focus(); + } + } else { + + + firstChild = Ext.ComponentQuery.query('>:focusable', focusedCmp)[0]; + if (firstChild) { + firstChild.focus(); + } else { + + if (Ext.isFunction(focusedCmp.onClick)) { + e.button = 0; + focusedCmp.onClick(e); + focusedCmp.focus(); + } + } + } + }, + + navigateOut: function(e) { + var me = this, + parent; + + if (!me.focusedCmp || !(parent = me.focusedCmp.up(':focusable'))) { + me.focusEl.focus(); + return; + } + + parent.focus(); + }, + + navigateSiblings: function(e, source, parent) { + var me = this, + src = source || me, + key = e.getKey(), + EO = Ext.EventObject, + goBack = e.shiftKey || key == EO.LEFT || key == EO.UP, + checkWhitelist = key == EO.LEFT || key == EO.RIGHT || key == EO.UP || key == EO.DOWN, + nextSelector = goBack ? 'prev' : 'next', + idx, next, focusedCmp; + + focusedCmp = (src.focusedCmp && src.focusedCmp.comp) || src.focusedCmp; + if (!focusedCmp && !parent) { + return; + } + + if (checkWhitelist && me.isWhitelisted(focusedCmp)) { + return true; + } + + parent = parent || focusedCmp.up(); + if (parent) { + idx = focusedCmp ? Ext.Array.indexOf(parent.getRefItems(), focusedCmp) : -1; + next = Ext.ComponentQuery.query('>:' + nextSelector + 'Focus(' + idx + ')', parent)[0]; + if (next && focusedCmp !== next) { + next.focus(); + return next; + } + } + }, + + onComponentBlur: function(cmp, e) { + var me = this; + + if (me.focusedCmp === cmp) { + me.previousFocusedCmp = cmp; + delete me.focusedCmp; + } + + if (me.focusFrame) { + me.focusFrame.hide(); + } + }, + + onComponentCreated: function(hash, id, cmp) { + this.setFocus(cmp, true, this.options); + }, + + onComponentDestroy: function(cmp) { + this.setFocus(cmp, false); + }, + + onComponentFocus: function(cmp, e) { + var me = this, + chain = me.focusChain; + + if (!Ext.ComponentQuery.is(cmp, ':focusable')) { + me.clearComponent(cmp); + + + + + + if (chain[cmp.id]) { + return; + } + + + var parent = cmp.up(); + if (parent) { + + + + chain[cmp.id] = true; + parent.focus(); + } + + return; + } + + + me.focusChain = {}; + + + + clearTimeout(me.cmpFocusDelay); + if (arguments.length !== 2) { + me.cmpFocusDelay = Ext.defer(me.onComponentFocus, 90, me, [cmp, e]); + return; + } + + if (me.fireEvent('beforecomponentfocus', me, cmp, me.previousFocusedCmp) === false) { + me.clearComponent(cmp); + return; + } + + me.focusedCmp = cmp; + + + if (me.shouldShowFocusFrame(cmp)) { + var cls = '.' + me.focusFrameCls + '-', + ff = me.focusFrame, + fw = me.focusFrameWidth, + box = cmp.el.getPageBox(), + + + + + bt = box.top, + bl = box.left, + bw = box.width, + bh = box.height, + ft = ff.child(cls + 'top'), + fb = ff.child(cls + 'bottom'), + 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); + + ff.show(); + } + + me.fireEvent('componentfocus', me, cmp, me.previousFocusedCmp); + }, + + onComponentHide: function(cmp) { + var me = this, + CQ = Ext.ComponentQuery, + cmpHadFocus = false, + focusedCmp, + parent; + + if (me.focusedCmp) { + focusedCmp = CQ.query('[id=' + me.focusedCmp.id + ']', cmp)[0]; + cmpHadFocus = me.focusedCmp.id === cmp.id || focusedCmp; + + if (focusedCmp) { + me.clearComponent(focusedCmp); + } + } + + me.clearComponent(cmp); + + if (cmpHadFocus) { + parent = CQ.query('^:focusable', cmp)[0]; + if (parent) { + parent.focus(); + } + } + }, + + removeDOM: function() { + var me = this; + + + + if (me.enabled || me.subscribers.length) { + return; + } + + Ext.destroy( + me.focusEl, + me.focusFrame + ); + delete me.focusEl; + delete me.focusFrame; + delete me.focusFrameWidth; + }, + + + removeXTypeFromWhitelist: function(xtype) { + var me = this; + + if (Ext.isArray(xtype)) { + Ext.Array.forEach(xtype, me.removeXTypeFromWhitelist, me); + return; + } + + Ext.Array.remove(me.whitelist, xtype); + }, + + setFocus: function(cmp, focusable, options) { + var me = this, + el, dom, data, + + needsTabIndex = function(n) { + return !Ext.Array.contains(me.tabIndexWhitelist, n.tagName.toLowerCase()) + && n.tabIndex <= 0; + }; + + options = options || {}; + + + if (!cmp.rendered) { + cmp.on('afterrender', Ext.pass(me.setFocus, arguments, me), me, { single: true }); + return; + } + + el = cmp.getFocusEl(); + dom = el.dom; + + + if ((focusable && !me.focusData[cmp.id]) || (!focusable && me.focusData[cmp.id])) { + if (focusable) { + data = { + focusFrame: options.focusFrame + }; + + + + + + if (needsTabIndex(dom)) { + data.tabIndex = dom.tabIndex; + dom.tabIndex = -1; + } + + el.on({ + focus: data.focusFn = Ext.bind(me.onComponentFocus, me, [cmp], 0), + blur: data.blurFn = Ext.bind(me.onComponentBlur, me, [cmp], 0), + scope: me + }); + cmp.on({ + hide: me.onComponentHide, + close: me.onComponentHide, + beforedestroy: me.onComponentDestroy, + scope: me + }); + + me.focusData[cmp.id] = data; + } else { + data = me.focusData[cmp.id]; + if ('tabIndex' in data) { + dom.tabIndex = data.tabIndex; + } + el.un('focus', data.focusFn, me); + el.un('blur', data.blurFn, me); + cmp.un('hide', me.onComponentHide, me); + cmp.un('close', me.onComponentHide, me); + cmp.un('beforedestroy', me.onComponentDestroy, me); + + delete me.focusData[cmp.id]; + } + } + }, + + setFocusAll: function(focusable, options) { + var me = this, + cmps = Ext.ComponentManager.all.getArray(), + len = cmps.length, + cmp, + i = 0; + + for (; i < len; i++) { + me.setFocus(cmps[i], focusable, options); + } + }, + + setupSubscriberKeys: function(container, keys) { + var me = this, + el = container.getFocusEl(), + scope = keys.scope, + handlers = { + backspace: me.focusLast, + enter: me.navigateIn, + esc: me.navigateOut, + scope: me + }, + + navSiblings = function(e) { + if (me.focusedCmp === container) { + + + + return me.navigateSiblings(e, me, container); + } else { + return me.navigateSiblings(e); + } + }; + + Ext.iterate(keys, function(key, cb) { + handlers[key] = function(e) { + var ret = navSiblings(e); + + if (Ext.isFunction(cb) && cb.call(scope || container, e, ret) === true) { + return true; + } + + return ret; + }; + }, me); + + return Ext.create('Ext.util.KeyNav', el, handlers); + }, + + shouldShowFocusFrame: function(cmp) { + var me = this, + opts = me.options || {}; + + if (!me.focusFrame || !cmp) { + return false; + } + + + if (opts.focusFrame) { + return true; + } + + if (me.focusData[cmp.id].focusFrame) { + return true; + } + + return false; + }, + + + subscribe: function(container, options) { + var me = this, + EA = Ext.Array, + data = {}, + subs = me.subscribers, + + + + + safeSetFocus = function(cmp) { + if (cmp.isContainer && !subs.containsKey(cmp.id)) { + EA.forEach(cmp.query('>'), safeSetFocus); + me.setFocus(cmp, true, options); + cmp.on('add', data.onAdd, me); + } else if (!cmp.isContainer) { + me.setFocus(cmp, true, options); + } + }; + + + if (!container || !container.isContainer) { + return; + } + + if (!container.rendered) { + container.on('afterrender', Ext.pass(me.subscribe, arguments, me), me, { single: true }); + return; + } + + + me.initDOM(options); + + + data.keyNav = me.setupSubscriberKeys(container, options.keys); + + + + + + data.onAdd = function(ct, cmp, idx) { + safeSetFocus(cmp); + }; + container.on('beforedestroy', me.unsubscribe, me); + + + safeSetFocus(container); + + + subs.add(container.id, data); + }, + + + unsubscribe: function(container) { + var me = this, + EA = Ext.Array, + subs = me.subscribers, + data, + + + + + safeSetFocus = function(cmp) { + if (cmp.isContainer && !subs.containsKey(cmp.id)) { + EA.forEach(cmp.query('>'), safeSetFocus); + me.setFocus(cmp, false); + cmp.un('add', data.onAdd, me); + } else if (!cmp.isContainer) { + me.setFocus(cmp, false); + } + }; + + if (!container || !subs.containsKey(container.id)) { + return; + } + + data = subs.get(container.id); + data.keyNav.destroy(); + container.un('beforedestroy', me.unsubscribe, me); + subs.removeAtKey(container.id); + safeSetFocus(container); + me.removeDOM(); + } +}); + +Ext.define('Ext.toolbar.Toolbar', { + extend: 'Ext.container.Container', + requires: [ + 'Ext.toolbar.Fill', + 'Ext.layout.container.HBox', + 'Ext.layout.container.VBox', + 'Ext.FocusManager' + ], + uses: [ + 'Ext.toolbar.Separator' + ], + alias: 'widget.toolbar', + alternateClassName: 'Ext.Toolbar', + + isToolbar: true, + baseCls : Ext.baseCSSPrefix + 'toolbar', + ariaRole : 'toolbar', + + defaultType: 'button', + + + vertical: false, + + + + + enableOverflow: false, + + + trackMenus: true, + + itemCls: Ext.baseCSSPrefix + 'toolbar-item', + + initComponent: function() { + var me = this, + keys; + + + if (!me.layout && me.enableOverflow) { + me.layout = { overflowHandler: 'Menu' }; + } + + if (me.dock === 'right' || me.dock === 'left') { + me.vertical = true; + } + + me.layout = Ext.applyIf(Ext.isString(me.layout) ? { + type: me.layout + } : me.layout || {}, { + type: me.vertical ? 'vbox' : 'hbox', + align: me.vertical ? 'stretchmax' : 'middle' + }); + + 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, { + keys: keys + }); + }, + + + + + lookupComponent: function(c) { + if (Ext.isString(c)) { + var shortcut = Ext.toolbar.Toolbar.shortcuts[c]; + if (shortcut) { + c = { + xtype: shortcut + }; + } else { + c = { + xtype: 'tbtext', + text: c + }; + } + this.applyDefaults(c); + } + return this.callParent(arguments); + }, + + + applyDefaults: function(c) { + if (!Ext.isString(c)) { + c = this.callParent(arguments); + var d = this.internalDefaults; + if (c.events) { + Ext.applyIf(c.initialConfig, d); + Ext.apply(c, d); + } else { + Ext.applyIf(c, d); + } + } + return c; + }, + + + trackMenu: function(item, remove) { + if (this.trackMenus && item.menu) { + var method = remove ? 'mun' : 'mon', + me = this; + + me[method](item, 'menutriggerover', me.onButtonTriggerOver, me); + me[method](item, 'menushow', me.onButtonMenuShow, me); + me[method](item, 'menuhide', me.onButtonMenuHide, me); + } + }, + + + constructButton: function(item) { + return item.events ? item : this.createComponent(item, item.split ? 'splitbutton' : this.defaultType); + }, + + + onBeforeAdd: function(component) { + 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); + }, + + + onAdd: function(component) { + this.callParent(arguments); + + this.trackMenu(component); + if (this.disabled) { + component.disable(); + } + }, + + + onRemove: function(c) { + this.callParent(arguments); + this.trackMenu(c, true); + }, + + + onButtonTriggerOver: function(btn){ + if (this.activeMenuBtn && this.activeMenuBtn != btn) { + this.activeMenuBtn.hideMenu(); + btn.showMenu(); + this.activeMenuBtn = btn; + } + }, + + + onButtonMenuShow: function(btn) { + this.activeMenuBtn = btn; + }, + + + onButtonMenuHide: function(btn) { + delete this.activeMenuBtn; + } +}, function() { + this.shortcuts = { + '-' : 'tbseparator', + ' ' : 'tbspacer', + '->': 'tbfill' + }; +}); + +Ext.define('Ext.panel.AbstractPanel', { + + + + extend: 'Ext.container.Container', + + requires: ['Ext.util.MixedCollection', 'Ext.core.Element', 'Ext.toolbar.Toolbar'], + + + + + baseCls : Ext.baseCSSPrefix + 'panel', + + + + + + + + + + isPanel: true, + + componentLayout: 'dock', + + renderTpl: ['
{bodyCls} {baseCls}-body-{ui} {parent.baseCls}-body-{parent.ui}-{.}" style="{bodyStyle}">
'], + + + + + border: true, + + initComponent : function() { + var me = this; + + me.addEvents( + + 'bodyresize' + + + + + ); + + Ext.applyIf(me.renderSelectors, { + body: '.' + me.baseCls + '-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(); + }, + + + initItems : function() { + var me = this, + items = me.dockedItems; + + me.callParent(); + me.dockedItems = Ext.create('Ext.util.MixedCollection', false, me.getComponentId); + if (items) { + me.addDocked(items); + } + }, + + + getDockedComponent: function(comp) { + if (Ext.isObject(comp)) { + comp = comp.getItemId(); + } + return this.dockedItems.get(comp); + }, + + + getComponent: function(comp) { + var component = this.callParent(arguments); + if (component === undefined && !Ext.isNumber(comp)) { + + component = this.getDockedComponent(comp); + } + return component; + }, + + + initBodyStyles: function() { + var me = this, + bodyStyle = me.bodyStyle, + styles = [], + Element = Ext.core.Element, + prop; + + if (Ext.isFunction(bodyStyle)) { + bodyStyle = bodyStyle(); + } + if (Ext.isString(bodyStyle)) { + styles = bodyStyle.split(';'); + } else { + for (prop in bodyStyle) { + if (bodyStyle.hasOwnProperty(prop)) { + styles.push(prop + ':' + bodyStyle[prop]); + } + } + } + + if (me.bodyPadding !== undefined) { + styles.push('padding: ' + Element.unitizeBox((me.bodyPadding === true) ? 5 : me.bodyPadding)); + } + if (me.frame && me.bodyBorder) { + if (!Ext.isNumber(me.bodyBorder)) { + me.bodyBorder = 1; + } + styles.push('border-width: ' + Element.unitizeBox(me.bodyBorder)); + } + 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; + }); + delete me.bodyCls; + } + return cls.length > 0 ? cls : undefined; + }, + + + initRenderData: function() { + return Ext.applyIf(this.callParent(), { + bodyStyle: this.initBodyStyles(), + bodyCls: this.initBodyCls() + }); + }, + + + addDocked : function(items, pos) { + var me = this, + i = 0, + item, length; + + items = me.prepareItems(items); + length = items.length; + + for (; i < length; i++) { + item = items[i]; + item.dock = item.dock || 'top'; + + + if (me.border === false) { + + } + + if (pos !== undefined) { + me.dockedItems.insert(pos + i, item); + } + else { + me.dockedItems.add(item); + } + item.onAdded(me, i); + me.onDockedAdd(item); + } + if (me.rendered) { + me.doComponentLayout(); + } + return items; + }, + + + onDockedAdd : Ext.emptyFn, + onDockedRemove : Ext.emptyFn, + + + insertDocked : function(pos, items) { + this.addDocked(items, pos); + }, + + + removeDocked : function(item, autoDestroy) { + var me = this, + layout, + hasLayout; + + if (!me.dockedItems.contains(item)) { + return item; + } + + layout = me.componentLayout; + hasLayout = layout && me.rendered; + + if (hasLayout) { + layout.onRemove(item); + } + + me.dockedItems.remove(item); + item.onRemoved(); + me.onDockedRemove(item); + + if (autoDestroy === true || (autoDestroy !== false && me.autoDestroy)) { + item.destroy(); + } + + if (hasLayout && !autoDestroy) { + layout.afterRemove(item); + } + + if (!this.destroying) { + me.doComponentLayout(); + } + + return item; + }, + + + getDockedItems : function(cqSelector) { + var me = this, + + + defaultWeight = { top: 1, left: 3, right: 5, bottom: 7 }, + dockedItems; + + if (me.dockedItems && me.dockedItems.items.length) { + + if (cqSelector) { + dockedItems = Ext.ComponentQuery.query(cqSelector, me.dockedItems.items); + } else { + dockedItems = me.dockedItems.items.slice(); + } + + 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)) { + return aw - bw; + } + return 0; + }); + + return dockedItems; + } + return []; + }, + + + addUIClsToElement: function(cls, force) { + var me = this; + + me.callParent(arguments); + + 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); + } + }, + + + removeUIClsFromElement: function(cls, force) { + var me = this; + + me.callParent(arguments); + + 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); + } + }, + + + addUIToElement: function(force) { + var me = this; + + me.callParent(arguments); + + if (!force && me.rendered) { + me.body.addCls(me.baseCls + '-body-' + me.ui); + } + }, + + + removeUIFromElement: function() { + var me = this; + + me.callParent(arguments); + + if (me.rendered) { + me.body.removeCls(me.baseCls + '-body-' + me.ui); + } + }, + + + getTargetEl : function() { + return this.body; + }, + + getRefItems: function(deep) { + var items = this.callParent(arguments), + + dockedItems = this.getDockedItems(deep ? '*,* *' : undefined), + ln = dockedItems.length, + i = 0, + item; + + + for (; i < ln; i++) { + item = dockedItems[i]; + if (item.dock === 'right' || item.dock === 'bottom') { + break; + } + } + + + + + return dockedItems.splice(0, i).concat(items).concat(dockedItems); + }, + + beforeDestroy: function(){ + var docked = this.dockedItems, + c; + + if (docked) { + while ((c = docked.first())) { + this.removeDocked(c, true); + } + } + this.callParent(); + }, + + setBorder: function(border) { + var me = this; + me.border = (border !== undefined) ? border : true; + if (me.rendered) { + me.doComponentLayout(); + } + } +}); + +Ext.define('Ext.panel.Header', { + extend: 'Ext.container.Container', + uses: ['Ext.panel.Tool', 'Ext.draw.Component', 'Ext.util.CSS'], + alias: 'widget.header', + + isHeader : true, + defaultType : 'tool', + indicateDrag : false, + weight : -1, + + renderTpl: ['
{bodyCls} {parent.baseCls}-body-{parent.ui}-{.}" style="{bodyStyle}">
'], + + initComponent: function() { + var me = this, + rule, + style, + titleTextEl, + ui; + + me.indicateDragCls = me.baseCls + '-draggable'; + me.title = me.title || ' '; + me.tools = me.tools || []; + me.items = me.items || []; + me.orientation = me.orientation || 'horizontal'; + me.dock = (me.dock) ? me.dock : (me.orientation == 'horizontal') ? 'top' : 'left'; + + + + me.addClsWithUI(me.orientation); + me.addClsWithUI(me.dock); + + Ext.applyIf(me.renderSelectors, { + body: '.' + me.baseCls + '-body' + }); + + + if (!Ext.isEmpty(me.iconCls)) { + me.initIconCmp(); + me.items.push(me.iconCmp); + } + + + if (me.orientation == 'vertical') { + + if (Ext.isIE6 || Ext.isIE7) { + me.width = this.width || 24; + } else if (Ext.isIEQuirks) { + me.width = this.width || 25; + } + + me.layout = { + type : 'vbox', + align: 'center', + clearInnerCtOnLayout: true, + bindToOwnerCtContainer: false + }; + me.textConfig = { + cls: me.baseCls + '-text', + type: 'text', + text: me.title, + rotate: { + degrees: 90 + } + }; + ui = me.ui; + if (Ext.isArray(ui)) { + ui = ui[0]; + } + rule = Ext.util.CSS.getRule('.' + me.baseCls + '-text-' + ui); + if (rule) { + style = rule.style; + } + if (style) { + Ext.apply(me.textConfig, { + 'font-family': style.fontFamily, + 'font-weight': style.fontWeight, + 'font-size': style.fontSize, + fill: style.color + }); + } + me.titleCmp = Ext.create('Ext.draw.Component', { + ariaRole : 'heading', + focusable: false, + viewBox: false, + autoSize: true, + margins: '5 0 0 0', + items: [ me.textConfig ], + renderSelectors: { + textEl: '.' + me.baseCls + '-text' + } + }); + } else { + me.layout = { + type : 'hbox', + align: 'middle', + clearInnerCtOnLayout: true, + bindToOwnerCtContainer: false + }; + me.titleCmp = Ext.create('Ext.Component', { + xtype : 'component', + ariaRole : 'heading', + focusable: false, + renderTpl : ['{title}'], + renderData: { + title: me.title, + cls : me.baseCls, + ui : me.ui + }, + renderSelectors: { + textEl: '.' + me.baseCls + '-text' + } + }); + } + me.items.push(me.titleCmp); + + + me.items.push({ + xtype: 'component', + html : ' ', + flex : 1, + focusable: false + }); + + + me.items = me.items.concat(me.tools); + this.callParent(); + }, + + initIconCmp: function() { + this.iconCmp = Ext.create('Ext.Component', { + focusable: false, + renderTpl : [''], + renderData: { + blank : Ext.BLANK_IMAGE_URL, + cls : this.baseCls, + iconCls: this.iconCls, + orientation: this.orientation + }, + renderSelectors: { + iconEl: '.' + this.baseCls + '-icon' + }, + iconCls: this.iconCls + }); + }, + + afterRender: function() { + var me = this; + + me.el.unselectable(); + if (me.indicateDrag) { + me.el.addCls(me.indicateDragCls); + } + me.mon(me.el, { + click: me.onClick, + scope: me + }); + me.callParent(); + }, + + afterLayout: function() { + var me = this; + me.callParent(arguments); + + + if (Ext.isIE7) { + me.el.repaint(); + } + }, + + + addUIClsToElement: function(cls, force) { + var me = this; + + me.callParent(arguments); + + if (!force && me.rendered) { + me.body.addCls(me.baseCls + '-body-' + cls); + me.body.addCls(me.baseCls + '-body-' + me.ui + '-' + cls); + } + }, + + + removeUIClsFromElement: function(cls, force) { + var me = this; + + me.callParent(arguments); + + if (!force && me.rendered) { + me.body.removeCls(me.baseCls + '-body-' + cls); + me.body.removeCls(me.baseCls + '-body-' + me.ui + '-' + cls); + } + }, + + + addUIToElement: function(force) { + var me = this; + + me.callParent(arguments); + + if (!force && me.rendered) { + me.body.addCls(me.baseCls + '-body-' + me.ui); + } + + if (!force && me.titleCmp && me.titleCmp.rendered && me.titleCmp.textEl) { + me.titleCmp.textEl.addCls(me.baseCls + '-text-' + me.ui); + } + }, + + + removeUIFromElement: function() { + var me = this; + + me.callParent(arguments); + + if (me.rendered) { + me.body.removeCls(me.baseCls + '-body-' + me.ui); + } + + if (me.titleCmp && me.titleCmp.rendered && me.titleCmp.textEl) { + me.titleCmp.textEl.removeCls(me.baseCls + '-text-' + me.ui); + } + }, + + onClick: function(e) { + if (!e.getTarget(Ext.baseCSSPrefix + 'tool')) { + this.fireEvent('click', e); + } + }, + + getTargetEl: function() { + return this.body || this.frameBody || this.el; + }, + + + setTitle: function(title) { + var me = this; + if (me.rendered) { + if (me.titleCmp.rendered) { + if (me.titleCmp.surface) { + me.title = title || ''; + var sprite = me.titleCmp.surface.items.items[0], + surface = me.titleCmp.surface; + + surface.remove(sprite); + me.textConfig.type = 'text'; + me.textConfig.text = title; + sprite = surface.add(me.textConfig); + sprite.setAttributes({ + rotate: { + degrees: 90 + } + }, true); + me.titleCmp.autoSizeSurface(); + } else { + me.title = title || ' '; + me.titleCmp.textEl.update(me.title); + } + } else { + me.titleCmp.on({ + render: function() { + me.setTitle(title); + }, + single: true + }); + } + } else { + me.on({ + render: function() { + me.layout.layout(); + me.setTitle(title); + }, + single: true + }); + } + }, + + + 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; + + el.removeCls(iconCmp.iconCls); + el.addCls(cls); + iconCmp.iconCls = cls; + } + } + }, + + + addTool: function(tool) { + this.tools.push(this.add(tool)); + }, + + + onAdd: function(component, index) { + this.callParent([arguments]); + if (component instanceof Ext.panel.Tool) { + component.bindTo(this.ownerCt); + this.tools[component.type] = component; + } + } +}); + + +Ext.define('Ext.fx.target.Element', { + + + + extend: 'Ext.fx.target.Target', + + + + type: 'element', + + getElVal: function(el, attr, val) { + if (val == undefined) { + if (attr === 'x') { + val = el.getX(); + } + else if (attr === 'y') { + val = el.getY(); + } + else if (attr === 'scrollTop') { + val = el.getScroll().top; + } + else if (attr === 'scrollLeft') { + val = el.getScroll().left; + } + else if (attr === 'height') { + val = el.getHeight(); + } + else if (attr === 'width') { + val = el.getWidth(); + } + else { + val = el.getStyle(attr); + } + } + return val; + }, + + getAttr: function(attr, val) { + var el = this.target; + return [[ el, this.getElVal(el, attr, val)]]; + }, + + setAttr: function(targetData) { + var target = this.target, + ln = targetData.length, + attrs, attr, o, i, j, ln2, element, value; + for (i = 0; i < ln; i++) { + attrs = targetData[i].attrs; + for (attr in attrs) { + if (attrs.hasOwnProperty(attr)) { + ln2 = attrs[attr].length; + for (j = 0; j < ln2; j++) { + o = attrs[attr][j]; + element = o[0]; + value = o[1]; + if (attr === 'x') { + element.setX(value); + } + else if (attr === 'y') { + element.setY(value); + } + else if (attr === 'scrollTop') { + element.scrollTo('top', value); + } + else if (attr === 'scrollLeft') { + element.scrollTo('left',value); + } + else { + element.setStyle(attr, value); + } + } + } + } + } + } +}); + + +Ext.define('Ext.fx.target.CompositeElement', { + + + + extend: 'Ext.fx.target.Element', + + + + isComposite: true, + + constructor: function(target) { + target.id = target.id || Ext.id(null, 'ext-composite-'); + this.callParent([target]); + }, + + getAttr: function(attr, val) { + var out = [], + target = this.target; + target.each(function(el) { + out.push([el, this.getElVal(el, attr, val)]); + }, this); + return out; + } +}); + + + +Ext.define('Ext.fx.Manager', { + + + + singleton: true, + + requires: ['Ext.util.MixedCollection', + 'Ext.fx.target.Element', + 'Ext.fx.target.CompositeElement', + 'Ext.fx.target.Sprite', + 'Ext.fx.target.CompositeSprite', + 'Ext.fx.target.Component'], + + mixins: { + queue: 'Ext.fx.Queue' + }, + + + + constructor: function() { + this.items = Ext.create('Ext.util.MixedCollection'); + this.mixins.queue.constructor.call(this); + + + + + + + + + + + + + + + + + + + }, + + + interval: 16, + + + forceJS: true, + + + createTarget: function(target) { + var me = this, + useCSS3 = !me.forceJS && Ext.supports.Transitions, + targetObj; + + me.useCSS3 = useCSS3; + + + if (Ext.isString(target)) { + target = Ext.get(target); + } + + if (target && target.tagName) { + target = Ext.get(target); + targetObj = Ext.create('Ext.fx.target.' + 'Element' + (useCSS3 ? 'CSS' : ''), target); + me.targets.add(targetObj); + return targetObj; + } + if (Ext.isObject(target)) { + + if (target.dom) { + targetObj = Ext.create('Ext.fx.target.' + 'Element' + (useCSS3 ? 'CSS' : ''), target); + } + + else if (target.isComposite) { + targetObj = Ext.create('Ext.fx.target.' + 'CompositeElement' + (useCSS3 ? 'CSS' : ''), target); + } + + else if (target.isSprite) { + targetObj = Ext.create('Ext.fx.target.Sprite', target); + } + + else if (target.isCompositeSprite) { + targetObj = Ext.create('Ext.fx.target.CompositeSprite', target); + } + + else if (target.isComponent) { + targetObj = Ext.create('Ext.fx.target.Component', target); + } + else if (target.isAnimTarget) { + return target; + } + else { + return null; + } + me.targets.add(targetObj); + return targetObj; + } + else { + return null; + } + }, + + + addAnim: function(anim) { + var items = this.items, + task = this.task; + + + + + + + + + + + + + + items.add(anim); + + + if (!task && items.length) { + task = this.task = { + run: this.runner, + interval: this.interval, + scope: this + }; + Ext.TaskManager.start(task); + } + + + + + + }, + + + removeAnim: function(anim) { + + var items = this.items, + task = this.task; + items.remove(anim); + + if (task && !items.length) { + Ext.TaskManager.stop(task); + delete this.task; + } + }, + + + startingFilter: function(o) { + return o.paused === false && o.running === false && o.iterations > 0; + }, + + + runningFilter: function(o) { + return o.paused === false && o.running === true && o.isAnimator !== true; + }, + + + runner: function() { + var me = this, + items = me.items; + + me.targetData = {}; + me.targetArr = {}; + + + me.timestamp = new Date(); + + + items.filterBy(me.startingFilter).each(me.startAnim, me); + + + items.filterBy(me.runningFilter).each(me.runAnim, me); + + + me.applyPendingAttrs(); + }, + + + startAnim: function(anim) { + anim.start(this.timestamp); + }, + + + runAnim: function(anim) { + if (!anim) { + return; + } + var me = this, + targetId = anim.target.getId(), + useCSS3 = me.useCSS3 && anim.target.type == 'element', + elapsedTime = me.timestamp - anim.startTime, + target, o; + + this.collectTargetData(anim, elapsedTime, useCSS3); + + + + if (useCSS3) { + + anim.target.setAttr(me.targetData[targetId], true); + + + me.targetData[targetId] = []; + me.collectTargetData(anim, anim.duration, useCSS3); + + + anim.paused = true; + + target = anim.target.target; + + if (anim.target.isComposite) { + target = anim.target.target.last(); + } + + + o = {}; + o[Ext.supports.CSS3TransitionEnd] = anim.lastFrame; + o.scope = anim; + o.single = true; + target.on(o); + } + + else if (elapsedTime >= anim.duration) { + me.applyPendingAttrs(true); + delete me.targetData[targetId]; + delete me.targetArr[targetId]; + anim.lastFrame(); + } + }, + + + collectTargetData: function(anim, elapsedTime, useCSS3) { + var targetId = anim.target.getId(), + targetData = this.targetData[targetId], + data; + + if (!targetData) { + targetData = this.targetData[targetId] = []; + this.targetArr[targetId] = anim.target; + } + + data = { + duration: anim.duration, + easing: (useCSS3 && anim.reverse) ? anim.easingFn.reverse().toCSS3() : anim.easing, + attrs: {} + }; + Ext.apply(data.attrs, anim.runAnim(elapsedTime)); + targetData.push(data); + }, + + + applyPendingAttrs: function(isLastFrame) { + var targetData = this.targetData, + targetArr = this.targetArr, + targetId; + for (targetId in targetData) { + if (targetData.hasOwnProperty(targetId)) { + targetArr[targetId].setAttr(targetData[targetId], false, isLastFrame); + } + } + } +}); + + +Ext.define('Ext.fx.Animator', { + + + + mixins: { + observable: 'Ext.util.Observable' + }, + + requires: ['Ext.fx.Manager'], + + + + isAnimator: true, + + + duration: 250, + + + delay: 0, + + + delayStart: 0, + + + dynamic: false, + + + easing: 'ease', + + + running: false, + + + paused: false, + + + damper: 1, + + + iterations: 1, + + + currentIteration: 0, + + + keyframeStep: 0, + + + animKeyFramesRE: /^(from|to|\d+%?)$/, + + + + + constructor: function(config) { + var me = this; + config = Ext.apply(me, config || {}); + me.config = config; + me.id = Ext.id(null, 'ext-animator-'); + me.addEvents( + + 'beforeanimate', + + 'keyframe', + + 'afteranimate' + ); + me.mixins.observable.constructor.call(me, config); + me.timeline = []; + me.createTimeline(me.keyframes); + if (me.target) { + me.applyAnimator(me.target); + Ext.fx.Manager.addAnim(me); + } + }, + + + sorter: function (a, b) { + return a.pct - b.pct; + }, + + + createTimeline: function(keyframes) { + var me = this, + attrs = [], + to = me.to || {}, + duration = me.duration, + prevMs, ms, i, ln, pct, anim, nextAnim, attr; + + for (pct in keyframes) { + if (keyframes.hasOwnProperty(pct) && me.animKeyFramesRE.test(pct)) { + attr = {attrs: Ext.apply(keyframes[pct], to)}; + + if (pct == "from") { + pct = 0; + } + else if (pct == "to") { + pct = 100; + } + + attr.pct = parseInt(pct, 10); + attrs.push(attr); + } + } + + Ext.Array.sort(attrs, me.sorter); + + + + + + ln = attrs.length; + for (i = 0; i < ln; i++) { + prevMs = (attrs[i - 1]) ? duration * (attrs[i - 1].pct / 100) : 0; + ms = duration * (attrs[i].pct / 100); + me.timeline.push({ + duration: ms - prevMs, + attrs: attrs[i].attrs + }); + } + }, + + + applyAnimator: function(target) { + var me = this, + anims = [], + timeline = me.timeline, + reverse = me.reverse, + ln = timeline.length, + anim, easing, damper, initial, attrs, lastAttrs, i; + + if (me.fireEvent('beforeanimate', me) !== false) { + for (i = 0; i < ln; i++) { + anim = timeline[i]; + attrs = anim.attrs; + easing = attrs.easing || me.easing; + damper = attrs.damper || me.damper; + delete attrs.easing; + delete attrs.damper; + anim = Ext.create('Ext.fx.Anim', { + target: target, + easing: easing, + damper: damper, + duration: anim.duration, + paused: true, + to: attrs + }); + anims.push(anim); + } + me.animations = anims; + me.target = anim.target; + for (i = 0; i < ln - 1; i++) { + anim = anims[i]; + anim.nextAnim = anims[i + 1]; + anim.on('afteranimate', function() { + this.nextAnim.paused = false; + }); + anim.on('afteranimate', function() { + this.fireEvent('keyframe', this, ++this.keyframeStep); + }, me); + } + anims[ln - 1].on('afteranimate', function() { + this.lastFrame(); + }, me); + } + }, + + + start: function(startTime) { + var me = this, + delay = me.delay, + delayStart = me.delayStart, + delayDelta; + if (delay) { + if (!delayStart) { + me.delayStart = startTime; + return; + } + else { + delayDelta = startTime - delayStart; + if (delayDelta < delay) { + return; + } + else { + + startTime = new Date(delayStart.getTime() + delay); + } + } + } + if (me.fireEvent('beforeanimate', me) !== false) { + me.startTime = startTime; + me.running = true; + me.animations[me.keyframeStep].paused = false; + } + }, + + + lastFrame: function() { + var me = this, + iter = me.iterations, + iterCount = me.currentIteration; + + iterCount++; + if (iterCount < iter) { + me.startTime = new Date(); + me.currentIteration = iterCount; + me.keyframeStep = 0; + me.applyAnimator(me.target); + me.animations[me.keyframeStep].paused = false; + } + else { + me.currentIteration = 0; + me.end(); + } + }, + + + end: function() { + var me = this; + me.fireEvent('afteranimate', me, me.startTime, new Date() - me.startTime); + } +}); + +Ext.ns('Ext.fx'); + +Ext.require('Ext.fx.CubicBezier', function() { + var math = Math, + pi = math.PI, + pow = math.pow, + sin = math.sin, + sqrt = math.sqrt, + abs = math.abs, + backInSeed = 1.70158; + Ext.fx.Easing = { + + + + + + + + + }; + + Ext.apply(Ext.fx.Easing, { + linear: function(n) { + return n; + }, + ease: function(n) { + var q = 0.07813 - n / 2, + alpha = -0.25, + Q = sqrt(0.0066 + q * q), + x = Q - q, + X = pow(abs(x), 1/3) * (x < 0 ? -1 : 1), + y = -Q - q, + Y = pow(abs(y), 1/3) * (y < 0 ? -1 : 1), + t = X + Y + 0.25; + return pow(1 - t, 2) * 3 * t * 0.1 + (1 - t) * 3 * t * t + t * t * t; + }, + easeIn: function (n) { + return pow(n, 1.7); + }, + easeOut: function (n) { + return pow(n, 0.48); + }, + easeInOut: function(n) { + var q = 0.48 - n / 1.04, + Q = sqrt(0.1734 + q * q), + x = Q - q, + X = pow(abs(x), 1/3) * (x < 0 ? -1 : 1), + y = -Q - q, + Y = pow(abs(y), 1/3) * (y < 0 ? -1 : 1), + t = X + Y + 0.5; + return (1 - t) * 3 * t * t + t * t * t; + }, + backIn: function (n) { + return n * n * ((backInSeed + 1) * n - backInSeed); + }, + backOut: function (n) { + n = n - 1; + return n * n * ((backInSeed + 1) * n + backInSeed) + 1; + }, + elasticIn: function (n) { + if (n === 0 || n === 1) { + return n; + } + var p = 0.3, + s = p / 4; + return pow(2, -10 * n) * sin((n - s) * (2 * pi) / p) + 1; + }, + elasticOut: function (n) { + return 1 - Ext.fx.Easing.elasticIn(1 - n); + }, + bounceIn: function (n) { + return 1 - Ext.fx.Easing.bounceOut(1 - n); + }, + bounceOut: function (n) { + var s = 7.5625, + p = 2.75, + l; + if (n < (1 / p)) { + l = s * n * n; + } else { + if (n < (2 / p)) { + n -= (1.5 / p); + l = s * n * n + 0.75; + } else { + if (n < (2.5 / p)) { + n -= (2.25 / p); + l = s * n * n + 0.9375; + } else { + n -= (2.625 / p); + l = s * n * n + 0.984375; + } + } + } + return l; + } + }); + Ext.apply(Ext.fx.Easing, { + 'back-in': Ext.fx.Easing.backIn, + 'back-out': Ext.fx.Easing.backOut, + 'ease-in': Ext.fx.Easing.easeIn, + 'ease-out': Ext.fx.Easing.easeOut, + 'elastic-in': Ext.fx.Easing.elasticIn, + 'elastic-out': Ext.fx.Easing.elasticIn, + 'bounce-in': Ext.fx.Easing.bounceIn, + 'bounce-out': Ext.fx.Easing.bounceOut, + 'ease-in-out': Ext.fx.Easing.easeInOut + }); +}); + + +Ext.define('Ext.draw.Draw', { + + + singleton: true, + + requires: ['Ext.draw.Color'], + + + + pathToStringRE: /,?([achlmqrstvxz]),?/gi, + pathCommandRE: /([achlmqstvz])[\s,]*((-?\d*\.?\d*(?:e[-+]?\d+)?\s*,?\s*)+)/ig, + pathValuesRE: /(-?\d*\.?\d*(?:e[-+]?\d+)?)\s*,?\s*/ig, + stopsRE: /^(\d+%?)$/, + radian: Math.PI / 180, + + availableAnimAttrs: { + along: "along", + blur: null, + "clip-rect": "csv", + cx: null, + cy: null, + fill: "color", + "fill-opacity": null, + "font-size": null, + height: null, + opacity: null, + path: "path", + r: null, + rotation: "csv", + rx: null, + ry: null, + scale: "csv", + stroke: "color", + "stroke-opacity": null, + "stroke-width": null, + translation: "csv", + width: null, + x: null, + y: null + }, + + is: function(o, type) { + type = String(type).toLowerCase(); + return (type == "object" && o === Object(o)) || + (type == "undefined" && typeof o == type) || + (type == "null" && o === null) || + (type == "array" && Array.isArray && Array.isArray(o)) || + (Object.prototype.toString.call(o).toLowerCase().slice(8, -1)) == type; + }, + + ellipsePath: function(sprite) { + var attr = sprite.attr; + return Ext.String.format("M{0},{1}A{2},{3},0,1,1,{0},{4}A{2},{3},0,1,1,{0},{1}z", attr.x, attr.y - attr.ry, attr.rx, attr.ry, attr.y + attr.ry); + }, + + rectPath: function(sprite) { + var attr = sprite.attr; + if (attr.radius) { + return Ext.String.format("M{0},{1}l{2},0a{3},{3},0,0,1,{3},{3}l0,{5}a{3},{3},0,0,1,{4},{3}l{6},0a{3},{3},0,0,1,{4},{4}l0,{7}a{3},{3},0,0,1,{3},{4}z", attr.x + attr.radius, attr.y, attr.width - attr.radius * 2, attr.radius, -attr.radius, attr.height - attr.radius * 2, attr.radius * 2 - attr.width, attr.radius * 2 - attr.height); + } + else { + return Ext.String.format("M{0},{1}l{2},0,0,{3},{4},0z", attr.x, attr.y, attr.width, attr.height, -attr.width); + } + }, + + path2string: function () { + return this.join(",").replace(Ext.draw.Draw.pathToStringRE, "$1"); + }, + + parsePathString: function (pathString) { + if (!pathString) { + return null; + } + var paramCounts = {a: 7, c: 6, h: 1, l: 2, m: 2, q: 4, s: 4, t: 2, v: 1, z: 0}, + data = [], + me = this; + if (me.is(pathString, "array") && me.is(pathString[0], "array")) { + data = me.pathClone(pathString); + } + if (!data.length) { + String(pathString).replace(me.pathCommandRE, function (a, b, c) { + var params = [], + name = b.toLowerCase(); + c.replace(me.pathValuesRE, function (a, b) { + b && params.push(+b); + }); + if (name == "m" && params.length > 2) { + data.push([b].concat(params.splice(0, 2))); + name = "l"; + b = (b == "m") ? "l" : "L"; + } + while (params.length >= paramCounts[name]) { + data.push([b].concat(params.splice(0, paramCounts[name]))); + if (!paramCounts[name]) { + break; + } + } + }); + } + data.toString = me.path2string; + return data; + }, + + mapPath: function (path, matrix) { + if (!matrix) { + return path; + } + var x, y, i, ii, j, jj, pathi; + path = this.path2curve(path); + for (i = 0, ii = path.length; i < ii; i++) { + pathi = path[i]; + for (j = 1, jj = pathi.length; j < jj-1; j += 2) { + x = matrix.x(pathi[j], pathi[j + 1]); + y = matrix.y(pathi[j], pathi[j + 1]); + pathi[j] = x; + pathi[j + 1] = y; + } + } + return path; + }, + + pathClone: function(pathArray) { + var res = [], + j, + jj, + i, + ii; + if (!this.is(pathArray, "array") || !this.is(pathArray && pathArray[0], "array")) { + pathArray = this.parsePathString(pathArray); + } + for (i = 0, ii = pathArray.length; i < ii; i++) { + res[i] = []; + for (j = 0, jj = pathArray[i].length; j < jj; j++) { + res[i][j] = pathArray[i][j]; + } + } + res.toString = this.path2string; + return res; + }, + + pathToAbsolute: function (pathArray) { + if (!this.is(pathArray, "array") || !this.is(pathArray && pathArray[0], "array")) { + pathArray = this.parsePathString(pathArray); + } + var res = [], + x = 0, + y = 0, + mx = 0, + my = 0, + start = 0, + i, + ii, + r, + pa, + j, + jj, + k, + kk; + if (pathArray[0][0] == "M") { + x = +pathArray[0][1]; + y = +pathArray[0][2]; + mx = x; + my = y; + start++; + res[0] = ["M", x, y]; + } + for (i = start, ii = pathArray.length; i < ii; i++) { + r = res[i] = []; + pa = pathArray[i]; + if (pa[0] != pa[0].toUpperCase()) { + r[0] = pa[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); + break; + case "V": + r[1] = +pa[1] + y; + break; + case "H": + r[1] = +pa[1] + x; + break; + case "M": + mx = +pa[1] + x; + my = +pa[2] + y; + default: + for (j = 1, jj = pa.length; j < jj; j++) { + r[j] = +pa[j] + ((j % 2) ? x : y); + } + } + } else { + for (k = 0, kk = pa.length; k < kk; k++) { + res[i][k] = pa[k]; + } + } + 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]; + default: + x = res[i][res[i].length - 2]; + y = res[i][res[i].length - 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); + } + var res = [], + x = 0, + y = 0, + mx = 0, + my = 0, + start = 0; + if (pathArray[0][0] == "M") { + x = pathArray[0][1]; + y = pathArray[0][2]; + mx = x; + my = y; + start++; + res.push(["M", x, y]); + } + for (var i = start, ii = pathArray.length; i < ii; i++) { + var r = res[i] = [], + pa = pathArray[i]; + if (pa[0] != pa[0].toLowerCase()) { + r[0] = pa[0].toLowerCase(); + 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).toFixed(3); + r[7] = +(pa[7] - y).toFixed(3); + break; + case "v": + r[1] = +(pa[1] - y).toFixed(3); + break; + case "m": + mx = pa[1]; + my = pa[2]; + default: + for (var j = 1, jj = pa.length; j < jj; j++) { + r[j] = +(pa[j] - ((j % 2) ? x : y)).toFixed(3); + } + } + } else { + r = res[i] = []; + if (pa[0] == "m") { + mx = pa[1] + x; + my = pa[2] + y; + } + for (var k = 0, kk = pa.length; k < kk; k++) { + res[i][k] = pa[k]; + } + } + var len = res[i].length; + switch (res[i][0]) { + case "z": + x = mx; + y = my; + break; + case "h": + x += +res[i][len - 1]; + break; + case "v": + y += +res[i][len - 1]; + break; + default: + x += +res[i][len - 2]; + y += +res[i][len - 1]; + } + } + res.toString = this.path2string; + return res; + }, + + + path2curve: function (path) { + var me = this, + points = me.pathToAbsolute(path), + ln = points.length, + attrs = {x: 0, y: 0, bx: 0, by: 0, X: 0, Y: 0, qx: null, qy: null}, + i, seg, segLn, point; + + for (i = 0; i < ln; i++) { + points[i] = me.command2curve(points[i], attrs); + if (points[i].length > 7) { + points[i].shift(); + point = points[i]; + while (point.length) { + points.splice(i++, 0, ["C"].concat(point.splice(0, 6))); + } + points.splice(i, 1); + ln = points.length; + } + seg = points[i]; + segLn = seg.length; + attrs.x = seg[segLn - 2]; + attrs.y = seg[segLn - 1]; + attrs.bx = parseFloat(seg[segLn - 4]) || attrs.x; + attrs.by = parseFloat(seg[segLn - 3]) || attrs.y; + } + return points; + }, + + interpolatePaths: function (path, path2) { + var me = this, + p = me.pathToAbsolute(path), + p2 = me.pathToAbsolute(path2), + attrs = {x: 0, y: 0, bx: 0, by: 0, X: 0, Y: 0, qx: null, qy: null}, + attrs2 = {x: 0, y: 0, bx: 0, by: 0, X: 0, Y: 0, qx: null, qy: null}, + fixArc = function (pp, i) { + if (pp[i].length > 7) { + pp[i].shift(); + var pi = pp[i]; + while (pi.length) { + pp.splice(i++, 0, ["C"].concat(pi.splice(0, 6))); + } + pp.splice(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]); + a1.bx = 0; + a1.by = 0; + a1.x = path1[i][1]; + a1.y = path1[i][2]; + ii = Math.max(p.length, p2.length || 0); + } + }; + for (var i = 0, ii = Math.max(p.length, p2.length || 0); i < ii; i++) { + p[i] = me.command2curve(p[i], attrs); + fixArc(p, i); + (p2[i] = me.command2curve(p2[i], attrs2)); + fixArc(p2, i); + fixM(p, p2, attrs, attrs2, i); + fixM(p2, p, attrs2, attrs, i); + var seg = p[i], + seg2 = p2[i], + seglen = seg.length, + seg2len = seg2.length; + attrs.x = seg[seglen - 2]; + attrs.y = seg[seglen - 1]; + attrs.bx = parseFloat(seg[seglen - 4]) || attrs.x; + attrs.by = parseFloat(seg[seglen - 3]) || attrs.y; + attrs2.bx = (parseFloat(seg2[seg2len - 4]) || attrs2.x); + attrs2.by = (parseFloat(seg2[seg2len - 3]) || attrs2.y); + attrs2.x = seg2[seg2len - 2]; + attrs2.y = seg2[seg2len - 1]; + } + return [p, p2]; + }, + + + command2curve: function (pathCommand, d) { + var me = this; + if (!pathCommand) { + return ["C", d.x, d.y, d.x, d.y, d.x, d.y]; + } + if (pathCommand[0] != "T" && pathCommand[0] != "Q") { + d.qx = d.qy = null; + } + switch (pathCommand[0]) { + case "M": + d.X = pathCommand[1]; + d.Y = pathCommand[2]; + break; + case "A": + pathCommand = ["C"].concat(me.arc2curve.apply(me, [d.x, d.y].concat(pathCommand.slice(1)))); + break; + case "S": + pathCommand = ["C", d.x + (d.x - (d.bx || d.x)), d.y + (d.y - (d.by || d.y))].concat(pathCommand.slice(1)); + break; + case "T": + d.qx = d.x + (d.x - (d.qx || d.x)); + d.qy = d.y + (d.y - (d.qy || d.y)); + pathCommand = ["C"].concat(me.quadratic2curve(d.x, d.y, d.qx, d.qy, pathCommand[1], pathCommand[2])); + break; + case "Q": + d.qx = pathCommand[1]; + d.qy = pathCommand[2]; + pathCommand = ["C"].concat(me.quadratic2curve(d.x, d.y, pathCommand[1], pathCommand[2], pathCommand[3], pathCommand[4])); + break; + case "L": + pathCommand = ["C"].concat(d.x, d.y, pathCommand[1], pathCommand[2], pathCommand[1], pathCommand[2]); + break; + case "H": + pathCommand = ["C"].concat(d.x, d.y, pathCommand[1], d.y, pathCommand[1], d.y); + break; + case "V": + pathCommand = ["C"].concat(d.x, d.y, d.x, pathCommand[1], d.x, pathCommand[1]); + break; + case "Z": + pathCommand = ["C"].concat(d.x, d.y, d.X, d.Y, d.X, d.Y); + break; + } + return pathCommand; + }, + + quadratic2curve: function (x1, y1, ax, ay, x2, y2) { + var _13 = 1 / 3, + _23 = 2 / 3; + return [ + _13 * x1 + _23 * ax, + _13 * y1 + _23 * ay, + _13 * x2 + _23 * ax, + _13 * y2 + _23 * ay, + x2, + y2 + ]; + }, + + rotate: function (x, y, rad) { + var cos = Math.cos(rad), + sin = Math.sin(rad), + X = x * cos - y * sin, + Y = x * sin + y * cos; + return {x: X, y: Y}; + }, + + arc2curve: function (x1, y1, rx, ry, angle, large_arc_flag, sweep_flag, x2, y2, recursive) { + + + var me = this, + PI = Math.PI, + radian = me.radian, + _120 = PI * 120 / 180, + rad = radian * (+angle || 0), + res = [], + math = Math, + mcos = math.cos, + msin = math.sin, + msqrt = math.sqrt, + mabs = math.abs, + masin = math.asin, + xy, cos, sin, x, y, h, rx2, ry2, k, cx, cy, f1, f2, df, c1, s1, c2, s2, + t, hx, hy, m1, m2, m3, m4, newres, i, ln, f2old, x2old, y2old; + if (!recursive) { + xy = me.rotate(x1, y1, -rad); + x1 = xy.x; + y1 = xy.y; + xy = me.rotate(x2, y2, -rad); + x2 = xy.x; + y2 = xy.y; + cos = mcos(radian * angle); + sin = msin(radian * angle); + x = (x1 - x2) / 2; + y = (y1 - y2) / 2; + h = (x * x) / (rx * rx) + (y * y) / (ry * ry); + if (h > 1) { + h = msqrt(h); + rx = h * rx; + ry = h * ry; + } + rx2 = rx * rx; + ry2 = ry * ry; + k = (large_arc_flag == sweep_flag ? -1 : 1) * + msqrt(mabs((rx2 * ry2 - rx2 * y * y - ry2 * x * x) / (rx2 * y * y + ry2 * x * x))); + cx = k * rx * y / ry + (x1 + x2) / 2; + cy = k * -ry * x / rx + (y1 + y2) / 2; + f1 = masin(((y1 - cy) / ry).toFixed(7)); + f2 = masin(((y2 - cy) / ry).toFixed(7)); + + f1 = x1 < cx ? PI - f1 : f1; + f2 = x2 < cx ? PI - f2 : f2; + if (f1 < 0) { + f1 = PI * 2 + f1; + } + if (f2 < 0) { + f2 = PI * 2 + f2; + } + if (sweep_flag && f1 > f2) { + f1 = f1 - PI * 2; + } + if (!sweep_flag && f2 > f1) { + f2 = f2 - PI * 2; + } + } + else { + f1 = recursive[0]; + f2 = recursive[1]; + cx = recursive[2]; + cy = recursive[3]; + } + df = f2 - f1; + if (mabs(df) > _120) { + f2old = f2; + x2old = x2; + y2old = y2; + f2 = f1 + _120 * (sweep_flag && f2 > f1 ? 1 : -1); + x2 = cx + rx * mcos(f2); + y2 = cy + ry * msin(f2); + res = me.arc2curve(x2, y2, rx, ry, angle, 0, sweep_flag, x2old, y2old, [f2, f2old, cx, cy]); + } + df = f2 - f1; + c1 = mcos(f1); + s1 = msin(f1); + c2 = mcos(f2); + s2 = msin(f2); + t = math.tan(df / 4); + hx = 4 / 3 * rx * t; + hy = 4 / 3 * ry * t; + m1 = [x1, y1]; + m2 = [x1 + hx * s1, y1 - hy * c1]; + m3 = [x2 + hx * s2, y2 - hy * c2]; + m4 = [x2, y2]; + m2[0] = 2 * m1[0] - m2[0]; + m2[1] = 2 * m1[1] - m2[1]; + if (recursive) { + return [m2, m3, m4].concat(res); + } + else { + res = [m2, m3, m4].concat(res).join().split(","); + newres = []; + ln = res.length; + for (i = 0; i < ln; i++) { + newres[i] = i % 2 ? me.rotate(res[i - 1], res[i], rad).y : me.rotate(res[i], res[i + 1], rad).x; + } + 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, + cy = sprite.rotation.y, + dx = sprite.translation.x, + dy = sprite.translation.y, + path, + i, + p, + xy, + j, + res = []; + if (!alpha && !dx && !dy) { + return this.pathToAbsolute(sprite.attr.path); + } + dx = dx || 0; + dy = dy || 0; + path = this.pathToAbsolute(sprite.attr.path); + for (i = path.length; i--;) { + p = res[i] = path[i].slice(); + if (p[0] == "A") { + xy = this.rotatePoint(p[6], p[7], alpha, cx, cy); + p[6] = xy.x + dx; + p[7] = xy.y + dy; + } else { + j = 1; + while (p[j + 1] != null) { + xy = this.rotatePoint(p[j], p[j + 1], alpha, cx, cy); + p[j] = xy.x + dx; + p[j + 1] = xy.y + dy; + j += 2; + } + } + } + return res; + }, + + pathDimensions: function (path) { + if (!path || !(path + "")) { + return {x: 0, y: 0, width: 0, height: 0}; + } + path = this.path2curve(path); + var x = 0, + y = 0, + X = [], + Y = [], + p, + i, + ii, + xmin, + ymin, + dim; + for (i = 0, ii = path.length; i < ii; i++) { + p = path[i]; + if (p[0] == "M") { + x = p[1]; + y = p[2]; + X.push(x); + Y.push(y); + } + else { + dim = this.curveDim(x, y, p[1], p[2], p[3], p[4], p[5], p[6]); + X = X.concat(dim.min.x, dim.max.x); + Y = Y.concat(dim.min.y, dim.max.y); + x = p[5]; + y = p[6]; + } + } + xmin = Math.min.apply(0, X); + ymin = Math.min.apply(0, Y); + return { + x: xmin, + y: ymin, + path: path, + width: Math.max.apply(0, X) - xmin, + height: Math.max.apply(0, Y) - ymin + }; + }, + + 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) { + cp2 = clipPolygon[i]; + var inputList = outputList; + outputList = []; + s = inputList[inputList.length -1]; + for (var j = 0, ln = inputList.length; j < ln; j++) { + e = inputList[j]; + if (inside(e)) { + if (!inside(s)) { + outputList.push(intersection()); + } + outputList.push(e); + } else if (inside(s)) { + outputList.push(intersection()); + } + s = e; + } + cp1 = cp2; + } + 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), + c = p1x - c1x, + t1 = (-b + Math.sqrt(b * b - 4 * a * c)) / 2 / a, + t2 = (-b - Math.sqrt(b * b - 4 * a * c)) / 2 / a, + y = [p1y, p2y], + x = [p1x, p2x], + dot; + if (Math.abs(t1) > 1e12) { + t1 = 0.5; + } + if (Math.abs(t2) > 1e12) { + t2 = 0.5; + } + if (t1 > 0 && t1 < 1) { + dot = this.findDotAtSegment(p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y, t1); + x.push(dot.x); + y.push(dot.y); + } + if (t2 > 0 && t2 < 1) { + dot = this.findDotAtSegment(p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y, t2); + x.push(dot.x); + y.push(dot.y); + } + a = (c2y - 2 * c1y + p1y) - (p2y - 2 * c2y + c1y); + b = 2 * (c1y - p1y) - 2 * (c2y - c1y); + c = p1y - c1y; + t1 = (-b + Math.sqrt(b * b - 4 * a * c)) / 2 / a; + t2 = (-b - Math.sqrt(b * b - 4 * a * c)) / 2 / a; + if (Math.abs(t1) > 1e12) { + t1 = 0.5; + } + if (Math.abs(t2) > 1e12) { + t2 = 0.5; + } + if (t1 > 0 && t1 < 1) { + dot = this.findDotAtSegment(p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y, t1); + x.push(dot.x); + y.push(dot.y); + } + if (t2 > 0 && t2 < 1) { + dot = this.findDotAtSegment(p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y, t2); + x.push(dot.x); + y.push(dot.y); + } + return { + min: {x: Math.min.apply(0, x), y: Math.min.apply(0, y)}, + max: {x: Math.max.apply(0, x), y: Math.max.apply(0, y)} + }; + }, + + getAnchors: function (p1x, p1y, p2x, p2y, p3x, p3y, 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; + }, + + + smooth: function (originalPath, value) { + var path = this.path2curve(originalPath), + newp = [path[0]], + x = path[0][1], + y = path[0][2], + j, + points, + i = 1, + ii = path.length, + beg = 1, + mx = x, + my = y, + cx = 0, + cy = 0; + for (; i < ii; i++) { + var pathi = path[i], + pathil = pathi.length, + pathim = path[i - 1], + pathiml = pathim.length, + pathip = path[i + 1], + pathipl = pathip && pathip.length; + if (pathi[0] == "M") { + mx = pathi[1]; + my = pathi[2]; + j = i + 1; + while (path[j][0] != "C") { + j++; + } + cx = path[j][5]; + cy = path[j][6]; + newp.push(["M", mx, my]); + beg = newp.length; + x = mx; + y = my; + continue; + } + if (pathi[pathil - 2] == mx && pathi[pathil - 1] == my && (!pathip || pathip[0] == "M")) { + var begl = newp[beg].length; + points = this.getAnchors(pathim[pathiml - 2], pathim[pathiml - 1], mx, my, newp[beg][begl - 2], newp[beg][begl - 1], value); + newp[beg][1] = points.x2; + newp[beg][2] = points.y2; + } + else if (!pathip || pathip[0] == "M") { + points = { + x1: pathi[pathil - 2], + y1: pathi[pathil - 1] + }; + } else { + points = this.getAnchors(pathim[pathiml - 2], pathim[pathiml - 1], pathi[pathil - 2], pathi[pathil - 1], pathip[pathipl - 2], pathip[pathipl - 1], value); + } + newp.push(["C", x, y, points.x1, points.y1, pathi[pathil - 2], pathi[pathil - 1]]); + x = points.x2; + y = points.y2; + } + return newp; + }, + + findDotAtSegment: function (p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y, t) { + var t1 = 1 - t; + return { + x: Math.pow(t1, 3) * p1x + Math.pow(t1, 2) * 3 * t * c1x + t1 * 3 * t * t * c2x + Math.pow(t, 3) * p2x, + y: Math.pow(t1, 3) * p1y + Math.pow(t1, 2) * 3 * t * c1y + t1 * 3 * t * t * c2y + Math.pow(t, 3) * p2y + }; + }, + + snapEnds: function (from, to, stepsMax) { + var step = (to - from) / stepsMax, + level = Math.floor(Math.log(step) / Math.LN10) + 1, + m = Math.pow(10, level), + cur, + modulo = Math.round((step % m) * Math.pow(10, 2 - level)), + interval = [[0, 15], [20, 4], [30, 2], [40, 4], [50, 9], [60, 4], [70, 2], [80, 4], [100, 15]], + stepCount = 0, + value, + weight, + i, + topValue, + topWeight = 1e9, + ln = interval.length; + cur = from = Math.floor(from / m) * m; + for (i = 0; i < ln; i++) { + value = interval[i][0]; + weight = (value - modulo) < 0 ? 1e6 : (value - modulo) / interval[i][1]; + if (weight < topWeight) { + topValue = value; + topWeight = weight; + } + } + step = Math.floor(step * Math.pow(10, -level)) * Math.pow(10, level) + topValue * Math.pow(10, level - 2); + while (cur < to) { + cur += step; + stepCount++; + } + to = +cur.toFixed(10); + return { + from: from, + to: to, + power: level, + step: step, + steps: stepCount + }; + }, + + sorter: function (a, b) { + return a.offset - b.offset; + }, + + rad: function(degrees) { + return degrees % 360 * Math.PI / 180; + }, + + degrees: function(radian) { + return radian * 180 / Math.PI % 360; + }, + + withinBox: function(x, y, bbox) { + bbox = bbox || {}; + return (x >= bbox.x && x <= (bbox.x + bbox.width) && y >= bbox.y && y <= (bbox.y + bbox.height)); + }, + + parseGradient: function(gradient) { + var me = this, + type = gradient.type || 'linear', + angle = gradient.angle || 0, + radian = me.radian, + stops = gradient.stops, + stopsArr = [], + stop, + vector, + max, + stopObj; + + if (type == 'linear') { + vector = [0, 0, Math.cos(angle * radian), Math.sin(angle * radian)]; + max = 1 / (Math.max(Math.abs(vector[2]), Math.abs(vector[3])) || 1); + vector[2] *= max; + vector[3] *= max; + if (vector[2] < 0) { + vector[0] = -vector[2]; + vector[2] = 0; + } + if (vector[3] < 0) { + vector[1] = -vector[3]; + vector[3] = 0; + } + } + + for (stop in stops) { + if (stops.hasOwnProperty(stop) && me.stopsRE.test(stop)) { + stopObj = { + offset: parseInt(stop, 10), + color: Ext.draw.Color.toHex(stops[stop].color) || '#ffffff', + opacity: stops[stop].opacity || 1 + }; + stopsArr.push(stopObj); + } + } + + Ext.Array.sort(stopsArr, me.sorter); + if (type == 'linear') { + return { + id: gradient.id, + type: type, + vector: vector, + stops: stopsArr + }; + } + else { + return { + id: gradient.id, + type: type, + centerX: gradient.centerX, + centerY: gradient.centerY, + focalX: gradient.focalX, + focalY: gradient.focalY, + radius: gradient.radius, + vector: vector, + stops: stopsArr + }; + } + } +}); + + +Ext.define('Ext.fx.PropertyHandler', { + + + + requires: ['Ext.draw.Draw'], + + statics: { + defaultHandler: { + pixelDefaults: ['width', 'height', 'top', 'left'], + unitRE: /^(-?\d*\.?\d*){1}(em|ex|px|in|cm|mm|pt|pc|%)*$/, + + computeDelta: function(from, end, damper, initial, attr) { + damper = (typeof damper == 'number') ? damper : 1; + var match = this.unitRE.exec(from), + start, units; + if (match) { + from = match[1]; + units = match[2]; + if (!units && Ext.Array.contains(this.pixelDefaults, attr)) { + units = 'px'; + } + } + from = +from || 0; + + match = this.unitRE.exec(end); + if (match) { + end = match[1]; + units = match[2] || units; + } + end = +end || 0; + start = (initial != null) ? initial : from; + return { + from: from, + delta: (end - start) * damper, + units: units + }; + }, + + get: function(from, end, damper, initialFrom, attr) { + var ln = from.length, + out = [], + i, initial, res, j, len; + for (i = 0; i < ln; i++) { + if (initialFrom) { + initial = initialFrom[i][1].from; + } + if (Ext.isArray(from[i][1]) && Ext.isArray(end)) { + res = []; + j = 0; + len = from[i][1].length; + for (; j < len; j++) { + res.push(this.computeDelta(from[i][1][j], end[j], damper, initial, attr)); + } + out.push([from[i][0], res]); + } + else { + out.push([from[i][0], this.computeDelta(from[i][1], end, damper, initial, attr)]); + } + } + return out; + }, + + set: function(values, easing) { + var ln = values.length, + out = [], + i, val, res, len, j; + for (i = 0; i < ln; i++) { + val = values[i][1]; + if (Ext.isArray(val)) { + res = []; + j = 0; + len = val.length; + for (; j < len; j++) { + res.push(val[j].from + (val[j].delta * easing) + (val[j].units || 0)); + } + out.push([values[i][0], res]); + } else { + out.push([values[i][0], val.from + (val.delta * easing) + (val.units || 0)]); + } + } + return out; + } + }, + color: { + rgbRE: /^rgb\(([0-9]+)\s*,\s*([0-9]+)\s*,\s*([0-9]+)\)$/i, + hexRE: /^#?([0-9A-F]{2})([0-9A-F]{2})([0-9A-F]{2})$/i, + hex3RE: /^#?([0-9A-F]{1})([0-9A-F]{1})([0-9A-F]{1})$/i, + + parseColor : function(color, damper) { + damper = (typeof damper == 'number') ? damper : 1; + var base, + out = false, + match; + + Ext.each([this.hexRE, this.rgbRE, this.hex3RE], function(re, idx) { + base = (idx % 2 == 0) ? 16 : 10; + match = re.exec(color); + if (match && match.length == 4) { + if (idx == 2) { + match[1] += match[1]; + match[2] += match[2]; + match[3] += match[3]; + } + out = { + red: parseInt(match[1], base), + green: parseInt(match[2], base), + blue: parseInt(match[3], base) + }; + return false; + } + }); + return out || color; + }, + + computeDelta: function(from, end, damper, initial) { + from = this.parseColor(from); + end = this.parseColor(end, damper); + var start = initial ? initial : from, + tfrom = typeof start, + tend = typeof end; + + if (tfrom == 'string' || tfrom == 'undefined' + || tend == 'string' || tend == 'undefined') { + return end || start; + } + return { + from: from, + delta: { + red: Math.round((end.red - start.red) * damper), + green: Math.round((end.green - start.green) * damper), + blue: Math.round((end.blue - start.blue) * damper) + } + }; + }, + + get: function(start, end, damper, initialFrom) { + var ln = start.length, + out = [], + i, initial; + for (i = 0; i < ln; i++) { + if (initialFrom) { + initial = initialFrom[i][1].from; + } + out.push([start[i][0], this.computeDelta(start[i][1], end, damper, initial)]); + } + return out; + }, + + set: function(values, easing) { + var ln = values.length, + out = [], + i, val, parsedString, from, delta; + for (i = 0; i < ln; i++) { + val = values[i][1]; + if (val) { + from = val.from; + delta = val.delta; + + val = (typeof val == 'object' && 'red' in val)? + 'rgb(' + val.red + ', ' + val.green + ', ' + val.blue + ')' : val; + val = (typeof val == 'object' && val.length)? val[0] : val; + if (typeof val == 'undefined') { + return []; + } + parsedString = typeof val == 'string'? val : + 'rgb(' + [ + (from.red + Math.round(delta.red * easing)) % 256, + (from.green + Math.round(delta.green * easing)) % 256, + (from.blue + Math.round(delta.blue * easing)) % 256 + ].join(',') + ')'; + out.push([ + values[i][0], + parsedString + ]); + } + } + return out; + } + }, + object: { + interpolate: function(prop, damper) { + damper = (typeof damper == 'number') ? damper : 1; + var out = {}, + p; + for(p in prop) { + out[p] = parseInt(prop[p], 10) * damper; + } + return out; + }, + + computeDelta: function(from, end, damper, initial) { + from = this.interpolate(from); + end = this.interpolate(end, damper); + var start = initial ? initial : from, + delta = {}, + p; + + for(p in end) { + delta[p] = end[p] - start[p]; + } + return { + from: from, + delta: delta + }; + }, + + get: function(start, end, damper, initialFrom) { + var ln = start.length, + out = [], + i, initial; + for (i = 0; i < ln; i++) { + if (initialFrom) { + initial = initialFrom[i][1].from; + } + out.push([start[i][0], this.computeDelta(start[i][1], end, damper, initial)]); + } + return out; + }, + + set: function(values, easing) { + var ln = values.length, + out = [], + outObject = {}, + i, from, delta, val, p; + for (i = 0; i < ln; i++) { + val = values[i][1]; + from = val.from; + delta = val.delta; + for (p in from) { + outObject[p] = Math.round(from[p] + delta[p] * easing); + } + out.push([ + values[i][0], + outObject + ]); + } + return out; + } + }, + + path: { + computeDelta: function(from, end, damper, initial) { + damper = (typeof damper == 'number') ? damper : 1; + var start; + from = +from || 0; + end = +end || 0; + start = (initial != null) ? initial : from; + return { + from: from, + delta: (end - start) * damper + }; + }, + + forcePath: function(path) { + if (!Ext.isArray(path) && !Ext.isArray(path[0])) { + path = Ext.draw.Draw.parsePathString(path); + } + return path; + }, + + get: function(start, end, damper, initialFrom) { + var endPath = this.forcePath(end), + out = [], + startLn = start.length, + startPathLn, pointsLn, i, deltaPath, initial, j, k, path, startPath; + for (i = 0; i < startLn; i++) { + startPath = this.forcePath(start[i][1]); + + deltaPath = Ext.draw.Draw.interpolatePaths(startPath, endPath); + startPath = deltaPath[0]; + endPath = deltaPath[1]; + + startPathLn = startPath.length; + path = []; + for (j = 0; j < startPathLn; j++) { + deltaPath = [startPath[j][0]]; + pointsLn = startPath[j].length; + for (k = 1; k < pointsLn; k++) { + initial = initialFrom && initialFrom[0][1][j][k].from; + deltaPath.push(this.computeDelta(startPath[j][k], endPath[j][k], damper, initial)); + } + path.push(deltaPath); + } + out.push([start[i][0], path]); + } + return out; + }, + + set: function(values, easing) { + var ln = values.length, + out = [], + i, j, k, newPath, calcPath, deltaPath, deltaPathLn, pointsLn; + for (i = 0; i < ln; i++) { + deltaPath = values[i][1]; + newPath = []; + deltaPathLn = deltaPath.length; + for (j = 0; j < deltaPathLn; j++) { + calcPath = [deltaPath[j][0]]; + pointsLn = deltaPath[j].length; + for (k = 1; k < pointsLn; k++) { + calcPath.push(deltaPath[j][k].from + deltaPath[j][k].delta * easing); + } + newPath.push(calcPath.join(',')); + } + out.push([values[i][0], newPath.join(',')]); + } + return out; + } + } + + } +}, function() { + Ext.each([ + 'outlineColor', + 'backgroundColor', + 'borderColor', + 'borderTopColor', + 'borderRightColor', + 'borderBottomColor', + 'borderLeftColor', + 'fill', + 'stroke' + ], function(prop) { + this[prop] = this.color; + }, this); +}); + +Ext.define('Ext.fx.Anim', { + + + + mixins: { + observable: 'Ext.util.Observable' + }, + + requires: ['Ext.fx.Manager', 'Ext.fx.Animator', 'Ext.fx.Easing', 'Ext.fx.CubicBezier', 'Ext.fx.PropertyHandler'], + + + + isAnimation: true, + + duration: 250, + + + delay: 0, + + + delayStart: 0, + + + dynamic: false, + + + easing: 'ease', + + + + + damper: 1, + + + bezierRE: /^(?:cubic-)?bezier\(([^,]+),([^,]+),([^,]+),([^\)]+)\)/, + + + reverse: false, + + + running: false, + + + paused: false, + + + iterations: 1, + + + alternate: false, + + + currentIteration: 0, + + + startTime: 0, + + + + + + + + + + + constructor: function(config) { + var me = this; + config = config || {}; + + if (config.keyframes) { + return Ext.create('Ext.fx.Animator', config); + } + config = Ext.apply(me, config); + if (me.from === undefined) { + me.from = {}; + } + me.propHandlers = {}; + me.config = config; + me.target = Ext.fx.Manager.createTarget(me.target); + me.easingFn = Ext.fx.Easing[me.easing]; + me.target.dynamic = me.dynamic; + + + 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]); + } + } + me.id = Ext.id(null, 'ext-anim-'); + Ext.fx.Manager.addAnim(me); + me.addEvents( + + 'beforeanimate', + + 'afteranimate', + + 'lastframe' + ); + me.mixins.observable.constructor.call(me, config); + if (config.callback) { + me.on('afteranimate', config.callback, config.scope); + } + return me; + }, + + + setAttr: function(attr, value) { + return Ext.fx.Manager.items.get(this.id).setAttr(this.target, attr, value); + }, + + + initAttrs: function() { + var me = this, + from = me.from, + to = me.to, + initialFrom = me.initialFrom || {}, + out = {}, + start, end, propHandler, attr; + + for (attr in to) { + if (to.hasOwnProperty(attr)) { + start = me.target.getAttr(attr, from[attr]); + end = to[attr]; + + if (!Ext.fx.PropertyHandler[attr]) { + if (Ext.isObject(end)) { + propHandler = me.propHandlers[attr] = Ext.fx.PropertyHandler.object; + } else { + propHandler = me.propHandlers[attr] = Ext.fx.PropertyHandler.defaultHandler; + } + } + + else { + propHandler = me.propHandlers[attr] = Ext.fx.PropertyHandler[attr]; + } + out[attr] = propHandler.get(start, end, me.damper, initialFrom[attr], attr); + } + } + me.currentAttrs = out; + }, + + + start: function(startTime) { + var me = this, + delay = me.delay, + delayStart = me.delayStart, + delayDelta; + if (delay) { + if (!delayStart) { + me.delayStart = startTime; + return; + } + else { + delayDelta = startTime - delayStart; + if (delayDelta < delay) { + return; + } + else { + + startTime = new Date(delayStart.getTime() + delay); + } + } + } + if (me.fireEvent('beforeanimate', me) !== false) { + me.startTime = startTime; + if (!me.paused && !me.currentAttrs) { + me.initAttrs(); + } + me.running = true; + } + }, + + + runAnim: function(elapsedTime) { + var me = this, + attrs = me.currentAttrs, + duration = me.duration, + easingFn = me.easingFn, + propHandlers = me.propHandlers, + ret = {}, + easing, values, attr, lastFrame; + + if (elapsedTime >= duration) { + elapsedTime = duration; + lastFrame = true; + } + if (me.reverse) { + elapsedTime = duration - elapsedTime; + } + + for (attr in attrs) { + if (attrs.hasOwnProperty(attr)) { + values = attrs[attr]; + easing = lastFrame ? 1 : easingFn(elapsedTime / duration); + ret[attr] = propHandlers[attr].set(values, easing); + } + } + return ret; + }, + + + lastFrame: function() { + var me = this, + iter = me.iterations, + iterCount = me.currentIteration; + + iterCount++; + if (iterCount < iter) { + if (me.alternate) { + me.reverse = !me.reverse; + } + me.startTime = new Date(); + me.currentIteration = iterCount; + + me.paused = false; + } + else { + me.currentIteration = 0; + me.end(); + me.fireEvent('lastframe', me, me.startTime); + } + }, + + + end: function() { + var me = this; + me.startTime = 0; + me.paused = false; + me.running = false; + Ext.fx.Manager.removeAnim(me); + me.fireEvent('afteranimate', me, me.startTime); + } +}); + +Ext.enableFx = true; + + + + + + +Ext.define('Ext.dd.DragDrop', { + requires: ['Ext.dd.DragDropManager'], + constructor: function(id, sGroup, config) { + if(id) { + this.init(id, sGroup, config); + } + }, + + + + + id: null, + + + config: null, + + + dragElId: null, + + + handleElId: null, + + + invalidHandleTypes: null, + + + invalidHandleIds: null, + + + invalidHandleClasses: null, + + + startPageX: 0, + + + startPageY: 0, + + + groups: null, + + + locked: false, + + + lock: function() { + this.locked = true; + }, + + + moveOnly: false, + + + unlock: function() { + this.locked = false; + }, + + + isTarget: true, + + + padding: null, + + + _domRef: null, + + + __ygDragDrop: true, + + + constrainX: false, + + + constrainY: false, + + + minX: 0, + + + maxX: 0, + + + minY: 0, + + + maxY: 0, + + + maintainOffset: false, + + + xTicks: null, + + + yTicks: null, + + + primaryButtonOnly: true, + + + available: false, + + + hasOuterHandles: false, + + + b4StartDrag: function(x, y) { }, + + + startDrag: function(x, y) { }, + + + b4Drag: function(e) { }, + + + onDrag: function(e) { }, + + + onDragEnter: function(e, id) { }, + + + b4DragOver: function(e) { }, + + + onDragOver: function(e, id) { }, + + + b4DragOut: function(e) { }, + + + onDragOut: function(e, id) { }, + + + b4DragDrop: function(e) { }, + + + onDragDrop: function(e, id) { }, + + + onInvalidDrop: function(e) { }, + + + b4EndDrag: function(e) { }, + + + endDrag: function(e) { }, + + + b4MouseDown: function(e) { }, + + + onMouseDown: function(e) { }, + + + onMouseUp: function(e) { }, + + + onAvailable: function () { + }, + + + defaultPadding: { + left: 0, + right: 0, + top: 0, + bottom: 0 + }, + + + constrainTo : function(constrainTo, pad, inContent){ + if(Ext.isNumber(pad)){ + pad = {left: pad, right:pad, top:pad, bottom:pad}; + } + pad = pad || this.defaultPadding; + var b = Ext.get(this.getEl()).getBox(), + ce = Ext.get(constrainTo), + s = ce.getScroll(), + 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()}; }else{ - ret = {left: d.scrollLeft, top: d.scrollTop}; + var xy = ce.getXY(); + c = {x : xy[0], y: xy[1], width: cd.clientWidth, height: cd.clientHeight}; + } + + + var topSpace = b.y - c.y, + leftSpace = b.x - c.x; + + this.resetConstraints(); + this.setXConstraint(leftSpace - (pad.left||0), + c.width - leftSpace - b.width - (pad.right||0), + this.xTickSize + ); + this.setYConstraint(topSpace - (pad.top||0), + c.height - topSpace - b.height - (pad.bottom||0), + this.yTickSize + ); + }, + + + getEl: function() { + if (!this._domRef) { + this._domRef = Ext.getDom(this.id); + } + + return this._domRef; + }, + + + getDragEl: function() { + return Ext.getDom(this.dragElId); + }, + + + init: function(id, sGroup, config) { + this.initTarget(id, sGroup, config); + Ext.EventManager.on(this.id, "mousedown", this.handleMouseDown, this); + + }, + + + initTarget: function(id, sGroup, config) { + + + this.config = config || {}; + + + this.DDMInstance = Ext.dd.DragDropManager; + + this.groups = {}; + + + + if (typeof id !== "string") { + id = Ext.id(id); + } + + + this.id = id; + + + this.addToGroup((sGroup) ? sGroup : "default"); + + + + this.handleElId = id; + + + this.setDragElId(id); + + + this.invalidHandleTypes = { A: "A" }; + this.invalidHandleIds = {}; + this.invalidHandleClasses = []; + + this.applyConfig(); + + this.handleOnAvailable(); + }, + + + applyConfig: function() { + + + + this.padding = this.config.padding || [0, 0, 0, 0]; + this.isTarget = (this.config.isTarget !== false); + this.maintainOffset = (this.config.maintainOffset); + this.primaryButtonOnly = (this.config.primaryButtonOnly !== false); + + }, + + + handleOnAvailable: function() { + this.available = true; + this.resetConstraints(); + this.onAvailable(); + }, + + + setPadding: function(iTop, iRight, iBot, iLeft) { + + if (!iRight && 0 !== iRight) { + this.padding = [iTop, iTop, iTop, iTop]; + } else if (!iBot && 0 !== iBot) { + this.padding = [iTop, iRight, iTop, iRight]; + } else { + this.padding = [iTop, iRight, iBot, iLeft]; + } + }, + + + setInitPosition: function(diffX, diffY) { + var el = this.getEl(); + + if (!this.DDMInstance.verifyEl(el)) { + return; + } + + var dx = diffX || 0; + var dy = diffY || 0; + + var p = Ext.core.Element.getXY( el ); + + this.initPageX = p[0] - dx; + this.initPageY = p[1] - dy; + + this.lastPageX = p[0]; + this.lastPageY = p[1]; + + this.setStartPosition(p); + }, + + + setStartPosition: function(pos) { + var p = pos || Ext.core.Element.getXY( this.getEl() ); + this.deltaSetXY = null; + + this.startPageX = p[0]; + this.startPageY = p[1]; + }, + + + addToGroup: function(sGroup) { + this.groups[sGroup] = true; + this.DDMInstance.regDragDrop(this, sGroup); + }, + + + removeFromGroup: function(sGroup) { + if (this.groups[sGroup]) { + delete this.groups[sGroup]; + } + + this.DDMInstance.removeDDFromGroup(this, sGroup); + }, + + + setDragElId: function(id) { + this.dragElId = id; + }, + + + setHandleElId: function(id) { + if (typeof id !== "string") { + id = Ext.id(id); + } + this.handleElId = id; + this.DDMInstance.regHandle(this.id, id); + }, + + + setOuterHandleElId: function(id) { + if (typeof id !== "string") { + id = Ext.id(id); + } + Ext.EventManager.on(id, "mousedown", this.handleMouseDown, this); + this.setHandleElId(id); + + this.hasOuterHandles = true; + }, + + + unreg: function() { + Ext.EventManager.un(this.id, "mousedown", this.handleMouseDown, this); + this._domRef = null; + this.DDMInstance._remove(this); + }, + + destroy : function(){ + this.unreg(); + }, + + + isLocked: function() { + return (this.DDMInstance.isLocked() || this.locked); + }, + + + handleMouseDown: function(e, oDD){ + if (this.primaryButtonOnly && e.button != 0) { + return; + } + + if (this.isLocked()) { + return; + } + + this.DDMInstance.refreshCache(this.groups); + + var pt = e.getPoint(); + if (!this.hasOuterHandles && !this.DDMInstance.isOverTarget(pt, this) ) { + } else { + if (this.clickValidator(e)) { + + this.setStartPosition(); + this.b4MouseDown(e); + this.onMouseDown(e); + + this.DDMInstance.handleMouseDown(e, this); + + this.DDMInstance.stopEvent(e); + } else { + + + } + } + }, + + clickValidator: function(e) { + var target = e.getTarget(); + return ( this.isValidHandleChild(target) && + (this.id == this.handleElId || + this.DDMInstance.handleWasClicked(target, this.id)) ); + }, + + + addInvalidHandleType: function(tagName) { + var type = tagName.toUpperCase(); + this.invalidHandleTypes[type] = type; + }, + + + addInvalidHandleId: function(id) { + if (typeof id !== "string") { + id = Ext.id(id); + } + this.invalidHandleIds[id] = id; + }, + + + addInvalidHandleClass: function(cssClass) { + this.invalidHandleClasses.push(cssClass); + }, + + + removeInvalidHandleType: function(tagName) { + var type = tagName.toUpperCase(); + + delete this.invalidHandleTypes[type]; + }, + + + removeInvalidHandleId: function(id) { + if (typeof id !== "string") { + id = Ext.id(id); + } + delete this.invalidHandleIds[id]; + }, + + + removeInvalidHandleClass: function(cssClass) { + for (var i=0, len=this.invalidHandleClasses.length; i= this.minX; i = i - iTickSize) { + if (!tickMap[i]) { + this.xTicks[this.xTicks.length] = i; + tickMap[i] = true; + } + } + + for (i = this.initPageX; i <= this.maxX; i = i + iTickSize) { + if (!tickMap[i]) { + this.xTicks[this.xTicks.length] = i; + tickMap[i] = true; + } + } + + Ext.Array.sort(this.xTicks, this.DDMInstance.numericSort); + }, + + + setYTicks: function(iStartY, iTickSize) { + this.yTicks = []; + this.yTickSize = iTickSize; + + var tickMap = {}; + + for (var i = this.initPageY; i >= this.minY; i = i - iTickSize) { + if (!tickMap[i]) { + this.yTicks[this.yTicks.length] = i; + tickMap[i] = true; + } + } + + for (i = this.initPageY; i <= this.maxY; i = i + iTickSize) { + if (!tickMap[i]) { + this.yTicks[this.yTicks.length] = i; + tickMap[i] = true; + } + } + + Ext.Array.sort(this.yTicks, this.DDMInstance.numericSort); + }, + + + setXConstraint: function(iLeft, iRight, iTickSize) { + this.leftConstraint = iLeft; + this.rightConstraint = iRight; + + this.minX = this.initPageX - iLeft; + this.maxX = this.initPageX + iRight; + if (iTickSize) { this.setXTicks(this.initPageX, iTickSize); } + + this.constrainX = true; + }, + + + clearConstraints: function() { + this.constrainX = false; + this.constrainY = false; + this.clearTicks(); + }, + + + clearTicks: function() { + this.xTicks = null; + this.yTicks = null; + this.xTickSize = 0; + this.yTickSize = 0; + }, + + + setYConstraint: function(iUp, iDown, iTickSize) { + this.topConstraint = iUp; + this.bottomConstraint = iDown; + + this.minY = this.initPageY - iUp; + this.maxY = this.initPageY + iDown; + if (iTickSize) { this.setYTicks(this.initPageY, iTickSize); } + + this.constrainY = true; + + }, + + + resetConstraints: function() { + + if (this.initPageX || this.initPageX === 0) { + + var dx = (this.maintainOffset) ? this.lastPageX - this.initPageX : 0; + var dy = (this.maintainOffset) ? this.lastPageY - this.initPageY : 0; + + this.setInitPosition(dx, dy); + + + } else { + this.setInitPosition(); + } + + if (this.constrainX) { + this.setXConstraint( this.leftConstraint, + this.rightConstraint, + this.xTickSize ); + } + + if (this.constrainY) { + this.setYConstraint( this.topConstraint, + this.bottomConstraint, + this.yTickSize ); + } + }, + + + getTick: function(val, tickArray) { + if (!tickArray) { + + + return val; + } else if (tickArray[0] >= val) { + + + return tickArray[0]; + } else { + for (var i=0, len=tickArray.length; i= val) { + var diff1 = val - tickArray[i]; + var diff2 = tickArray[next] - val; + return (diff2 > diff1) ? tickArray[i] : tickArray[next]; + } + } + + + + return tickArray[tickArray.length - 1]; + } + }, + + + toString: function() { + return ("DragDrop " + this.id); + } + +}); + + + + + +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); + } + }, + + + scroll: true, + + + autoOffset: function(iPageX, iPageY) { + var x = iPageX - this.startPageX; + var y = iPageY - this.startPageY; + this.setDelta(x, y); + }, + + + setDelta: function(iDeltaX, iDeltaY) { + this.deltaX = iDeltaX; + this.deltaY = iDeltaY; + }, + + + setDragElPos: function(iPageX, iPageY) { + + + + var el = this.getDragEl(); + this.alignElWithMouse(el, iPageX, iPageY); + }, + + + alignElWithMouse: function(el, iPageX, iPageY) { + var oCoord = this.getTargetCoord(iPageX, iPageY), + fly = el.dom ? el : Ext.fly(el, '_dd'), + elSize = fly.getSize(), + EL = Ext.core.Element, + vpSize; + + if (!this.deltaSetXY) { + vpSize = this.cachedViewportSize = { width: EL.getDocumentWidth(), height: EL.getDocumentHeight() }; + var aCoord = [ + Math.max(0, Math.min(oCoord.x, vpSize.width - elSize.width)), + Math.max(0, Math.min(oCoord.y, vpSize.height - elSize.height)) + ]; + fly.setXY(aCoord); + var newLeft = fly.getLeft(true); + var newTop = fly.getTop(true); + this.deltaSetXY = [newLeft - oCoord.x, newTop - oCoord.y]; + } else { + vpSize = this.cachedViewportSize; + fly.setLeftTop( + Math.max(0, Math.min(oCoord.x + this.deltaSetXY[0], vpSize.width - elSize.width)), + Math.max(0, Math.min(oCoord.y + this.deltaSetXY[1], vpSize.height - elSize.height)) + ); + } + + this.cachePosition(oCoord.x, oCoord.y); + this.autoScroll(oCoord.x, oCoord.y, el.offsetHeight, el.offsetWidth); + return oCoord; + }, + + + cachePosition: function(iPageX, iPageY) { + if (iPageX) { + this.lastPageX = iPageX; + this.lastPageY = iPageY; + } else { + var aCoord = Ext.core.Element.getXY(this.getEl()); + this.lastPageX = aCoord[0]; + this.lastPageY = aCoord[1]; + } + }, + + + autoScroll: function(x, y, h, w) { + + if (this.scroll) { + + var clientH = Ext.core.Element.getViewHeight(); + + + var clientW = Ext.core.Element.getViewWidth(); + + + var st = this.DDMInstance.getScrollTop(); + + + var sl = this.DDMInstance.getScrollLeft(); + + + var bot = h + y; + + + var right = w + x; + + + + + var toBot = (clientH + st - y - this.deltaY); + + + var toRight = (clientW + sl - x - this.deltaX); + + + + + var thresh = 40; + + + + + var scrAmt = (document.all) ? 80 : 30; + + + + if ( bot > clientH && toBot < thresh ) { + window.scrollTo(sl, st + scrAmt); + } + + + + if ( y < st && st > 0 && y - st < thresh ) { + window.scrollTo(sl, st - scrAmt); + } + + + + if ( right > clientW && toRight < thresh ) { + window.scrollTo(sl + scrAmt, st); + } + + + + if ( x < sl && sl > 0 && x - sl < thresh ) { + window.scrollTo(sl - scrAmt, st); + } + } + }, + + + getTargetCoord: function(iPageX, iPageY) { + var x = iPageX - this.deltaX; + var y = iPageY - this.deltaY; + + if (this.constrainX) { + if (x < this.minX) { + x = this.minX; + } + if (x > this.maxX) { + x = this.maxX; + } + } + + if (this.constrainY) { + if (y < this.minY) { + y = this.minY; + } + if (y > this.maxY) { + y = this.maxY; + } + } + + x = this.getTick(x, this.xTicks); + y = this.getTick(y, this.yTicks); + + + return {x: x, y: y}; + }, + + + applyConfig: function() { + this.callParent(); + this.scroll = (this.config.scroll !== false); + }, + + + b4MouseDown: function(e) { + + this.autoOffset(e.getPageX(), e.getPageY()); + }, + + + b4Drag: function(e) { + this.setDragElPos(e.getPageX(), e.getPageY()); + }, + + toString: function() { + return ("DD " + this.id); + } + + + + + + +}); + + + + +Ext.define('Ext.dd.DDProxy', { + extend: 'Ext.dd.DD', + + statics: { + + dragElId: "ygddfdiv" + }, + + constructor: function(id, sGroup, config) { + if (id) { + this.init(id, sGroup, config); + this.initFrame(); + } + }, + + + resizeFrame: true, + + + centerFrame: false, + + + createFrame: function() { + var self = this; + var body = document.body; + + if (!body || !body.firstChild) { + setTimeout( function() { self.createFrame(); }, 50 ); + return; + } + + var div = this.getDragEl(); + + if (!div) { + div = document.createElement("div"); + div.id = this.dragElId; + var s = div.style; + + s.position = "absolute"; + s.visibility = "hidden"; + s.cursor = "move"; + s.border = "2px solid #aaa"; + s.zIndex = 999; + + + + + body.insertBefore(div, body.firstChild); + } + }, + + + initFrame: function() { + this.createFrame(); + }, + + applyConfig: function() { + this.callParent(); + + this.resizeFrame = (this.config.resizeFrame !== false); + this.centerFrame = (this.config.centerFrame); + this.setDragElId(this.config.dragElId || Ext.dd.DDProxy.dragElId); + }, + + + showFrame: function(iPageX, iPageY) { + var el = this.getEl(); + var dragEl = this.getDragEl(); + var s = dragEl.style; + + this._resizeProxy(); + + if (this.centerFrame) { + this.setDelta( Math.round(parseInt(s.width, 10)/2), + Math.round(parseInt(s.height, 10)/2) ); + } + + this.setDragElPos(iPageX, iPageY); + + Ext.fly(dragEl).show(); + }, + + + _resizeProxy: function() { + if (this.resizeFrame) { + var el = this.getEl(); + Ext.fly(this.getDragEl()).setSize(el.offsetWidth, el.offsetHeight); + } + }, + + + b4MouseDown: function(e) { + var x = e.getPageX(); + var y = e.getPageY(); + this.autoOffset(x, y); + this.setDragElPos(x, y); + }, + + + b4StartDrag: function(x, y) { + + this.showFrame(x, y); + }, + + + b4EndDrag: function(e) { + Ext.fly(this.getDragEl()).hide(); + }, + + + + + endDrag: function(e) { + + var lel = this.getEl(); + var del = this.getDragEl(); + + + del.style.visibility = ""; + + this.beforeMove(); + + + lel.style.visibility = "hidden"; + Ext.dd.DDM.moveToEl(lel, del); + del.style.visibility = "hidden"; + lel.style.visibility = ""; + + this.afterDrag(); + }, + + beforeMove : function(){ + + }, + + afterDrag : function(){ + + }, + + toString: function() { + return ("DDProxy " + this.id); + } + +}); + + +Ext.define('Ext.dd.DragSource', { + extend: 'Ext.dd.DDProxy', + requires: [ + 'Ext.dd.StatusProxy', + 'Ext.dd.DragDropManager' + ], + + + + + + dropAllowed : Ext.baseCSSPrefix + 'dd-drop-ok', + + dropNotAllowed : Ext.baseCSSPrefix + 'dd-drop-nodrop', + + + animRepair: true, + + + repairHighlightColor: 'c3daf9', + + constructor: function(el, config) { + this.el = Ext.get(el); + if(!this.dragData){ + this.dragData = {}; + } + + Ext.apply(this, config); + + if(!this.proxy){ + this.proxy = Ext.create('Ext.dd.StatusProxy', { + animRepair: this.animRepair + }); + } + this.callParent([this.el.dom, this.ddGroup || this.group, + {dragElId : this.proxy.id, resizeFrame: false, isTarget: false, scroll: this.scroll === true}]); + + this.dragging = false; + }, + + + getDragData : function(e){ + return this.dragData; + }, + + + onDragEnter : function(e, id){ + var target = Ext.dd.DragDropManager.getDDById(id); + this.cachedTarget = target; + if (this.beforeDragEnter(target, e, id) !== false) { + if (target.isNotifyTarget) { + var status = target.notifyEnter(this, e, this.dragData); + this.proxy.setStatus(status); + } else { + this.proxy.setStatus(this.dropAllowed); + } + + if (this.afterDragEnter) { + + this.afterDragEnter(target, e, id); + } + } + }, + + + beforeDragEnter: function(target, e, id) { + return true; + }, + + + alignElWithMouse: function() { + this.callParent(arguments); + this.proxy.sync(); + }, + + + onDragOver: function(e, id) { + var target = this.cachedTarget || Ext.dd.DragDropManager.getDDById(id); + if (this.beforeDragOver(target, e, id) !== false) { + if(target.isNotifyTarget){ + var status = target.notifyOver(this, e, this.dragData); + this.proxy.setStatus(status); + } + + if (this.afterDragOver) { + + this.afterDragOver(target, e, id); + } + } + }, + + + beforeDragOver: function(target, e, id) { + return true; + }, + + + onDragOut: function(e, id) { + var target = this.cachedTarget || Ext.dd.DragDropManager.getDDById(id); + if (this.beforeDragOut(target, e, id) !== false) { + if (target.isNotifyTarget) { + target.notifyOut(this, e, this.dragData); + } + this.proxy.reset(); + if (this.afterDragOut) { + + this.afterDragOut(target, e, id); + } + } + this.cachedTarget = null; + }, + + + beforeDragOut: function(target, e, id){ + return true; + }, + + + onDragDrop: function(e, id){ + var target = this.cachedTarget || Ext.dd.DragDropManager.getDDById(id); + if (this.beforeDragDrop(target, e, id) !== false) { + if (target.isNotifyTarget) { + if (target.notifyDrop(this, e, this.dragData) !== false) { + this.onValidDrop(target, e, id); + } else { + this.onInvalidDrop(target, e, id); + } + } else { + this.onValidDrop(target, e, id); + } + + if (this.afterDragDrop) { + + this.afterDragDrop(target, e, id); + } + } + delete this.cachedTarget; + }, + + + beforeDragDrop: function(target, e, id){ + return true; + }, + + + onValidDrop: function(target, e, id){ + this.hideProxy(); + if(this.afterValidDrop){ + + this.afterValidDrop(target, e, id); + } + }, + + + getRepairXY: function(e, data){ + return this.el.getXY(); + }, + + + onInvalidDrop: function(target, e, id) { + this.beforeInvalidDrop(target, e, id); + if (this.cachedTarget) { + if(this.cachedTarget.isNotifyTarget){ + this.cachedTarget.notifyOut(this, e, this.dragData); + } + this.cacheTarget = null; + } + this.proxy.repair(this.getRepairXY(e, this.dragData), this.afterRepair, this); + + if (this.afterInvalidDrop) { + + this.afterInvalidDrop(e, id); + } + }, + + + afterRepair: function() { + var me = this; + if (Ext.enableFx) { + me.el.highlight(me.repairHighlightColor); + } + me.dragging = false; + }, + + + beforeInvalidDrop: function(target, e, id) { + return true; + }, + + + handleMouseDown: function(e) { + if (this.dragging) { + return; + } + var data = this.getDragData(e); + if (data && this.onBeforeDrag(data, e) !== false) { + this.dragData = data; + this.proxy.stop(); + this.callParent(arguments); + } + }, + + + onBeforeDrag: function(data, e){ + return true; + }, + + + onStartDrag: Ext.emptyFn, + + + startDrag: function(x, y) { + this.proxy.reset(); + this.dragging = true; + this.proxy.update(""); + this.onInitDrag(x, y); + this.proxy.show(); + }, + + + onInitDrag: function(x, y) { + var clone = this.el.dom.cloneNode(true); + clone.id = Ext.id(); + this.proxy.update(clone); + this.onStartDrag(x, y); + return true; + }, + + + getProxy: function() { + return this.proxy; + }, + + + hideProxy: function() { + this.proxy.hide(); + this.proxy.reset(true); + this.dragging = false; + }, + + + triggerCacheRefresh: function() { + Ext.dd.DDM.refreshCache(this.groups); + }, + + + b4EndDrag: function(e) { + }, + + + endDrag : function(e){ + this.onEndDrag(this.dragData, e); + }, + + + onEndDrag : function(data, e){ + }, + + + autoOffset : function(x, y) { + this.setDelta(-12, -20); + }, + + destroy: function(){ + this.callParent(); + Ext.destroy(this.proxy); + } +}); + + +Ext.define('Ext.panel.DD', { + extend: 'Ext.dd.DragSource', + requires: ['Ext.panel.Proxy'], + + constructor : function(panel, cfg){ + this.panel = panel; + this.dragData = {panel: panel}; + this.proxy = Ext.create('Ext.panel.Proxy', panel, cfg); + + this.callParent([panel.el, cfg]); + + Ext.defer(function() { + var header = panel.header, + el = panel.body; + + if(header){ + this.setHandleElId(header.id); + el = header.el; + } + el.setStyle('cursor', 'move'); + this.scroll = false; + }, 200, this); + }, + + showFrame: Ext.emptyFn, + startDrag: Ext.emptyFn, + b4StartDrag: function(x, y) { + this.proxy.show(); + }, + b4MouseDown: function(e) { + var x = e.getPageX(), + y = e.getPageY(); + this.autoOffset(x, y); + }, + onInitDrag : function(x, y){ + this.onStartDrag(x, y); + return true; + }, + createFrame : Ext.emptyFn, + getDragEl : function(e){ + return this.proxy.ghost.el.dom; + }, + endDrag : function(e){ + this.proxy.hide(); + this.panel.saveState(); + }, + + autoOffset : function(x, y) { + x -= this.startPageX; + y -= this.startPageY; + this.setDelta(x, y); + } +}); + + +Ext.define('Ext.layout.component.Dock', { + + + + alias: ['layout.dock'], + + extend: 'Ext.layout.component.AbstractDock' + + + +}); + +Ext.define('Ext.panel.Panel', { + extend: 'Ext.panel.AbstractPanel', + requires: [ + 'Ext.panel.Header', + 'Ext.fx.Anim', + 'Ext.util.KeyMap', + 'Ext.panel.DD', + 'Ext.XTemplate', + 'Ext.layout.component.Dock' + ], + alias: 'widget.panel', + alternateClassName: 'Ext.Panel', + + + collapsedCls: 'collapsed', + + + animCollapse: Ext.enableFx, + + + minButtonWidth: 75, + + + collapsed: false, + + + collapseFirst: true, + + + hideCollapseTool: false, + + + titleCollapse: false, + + + + + + + floatable: true, + + + collapsible: false, + + + + + closable: false, + + + closeAction: 'destroy', + + + + + preventHeader: false, + + + headerPosition: 'top', + + + frame: false, + + + frameHeader: true, + + + + + initComponent: function() { + var me = this, + cls; + + me.addEvents( + + 'titlechange', + + 'iconchange' + ); + + if (me.unstyled) { + me.setUI('plain'); } - return ret; + + if (me.frame) { + me.setUI('default-framed'); + } + + me.callParent(); + + me.collapseDirection = me.collapseDirection || me.headerPosition || Ext.Component.DIRECTION_TOP; + + + me.bridgeToolbars(); + }, + + setBorder: function(border) { + + + + + + + + + + + + + + + + + this.callParent(arguments); + }, + + beforeDestroy: function() { + Ext.destroy( + this.ghostPanel, + this.dd + ); + this.callParent(); + }, + + initAria: function() { + this.callParent(); + this.initHeaderAria(); + }, + + initHeaderAria: function() { + var me = this, + el = me.el, + header = me.header; + if (el && header) { + el.dom.setAttribute('aria-labelledby', header.titleCmp.id); + } + }, + + getHeader: function() { + return this.header; + }, + + + setTitle: function(newTitle) { + var me = this, + oldTitle = this.title; + + me.title = newTitle; + if (me.header) { + me.header.setTitle(newTitle); + } else { + me.updateHeader(); + } + + if (me.reExpander) { + me.reExpander.setTitle(newTitle); + } + me.fireEvent('titlechange', me, newTitle, oldTitle); + }, + + + setIconCls: function(newIconCls) { + var me = this, + oldIconCls = me.iconCls; + + me.iconCls = newIconCls; + var header = me.header; + if (header) { + header.setIconCls(newIconCls); + } + me.fireEvent('iconchange', me, newIconCls, oldIconCls); + }, + + bridgeToolbars: function() { + var me = this, + fbar, + fbarDefaults, + minButtonWidth = me.minButtonWidth; + + function initToolbar (toolbar, pos) { + if (Ext.isArray(toolbar)) { + toolbar = { + xtype: 'toolbar', + items: toolbar + }; + } + else if (!toolbar.xtype) { + toolbar.xtype = 'toolbar'; + } + toolbar.dock = pos; + if (pos == 'left' || pos == 'right') { + toolbar.vertical = true; + } + return toolbar; + } + + + + + if (me.tbar) { + me.addDocked(initToolbar(me.tbar, 'top')); + me.tbar = null; + } + + + if (me.bbar) { + me.addDocked(initToolbar(me.bbar, 'bottom')); + me.bbar = null; + } + + + if (me.buttons) { + me.fbar = me.buttons; + me.buttons = null; + } + + + if (me.fbar) { + fbar = initToolbar(me.fbar, 'bottom'); + fbar.ui = 'footer'; + + + if (minButtonWidth) { + fbarDefaults = fbar.defaults; + fbar.defaults = function(config) { + var defaults = fbarDefaults || {}; + if ((!config.xtype || config.xtype === 'button' || (config.isComponent && config.isXType('button'))) && + !('minWidth' in defaults)) { + defaults = Ext.apply({minWidth: minButtonWidth}, defaults); + } + return defaults; + }; + } + + fbar = me.addDocked(fbar)[0]; + fbar.insert(0, { + flex: 1, + xtype: 'component', + focusable: false + }); + me.fbar = null; + } + + + if (me.lbar) { + me.addDocked(initToolbar(me.lbar, 'left')); + me.lbar = null; + } + + + if (me.rbar) { + me.addDocked(initToolbar(me.rbar, 'right')); + me.rbar = null; + } + }, + + + initTools: function() { + var me = this; + + me.tools = me.tools || []; + + + + if (me.collapsible && !(me.hideCollapseTool || me.header === false)) { + me.collapseDirection = me.collapseDirection || me.headerPosition || 'top'; + me.collapseTool = me.expandTool = me.createComponent({ + xtype: 'tool', + type: 'collapse-' + me.collapseDirection, + expandType: me.getOppositeDirection(me.collapseDirection), + handler: me.toggleCollapse, + scope: me + }); + + + if (me.collapseFirst) { + me.tools.unshift(me.collapseTool); + } + } + + + me.addTools(); + + + if (me.closable) { + me.addClsWithUI('closable'); + me.addTool({ + type: 'close', + handler: Ext.Function.bind(me.close, this, []) + }); + } + + + if (me.collapseTool && !me.collapseFirst) { + me.tools.push(me.collapseTool); + } + }, + + + addTools: Ext.emptyFn, + + + close: function() { + if (this.fireEvent('beforeclose', this) !== false) { + this.doClose(); + } + }, + + + doClose: function() { + this.fireEvent('close', this); + this[this.closeAction](); + }, + + onRender: function(ct, position) { + var me = this, + topContainer; + + + + me.initTools(); + + + me.updateHeader(); + + + + 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.callParent(arguments); + }, + + + updateHeader: function(force) { + var me = this, + header = me.header, + title = me.title, + tools = me.tools; + + if (!me.preventHeader && (force || title || (tools && tools.length))) { + if (!header) { + header = me.header = Ext.create('Ext.panel.Header', { + title : title, + orientation : (me.headerPosition == 'left' || me.headerPosition == 'right') ? 'vertical' : 'horizontal', + dock : me.headerPosition || 'top', + textCls : me.headerTextCls, + iconCls : me.iconCls, + baseCls : me.baseCls + '-header', + tools : tools, + ui : me.ui, + indicateDrag: me.draggable, + border : me.border, + frame : me.frame && me.frameHeader, + ignoreParentFrame : me.frame || me.overlapHeader, + ignoreBorderManagement: me.frame || me.ignoreHeaderBorderManagement, + listeners : me.collapsible && me.titleCollapse ? { + click: me.toggleCollapse, + scope: me + } : null + }); + me.addDocked(header, 0); + + + + me.tools = header.tools; + } + header.show(); + me.initHeaderAria(); + } else if (header) { + header.hide(); + } + }, + + + setUI: function(ui) { + var me = this; + + me.callParent(arguments); + + if (me.header) { + me.header.setUI(ui); + } + }, + + + getContentTarget: function() { + return this.body; + }, + + getTargetEl: function() { + return this.body || this.frameBody || this.el; + }, + + addTool: function(tool) { + this.tools.push(tool); + var header = this.header; + if (header) { + header.addTool(tool); + } + this.updateHeader(); + }, + + getOppositeDirection: function(d) { + var c = Ext.Component; + switch (d) { + case c.DIRECTION_TOP: + return c.DIRECTION_BOTTOM; + case c.DIRECTION_RIGHT: + return c.DIRECTION_LEFT; + case c.DIRECTION_BOTTOM: + return c.DIRECTION_TOP; + case c.DIRECTION_LEFT: + return c.DIRECTION_RIGHT; + } + }, + + + collapse: function(direction, animate, internal) { + var me = this, + c = Ext.Component, + height = me.getHeight(), + width = me.getWidth(), + frameInfo, + newSize = 0, + dockedItems = me.dockedItems.items, + dockedItemCount = dockedItems.length, + i = 0, + comp, + pos, + anim = { + from: { + height: height, + width: width + }, + to: { + height: height, + width: width + }, + listeners: { + afteranimate: me.afterCollapse, + scope: me + }, + duration: Ext.Number.from(animate, Ext.fx.Anim.prototype.duration) + }, + reExpander, + reExpanderOrientation, + reExpanderDock, + getDimension, + setDimension, + collapseDimension; + + if (!direction) { + direction = me.collapseDirection; + } + + + if (internal) { + animate = false; + } else if (me.collapsed || me.fireEvent('beforecollapse', me, direction, animate) === false) { + return false; + } + + reExpanderDock = direction; + me.expandDirection = me.getOppositeDirection(direction); + + + me.hiddenDocked = []; + + 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')) { + reExpander = comp; + } else { + me.hiddenDocked.push(comp); + } + } + } + + if (direction == Ext.Component.DIRECTION_BOTTOM) { + pos = me.getPosition()[1] - Ext.fly(me.el.dom.offsetParent).getRegion().top; + anim.from.top = pos; + } + break; + + 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()) { + if (comp.isHeader && (comp.dock == 'left' || comp.dock == 'right')) { + reExpander = comp; + } else { + me.hiddenDocked.push(comp); + } + } + } + + if (direction == Ext.Component.DIRECTION_RIGHT) { + pos = me.getPosition()[0] - Ext.fly(me.el.dom.offsetParent).getRegion().left; + anim.from.left = pos; + } + break; + + default: + throw('Panel collapse must be passed a valid Component collapse direction'); + } + + + + me.setAutoScroll(false); + me.suspendLayout = true; + me.body.setVisibilityMode(Ext.core.Element.DISPLAY); + + + if (animate && me.collapseTool) { + me.collapseTool.disable(); + } + + + me.addClsWithUI(me.collapsedCls); + + + + + + if (reExpander) { + + reExpander.addClsWithUI(me.collapsedCls); + reExpander.addClsWithUI(me.collapsedCls + '-' + reExpander.dock); + if (me.border && (!me.frame || (me.frame && Ext.supports.CSS3BorderRadius))) { + reExpander.addClsWithUI(me.collapsedCls + '-border-' + reExpander.dock); + } + + frameInfo = reExpander.getFrameInfo(); + + + newSize = reExpander[getDimension]() + (frameInfo ? frameInfo[direction] : 0); + + + reExpander.removeClsWithUI(me.collapsedCls); + reExpander.removeClsWithUI(me.collapsedCls + '-' + reExpander.dock); + if (me.border && (!me.frame || (me.frame && Ext.supports.CSS3BorderRadius))) { + reExpander.removeClsWithUI(me.collapsedCls + '-border-' + reExpander.dock); + } + } + + else { + reExpander = { + hideMode: 'offsets', + temporary: true, + title: me.title, + orientation: reExpanderOrientation, + dock: reExpanderDock, + textCls: me.headerTextCls, + iconCls: me.iconCls, + baseCls: me.baseCls + '-header', + ui: me.ui, + frame: me.frame && me.frameHeader, + ignoreParentFrame: me.frame || me.overlapHeader, + indicateDrag: me.draggable, + 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 + }]; + + + + reExpander = me.reExpander = Ext.create('Ext.panel.Header', reExpander); + newSize = reExpander[getDimension]() + ((reExpander.frame) ? reExpander.frameSize[direction] : 0); + reExpander.hide(); + + + me.insertDocked(0, reExpander); + } + + me.reExpander = reExpander; + me.reExpander.addClsWithUI(me.collapsedCls); + me.reExpander.addClsWithUI(me.collapsedCls + '-' + reExpander.dock); + if (me.border && (!me.frame || (me.frame && Ext.supports.CSS3BorderRadius))) { + me.reExpander.addClsWithUI(me.collapsedCls + '-border-' + me.reExpander.dock); + } + + + if (direction == Ext.Component.DIRECTION_RIGHT) { + anim.to.left = pos + (width - newSize); + } else if (direction == Ext.Component.DIRECTION_BOTTOM) { + anim.to.top = pos + (height - newSize); + } + + + anim.to[collapseDimension] = newSize; + + + me.savedFlex = me.flex; + me.savedMinWidth = me.minWidth; + me.savedMinHeight = me.minHeight; + me.minWidth = 0; + me.minHeight = 0; + delete me.flex; + + if (animate) { + me.animate(anim); + } else { + me.setSize(anim.to.width, anim.to.height); + if (Ext.isDefined(anim.to.left) || Ext.isDefined(anim.to.top)) { + me.setPosition(anim.to.left, anim.to.top); + } + me.afterCollapse(false, internal); + } + return me; + }, + + afterCollapse: function(animated, internal) { + var me = this, + i = 0, + l = me.hiddenDocked.length; + + me.minWidth = me.savedMinWidth; + me.minHeight = me.savedMinHeight; + + me.body.hide(); + for (; i < l; i++) { + me.hiddenDocked[i].hide(); + } + if (me.reExpander) { + me.reExpander.updateFrame(); + me.reExpander.show(); + } + me.collapsed = true; + + if (!internal) { + me.doComponentLayout(); + } + + if (me.resizer) { + me.resizer.disable(); + } + + + if (me.collapseTool) { + me.collapseTool.setType('expand-' + me.expandDirection); + } + if (!internal) { + me.fireEvent('collapse', me); + } + + + if (animated && me.collapseTool) { + me.collapseTool.enable(); + } + }, + + + expand: function(animate) { + if (!this.collapsed || this.fireEvent('beforeexpand', this, animate) === false) { + return false; + } + var me = this, + i = 0, + l = me.hiddenDocked.length, + direction = me.expandDirection, + height = me.getHeight(), + width = me.getWidth(), + pos, anim, satisfyJSLint; + + + if (animate && me.collapseTool) { + me.collapseTool.disable(); + } + + + + for (; i < l; i++) { + me.hiddenDocked[i].hidden = false; + me.hiddenDocked[i].el.show(); + } + if (me.reExpander) { + if (me.reExpander.temporary) { + me.reExpander.hide(); + } else { + me.reExpander.removeClsWithUI(me.collapsedCls); + me.reExpander.removeClsWithUI(me.collapsedCls + '-' + me.reExpander.dock); + if (me.border && (!me.frame || (me.frame && Ext.supports.CSS3BorderRadius))) { + me.reExpander.removeClsWithUI(me.collapsedCls + '-border-' + me.reExpander.dock); + } + me.reExpander.updateFrame(); + } + } + + + if (me.collapseTool) { + me.collapseTool.setType('collapse-' + me.collapseDirection); + } + + + me.collapsed = false; + + + me.body.show(); + + + me.removeClsWithUI(me.collapsedCls); + + + + + anim = { + to: { + }, + from: { + height: height, + width: width + }, + listeners: { + afteranimate: me.afterExpand, + scope: me + } + }; + + if ((direction == Ext.Component.DIRECTION_TOP) || (direction == Ext.Component.DIRECTION_BOTTOM)) { + + + if (me.autoHeight) { + me.setCalculatedSize(me.width, null); + anim.to.height = me.getHeight(); + + + me.setCalculatedSize(me.width, anim.from.height); + } + + + else if (me.savedFlex) { + me.flex = me.savedFlex; + anim.to.height = me.ownerCt.layout.calculateChildBox(me).height; + delete me.flex; + } + + else { + anim.to.height = me.expandedSize; + } + + + if (direction == Ext.Component.DIRECTION_TOP) { + pos = me.getPosition()[1] - Ext.fly(me.el.dom.offsetParent).getRegion().top; + anim.from.top = pos; + anim.to.top = pos - (anim.to.height - height); + } + } else if ((direction == Ext.Component.DIRECTION_LEFT) || (direction == Ext.Component.DIRECTION_RIGHT)) { + + + if (me.autoWidth) { + me.setCalculatedSize(null, me.height); + anim.to.width = me.getWidth(); + + + me.setCalculatedSize(anim.from.width, me.height); + } + + + else if (me.savedFlex) { + me.flex = me.savedFlex; + anim.to.width = me.ownerCt.layout.calculateChildBox(me).width; + delete me.flex; + } + + else { + anim.to.width = me.expandedSize; + } + + + if (direction == Ext.Component.DIRECTION_LEFT) { + pos = me.getPosition()[0] - Ext.fly(me.el.dom.offsetParent).getRegion().left; + anim.from.left = pos; + anim.to.left = pos - (anim.to.width - width); + } + } + + if (animate) { + me.animate(anim); + } else { + me.setSize(anim.to.width, anim.to.height); + if (anim.to.x) { + me.setLeft(anim.to.x); + } + if (anim.to.y) { + me.setTop(anim.to.y); + } + me.afterExpand(false); + } + + return me; + }, + + afterExpand: function(animated) { + var me = this; + me.setAutoScroll(me.initialConfig.autoScroll); + + + if (me.savedFlex) { + me.flex = me.savedFlex; + delete me.savedFlex; + delete me.width; + delete me.height; + } + + + delete me.suspendLayout; + if (animated && me.ownerCt) { + me.ownerCt.doLayout(); + } + + if (me.resizer) { + me.resizer.enable(); + } + + me.fireEvent('expand', me); + + + if (animated && me.collapseTool) { + me.collapseTool.enable(); + } + }, + + + toggleCollapse: function() { + if (this.collapsed) { + this.expand(this.animCollapse); + } else { + this.collapse(this.collapseDirection, this.animCollapse); + } + return this; + }, + + + getKeyMap : function(){ + if(!this.keyMap){ + this.keyMap = Ext.create('Ext.util.KeyMap', this.el, this.keys); + } + return this.keyMap; + }, + + + initDraggable : function(){ + + this.dd = Ext.create('Ext.panel.DD', this, Ext.isBoolean(this.draggable) ? null : this.draggable); + }, + + + ghostTools : function() { + var tools = [], + origTools = this.initialConfig.tools; + + if (origTools) { + Ext.each(origTools, function(tool) { + + + + + tools.push({ + type: tool.type + }); + }); + } + else { + tools = [{ + type: 'placeholder' + }]; + } + return tools; + }, + + + ghost: function(cls) { + var me = this, + ghostPanel = me.ghostPanel, + box = me.getBox(); + + if (!ghostPanel) { + ghostPanel = Ext.create('Ext.panel.Panel', { + renderTo: 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; + } + ghostPanel.floatParent = me.floatParent; + if (me.floating) { + ghostPanel.setZIndex(Ext.Number.from(me.el.getStyle('zIndex'), 0)); + } else { + ghostPanel.toFront(); + } + ghostPanel.el.show(); + ghostPanel.setPosition(box.x, box.y); + ghostPanel.setSize(box.width, box.height); + me.el.hide(); + if (me.floatingItems) { + me.floatingItems.hide(); + } + return ghostPanel; + }, + + + unghost: function(show, matchPosition) { + var me = this; + if (!me.ghostPanel) { + return; + } + if (show !== false) { + me.el.show(); + if (matchPosition !== false) { + me.setPosition(me.ghostPanel.getPosition()); + } + if (me.floatingItems) { + me.floatingItems.show(); + } + Ext.defer(me.focus, 10, me); + } + me.ghostPanel.el.hide(); + }, + + initResizable: function(resizable) { + if (this.collapsed) { + resizable.disabled = true; + } + this.callParent([resizable]); + } +}); + + + +Ext.define('Ext.layout.component.Tip', { + + + + alias: ['layout.tip'], + + extend: 'Ext.layout.component.Dock', + + + + type: 'tip', + + onLayout: function(width, height) { + var me = this, + owner = me.owner, + el = owner.el, + minWidth, + maxWidth, + naturalWidth, + constrainedWidth, + xy = el.getXY(); + + + el.setXY([-9999,-9999]); + + + this.callParent(arguments); + + + if (!Ext.isNumber(width)) { + minWidth = owner.minWidth; + maxWidth = owner.maxWidth; + + if (Ext.isStrict && (Ext.isIE6 || Ext.isIE7)) { + constrainedWidth = me.doAutoWidth(); + } else { + naturalWidth = el.getWidth(); + } + if (naturalWidth < minWidth) { + constrainedWidth = minWidth; + } + else if (naturalWidth > maxWidth) { + constrainedWidth = maxWidth; + } + if (constrainedWidth) { + this.callParent([constrainedWidth, height]); + } + } + + + el.setXY(xy); + }, + + doAutoWidth: function(){ + var me = this, + owner = me.owner, + body = owner.body, + width = body.getTextWidth(); + + if (owner.header) { + width = Math.max(width, owner.header.getWidth()); + } + if (!Ext.isDefined(me.frameWidth)) { + me.frameWidth = owner.el.getWidth() - body.getWidth(); + } + width += me.frameWidth + body.getPadding('lr'); + return width; } }); -Ext.Element.VISIBILITY = 1; -Ext.Element.DISPLAY = 2; +Ext.define('Ext.tip.Tip', { + extend: 'Ext.panel.Panel', + requires: [ 'Ext.layout.component.Tip' ], + alternateClassName: 'Ext.Tip', + + + + minWidth : 40, + + maxWidth : 300, + + shadow : "sides", + + defaultAlign : "tl-bl?", + + constrainPosition : true, -Ext.Element.OFFSETS = 3; + + frame: false, + + autoRender: true, + hidden: true, + baseCls: Ext.baseCSSPrefix + 'tip', + floating: { + shadow: true, + shim: true, + constrain: true + }, + focusOnToFront: false, + componentLayout: 'tip', -Ext.Element.ASCLASS = 4; + closeAction: 'hide', + ariaRole: 'tooltip', -Ext.Element.visibilityCls = 'x-hide-nosize'; + initComponent: function() { + this.callParent(arguments); -Ext.Element.addMethods(function(){ - var El = Ext.Element, - OPACITY = "opacity", - VISIBILITY = "visibility", - DISPLAY = "display", - HIDDEN = "hidden", - OFFSETS = "offsets", - ASCLASS = "asclass", - NONE = "none", - NOSIZE = 'nosize', - ORIGINALDISPLAY = 'originalDisplay', - VISMODE = 'visibilityMode', - ISVISIBLE = 'isVisible', - data = El.data, - getDisplay = function(dom){ - var d = data(dom, ORIGINALDISPLAY); - if(d === undefined){ - data(dom, ORIGINALDISPLAY, d = ''); - } - return d; - }, - getVisMode = function(dom){ - var m = data(dom, VISMODE); - if(m === undefined){ - data(dom, VISMODE, m = 1); - } - return m; - }; + + this.constrain = this.constrain || this.constrainPosition; + }, - return { + + showAt : function(xy){ + var me = this; + this.callParent(); - originalDisplay : "", - visibilityMode : 1, + if (me.isVisible()) { + me.setPagePosition(xy[0], xy[1]); + if (me.constrainPosition || me.constrain) { + me.doConstrain(); + } + me.toFront(true); + } + }, + + + showBy : function(el, pos) { + this.showAt(this.el.getAlignToXY(el, pos || this.defaultAlign)); + }, + + initDraggable : function(){ + var me = this; + me.draggable = { + el: me.getDragEl(), + delegate: me.header.el, + constrain: me, + constrainTo: me.el.dom.parentNode + }; - setVisibilityMode : function(visMode){ - data(this.dom, VISMODE, visMode); - return this; - }, + Ext.Component.prototype.initDraggable.call(me); + }, + + + ghost: undefined, + unghost: undefined +}); + + +Ext.define('Ext.tip.ToolTip', { + extend: 'Ext.tip.Tip', + alias: 'widget.tooltip', + alternateClassName: 'Ext.ToolTip', + + + + + showDelay: 500, + + hideDelay: 200, + + dismissDelay: 5000, + + + trackMouse: false, + + + anchorToTarget: true, + + anchorOffset: 0, + + + + targetCounter: 0, + quickShowInterval: 250, + + + initComponent: function() { + var me = this; + me.callParent(arguments); + me.lastActive = new Date(); + me.setTarget(me.target); + me.origAnchor = me.anchor; + }, + + + onRender: function(ct, position) { + var me = this; + me.callParent(arguments); + me.anchorCls = Ext.baseCSSPrefix + 'tip-anchor-' + me.getAnchorPosition(); + me.anchorEl = me.el.createChild({ + cls: Ext.baseCSSPrefix + 'tip-anchor ' + me.anchorCls + }); + }, + + + afterRender: function() { + var me = this, + zIndex; + + me.callParent(arguments); + zIndex = parseInt(me.el.getZIndex(), 10) || 0; + me.anchorEl.setStyle('z-index', zIndex + 1).setVisibilityMode(Ext.core.Element.DISPLAY); + }, + + setTarget: function(target) { + var me = this, + t = Ext.get(target), + tg; + + if (me.target) { + tg = Ext.get(me.target); + me.mun(tg, 'mouseover', me.onTargetOver, me); + me.mun(tg, 'mouseout', me.onTargetOut, me); + me.mun(tg, 'mousemove', me.onMouseMove, me); + } - animate : function(args, duration, onComplete, easing, animType){ - this.anim(args, {duration: duration, callback: onComplete, easing: easing}, animType); - return this; - }, + me.target = t; + if (t) { + + me.mon(t, { + + + freezeEvent: true, + + mouseover: me.onTargetOver, + mouseout: me.onTargetOut, + mousemove: me.onMouseMove, + scope: me + }); + } + if (me.anchor) { + me.anchorTarget = me.target; + } + }, + + + onMouseMove: function(e) { + var me = this, + t = me.delegate ? e.getTarget(me.delegate) : me.triggerElement = true, + xy; + if (t) { + me.targetXY = e.getXY(); + if (t === me.triggerElement) { + if (!me.hidden && me.trackMouse) { + xy = me.getTargetXY(); + if (me.constrainPosition) { + xy = me.el.adjustForConstraints(xy, me.el.dom.parentNode); + } + me.setPagePosition(xy); + } + } else { + me.hide(); + me.lastActive = new Date(0); + me.onTargetOver(e); + } + } else if ((!me.closable && me.isVisible()) && me.autoHide !== false) { + me.hide(); + } + }, + + + getTargetXY: function() { + var me = this, + mouseOffset; + if (me.delegate) { + me.anchorTarget = me.triggerElement; + } + if (me.anchor) { + 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, + de = document.documentElement, + bd = document.body, + scrollX = (de.scrollLeft || bd.scrollLeft || 0) + 5, + scrollY = (de.scrollTop || bd.scrollTop || 0) + 5, + axy = [xy[0] + offsets[0], xy[1] + offsets[1]], + sz = me.getSize(), + constrainPosition = me.constrainPosition; + + me.anchorEl.removeCls(me.anchorCls); + + if (me.targetCounter < 2 && constrainPosition) { + if (axy[0] < scrollX) { + if (me.anchorToTarget) { + me.defaultAlign = 'l-r'; + if (me.mouseOffset) { + me.mouseOffset[0] *= -1; + } + } + me.anchor = 'left'; + return me.getTargetXY(); + } + if (axy[0] + sz.width > dw) { + if (me.anchorToTarget) { + me.defaultAlign = 'r-l'; + if (me.mouseOffset) { + me.mouseOffset[0] *= -1; + } + } + me.anchor = 'right'; + return me.getTargetXY(); + } + if (axy[1] < scrollY) { + if (me.anchorToTarget) { + me.defaultAlign = 't-b'; + if (me.mouseOffset) { + me.mouseOffset[1] *= -1; + } + } + me.anchor = 'top'; + return me.getTargetXY(); + } + if (axy[1] + sz.height > dh) { + if (me.anchorToTarget) { + me.defaultAlign = 'b-t'; + if (me.mouseOffset) { + me.mouseOffset[1] *= -1; + } + } + me.anchor = 'bottom'; + return me.getTargetXY(); + } + } + + me.anchorCls = Ext.baseCSSPrefix + 'tip-anchor-' + me.getAnchorPosition(); + me.anchorEl.addCls(me.anchorCls); + me.targetCounter = 0; + return axy; + } else { + mouseOffset = me.getMouseOffset(); + return (me.targetXY) ? [me.targetXY[0] + mouseOffset[0], me.targetXY[1] + mouseOffset[1]] : mouseOffset; + } + }, + + getMouseOffset: function() { + var me = this, + offset = me.anchor ? [0, 0] : [15, 18]; + if (me.mouseOffset) { + offset[0] += me.mouseOffset[0]; + offset[1] += me.mouseOffset[1]; + } + return offset; + }, + + + getAnchorPosition: function() { + var me = this, + m; + if (me.anchor) { + 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); + } + + switch (me.tipAnchor) { + case 't': + return 'top'; + case 'b': + return 'bottom'; + case 'r': + return 'right'; + } + return 'left'; + }, + + + getAnchorAlign: function() { + switch (this.anchor) { + case 'top': + return 'tl-bl'; + case 'left': + return 'tl-tr'; + case 'right': + return 'tr-tl'; + default: + return 'bl-tl'; + } + }, + + + getOffsets: function() { + var me = this, + mouseOffset, + offsets, + ap = me.getAnchorPosition().charAt(0); + if (me.anchorToTarget && !me.trackMouse) { + switch (ap) { + case 't': + offsets = [0, 9]; + break; + case 'b': + offsets = [0, -13]; + break; + case 'r': + offsets = [ - 13, 0]; + break; + default: + offsets = [9, 0]; + break; + } + } else { + switch (ap) { + case 't': + offsets = [ - 15 - me.anchorOffset, 30]; + break; + case 'b': + offsets = [ - 19 - me.anchorOffset, -13 - me.el.dom.offsetHeight]; + break; + case 'r': + offsets = [ - 15 - me.el.dom.offsetWidth, -13 - me.anchorOffset]; + break; + default: + offsets = [25, -13 - me.anchorOffset]; + break; + } + } + mouseOffset = me.getMouseOffset(); + offsets[0] += mouseOffset[0]; + offsets[1] += mouseOffset[1]; + + return offsets; + }, + + + onTargetOver: function(e) { + var me = this, + t; + + if (me.disabled || e.within(me.target.dom, true)) { + return; + } + t = e.getTarget(me.delegate); + if (t) { + me.triggerElement = t; + me.clearTimer('hide'); + me.targetXY = e.getXY(); + me.delayShow(); + } + }, + + + delayShow: function() { + var me = this; + if (me.hidden && !me.showTimer) { + if (Ext.Date.getElapsed(me.lastActive) < me.quickShowInterval) { + me.show(); + } else { + me.showTimer = Ext.defer(me.show, me.showDelay, me); + } + } + else if (!me.hidden && me.autoHide !== false) { + me.show(); + } + }, + + + onTargetOut: function(e) { + var me = this; + if (me.disabled || e.within(me.target.dom, true)) { + return; + } + me.clearTimer('show'); + if (me.autoHide !== false) { + me.delayHide(); + } + }, + + + delayHide: function() { + var me = this; + if (!me.hidden && !me.hideTimer) { + me.hideTimer = Ext.defer(me.hide, me.hideDelay, me); + } + }, + + + hide: function() { + var me = this; + me.clearTimer('dismiss'); + me.lastActive = new Date(); + if (me.anchorEl) { + me.anchorEl.hide(); + } + me.callParent(arguments); + delete me.triggerElement; + }, + + + show: function() { + var me = this; - anim : function(args, opt, animType, defaultDur, defaultEase, cb){ - animType = animType || 'run'; - opt = opt || {}; - var me = this, - anim = Ext.lib.Anim[animType]( - me.dom, - args, - (opt.duration || defaultDur) || .35, - (opt.easing || defaultEase) || 'easeOut', - function(){ - if(cb) cb.call(me); - if(opt.callback) opt.callback.call(opt.scope || me, me, opt); - }, - me - ); - opt.anim = anim; - return anim; - }, + + this.callParent(); + if (this.hidden === false) { + me.setPagePosition(-10000, -10000); + + if (me.anchor) { + me.anchor = me.origAnchor; + } + me.showAt(me.getTargetXY()); + + if (me.anchor) { + me.syncAnchor(); + me.anchorEl.show(); + } else { + me.anchorEl.hide(); + } + } + }, + + + showAt: function(xy) { + var me = this; + me.lastActive = new Date(); + me.clearTimers(); - preanim : function(a, i){ - return !a[i] ? false : (typeof a[i] == 'object' ? a[i]: {duration: a[i+1], callback: a[i+2], easing: a[i+3]}); - }, + if (!me.isVisible()) { + this.callParent(arguments); + } - isVisible : function() { - var me = this, - dom = me.dom, - visible = data(dom, ISVISIBLE); + if (me.isVisible()) { + me.setPagePosition(xy[0], xy[1]); + if (me.constrainPosition || me.constrain) { + me.doConstrain(); + } + me.toFront(true); + } - if(typeof visible == 'boolean'){ - return visible; + if (me.dismissDelay && me.autoHide !== false) { + me.dismissTimer = Ext.defer(me.hide, me.dismissDelay, me); + } + if (me.anchor) { + me.syncAnchor(); + if (!me.anchorEl.isVisible()) { + me.anchorEl.show(); } - - visible = !me.isStyle(VISIBILITY, HIDDEN) && - !me.isStyle(DISPLAY, NONE) && - !((getVisMode(dom) == El.ASCLASS) && me.hasClass(me.visibilityCls || El.visibilityCls)); + } else { + me.anchorEl.hide(); + } + }, - data(dom, ISVISIBLE, visible); - return visible; - }, + + syncAnchor: function() { + var me = this, + anchorPos, + targetPos, + offset; + switch (me.tipAnchor.charAt(0)) { + case 't': + anchorPos = 'b'; + targetPos = 'tl'; + offset = [20 + me.anchorOffset, 1]; + break; + case 'r': + anchorPos = 'l'; + targetPos = 'tr'; + offset = [ - 1, 12 + me.anchorOffset]; + break; + case 'b': + anchorPos = 't'; + targetPos = 'bl'; + offset = [20 + me.anchorOffset, -1]; + break; + default: + anchorPos = 'r'; + targetPos = 'tl'; + offset = [1, 12 + me.anchorOffset]; + break; + } + me.anchorEl.alignTo(me.el, anchorPos + '-' + targetPos, offset); + }, + + + setPagePosition: function(x, y) { + var me = this; + me.callParent(arguments); + if (me.anchor) { + me.syncAnchor(); + } + }, + + + clearTimer: function(name) { + name = name + 'Timer'; + clearTimeout(this[name]); + delete this[name]; + }, + + + clearTimers: function() { + var me = this; + me.clearTimer('show'); + me.clearTimer('dismiss'); + me.clearTimer('hide'); + }, + + + onShow: function() { + var me = this; + me.callParent(); + me.mon(Ext.getDoc(), 'mousedown', me.onDocMouseDown, me); + }, + + + onHide: function() { + var me = this; + me.callParent(); + me.mun(Ext.getDoc(), 'mousedown', me.onDocMouseDown, me); + }, + + + onDocMouseDown: function(e) { + var me = this; + if (me.autoHide !== true && !me.closable && !e.within(me.el.dom)) { + me.disable(); + Ext.defer(me.doEnable, 100, me); + } + }, + + + doEnable: function() { + if (!this.isDestroyed) { + this.enable(); + } + }, + + + onDisable: function() { + this.callParent(); + this.clearTimers(); + this.hide(); + }, + beforeDestroy: function() { + var me = this; + me.clearTimers(); + Ext.destroy(me.anchorEl); + delete me.anchorEl; + delete me.target; + delete me.anchorTarget; + delete me.triggerElement; + me.callParent(); + }, + + + onDestroy: function() { + Ext.getDoc().un('mousedown', this.onDocMouseDown, this); + this.callParent(); + } +}); + + +Ext.define('Ext.tip.QuickTip', { + extend: 'Ext.tip.ToolTip', + alternateClassName: 'Ext.QuickTip', + + + interceptTitles : false, + + + title: ' ', + + + tagConfig : { + namespace : "data-", + attribute : "qtip", + width : "qwidth", + target : "target", + title : "qtitle", + hide : "hide", + cls : "qclass", + align : "qalign", + anchor : "anchor" + }, + + + initComponent : function(){ + var me = this; - setVisible : function(visible, animate){ - var me = this, isDisplay, isVisibility, isOffsets, isNosize, - dom = me.dom, - visMode = getVisMode(dom); + me.target = me.target || Ext.getDoc(); + me.targets = me.targets || {}; + me.callParent(); + }, + + register : function(config){ + var configs = Ext.isArray(config) ? config : arguments, + i = 0, + len = configs.length, + target, j, targetLen; + + for (; i < len; i++) { + config = configs[i]; + target = config.target; + if (target) { + if (Ext.isArray(target)) { + for (j = 0, targetLen = target.length; j < targetLen; j++) { + this.targets[Ext.id(target[j])] = config; + } + } else{ + this.targets[Ext.id(target)] = config; + } + } + } + }, + + unregister : function(el){ + delete this.targets[Ext.id(el)]; + }, + + + cancelShow: function(el){ + var me = this, + activeTarget = me.activeTarget; - if (typeof animate == 'string'){ - switch (animate) { - case DISPLAY: - visMode = El.DISPLAY; - break; - case VISIBILITY: - visMode = El.VISIBILITY; - break; - case OFFSETS: - visMode = El.OFFSETS; - break; - case NOSIZE: - case ASCLASS: - visMode = El.ASCLASS; - break; - } - me.setVisibilityMode(visMode); - animate = false; + el = Ext.get(el).dom; + if (me.isVisible()) { + if (activeTarget && activeTarget.el == el) { + me.hide(); + } + } else if (activeTarget && activeTarget.el == el) { + me.clearTimer('show'); + } + }, + + getTipCfg: function(e) { + var t = e.getTarget(), + ttp, + cfg; + + if(this.interceptTitles && t.title && Ext.isString(t.title)){ + ttp = t.title; + t.qtip = ttp; + t.removeAttribute("title"); + e.preventDefault(); + } + else { + cfg = this.tagConfig; + t = e.getTarget('[' + cfg.namespace + cfg.attribute + ']'); + if (t) { + ttp = t.getAttribute(cfg.namespace + cfg.attribute); } + } + return ttp; + }, - if (!animate || !me.anim) { - if(visMode == El.ASCLASS ){ + + onTargetOver : function(e){ + var me = this, + target = e.getTarget(), + elTarget, + cfg, + ns, + ttp, + autoHide; + + if (me.disabled) { + return; + } - me[visible?'removeClass':'addClass'](me.visibilityCls || El.visibilityCls); + + + + me.targetXY = e.getXY(); - } else if (visMode == El.DISPLAY){ + 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); + if (targetEl && (targetEl.dom === target || targetEl.contains(target))) { + elTarget = targetEl.dom; + return false; + } + }); + if (elTarget) { + me.activeTarget = me.targets[elTarget.id]; + me.activeTarget.el = target; + me.anchor = me.activeTarget.anchor; + if (me.anchor) { + me.anchorTarget = target; + } + me.delayShow(); + return; + } + } - return me.setDisplayed(visible); + elTarget = Ext.get(target); + cfg = me.tagConfig; + ns = cfg.namespace; + ttp = me.getTipCfg(e); + + if (ttp) { + autoHide = elTarget.getAttribute(ns + cfg.hide); + + me.activeTarget = { + el: target, + text: ttp, + 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) { + me.anchorTarget = target; + } + me.delayShow(); + } + }, - } else if (visMode == El.OFFSETS){ + + onTargetOut : function(e){ + var me = this; + + + if (me.activeTarget && e.within(me.activeTarget.el) && !me.getTipCfg(e)) { + return; + } - if (!visible){ - me.hideModeStyles = { - position: me.getStyle('position'), - top: me.getStyle('top'), - left: me.getStyle('left') - }; - me.applyStyles({position: 'absolute', top: '-10000px', left: '-10000px'}); - } else { - me.applyStyles(me.hideModeStyles || {position: '', top: '', left: ''}); - delete me.hideModeStyles; - } + me.clearTimer('show'); + if (me.autoHide !== false) { + me.delayHide(); + } + }, - }else{ - me.fixDisplay(); - dom.style.visibility = visible ? "visible" : HIDDEN; - } + + showAt : function(xy){ + var me = this, + target = me.activeTarget; + + if (target) { + if (!me.rendered) { + me.render(Ext.getBody()); + me.activeTarget = target; + } + if (target.title) { + me.setTitle(target.title || ''); + me.header.show(); + } else { + me.header.hide(); + } + me.body.update(target.text); + me.autoHide = target.autoHide; + me.dismissDelay = target.dismissDelay || me.dismissDelay; + if (me.lastCls) { + me.el.removeCls(me.lastCls); + delete me.lastCls; + } + if (target.cls) { + me.el.addCls(target.cls); + me.lastCls = target.cls; + } + + me.setWidth(target.width); + + if (me.anchor) { + me.constrainPosition = false; + } else if (target.align) { + xy = me.el.getAlignToXY(target.el, target.align); + me.constrainPosition = false; }else{ - - if(visible){ - me.setOpacity(.01); - me.setVisible(true); + me.constrainPosition = true; + } + } + me.callParent([xy]); + }, + + + hide: function(){ + delete this.activeTarget; + this.callParent(); + } +}); + + +Ext.define('Ext.tip.QuickTipManager', function() { + var tip, + disabled = false; + + return { + requires: ['Ext.tip.QuickTip'], + singleton: true, + alternateClassName: 'Ext.QuickTips', + + init : function(autoRender){ + if (!tip) { + if (!Ext.isReady) { + Ext.onReady(function(){ + Ext.tip.QuickTipManager.init(autoRender); + }); + return; } - me.anim({opacity: { to: (visible?1:0) }}, - me.preanim(arguments, 1), - null, - .35, - 'easeIn', - function(){ - visible || me.setVisible(false).setOpacity(1); - }); + tip = Ext.create('Ext.tip.QuickTip', { + disabled: disabled, + renderTo: autoRender !== false ? document.body : undefined + }); } - data(dom, ISVISIBLE, visible); - return me; }, - - hasMetrics : function(){ - var dom = this.dom; - return this.isVisible() || (getVisMode(dom) == El.VISIBILITY); + destroy: function() { + if (tip) { + var undef; + tip.destroy(); + tip = undef; + } }, - toggle : function(animate){ - var me = this; - me.setVisible(!me.isVisible(), me.preanim(arguments, 0)); - return me; + ddDisable : function(){ + + if(tip && !disabled){ + tip.disable(); + } }, - setDisplayed : function(value) { - if(typeof value == "boolean"){ - value = value ? getDisplay(this.dom) : NONE; + ddEnable : function(){ + + if(tip && !disabled){ + tip.enable(); } - this.setStyle(DISPLAY, value); - return this; }, - fixDisplay : function(){ - var me = this; - if(me.isStyle(DISPLAY, NONE)){ - me.setStyle(VISIBILITY, HIDDEN); - me.setStyle(DISPLAY, getDisplay(this.dom)); - if(me.isStyle(DISPLAY, NONE)){ - me.setStyle(DISPLAY, "block"); - } + enable : function(){ + if(tip){ + tip.enable(); } + disabled = false; }, - hide : function(animate){ - - if (typeof animate == 'string'){ - this.setVisible(false, animate); - return this; + disable : function(){ + if(tip){ + tip.disable(); } - this.setVisible(false, this.preanim(arguments, 0)); - return this; + disabled = true; }, - show : function(animate){ - - if (typeof animate == 'string'){ - this.setVisible(true, animate); - return this; - } - this.setVisible(true, this.preanim(arguments, 0)); - return this; - } - }; -}());(function(){ - - var NULL = null, - UNDEFINED = undefined, - TRUE = true, - FALSE = false, - SETX = "setX", - SETY = "setY", - SETXY = "setXY", - LEFT = "left", - BOTTOM = "bottom", - TOP = "top", - RIGHT = "right", - HEIGHT = "height", - WIDTH = "width", - POINTS = "points", - HIDDEN = "hidden", - ABSOLUTE = "absolute", - VISIBLE = "visible", - MOTION = "motion", - POSITION = "position", - EASEOUT = "easeOut", + isEnabled : function(){ + return tip !== undefined && !tip.disabled; + }, + - flyEl = new Ext.Element.Flyweight(), - queues = {}, - getObject = function(o){ - return o || {}; + getQuickTip : function(){ + return tip; }, - fly = function(dom){ - flyEl.dom = dom; - flyEl.id = Ext.id(dom); - return flyEl; + + + register : function(){ + tip.register.apply(tip, arguments); }, + - getQueue = function(id){ - if(!queues[id]){ - queues[id] = []; - } - return queues[id]; + unregister : function(){ + tip.unregister.apply(tip, arguments); }, - setQueue = function(id, value){ - queues[id] = value; - }; + + tips : function(){ + tip.register.apply(tip, arguments); + } + }; +}()); -Ext.enableFx = TRUE; +Ext.define('Ext.app.Application', { + extend: 'Ext.app.Controller', + requires: [ + 'Ext.ModelManager', + 'Ext.data.Model', + 'Ext.data.StoreManager', + 'Ext.tip.QuickTipManager', + 'Ext.ComponentManager', + 'Ext.app.EventBus' + ], -Ext.Fx = { - - - - switchStatements : function(key, fn, argHash){ - return fn.apply(this, argHash[key]); - }, + - slideIn : function(anchor, o){ - o = getObject(o); - var me = this, - dom = me.dom, - st = dom.style, - xy, - r, - b, - wrap, - after, - st, - args, - pt, - bw, - bh; - - anchor = anchor || "t"; + scope: undefined, - me.queueFx(o, function(){ - xy = fly(dom).getXY(); - - fly(dom).fixDisplay(); - - - r = fly(dom).getFxRestore(); - b = {x: xy[0], y: xy[1], 0: xy[0], 1: xy[1], width: dom.offsetWidth, height: dom.offsetHeight}; - b.right = b.x + b.width; - b.bottom = b.y + b.height; - - - fly(dom).setWidth(b.width).setHeight(b.height); - - - wrap = fly(dom).fxWrap(r.pos, o, HIDDEN); - - st.visibility = VISIBLE; - st.position = ABSOLUTE; - - - function after(){ - fly(dom).fxUnwrap(wrap, r.pos, o); - st.width = r.width; - st.height = r.height; - fly(dom).afterFx(o); - } - - - pt = {to: [b.x, b.y]}; - bw = {to: b.width}; - bh = {to: b.height}; - - function argCalc(wrap, style, ww, wh, sXY, sXYval, s1, s2, w, h, p){ - var ret = {}; - fly(wrap).setWidth(ww).setHeight(wh); - if(fly(wrap)[sXY]){ - fly(wrap)[sXY](sXYval); - } - style[s1] = style[s2] = "0"; - if(w){ - ret.width = w; - } - if(h){ - ret.height = h; - } - if(p){ - ret.points = p; - } - return ret; - }; + + enableQuickTips: true, - args = fly(dom).switchStatements(anchor.toLowerCase(), argCalc, { - t : [wrap, st, b.width, 0, NULL, NULL, LEFT, BOTTOM, NULL, bh, NULL], - l : [wrap, st, 0, b.height, NULL, NULL, RIGHT, TOP, bw, NULL, NULL], - r : [wrap, st, b.width, b.height, SETX, b.right, LEFT, TOP, NULL, NULL, pt], - b : [wrap, st, b.width, b.height, SETY, b.bottom, LEFT, TOP, NULL, bh, pt], - tl : [wrap, st, 0, 0, NULL, NULL, RIGHT, BOTTOM, bw, bh, pt], - bl : [wrap, st, 0, 0, SETY, b.y + b.height, RIGHT, TOP, bw, bh, pt], - br : [wrap, st, 0, 0, SETXY, [b.right, b.bottom], LEFT, TOP, bw, bh, pt], - tr : [wrap, st, 0, 0, SETX, b.x + b.width, LEFT, BOTTOM, bw, bh, pt] - }); - - st.visibility = VISIBLE; - fly(wrap).show(); + - arguments.callee.anim = fly(wrap).fxanim(args, - o, - MOTION, - .5, - EASEOUT, - after); - }); - return me; - }, + appFolder: 'app', + - slideOut : function(anchor, o){ - o = getObject(o); - var me = this, - dom = me.dom, - st = dom.style, - xy = me.getXY(), - wrap, - r, - b, - a, - zero = {to: 0}; - - anchor = anchor || "t"; + autoCreateViewport: true, - me.queueFx(o, function(){ - - - r = fly(dom).getFxRestore(); - b = {x: xy[0], y: xy[1], 0: xy[0], 1: xy[1], width: dom.offsetWidth, height: dom.offsetHeight}; - b.right = b.x + b.width; - b.bottom = b.y + b.height; - - - fly(dom).setWidth(b.width).setHeight(b.height); + constructor: function(config) { + config = config || {}; + Ext.apply(this, config); - - wrap = fly(dom).fxWrap(r.pos, o, VISIBLE); - - st.visibility = VISIBLE; - st.position = ABSOLUTE; - fly(wrap).setWidth(b.width).setHeight(b.height); + var requires = config.requires || []; - function after(){ - o.useDisplay ? fly(dom).setDisplayed(FALSE) : fly(dom).hide(); - fly(dom).fxUnwrap(wrap, r.pos, o); - st.width = r.width; - st.height = r.height; - fly(dom).afterFx(o); - } - - function argCalc(style, s1, s2, p1, v1, p2, v2, p3, v3){ - var ret = {}; - - style[s1] = style[s2] = "0"; - ret[p1] = v1; - if(p2){ - ret[p2] = v2; - } - if(p3){ - ret[p3] = v3; - } - - return ret; - }; - - a = fly(dom).switchStatements(anchor.toLowerCase(), argCalc, { - t : [st, LEFT, BOTTOM, HEIGHT, zero], - l : [st, RIGHT, TOP, WIDTH, zero], - r : [st, LEFT, TOP, WIDTH, zero, POINTS, {to : [b.right, b.y]}], - b : [st, LEFT, TOP, HEIGHT, zero, POINTS, {to : [b.x, b.bottom]}], - tl : [st, RIGHT, BOTTOM, WIDTH, zero, HEIGHT, zero], - bl : [st, RIGHT, TOP, WIDTH, zero, HEIGHT, zero, POINTS, {to : [b.x, b.bottom]}], - br : [st, LEFT, TOP, WIDTH, zero, HEIGHT, zero, POINTS, {to : [b.x + b.width, b.bottom]}], - tr : [st, LEFT, BOTTOM, WIDTH, zero, HEIGHT, zero, POINTS, {to : [b.right, b.y]}] + Ext.Loader.setPath(this.name, this.appFolder); + + if (this.paths) { + Ext.Object.each(this.paths, function(key, value) { + Ext.Loader.setPath(key, value); }); - - arguments.callee.anim = fly(wrap).fxanim(a, - o, - MOTION, - .5, - EASEOUT, - after); - }); - return me; - }, + } - - puff : function(o){ - o = getObject(o); - var me = this, - dom = me.dom, - st = dom.style, - width, - height, - r; + this.callParent(arguments); - me.queueFx(o, function(){ - width = fly(dom).getWidth(); - height = fly(dom).getHeight(); - fly(dom).clearOpacity(); - fly(dom).show(); - - - r = fly(dom).getFxRestore(); - - function after(){ - o.useDisplay ? fly(dom).setDisplayed(FALSE) : fly(dom).hide(); - fly(dom).clearOpacity(); - fly(dom).setPositioning(r.pos); - st.width = r.width; - st.height = r.height; - st.fontSize = ''; - fly(dom).afterFx(o); - } - - arguments.callee.anim = fly(dom).fxanim({ - width : {to : fly(dom).adjustWidth(width * 2)}, - height : {to : fly(dom).adjustHeight(height * 2)}, - points : {by : [-width * .5, -height * .5]}, - opacity : {to : 0}, - fontSize: {to : 200, unit: "%"} - }, - o, - MOTION, - .5, - EASEOUT, - after); - }); - return me; - }, + this.eventbus = Ext.create('Ext.app.EventBus'); - - switchOff : function(o){ - o = getObject(o); - var me = this, - dom = me.dom, - st = dom.style, - r; + var controllers = this.controllers, + ln = controllers.length, + i, controller; - me.queueFx(o, function(){ - fly(dom).clearOpacity(); - fly(dom).clip(); + this.controllers = Ext.create('Ext.util.MixedCollection'); - - r = fly(dom).getFxRestore(); - - function after(){ - o.useDisplay ? fly(dom).setDisplayed(FALSE) : fly(dom).hide(); - fly(dom).clearOpacity(); - fly(dom).setPositioning(r.pos); - st.width = r.width; - st.height = r.height; - fly(dom).afterFx(o); - }; + if (this.autoCreateViewport) { + requires.push(this.getModuleClassName('Viewport', 'view')); + } - fly(dom).fxanim({opacity : {to : 0.3}}, - NULL, - NULL, - .1, - NULL, - function(){ - fly(dom).clearOpacity(); - (function(){ - fly(dom).fxanim({ - height : {to : 1}, - points : {by : [0, fly(dom).getHeight() * .5]} - }, - o, - MOTION, - 0.3, - 'easeIn', - after); - }).defer(100); - }); - }); - return me; - }, + for (i = 0; i < ln; i++) { + requires.push(this.getModuleClassName(controllers[i], 'controller')); + } - - highlight : function(color, o){ - o = getObject(o); - var me = this, - dom = me.dom, - attr = o.attr || "backgroundColor", - a = {}, - restore; + Ext.require(requires); - me.queueFx(o, function(){ - fly(dom).clearOpacity(); - fly(dom).show(); + Ext.onReady(function() { + for (i = 0; i < ln; i++) { + controller = this.getController(controllers[i]); + controller.init(this); + } - function after(){ - dom.style[attr] = restore; - fly(dom).afterFx(o); - } - restore = dom.style[attr]; - a[attr] = {from: color || "ffff9c", to: o.endColor || fly(dom).getColor(attr) || "ffffff"}; - arguments.callee.anim = fly(dom).fxanim(a, - o, - 'color', - 1, - 'easeIn', - after); - }); - return me; + this.onBeforeLaunch.call(this); + }, this); }, - - frame : function(color, count, o){ - o = getObject(o); - var me = this, - dom = me.dom, - proxy, - active; + control: function(selectors, listeners, controller) { + this.eventbus.control(selectors, listeners, controller); + }, - me.queueFx(o, function(){ - color = color || '#C3DAF9'; - if(color.length == 6){ - color = '#' + color; - } - count = count || 1; - fly(dom).show(); - - var xy = fly(dom).getXY(), - b = {x: xy[0], y: xy[1], 0: xy[0], 1: xy[1], width: dom.offsetWidth, height: dom.offsetHeight}, - queue = function(){ - proxy = fly(document.body || document.documentElement).createChild({ - style:{ - position : ABSOLUTE, - 'z-index': 35000, - border : '0px solid ' + color - } - }); - return proxy.queueFx({}, animFn); - }; - - - arguments.callee.anim = { - isAnimated: true, - stop: function() { - count = 0; - proxy.stopFx(); - } - }; - - function animFn(){ - var scale = Ext.isBorderBox ? 2 : 1; - active = proxy.anim({ - top : {from : b.y, to : b.y - 20}, - left : {from : b.x, to : b.x - 20}, - borderWidth : {from : 0, to : 10}, - opacity : {from : 1, to : 0}, - height : {from : b.height, to : b.height + 20 * scale}, - width : {from : b.width, to : b.width + 20 * scale} - },{ - duration: o.duration || 1, - callback: function() { - proxy.remove(); - --count > 0 ? queue() : fly(dom).afterFx(o); - } - }); - arguments.callee.anim = { - isAnimated: true, - stop: function(){ - active.stop(); - } - }; - }; - queue(); - }); - return me; + + launch: Ext.emptyFn, + + + onBeforeLaunch: function() { + if (this.enableQuickTips) { + Ext.tip.QuickTipManager.init(); + } + + if (this.autoCreateViewport) { + this.getView('Viewport').create(); + } + + this.launch.call(this.scope || this); + this.launched = true; + this.fireEvent('launch', this); + + this.controllers.each(function(controller) { + controller.onLaunch(this); + }, this); }, - - pause : function(seconds){ - var dom = this.dom, - t; + getModuleClassName: function(name, type) { + var namespace = Ext.Loader.getPrefix(name); - this.queueFx({}, function(){ - t = setTimeout(function(){ - fly(dom).afterFx({}); - }, seconds * 1000); - arguments.callee.anim = { - isAnimated: true, - stop: function(){ - clearTimeout(t); - fly(dom).afterFx({}); - } - }; - }); - return this; + if (namespace.length > 0 && namespace !== name) { + return name; + } + + return this.name + '.' + type + '.' + name; }, - - fadeIn : function(o){ - o = getObject(o); - var me = this, - dom = me.dom, - to = o.endOpacity || 1; - - me.queueFx(o, function(){ - fly(dom).setOpacity(0); - fly(dom).fixDisplay(); - dom.style.visibility = VISIBLE; - arguments.callee.anim = fly(dom).fxanim({opacity:{to:to}}, - o, NULL, .5, EASEOUT, function(){ - if(to == 1){ - fly(dom).clearOpacity(); - } - fly(dom).afterFx(o); + getController: function(name) { + var controller = this.controllers.get(name); + + if (!controller) { + controller = Ext.create(this.getModuleClassName(name, 'controller'), { + application: this, + id: name }); - }); - return me; + + this.controllers.add(controller); + } + + return controller; }, - - fadeOut : function(o){ - o = getObject(o); - var me = this, - dom = me.dom, - style = dom.style, - to = o.endOpacity || 0; - - me.queueFx(o, function(){ - arguments.callee.anim = fly(dom).fxanim({ - opacity : {to : to}}, - o, - NULL, - .5, - EASEOUT, - function(){ - if(to == 0){ - Ext.Element.data(dom, 'visibilityMode') == Ext.Element.DISPLAY || o.useDisplay ? - style.display = "none" : - style.visibility = HIDDEN; - - fly(dom).clearOpacity(); - } - fly(dom).afterFx(o); + getStore: function(name) { + var store = Ext.StoreManager.get(name); + + if (!store) { + store = Ext.create(this.getModuleClassName(name, 'store'), { + storeId: name }); - }); - return me; - }, + } - - scale : function(w, h, o){ - this.shift(Ext.apply({}, o, { - width: w, - height: h - })); - return this; + return store; }, - - shift : function(o){ - o = getObject(o); - var dom = this.dom, - a = {}; - - this.queueFx(o, function(){ - for (var prop in o) { - if (o[prop] != UNDEFINED) { - a[prop] = {to : o[prop]}; - } - } - - a.width ? a.width.to = fly(dom).adjustWidth(o.width) : a; - a.height ? a.height.to = fly(dom).adjustWidth(o.height) : a; - - if (a.x || a.y || a.xy) { - a.points = a.xy || - {to : [ a.x ? a.x.to : fly(dom).getX(), - a.y ? a.y.to : fly(dom).getY()]}; - } + getModel: function(model) { + model = this.getModuleClassName(model, 'model'); - arguments.callee.anim = fly(dom).fxanim(a, - o, - MOTION, - .35, - EASEOUT, - function(){ - fly(dom).afterFx(o); - }); - }); - return this; + return Ext.ModelManager.getModel(model); }, - - ghost : function(anchor, o){ - o = getObject(o); - var me = this, - dom = me.dom, - st = dom.style, - a = {opacity: {to: 0}, points: {}}, - pt = a.points, - r, - w, - h; - - anchor = anchor || "b"; + getView: function(view) { + view = this.getModuleClassName(view, 'view'); - me.queueFx(o, function(){ - - r = fly(dom).getFxRestore(); - w = fly(dom).getWidth(); - h = fly(dom).getHeight(); - - function after(){ - o.useDisplay ? fly(dom).setDisplayed(FALSE) : fly(dom).hide(); - fly(dom).clearOpacity(); - fly(dom).setPositioning(r.pos); - st.width = r.width; - st.height = r.height; - fly(dom).afterFx(o); - } - - pt.by = fly(dom).switchStatements(anchor.toLowerCase(), function(v1,v2){ return [v1, v2];}, { - t : [0, -h], - l : [-w, 0], - r : [w, 0], - b : [0, h], - tl : [-w, -h], - bl : [-w, h], - br : [w, h], - tr : [w, -h] - }); - - arguments.callee.anim = fly(dom).fxanim(a, - o, - MOTION, - .5, - EASEOUT, after); - }); - return me; - }, + return Ext.ClassManager.get(view); + } +}); - - syncFx : function(){ - var me = this; - me.fxDefaults = Ext.apply(me.fxDefaults || {}, { - block : FALSE, - concurrent : TRUE, - stopFx : FALSE - }); - return me; - }, + +Ext.define('Ext.chart.Callout', { - sequenceFx : function(){ - var me = this; - me.fxDefaults = Ext.apply(me.fxDefaults || {}, { - block : FALSE, - concurrent : FALSE, - stopFx : FALSE - }); - return me; - }, - nextFx : function(){ - var ef = getQueue(this.dom.id)[0]; - if(ef){ - ef.call(this); + + constructor: function(config) { + if (config.callouts) { + config.callouts.styles = Ext.applyIf(config.callouts.styles || {}, { + color: "#000", + font: "11px Helvetica, sans-serif" + }); + this.callouts = Ext.apply(this.callouts || {}, config.callouts); + this.calloutsArray = []; } }, - - hasActiveFx : function(){ - return getQueue(this.dom.id)[0]; - }, + renderCallouts: function() { + if (!this.callouts) { + return; + } - - stopFx : function(finish){ var me = this, - id = me.dom.id; - if(me.hasActiveFx()){ - var cur = getQueue(id)[0]; - if(cur && cur.anim){ - if(cur.anim.isAnimated){ - setQueue(id, [cur]); - cur.anim.stop(finish !== undefined ? finish : TRUE); - }else{ - setQueue(id, []); + items = me.items, + animate = me.chart.animate, + config = me.callouts, + styles = config.styles, + group = me.calloutsArray, + store = me.chart.store, + len = store.getCount(), + ratio = items.length / len, + previouslyPlacedCallouts = [], + i, + count, + j, + p; + + for (i = 0, count = 0; i < len; i++) { + for (j = 0; j < ratio; j++) { + var item = items[count], + label = group[count], + storeItem = store.getAt(i), + display; + + display = config.filter(storeItem); + + if (!display && !label) { + count++; + continue; + } + + if (!label) { + group[count] = label = me.onCreateCallout(storeItem, item, i, display, j, count); + } + for (p in label) { + if (label[p] && label[p].setAttributes) { + label[p].setAttributes(styles, true); + } + } + if (!display) { + for (p in label) { + if (label[p]) { + if (label[p].setAttributes) { + label[p].setAttributes({ + hidden: true + }, true); + } else if(label[p].setVisible) { + label[p].setVisible(false); + } + } + } } + config.renderer(label, storeItem); + me.onPlaceCallout(label, storeItem, item, i, display, animate, + j, count, previouslyPlacedCallouts); + previouslyPlacedCallouts.push(label); + count++; } } - return me; + this.hideCallouts(count); }, - - beforeFx : function(o){ - if(this.hasActiveFx() && !o.concurrent){ - if(o.stopFx){ - this.stopFx(); - return TRUE; - } - return FALSE; + onCreateCallout: function(storeItem, item, i, display) { + var me = this, + group = me.calloutsGroup, + config = me.callouts, + styles = config.styles, + width = styles.width, + height = styles.height, + chart = me.chart, + surface = chart.surface, + calloutObj = { + + + lines: false + }; + + calloutObj.lines = surface.add(Ext.apply({}, + { + type: 'path', + path: 'M0,0', + stroke: me.getLegendColor() || '#555' + }, + styles)); + + if (config.items) { + calloutObj.panel = Ext.create('widget.panel', { + style: "position: absolute;", + width: width, + height: height, + items: config.items, + renderTo: chart.el + }); } - return TRUE; - }, - - hasFxBlock : function(){ - var q = getQueue(this.dom.id); - return q && q[0] && q[0].block; + return calloutObj; }, - - queueFx : function(o, fn){ - var me = fly(this.dom); - if(!me.hasFxBlock()){ - Ext.applyIf(o, me.fxDefaults); - if(!o.concurrent){ - var run = me.beforeFx(o); - fn.block = o.block; - getQueue(me.dom.id).push(fn); - if(run){ - me.nextFx(); + hideCallouts: function(index) { + var calloutsArray = this.calloutsArray, + len = calloutsArray.length, + co, + p; + while (len-->index) { + co = calloutsArray[len]; + for (p in co) { + if (co[p]) { + co[p].hide(true); } - }else{ - fn.call(me); } } - return me; - }, + } +}); + + +Ext.define('Ext.draw.CompositeSprite', { - fxWrap : function(pos, o, vis){ - var dom = this.dom, - wrap, - wrapXY; - if(!o.wrap || !(wrap = Ext.getDom(o.wrap))){ - if(o.fixPosition){ - wrapXY = fly(dom).getXY(); - } - var div = document.createElement("div"); - div.style.visibility = vis; - wrap = dom.parentNode.insertBefore(div, dom); - fly(wrap).setPositioning(pos); - if(fly(wrap).isStyle(POSITION, "static")){ - fly(wrap).position("relative"); - } - fly(dom).clearPositioning('auto'); - fly(wrap).clip(); - wrap.appendChild(dom); - if(wrapXY){ - fly(wrap).setXY(wrapXY); - } - } - return wrap; + + extend: 'Ext.util.MixedCollection', + mixins: { + animate: 'Ext.util.Animate' }, - fxUnwrap : function(wrap, pos, o){ - var dom = this.dom; - fly(dom).clearPositioning(); - fly(dom).setPositioning(pos); - if(!o.wrap){ - var pn = fly(wrap).dom.parentNode; - pn.insertBefore(dom, wrap); - fly(wrap).remove(); - } + isCompositeSprite: true, + constructor: function(config) { + var me = this; + + config = config || {}; + Ext.apply(me, config); + + me.addEvents( + 'mousedown', + 'mouseup', + 'mouseover', + 'mouseout', + 'click' + ); + me.id = Ext.id(null, 'ext-sprite-group-'); + me.callParent(); }, - getFxRestore : function(){ - var st = this.dom.style; - return {pos: this.getPositioning(), width: st.width, height : st.height}; + onClick: function(e) { + this.fireEvent('click', e); }, - afterFx : function(o){ - var dom = this.dom, - id = dom.id; - if(o.afterStyle){ - fly(dom).setStyle(o.afterStyle); - } - if(o.afterCls){ - fly(dom).addClass(o.afterCls); - } - if(o.remove == TRUE){ - fly(dom).remove(); - } - if(o.callback){ - o.callback.call(o.scope, fly(dom)); - } - if(!o.concurrent){ - getQueue(id).shift(); - fly(dom).nextFx(); - } + onMouseUp: function(e) { + this.fireEvent('mouseup', e); }, - fxanim : function(args, opt, animType, defaultDur, defaultEase, cb){ - animType = animType || 'run'; - opt = opt || {}; - var anim = Ext.lib.Anim[animType]( - this.dom, - args, - (opt.duration || defaultDur) || .35, - (opt.easing || defaultEase) || EASEOUT, - cb, - this - ); - opt.anim = anim; - return anim; - } -}; - - -Ext.Fx.resize = Ext.Fx.scale; - - - -Ext.Element.addMethods(Ext.Fx); -})(); + onMouseDown: function(e) { + this.fireEvent('mousedown', e); + }, -Ext.CompositeElementLite = function(els, root){ - this.elements = []; - this.add(els, root); - this.el = new Ext.Element.Flyweight(); -}; - -Ext.CompositeElementLite.prototype = { - isComposite: true, + onMouseOver: function(e) { + this.fireEvent('mouseover', e); + }, - getElement : function(el){ + onMouseOut: function(e) { + this.fireEvent('mouseout', e); + }, + + attachEvents: function(o) { + var me = this; - var e = this.el; - e.dom = el; - e.id = el.id; - return e; + o.on({ + scope: me, + mousedown: me.onMouseDown, + mouseup: me.onMouseUp, + mouseover: me.onMouseOver, + mouseout: me.onMouseOut, + click: me.onClick + }); }, - transformElement : function(el){ - return Ext.getDom(el); + add: function(key, o) { + var result = this.callParent(arguments); + this.attachEvents(result); + return result; + }, + + insert: function(index, key, o) { + return this.callParent(arguments); }, - getCount : function(){ - return this.elements.length; + remove: function(o) { + var me = this; + + o.un({ + scope: me, + mousedown: me.onMouseDown, + mouseup: me.onMouseUp, + mouseover: me.onMouseOver, + mouseout: me.onMouseOut, + click: me.onClick + }); + me.callParent(arguments); }, - add : function(els, root){ - var me = this, - elements = me.elements; - if(!els){ - return this; - } - if(typeof els == "string"){ - els = Ext.Element.selectorFunction(els, root); - }else if(els.isComposite){ - els = els.elements; - }else if(!Ext.isIterable(els)){ - els = [els]; - } - - for(var i = 0, len = els.length; i < len; ++i){ - elements.push(me.transformElement(els[i])); + + getBBox: function() { + var i = 0, + sprite, + bb, + items = this.items, + len = this.length, + infinity = Infinity, + minX = infinity, + maxHeight = -infinity, + minY = infinity, + maxWidth = -infinity, + maxWidthBBox, maxHeightBBox; + + for (; i < len; i++) { + sprite = items[i]; + if (sprite.el) { + bb = sprite.getBBox(); + minX = Math.min(minX, bb.x); + minY = Math.min(minY, bb.y); + maxHeight = Math.max(maxHeight, bb.height + bb.y); + maxWidth = Math.max(maxWidth, bb.width + bb.x); + } } - return me; + + return { + x: minX, + y: minY, + height: maxHeight - minY, + width: maxWidth - minX + }; }, - invoke : function(fn, args){ - var me = this, - els = me.elements, - len = els.length, - e, - i; - - for(i = 0; i < len; i++) { - e = els[i]; - if(e){ - Ext.Element.prototype[fn].apply(me.getElement(e), args); - } + + setAttributes: function(attrs, redraw) { + var i = 0, + items = this.items, + len = this.length; + + for (; i < len; i++) { + items[i].setAttributes(attrs, redraw); } - return me; + return this; }, - - item : function(index){ - var me = this, - el = me.elements[index], - out = null; - if(el){ - out = me.getElement(el); + + hide: function(attrs) { + var i = 0, + items = this.items, + len = this.length; + + for (; i < len; i++) { + items[i].hide(); } - return out; + return this; }, - addListener : function(eventName, handler, scope, opt){ - var els = this.elements, - len = els.length, - i, e; - - for(i = 0; i -1){ - replacement = Ext.getDom(replacement); - if(domReplace){ - d = this.elements[index]; - d.parentNode.insertBefore(replacement, d); - Ext.removeNode(d); - } - this.elements.splice(index, 1, replacement); + + getSurface: function(){ + var first = this.first(); + if (first) { + return first.surface; } - return this; + return null; }, - - clear : function(){ - this.elements = []; + + destroy: function(){ + var me = this, + surface = me.getSurface(), + item; + + if (surface) { + while (me.getCount() > 0) { + item = me.first(); + me.remove(item); + surface.remove(item); + } + } + me.clearListeners(); } -}; +}); -Ext.CompositeElementLite.prototype.on = Ext.CompositeElementLite.prototype.addListener; -Ext.CompositeElementLite.importElementMethods = function() { - var fnName, - ElProto = Ext.Element.prototype, - CelProto = Ext.CompositeElementLite.prototype; +Ext.define('Ext.layout.component.Draw', { - for (fnName in ElProto) { - if (typeof ElProto[fnName] == 'function'){ - (function(fnName) { - CelProto[fnName] = CelProto[fnName] || function() { - return this.invoke(fnName, arguments); - }; - }).call(CelProto, fnName); + - } - } -}; + alias: 'layout.draw', -Ext.CompositeElementLite.importElementMethods(); + extend: 'Ext.layout.component.Auto', -if(Ext.DomQuery){ - Ext.Element.selectorFunction = Ext.DomQuery.select; -} + + type: 'draw', -Ext.Element.select = function(selector, root){ - var els; - if(typeof selector == "string"){ - els = Ext.Element.selectorFunction(selector, root); - }else if(selector.length !== undefined){ - els = selector; - }else{ - throw "Invalid selector"; + onLayout : function(width, height) { + this.owner.surface.setSize(width, height); + this.callParent(arguments); } - return new Ext.CompositeElementLite(els); -}; +}); -Ext.select = Ext.Element.select; -(function(){ - var BEFOREREQUEST = "beforerequest", - REQUESTCOMPLETE = "requestcomplete", - REQUESTEXCEPTION = "requestexception", - UNDEFINED = undefined, - LOAD = 'load', - POST = 'POST', - GET = 'GET', - WINDOW = window; +Ext.define('Ext.chart.theme.Theme', { - Ext.data.Connection = function(config){ - Ext.apply(this, config); - this.addEvents( - - BEFOREREQUEST, - - REQUESTCOMPLETE, - - REQUESTEXCEPTION - ); - Ext.data.Connection.superclass.constructor.call(this); - }; - - Ext.extend(Ext.data.Connection, Ext.util.Observable, { - - - - - - timeout : 30000, - - autoAbort:false, - - disableCaching: true, + requires: ['Ext.draw.Color'], - - disableCachingParam: '_dc', + - - request : function(o){ - var me = this; - if(me.fireEvent(BEFOREREQUEST, me, o)){ - if (o.el) { - if(!Ext.isEmpty(o.indicatorText)){ - me.indicatorText = '
'+o.indicatorText+"
"; + theme: 'Base', + themeAttrs: false, + + initTheme: function(theme) { + var me = this, + themes = Ext.chart.theme, + key, gradients; + if (theme) { + theme = theme.split(':'); + for (key in themes) { + if (key == theme[0]) { + gradients = theme[1] == 'gradients'; + me.themeAttrs = new themes[key]({ + useGradients: gradients + }); + if (gradients) { + me.gradients = me.themeAttrs.gradients; } - if(me.indicatorText) { - Ext.getDom(o.el).innerHTML = me.indicatorText; + if (me.themeAttrs.background) { + me.background = me.themeAttrs.background; } - o.success = (Ext.isFunction(o.success) ? o.success : function(){}).createInterceptor(function(response) { - Ext.getDom(o.el).innerHTML = response.responseText; - }); + return; } + } + Ext.Error.raise('No theme found named "' + theme + '"'); + } + } +}, - var p = o.params, - url = o.url || me.url, - method, - cb = {success: me.handleResponse, - failure: me.handleFailure, - scope: me, - argument: {options: o}, - timeout : Ext.num(o.timeout, me.timeout) - }, - form, - serForm; - +function() { + - if (Ext.isFunction(p)) { - p = p.call(o.scope||WINDOW, o); +(function() { + Ext.chart.theme = function(config, base) { + config = config || {}; + var i = 0, l, colors, color, + seriesThemes, markerThemes, + seriesTheme, markerTheme, + key, gradients = [], + midColor, midL; + + if (config.baseColor) { + midColor = Ext.draw.Color.fromString(config.baseColor); + midL = midColor.getHSL()[2]; + if (midL < 0.15) { + midColor = midColor.getLighter(0.3); + } else if (midL < 0.3) { + midColor = midColor.getLighter(0.15); + } else if (midL > 0.85) { + midColor = midColor.getDarker(0.3); + } else if (midL > 0.7) { + midColor = midColor.getDarker(0.15); + } + config.colors = [ midColor.getDarker(0.3).toString(), + midColor.getDarker(0.15).toString(), + midColor.toString(), + midColor.getLighter(0.15).toString(), + midColor.getLighter(0.3).toString()]; + + delete config.baseColor; + } + if (config.colors) { + colors = config.colors.slice(); + markerThemes = base.markerThemes; + seriesThemes = base.seriesThemes; + l = colors.length; + base.colors = colors; + for (; i < l; i++) { + color = colors[i]; + markerTheme = markerThemes[i] || {}; + seriesTheme = seriesThemes[i] || {}; + markerTheme.fill = seriesTheme.fill = markerTheme.stroke = seriesTheme.stroke = color; + markerThemes[i] = markerTheme; + seriesThemes[i] = seriesTheme; + } + base.markerThemes = markerThemes.slice(0, l); + base.seriesThemes = seriesThemes.slice(0, l); + + } + for (key in base) { + if (key in config) { + if (Ext.isObject(config[key]) && Ext.isObject(base[key])) { + Ext.apply(base[key], config[key]); + } else { + base[key] = config[key]; } - - p = Ext.urlEncode(me.extraParams, Ext.isObject(p) ? Ext.urlEncode(p) : p); - - if (Ext.isFunction(url)) { - url = url.call(o.scope || WINDOW, o); + } + } + if (config.useGradients) { + colors = base.colors || (function () { + var ans = []; + for (i = 0, seriesThemes = base.seriesThemes, l = seriesThemes.length; i < l; i++) { + ans.push(seriesThemes[i].fill || seriesThemes[i].stroke); } - - if((form = Ext.getDom(o.form))){ - url = url || form.action; - if(o.isUpload || (/multipart\/form-data/i.test(form.getAttribute("enctype")))) { - return me.doFormUpload.call(me, o, p, url); - } - serForm = Ext.lib.Ajax.serializeForm(form); - p = p ? (p + '&' + serForm) : serForm; + return ans; + })(); + for (i = 0, l = colors.length; i < l; i++) { + midColor = Ext.draw.Color.fromString(colors[i]); + if (midColor) { + color = midColor.getDarker(0.1).toString(); + midColor = midColor.toString(); + key = 'theme-' + midColor.substr(1) + '-' + color.substr(1); + gradients.push({ + id: key, + angle: 45, + stops: { + 0: { + color: midColor.toString() + }, + 100: { + color: color.toString() + } + } + }); + colors[i] = 'url(#' + key + ')'; } + } + base.gradients = gradients; + base.colors = colors; + } + + Ext.apply(this, base); + }; +})(); +}); - method = o.method || me.method || ((p || o.xmlData || o.jsonData) ? POST : GET); - if(method === GET && (me.disableCaching && o.disableCaching !== false) || o.disableCaching === true){ - var dcp = o.disableCachingParam || me.disableCachingParam; - url = Ext.urlAppend(url, dcp + '=' + (new Date().getTime())); - } +Ext.define('Ext.chart.Mask', { + constructor: function(config) { + var me = this; - o.headers = Ext.apply(o.headers || {}, me.defaultHeaders || {}); + me.addEvents('select'); - if(o.autoAbort === true || me.autoAbort) { - me.abort(); - } + if (config) { + Ext.apply(me, config); + } + if (me.mask) { + me.on('afterrender', function() { + + var comp = Ext.create('Ext.chart.MaskLayer', { + renderTo: me.el + }); + comp.el.on({ + 'mousemove': function(e) { + me.onMouseMove(e); + }, + 'mouseup': function(e) { + me.resized(e); + } + }); + + var resizeHandler = Ext.create('Ext.resizer.Resizer', { + el: comp.el, + handles: 'all', + pinned: true + }); + resizeHandler.on({ + 'resize': function(e) { + me.resized(e); + } + }); + comp.initDraggable(); + me.maskType = me.mask; + me.mask = comp; + me.maskSprite = me.surface.add({ + type: 'path', + path: ['M', 0, 0], + zIndex: 1001, + opacity: 0.7, + hidden: true, + stroke: '#444' + }); + }, me, { single: true }); + } + }, + + resized: function(e) { + var me = this, + bbox = me.bbox || me.chartBBox, + x = bbox.x, + y = bbox.y, + width = bbox.width, + height = bbox.height, + box = me.mask.getBox(true), + max = Math.max, + min = Math.min, + staticX = box.x - x, + staticY = box.y - y; + + staticX = max(staticX, x); + staticY = max(staticY, y); + staticX = min(staticX, width); + staticY = min(staticY, height); + box.x = staticX; + box.y = staticY; + me.fireEvent('select', me, box); + }, - if((method == GET || o.xmlData || o.jsonData) && p){ - url = Ext.urlAppend(url, p); - p = ''; - } - return (me.transId = Ext.lib.Ajax.request(method, url, cb, p, o)); - }else{ - return o.callback ? o.callback.apply(o.scope, [o,UNDEFINED,UNDEFINED]) : null; - } - }, + onMouseUp: function(e) { + var me = this, + bbox = me.bbox || me.chartBBox, + sel = me.maskSelection; + me.maskMouseDown = false; + me.mouseDown = false; + if (me.mouseMoved) { + me.onMouseMove(e); + me.mouseMoved = false; + me.fireEvent('select', me, { + x: sel.x - bbox.x, + y: sel.y - bbox.y, + width: sel.width, + height: sel.height + }); + } + }, - - isLoading : function(transId){ - return transId ? Ext.lib.Ajax.isCallInProgress(transId) : !! this.transId; - }, + onMouseDown: function(e) { + var me = this; + me.mouseDown = true; + me.mouseMoved = false; + me.maskMouseDown = { + x: e.getPageX() - me.el.getX(), + y: e.getPageY() - me.el.getY() + }; + }, - - abort : function(transId){ - if(transId || this.isLoading()){ - Ext.lib.Ajax.abort(transId || this.transId); + onMouseMove: function(e) { + var me = this, + mask = me.maskType, + bbox = me.bbox || me.chartBBox, + x = bbox.x, + y = bbox.y, + math = Math, + floor = math.floor, + abs = math.abs, + min = math.min, + max = math.max, + height = floor(y + bbox.height), + width = floor(x + bbox.width), + posX = e.getPageX(), + posY = e.getPageY(), + staticX = posX - me.el.getX(), + staticY = posY - me.el.getY(), + maskMouseDown = me.maskMouseDown, + path; + + me.mouseMoved = me.mouseDown; + staticX = max(staticX, x); + staticY = max(staticY, y); + staticX = min(staticX, width); + staticY = min(staticY, height); + if (maskMouseDown && me.mouseDown) { + if (mask == 'horizontal') { + staticY = y; + maskMouseDown.y = height; + posY = me.el.getY() + bbox.height + me.insetPadding; + } + else if (mask == 'vertical') { + staticX = x; + maskMouseDown.x = width; + } + width = maskMouseDown.x - staticX; + height = maskMouseDown.y - staticY; + path = ['M', staticX, staticY, 'l', width, 0, 0, height, -width, 0, 'z']; + me.maskSelection = { + x: width > 0 ? staticX : staticX + width, + y: height > 0 ? staticY : staticY + height, + 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.show(); + me.maskSprite.setAttributes({ + hidden: true + }, true); + } + else { + if (mask == 'horizontal') { + path = ['M', staticX, y, 'L', staticX, height]; } - }, - - - handleResponse : function(response){ - this.transId = false; - var options = response.argument.options; - response.argument = options ? options.argument : null; - this.fireEvent(REQUESTCOMPLETE, this, response, options); - if(options.success){ - options.success.call(options.scope, response, options); + else if (mask == 'vertical') { + path = ['M', x, staticY, 'L', width, staticY]; } - if(options.callback){ - options.callback.call(options.scope, options, true, response); + else { + path = ['M', staticX, y, 'L', staticX, height, 'M', x, staticY, 'L', width, staticY]; } - }, + me.maskSprite.setAttributes({ + path: path, + fill: me.maskMouseDown ? me.maskSprite.stroke : false, + 'stroke-width': mask === true ? 1 : 3, + hidden: false + }, true); + } + }, - - handleFailure : function(response, e){ - this.transId = false; - var options = response.argument.options; - response.argument = options ? options.argument : null; - this.fireEvent(REQUESTEXCEPTION, this, response, options, e); - if(options.failure){ - options.failure.call(options.scope, response, options); - } - if(options.callback){ - options.callback.call(options.scope, options, false, response); - } - }, + onMouseLeave: function(e) { + var me = this; + me.mouseMoved = false; + me.mouseDown = false; + me.maskMouseDown = false; + me.mask.hide(); + me.maskSprite.hide(true); + } +}); + - - doFormUpload : function(o, ps, url){ - var id = Ext.id(), - doc = document, - frame = doc.createElement('iframe'), - form = Ext.getDom(o.form), - hiddens = [], - hd, - encoding = 'multipart/form-data', - buf = { - target: form.target, - method: form.method, - encoding: form.encoding, - enctype: form.enctype, - action: form.action - }; +Ext.define('Ext.chart.Navigation', { + constructor: function() { + this.originalStore = this.store; + }, + + + setZoom: function(zoomConfig) { + var me = this, + store = me.substore || me.store, + 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 = {}; - Ext.fly(frame).set({ - id: id, - name: id, - cls: 'x-hidden', - src: Ext.SSL_SECURE_URL - }); - - doc.body.appendChild(frame); - + if (!recFields.length) { + rec.fields.each(function(f) { + recFields.push(f.name); + }); + recFieldsLen = recFields.length; + } - if(Ext.isIE){ - document.frames[id].name = id; + for (i = 0; i < recFieldsLen; i++) { + curField = recFields[i]; + obj[curField] = rec.get(curField); } + json.push(obj); + }); + me.store = me.substore = Ext.create('Ext.data.JsonStore', { + fields: recFields, + data: json + }); + me.redraw(true); + }, + restoreZoom: function() { + this.store = this.substore = this.originalStore; + this.redraw(true); + } + +}); - Ext.fly(form).set({ - target: id, - method: POST, - enctype: encoding, - encoding: encoding, - action: url || buf.action - }); +Ext.define('Ext.chart.Shape', { + + + + singleton: true, + + + + circle: function (surface, opts) { + return surface.add(Ext.apply({ + type: 'circle', + x: opts.x, + y: opts.y, + stroke: null, + radius: opts.radius + }, opts)); + }, + line: function (surface, opts) { + return surface.add(Ext.apply({ + type: 'rect', + x: opts.x - opts.radius, + y: opts.y - opts.radius, + height: 2 * opts.radius, + width: 2 * opts.radius / 5 + }, opts)); + }, + square: function (surface, opts) { + return surface.add(Ext.applyIf({ + type: 'rect', + x: opts.x - opts.radius, + y: opts.y - opts.radius, + height: 2 * opts.radius, + width: 2 * opts.radius, + radius: null + }, opts)); + }, + triangle: function (surface, opts) { + opts.radius *= 1.75; + return surface.add(Ext.apply({ + type: 'path', + stroke: null, + path: "M".concat(opts.x, ",", opts.y, "m0-", opts.radius * 0.58, "l", opts.radius * 0.5, ",", opts.radius * 0.87, "-", opts.radius, ",0z") + }, opts)); + }, + diamond: function (surface, opts) { + var r = opts.radius; + r *= 1.5; + return surface.add(Ext.apply({ + type: 'path', + stroke: null, + path: ["M", opts.x, opts.y - r, "l", r, r, -r, r, -r, -r, r, -r, "z"] + }, opts)); + }, + cross: function (surface, opts) { + var r = opts.radius; + r = r / 1.7; + return surface.add(Ext.apply({ + type: 'path', + stroke: null, + path: "M".concat(opts.x - r, ",", opts.y, "l", [-r, -r, r, -r, r, r, r, -r, r, r, -r, r, r, r, -r, r, -r, -r, -r, r, -r, -r, "z"]) + }, opts)); + }, + plus: function (surface, opts) { + var r = opts.radius / 1.3; + return surface.add(Ext.apply({ + type: 'path', + stroke: null, + path: "M".concat(opts.x - r / 2, ",", opts.y - r / 2, "l", [0, -r, r, 0, 0, r, r, 0, 0, r, -r, 0, 0, r, -r, 0, 0, -r, -r, 0, 0, -r, "z"]) + }, opts)); + }, + arrow: function (surface, opts) { + var r = opts.radius; + return surface.add(Ext.apply({ + type: 'path', + path: "M".concat(opts.x - r * 0.7, ",", opts.y - r * 0.4, "l", [r * 0.6, 0, 0, -r * 0.4, r, r * 0.8, -r, r * 0.8, 0, -r * 0.4, -r * 0.6, 0], "z") + }, opts)); + }, + drop: function (surface, x, y, text, size, angle) { + size = size || 30; + angle = angle || 0; + surface.add({ + type: 'path', + path: ['M', x, y, 'l', size, 0, 'A', size * 0.4, size * 0.4, 0, 1, 0, x + size * 0.7, y - size * 0.7, 'z'], + fill: '#000', + stroke: 'none', + rotate: { + degrees: 22.5 - angle, + x: x, + y: y + } + }); + angle = (angle + 90) * Math.PI / 180; + surface.add({ + type: 'text', + x: x + size * Math.sin(angle) - 10, + y: y + size * Math.cos(angle) + 5, + text: text, + 'font-size': size * 12 / 40, + stroke: 'none', + fill: '#fff' + }); + } +}); - - Ext.iterate(Ext.urlDecode(ps, false), function(k, v){ - hd = doc.createElement('input'); - Ext.fly(hd).set({ - type: 'hidden', - value: v, - name: k - }); - form.appendChild(hd); - hiddens.push(hd); - }); +Ext.define('Ext.draw.Surface', { - function cb(){ - var me = this, - - r = {responseText : '', - responseXML : null, - argument : o.argument}, - doc, - firstChild; + - 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)){ - r.responseText = firstChild.value; - }else{ - r.responseText = doc.body.innerHTML; - } - } - - r.responseXML = doc.XMLDocument || doc; - } - } - catch(e) {} + mixins: { + observable: 'Ext.util.Observable' + }, - Ext.EventManager.removeListener(frame, LOAD, cb, me); + requires: ['Ext.draw.CompositeSprite'], + uses: ['Ext.draw.engine.Svg', 'Ext.draw.engine.Vml'], - me.fireEvent(REQUESTCOMPLETE, me, r, o); + separatorRe: /[, ]+/, - function runCallback(fn, scope, args){ - if(Ext.isFunction(fn)){ - fn.apply(scope, args); - } - } + statics: { + + create: function(config, enginePriority) { + enginePriority = enginePriority || ['Svg', 'Vml']; - runCallback(o.success, o.scope, [r, o]); - runCallback(o.callback, o.scope, [o, true, r]); + var i = 0, + len = enginePriority.length, + surfaceClass; - if(!me.debugUploads){ - setTimeout(function(){Ext.removeNode(frame);}, 100); + for (; i < len; i++) { + if (Ext.supports[enginePriority[i]]) { + return Ext.create('Ext.draw.engine.' + enginePriority[i], config); } } - - Ext.EventManager.on(frame, LOAD, cb, this); - form.submit(); - - Ext.fly(form).set(buf); - Ext.each(hiddens, function(h) { - Ext.removeNode(h); - }); + return false; } - }); -})(); - + }, -Ext.Ajax = new Ext.data.Connection({ - - - - - + availableAttrs: { + blur: 0, + "clip-rect": "0 0 1e9 1e9", + cursor: "default", + cx: 0, + cy: 0, + 'dominant-baseline': 'auto', + fill: "none", + "fill-opacity": 1, + font: '10px "Arial"', + "font-family": '"Arial"', + "font-size": "10", + "font-style": "normal", + "font-weight": 400, + gradient: "", + height: 0, + hidden: false, + href: "http://sencha.com/", + opacity: 1, + path: "M0,0", + radius: 0, + rx: 0, + ry: 0, + scale: "1 1", + src: "", + stroke: "#000", + "stroke-dasharray": "", + "stroke-linecap": "butt", + "stroke-linejoin": "butt", + "stroke-miterlimit": 0, + "stroke-opacity": 1, + "stroke-width": 1, + target: "_blank", + text: "", + "text-anchor": "middle", + title: "Ext Draw", + width: 0, + x: 0, + y: 0, + zIndex: 0 + }, + + + + container: undefined, + height: 352, + width: 512, + x: 0, + y: 0, + + constructor: function(config) { + var me = this; + config = config || {}; + Ext.apply(me, config); + + me.domRef = Ext.getDoc().dom; + + me.customAttributes = {}; + + me.addEvents( + 'mousedown', + 'mouseup', + 'mouseover', + 'mouseout', + 'mousemove', + 'mouseenter', + 'mouseleave', + 'click' + ); + + me.mixins.observable.constructor.call(me); + + me.getId(); + me.initGradients(); + me.initItems(); + if (me.renderTo) { + me.render(me.renderTo); + delete me.renderTo; + } + me.initBackground(config.background); + }, + initSurface: Ext.emptyFn, + - - + renderItem: Ext.emptyFn, - autoAbort : false, + renderItems: Ext.emptyFn, - serializeForm : function(form){ - return Ext.lib.Ajax.serializeForm(form); - } -}); + setViewBox: Ext.emptyFn, -Ext.util.JSON = new (function(){ - var useHasOwn = !!{}.hasOwnProperty, - isNative = function() { - var useNative = null; - - return function() { - if (useNative === null) { - useNative = Ext.USE_NATIVE_JSON && window.JSON && JSON.toString() == '[object JSON]'; - } - - return useNative; - }; - }(), - pad = function(n) { - return n < 10 ? "0" + n : n; - }, - doDecode = function(json){ - return eval("(" + json + ")"); - }, - doEncode = function(o){ - if(!Ext.isDefined(o) || o === null){ - return "null"; - }else if(Ext.isArray(o)){ - return encodeArray(o); - }else if(Ext.isDate(o)){ - return Ext.util.JSON.encodeDate(o); - }else if(Ext.isString(o)){ - return encodeString(o); - }else if(typeof o == "number"){ - - return isFinite(o) ? String(o) : "null"; - }else if(Ext.isBoolean(o)){ - return String(o); - }else { - var a = ["{"], b, i, v; - for (i in o) { - - if(!o.getElementsByTagName){ - if(!useHasOwn || o.hasOwnProperty(i)) { - v = o[i]; - switch (typeof v) { - case "undefined": - case "function": - case "unknown": - break; - default: - if(b){ - a.push(','); - } - a.push(doEncode(i), ":", - v === null ? "null" : doEncode(v)); - b = true; - } - } - } - } - a.push("}"); - return a.join(""); - } - }, - m = { - "\b": '\\b', - "\t": '\\t', - "\n": '\\n', - "\f": '\\f', - "\r": '\\r', - '"' : '\\"', - "\\": '\\\\' - }, - encodeString = function(s){ - if (/["\\\x00-\x1f]/.test(s)) { - return '"' + s.replace(/([\x00-\x1f\\"])/g, function(a, b) { - var c = m[b]; - if(c){ - return c; - } - c = b.charCodeAt(); - return "\\u00" + - Math.floor(c / 16).toString(16) + - (c % 16).toString(16); - }) + '"'; - } - return '"' + s + '"'; - }, - encodeArray = function(o){ - var a = ["["], b, i, l = o.length, v; - for (i = 0; i < l; i += 1) { - v = o[i]; - switch (typeof v) { - case "undefined": - case "function": - case "unknown": - break; - default: - if (b) { - a.push(','); - } - a.push(v === null ? "null" : Ext.util.JSON.encode(v)); - b = true; - } - } - a.push("]"); - return a.join(""); - }; + + addCls: Ext.emptyFn, - this.encodeDate = function(o){ - return '"' + o.getFullYear() + "-" + - pad(o.getMonth() + 1) + "-" + - pad(o.getDate()) + "T" + - pad(o.getHours()) + ":" + - pad(o.getMinutes()) + ":" + - pad(o.getSeconds()) + '"'; - }; + removeCls: Ext.emptyFn, - this.encode = function() { - var ec; - return function(o) { - if (!ec) { - - ec = isNative() ? JSON.stringify : doEncode; - } - return ec(o); - }; - }(); + setStyle: Ext.emptyFn, + + initGradients: function() { + var gradients = this.gradients; + if (gradients) { + Ext.each(gradients, this.addGradient, this); + } + }, - this.decode = function() { - var dc; - return function(json) { - if (!dc) { - - dc = isNative() ? JSON.parse : doDecode; + initItems: function() { + var items = this.items; + this.items = Ext.create('Ext.draw.CompositeSprite'); + this.groups = Ext.create('Ext.draw.CompositeSprite'); + if (items) { + this.add(items); + } + }, + + + initBackground: function(config) { + var gradientId, + gradient, + backgroundSprite, + width = this.width, + height = this.height; + if (config) { + if (config.gradient) { + gradient = config.gradient; + gradientId = gradient.id; + this.addGradient(gradient); + this.background = this.add({ + type: 'rect', + x: 0, + y: 0, + width: width, + height: height, + fill: 'url(#' + gradientId + ')' + }); + } else if (config.fill) { + this.background = this.add({ + type: 'rect', + x: 0, + y: 0, + width: width, + height: height, + fill: config.fill + }); + } else if (config.image) { + this.background = this.add({ + type: 'image', + x: 0, + y: 0, + width: width, + height: height, + src: config.image + }); } - return dc(json); - }; - }(); - -})(); - -Ext.encode = Ext.util.JSON.encode; - -Ext.decode = Ext.util.JSON.decode; - -Ext.EventManager = function(){ - var docReadyEvent, - docReadyProcId, - docReadyState = false, - DETECT_NATIVE = Ext.isGecko || Ext.isWebKit || Ext.isSafari, - E = Ext.lib.Event, - D = Ext.lib.Dom, - DOC = document, - WINDOW = window, - DOMCONTENTLOADED = "DOMContentLoaded", - COMPLETE = 'complete', - propRe = /^(?:scope|delay|buffer|single|stopEvent|preventDefault|stopPropagation|normalized|args|delegate)$/, - - specialElCache = []; + } + }, + + + setSize: function(w, h) { + if (this.background) { + this.background.setAttributes({ + width: w, + height: h, + hidden: false + }, true); + } + }, - function getId(el){ - var id = false, - i = 0, - len = specialElCache.length, - skip = false, - o; + + scrubAttrs: function(sprite) { + var i, + attrs = {}, + exclude = {}, + sattr = sprite.attr; + for (i in sattr) { - if (el) { - if (el.getElementById || el.navigator) { + if (this.translateAttrs.hasOwnProperty(i)) { - for(; i < len; ++i){ - o = specialElCache[i]; - if(o.el === el){ - id = o.id; - break; - } - } - if(!id){ - - id = Ext.id(el); - specialElCache.push({ - id: id, - el: el - }); - skip = true; - } - }else{ - id = Ext.id(el); + attrs[this.translateAttrs[i]] = sattr[i]; + exclude[this.translateAttrs[i]] = true; } - if(!Ext.elCache[id]){ - Ext.Element.addToCache(new Ext.Element(el), id); - if(skip){ - Ext.elCache[id].skipGC = true; - } + else if (this.availableAttrs.hasOwnProperty(i) && !exclude[i]) { + + attrs[i] = sattr[i]; } } - return id; - } + return attrs; + }, - function addListener(el, ename, fn, task, wrap, scope){ - el = Ext.getDom(el); - var id = getId(el), - es = Ext.elCache[id].events, - wfn; + onClick: function(e) { + this.processEvent('click', e); + }, - wfn = E.on(el, ename, wrap); - es[ename] = es[ename] || []; + + onMouseUp: function(e) { + this.processEvent('mouseup', e); + }, - - es[ename].push([fn, wrap, scope, wfn, task]); + + onMouseDown: function(e) { + this.processEvent('mousedown', e); + }, - - + + onMouseOver: function(e) { + this.processEvent('mouseover', e); + }, - - if(el.addEventListener && ename == "mousewheel"){ - var args = ["DOMMouseScroll", wrap, false]; - el.addEventListener.apply(el, args); - Ext.EventManager.addListener(WINDOW, 'unload', function(){ - el.removeEventListener.apply(el, args); - }); - } + + onMouseOut: function(e) { + this.processEvent('mouseout', e); + }, - - if(el == DOC && ename == "mousedown"){ - Ext.EventManager.stoppedMouseDownEvent.addListener(wrap); - } - } + + onMouseMove: function(e) { + this.fireEvent('mousemove', e); + }, - function doScrollChk(){ - - if(window != top){ - return false; - } + + onMouseEnter: Ext.emptyFn, - try{ - DOC.documentElement.doScroll('left'); - }catch(e){ - return false; - } + + onMouseLeave: Ext.emptyFn, - fireDocReady(); - return true; - } - function checkReadyState(e){ + addGradient: Ext.emptyFn, - if(Ext.isIE && doScrollChk()){ - return true; - } - if(DOC.readyState == COMPLETE){ - fireDocReady(); - return true; - } - docReadyState || (docReadyProcId = setTimeout(arguments.callee, 2)); - return false; - } + + add: function() { + var args = Array.prototype.slice.call(arguments), + sprite, + index; - var styles; - function checkStyleSheets(e){ - styles || (styles = Ext.query('style, link[rel=stylesheet]')); - if(styles.length == DOC.styleSheets.length){ - fireDocReady(); - return true; - } - docReadyState || (docReadyProcId = setTimeout(arguments.callee, 2)); - return false; - } + var hasMultipleArgs = args.length > 1; + if (hasMultipleArgs || Ext.isArray(args[0])) { + var items = hasMultipleArgs ? args : args[0], + results = [], + i, ln, item; - function OperaDOMContentLoaded(e){ - DOC.removeEventListener(DOMCONTENTLOADED, arguments.callee, false); - checkStyleSheets(); - } + for (i = 0, ln = items.length; i < ln; i++) { + item = items[i]; + item = this.add(item); + results.push(item); + } - function fireDocReady(e){ - if(!docReadyState){ - docReadyState = true; + return results; + } + sprite = this.prepareItems(args[0], true)[0]; + this.normalizeSpriteCollection(sprite); + this.onAdd(sprite); + return sprite; + }, - if(docReadyProcId){ - clearTimeout(docReadyProcId); - } - if(DETECT_NATIVE) { - DOC.removeEventListener(DOMCONTENTLOADED, fireDocReady, false); - } - if(Ext.isIE && checkReadyState.bindIE){ - DOC.detachEvent('onreadystatechange', checkReadyState); + + normalizeSpriteCollection: function(sprite) { + var items = this.items, + zIndex = sprite.attr.zIndex, + idx = items.indexOf(sprite); + + 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; } - E.un(WINDOW, "load", arguments.callee); + items.insert(idx, sprite); } - if(docReadyEvent && !Ext.isReady){ - Ext.isReady = true; - docReadyEvent.fire(); - docReadyEvent.listeners = []; - } - - } + return idx; + }, - function initDocReady(){ - docReadyEvent || (docReadyEvent = new Ext.util.Event()); - if (DETECT_NATIVE) { - DOC.addEventListener(DOMCONTENTLOADED, fireDocReady, false); - } - - if (Ext.isIE){ - - - if(!checkReadyState()){ - checkReadyState.bindIE = true; - DOC.attachEvent('onreadystatechange', checkReadyState); + onAdd: function(sprite) { + var group = sprite.group, + draggable = sprite.draggable, + groups, ln, i; + if (group) { + groups = [].concat(group); + ln = groups.length; + for (i = 0; i < ln; i++) { + group = groups[i]; + this.getGroup(group).add(sprite); } - - }else if(Ext.isOpera ){ - - - - (DOC.readyState == COMPLETE && checkStyleSheets()) || - DOC.addEventListener(DOMCONTENTLOADED, OperaDOMContentLoaded, false); - - }else if (Ext.isWebKit){ - - checkReadyState(); + delete sprite.group; } - - E.on(WINDOW, "load", fireDocReady); - } + if (draggable) { + sprite.initDraggable(); + } + }, - function createTargeted(h, o){ - return function(){ - var args = Ext.toArray(arguments); - if(o.target == Ext.EventObject.setEvent(args[0]).target){ - h.apply(this, args); + + remove: function(sprite, destroySprite) { + if (sprite) { + this.items.remove(sprite); + this.groups.each(function(item) { + item.remove(sprite); + }); + sprite.onRemove(); + if (destroySprite === true) { + sprite.destroy(); } - }; - } - - function createBuffered(h, o, task){ - return function(e){ - - task.delay(o.buffer, h, null, [new Ext.EventObjectImpl(e)]); - }; - } + } + }, - function createSingle(h, el, ename, fn, scope){ - return function(e){ - Ext.EventManager.removeListener(el, ename, fn, scope); - h(e); - }; - } + + removeAll: function(destroySprites) { + var items = this.items.items, + ln = items.length, + i; + for (i = ln - 1; i > -1; i--) { + this.remove(items[i], destroySprites); + } + }, - function createDelayed(h, o, fn){ - return function(e){ - var task = new Ext.util.DelayedTask(h); - if(!fn.tasks) { - fn.tasks = []; - } - fn.tasks.push(task); - task.delay(o.delay || 10, h, null, [new Ext.EventObjectImpl(e)]); - }; - } + onRemove: Ext.emptyFn, - function listen(element, ename, opt, fn, scope){ - var o = (!opt || typeof opt == "boolean") ? {} : opt, - el = Ext.getDom(element), task; + onDestroy: Ext.emptyFn, - fn = fn || o.fn; - scope = scope || o.scope; + + applyTransformations: function(sprite) { + sprite.bbox.transform = 0; + this.transform(sprite); - if(!el){ - throw "Error listening for \"" + ename + '\". Element "' + element + '" doesn\'t exist.'; - } - function h(e){ - - if(!Ext){ - return; - } - e = Ext.EventObject.setEvent(e); - var t; - if (o.delegate) { - if(!(t = e.getTarget(o.delegate, el))){ - return; - } - } else { - t = e.target; - } - if (o.stopEvent) { - e.stopEvent(); - } - if (o.preventDefault) { - e.preventDefault(); - } - if (o.stopPropagation) { - e.stopPropagation(); - } - if (o.normalized === false) { - e = e.browserEvent; - } + var me = this, + dirty = false, + attr = sprite.attr; - fn.call(scope || el, e, t, o); - } - if(o.target){ - h = createTargeted(h, o); + if (attr.translation.x != null || attr.translation.y != null) { + me.translate(sprite); + dirty = true; } - if(o.delay){ - h = createDelayed(h, o, fn); + if (attr.scaling.x != null || attr.scaling.y != null) { + me.scale(sprite); + dirty = true; } - if(o.single){ - h = createSingle(h, el, ename, fn, scope); + if (attr.rotation.degrees != null) { + me.rotate(sprite); + dirty = true; } - if(o.buffer){ - task = new Ext.util.DelayedTask(h); - h = createBuffered(h, o, task); + if (dirty) { + sprite.bbox.transform = 0; + this.transform(sprite); + sprite.transformations = []; } + }, - addListener(el, ename, fn, task, h, scope); - return h; - } - - var pub = { - - addListener : function(element, eventName, fn, scope, options){ - if(typeof eventName == 'object'){ - var o = eventName, e, val; - for(e in o){ - val = o[e]; - if(!propRe.test(e)){ - if(Ext.isFunction(val)){ - - listen(element, e, o, val, o.scope); - }else{ - - listen(element, e, val); - } - } - } - } else { - listen(element, eventName, options, fn, scope); - } - }, + + rotate: function (sprite) { + var bbox, + deg = sprite.attr.rotation.degrees, + centerX = sprite.attr.rotation.x, + centerY = sprite.attr.rotation.y; + if (!Ext.isNumber(centerX) || !Ext.isNumber(centerY)) { + bbox = this.getBBox(sprite); + centerX = !Ext.isNumber(centerX) ? bbox.x + bbox.width / 2 : centerX; + centerY = !Ext.isNumber(centerY) ? bbox.y + bbox.height / 2 : centerY; + } + sprite.transformations.push({ + type: "rotate", + degrees: deg, + x: centerX, + y: centerY + }); + }, - - removeListener : function(el, eventName, fn, scope){ - el = Ext.getDom(el); - var id = getId(el), - f = el && (Ext.elCache[id].events)[eventName] || [], - wrap, i, l, k, len, fnc; + + translate: function(sprite) { + var x = sprite.attr.translation.x || 0, + y = sprite.attr.translation.y || 0; + sprite.transformations.push({ + type: "translate", + x: x, + y: y + }); + }, - for (i = 0, len = f.length; i < len; i++) { + + scale: function(sprite) { + var bbox, + x = sprite.attr.scaling.x || 1, + y = sprite.attr.scaling.y || 1, + centerX = sprite.attr.scaling.centerX, + centerY = sprite.attr.scaling.centerY; - - if (Ext.isArray(fnc = f[i]) && fnc[0] == fn && (!scope || fnc[2] == scope)) { - if(fnc[4]) { - fnc[4].cancel(); - } - k = fn.tasks && fn.tasks.length; - if(k) { - while(k--) { - fn.tasks[k].cancel(); - } - delete fn.tasks; - } - wrap = fnc[1]; - E.un(el, eventName, E.extAdapter ? fnc[3] : wrap); + if (!Ext.isNumber(centerX) || !Ext.isNumber(centerY)) { + bbox = this.getBBox(sprite); + centerX = !Ext.isNumber(centerX) ? bbox.x + bbox.width / 2 : centerX; + centerY = !Ext.isNumber(centerY) ? bbox.y + bbox.height / 2 : centerY; + } + sprite.transformations.push({ + type: "scale", + x: x, + y: y, + centerX: centerX, + centerY: centerY + }); + }, - - if(wrap && el.addEventListener && eventName == "mousewheel"){ - el.removeEventListener("DOMMouseScroll", wrap, false); - } + + rectPath: function (x, y, w, h, r) { + if (r) { + return [["M", x + r, y], ["l", w - r * 2, 0], ["a", r, r, 0, 0, 1, r, r], ["l", 0, h - r * 2], ["a", r, r, 0, 0, 1, -r, r], ["l", r * 2 - w, 0], ["a", r, r, 0, 0, 1, -r, -r], ["l", 0, r * 2 - h], ["a", r, r, 0, 0, 1, r, -r], ["z"]]; + } + return [["M", x, y], ["l", w, 0], ["l", 0, h], ["l", -w, 0], ["z"]]; + }, - - if(wrap && el == DOC && eventName == "mousedown"){ - Ext.EventManager.stoppedMouseDownEvent.removeListener(wrap); - } + + ellipsePath: function (x, y, rx, ry) { + if (ry == null) { + ry = rx; + } + return [["M", x, y], ["m", 0, -ry], ["a", rx, ry, 0, 1, 1, 0, 2 * ry], ["a", rx, ry, 0, 1, 1, 0, -2 * ry], ["z"]]; + }, - f.splice(i, 1); - if (f.length === 0) { - delete Ext.elCache[id].events[eventName]; - } - for (k in Ext.elCache[id].events) { - return false; - } - Ext.elCache[id].events = {}; - return false; - } - } - }, + + getPathpath: function (el) { + return el.attr.path; + }, - - removeAll : function(el){ - el = Ext.getDom(el); - var id = getId(el), - ec = Ext.elCache[id] || {}, - es = ec.events || {}, - f, i, len, ename, fn, k, wrap; - - for(ename in es){ - if(es.hasOwnProperty(ename)){ - f = es[ename]; - - for (i = 0, len = f.length; i < len; i++) { - fn = f[i]; - if(fn[4]) { - fn[4].cancel(); - } - if(fn[0].tasks && (k = fn[0].tasks.length)) { - while(k--) { - fn[0].tasks[k].cancel(); - } - delete fn.tasks; - } - wrap = fn[1]; - E.un(el, ename, E.extAdapter ? fn[3] : wrap); + + getPathcircle: function (el) { + var a = el.attr; + return this.ellipsePath(a.x, a.y, a.radius, a.radius); + }, - - if(el.addEventListener && wrap && ename == "mousewheel"){ - el.removeEventListener("DOMMouseScroll", wrap, false); - } + + getPathellipse: function (el) { + var a = el.attr; + return this.ellipsePath(a.x, a.y, a.radiusX, a.radiusY); + }, - - if(wrap && el == DOC && ename == "mousedown"){ - Ext.EventManager.stoppedMouseDownEvent.removeListener(wrap); - } - } - } - } - if (Ext.elCache[id]) { - Ext.elCache[id].events = {}; - } - }, + + getPathrect: function (el) { + var a = el.attr; + return this.rectPath(a.x, a.y, a.width, a.height, a.r); + }, - getListeners : function(el, eventName) { - el = Ext.getDom(el); - var id = getId(el), - ec = Ext.elCache[id] || {}, - es = ec.events || {}, - results = []; - if (es && es[eventName]) { - return es[eventName]; - } else { - return null; - } - }, + + getPathimage: function (el) { + var a = el.attr; + return this.rectPath(a.x || 0, a.y || 0, a.width, a.height); + }, - purgeElement : function(el, recurse, eventName) { - el = Ext.getDom(el); - var id = getId(el), - ec = Ext.elCache[id] || {}, - es = ec.events || {}, - i, f, len; - if (eventName) { - if (es && es.hasOwnProperty(eventName)) { - f = es[eventName]; - for (i = 0, len = f.length; i < len; i++) { - Ext.EventManager.removeListener(el, eventName, f[i][0]); - } - } - } else { - Ext.EventManager.removeAll(el); - } - if (recurse && el && el.childNodes) { - for (i = 0, len = el.childNodes.length; i < len; i++) { - Ext.EventManager.purgeElement(el.childNodes[i], recurse, eventName); - } - } - }, + + getPathtext: function (el) { + var bbox = this.getBBoxText(el); + return this.rectPath(bbox.x, bbox.y, bbox.width, bbox.height); + }, - _unload : function() { - var el; - for (el in Ext.elCache) { - Ext.EventManager.removeAll(el); - } - delete Ext.elCache; - delete Ext.Element._flyweights; + createGroup: function(id) { + var group = this.groups.get(id); + if (!group) { + group = Ext.create('Ext.draw.CompositeSprite', { + surface: this + }); + group.id = id || Ext.id(null, 'ext-surface-group-'); + this.groups.add(group); + } + return group; + }, - - var c, - conn, - tid, - ajax = Ext.lib.Ajax; - (typeof ajax.conn == 'object') ? conn = ajax.conn : conn = {}; - for (tid in conn) { - c = conn[tid]; - if (c) { - ajax.abort({conn: c, tId: tid}); - } + + getGroup: function(id) { + if (typeof id == "string") { + var group = this.groups.get(id); + if (!group) { + group = this.createGroup(id); } - }, + } else { + group = id; + } + return group; + }, + + + prepareItems: function(items, applyDefaults) { + items = [].concat(items); - onDocumentReady : function(fn, scope, options){ - if (Ext.isReady) { - docReadyEvent || (docReadyEvent = new Ext.util.Event()); - docReadyEvent.addListener(fn, scope, options); - docReadyEvent.fire(); - docReadyEvent.listeners = []; + var item, i, ln; + for (i = 0, ln = items.length; i < ln; i++) { + item = items[i]; + if (!(item instanceof Ext.draw.Sprite)) { + + item.surface = this; + items[i] = this.createItem(item); } else { - if (!docReadyEvent) { - initDocReady(); - } - options = options || {}; - options.delay = options.delay || 1; - docReadyEvent.addListener(fn, scope, options); + item.surface = this; } - }, + } + return items; + }, + + + setText: Ext.emptyFn, + + //@private Creates an item and appends it to the surface. Called - - fireDocReady : fireDocReady - }; - - pub.on = pub.addListener; - pub.un = pub.removeListener; + createItem: Ext.emptyFn, - pub.stoppedMouseDownEvent = new Ext.util.Event(); - return pub; -}(); + + getId: function() { + return this.id || (this.id = Ext.id(null, 'ext-surface-')); + }, -Ext.onReady = Ext.EventManager.onDocumentReady; + + destroy: function() { + delete this.domRef; + this.removeAll(); + } +}); +Ext.define('Ext.draw.Component', { + -(function(){ - var initExtCss = function() { - - var bd = document.body || document.getElementsByTagName('body')[0]; - if (!bd) { - return false; - } - - var cls = [' ', - Ext.isIE ? "ext-ie " + (Ext.isIE6 ? 'ext-ie6' : (Ext.isIE7 ? 'ext-ie7' : 'ext-ie8')) - : Ext.isGecko ? "ext-gecko " + (Ext.isGecko2 ? 'ext-gecko2' : 'ext-gecko3') - : Ext.isOpera ? "ext-opera" - : Ext.isWebKit ? "ext-webkit" : ""]; + alias: 'widget.draw', - if (Ext.isSafari) { - cls.push("ext-safari " + (Ext.isSafari2 ? 'ext-safari2' : (Ext.isSafari3 ? 'ext-safari3' : 'ext-safari4'))); - } else if(Ext.isChrome) { - cls.push("ext-chrome"); - } + extend: 'Ext.Component', - if (Ext.isMac) { - cls.push("ext-mac"); - } - if (Ext.isLinux) { - cls.push("ext-linux"); - } + requires: [ + 'Ext.draw.Surface', + 'Ext.layout.component.Draw' + ], - - if (Ext.isStrict || Ext.isBorderBox) { - var p = bd.parentNode; - if (p) { - Ext.fly(p, '_internal').addClass(((Ext.isStrict && Ext.isIE ) || (!Ext.enableForcedBoxModel && !Ext.isIE)) ? ' ext-strict' : ' ext-border-box'); - } - } - - - if (Ext.enableForcedBoxModel && !Ext.isIE) { - Ext.isForcedBorderBox = true; - cls.push("ext-forced-border-box"); - } - - Ext.fly(bd, '_internal').addClass(cls); - return true; - }; - if (!initExtCss()) { - Ext.onReady(initExtCss); - } -})(); + + enginePriority: ['Svg', 'Vml'], + + baseCls: Ext.baseCSSPrefix + 'surface', + + componentLayout: 'draw', -(function(){ - var supports = Ext.apply(Ext.supports, { - - correctRightMargin: true, - - - correctTransparentColor: true, - - - cssFloat: true - }); - var supportTests = function(){ - var div = document.createElement('div'), - doc = document, - view, - last; - - div.innerHTML = '
'; - doc.body.appendChild(div); - last = div.lastChild; - - if((view = doc.defaultView)){ - if(view.getComputedStyle(div.firstChild.firstChild, null).marginRight != '0px'){ - supports.correctRightMargin = false; - } - if(view.getComputedStyle(last, null).backgroundColor != 'transparent'){ - supports.correctTransparentColor = false; - } - } - supports.cssFloat = !!last.style.cssFloat; - doc.body.removeChild(div); - }; + viewBox: true, + + + autoSize: false, + - if (Ext.isReady) { - supportTests(); - } else { - Ext.onReady(supportTests); - } -})(); + initComponent: function() { + this.callParent(arguments); + this.addEvents( + 'mousedown', + 'mouseup', + 'mousemove', + 'mouseenter', + 'mouseleave', + 'click' + ); + }, -Ext.EventObject = function(){ - var E = Ext.lib.Event, - clickRe = /(dbl)?click/, - - safariKeys = { - 3 : 13, - 63234 : 37, - 63235 : 39, - 63232 : 38, - 63233 : 40, - 63276 : 33, - 63277 : 34, - 63272 : 46, - 63273 : 36, - 63275 : 35 - }, - - btnMap = Ext.isIE ? {1:0,4:1,2:2} : {0:0,1:1,2:2}; + + onRender: function() { + var me = this, + viewBox = me.viewBox, + autoSize = me.autoSize, + bbox, items, width, height, x, y; + me.callParent(arguments); - Ext.EventObjectImpl = function(e){ - if(e){ - this.setEvent(e.browserEvent || e); - } - }; + me.createSurface(); - Ext.EventObjectImpl.prototype = { - - setEvent : function(e){ - var me = this; - if(e == me || (e && e.browserEvent)){ - return e; + 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); } - me.browserEvent = e; - if(e){ - - me.button = e.button ? btnMap[e.button] : (e.which ? e.which - 1 : -1); - if(clickRe.test(e.type) && me.button == -1){ - me.button = 0; - } - me.type = e.type; - me.shiftKey = e.shiftKey; - - me.ctrlKey = e.ctrlKey || e.metaKey || false; - me.altKey = e.altKey; - - me.keyCode = e.keyCode; - me.charCode = e.charCode; - - me.target = E.getTarget(e); + else { - me.xy = E.getXY(e); - }else{ - me.button = -1; - me.shiftKey = false; - me.ctrlKey = false; - me.altKey = false; - me.keyCode = 0; - me.charCode = 0; - me.target = null; - me.xy = [0, 0]; + me.autoSizeSurface(); } - return me; - }, + } + }, - - stopEvent : function(){ - var me = this; - if(me.browserEvent){ - if(me.browserEvent.type == 'mousedown'){ - Ext.EventManager.stoppedMouseDownEvent.fire(me); - } - E.stopEvent(me.browserEvent); - } - }, + //@private - - preventDefault : function(){ - if(this.browserEvent){ - E.preventDefault(this.browserEvent); + autoSizeSurface: function() { + var me = this, + items = me.surface.items, + bbox = items.getBBox(), + width = bbox.width, + height = bbox.height; + items.setAttributes({ + translate: { + x: -bbox.x, + + y: -bbox.y + (+Ext.isOpera) } - }, + }, true); + if (me.rendered) { + me.setSize(width, height); + } + else { + me.surface.setSize(width, height); + } + me.el.setSize(width, height); + }, - - stopPropagation : function(){ - var me = this; - if(me.browserEvent){ - if(me.browserEvent.type == 'mousedown'){ - Ext.EventManager.stoppedMouseDownEvent.fire(me); - } - E.stopPropagation(me.browserEvent); - } - }, + + createSurface: function() { + var surface = Ext.draw.Surface.create(Ext.apply({}, { + width: this.width, + height: this.height, + renderTo: this.el + }, this.initialConfig)); + this.surface = surface; - - getCharCode : function(){ - return this.charCode || this.keyCode; - }, + function refire(eventName) { + return function(e) { + this.fireEvent(eventName, e); + }; + } - - getKey : function(){ - return this.normalizeKey(this.keyCode || this.charCode); - }, + surface.on({ + scope: this, + mouseup: refire('mouseup'), + mousedown: refire('mousedown'), + mousemove: refire('mousemove'), + mouseenter: refire('mouseenter'), + mouseleave: refire('mouseleave'), + click: refire('click') + }); + }, - - normalizeKey: function(k){ - return Ext.isSafari ? (safariKeys[k] || k) : k; - }, - - getPageX : function(){ - return this.xy[0]; - }, + + onDestroy: function() { + var surface = this.surface; + if (surface) { + surface.destroy(); + } + this.callParent(arguments); + } - - getPageY : function(){ - return this.xy[1]; - }, +}); - - getXY : function(){ - return this.xy; - }, - - getTarget : function(selector, maxDepth, returnEl){ - return selector ? Ext.fly(this.target).findParent(selector, maxDepth, returnEl) : (returnEl ? Ext.get(this.target) : this.target); - }, +Ext.define('Ext.chart.LegendItem', { - - getRelatedTarget : function(){ - return this.browserEvent ? E.getRelatedTarget(this.browserEvent) : null; - }, + - - getWheelDelta : function(){ - var e = this.browserEvent; - var delta = 0; - if(e.wheelDelta){ - delta = e.wheelDelta/120; - }else if(e.detail){ - delta = -e.detail/3; - } - return delta; - }, + extend: 'Ext.draw.CompositeSprite', - - within : function(el, related, allowEl){ - if(el){ - var t = this[related ? "getRelatedTarget" : "getTarget"](); - return t && ((allowEl ? (t == Ext.getDom(el)) : false) || Ext.fly(el).contains(t)); - } - return false; - } - }; + requires: ['Ext.chart.Shape'], - return new Ext.EventObjectImpl(); -}(); + + + + x: 0, + y: 0, + zIndex: 500, + + constructor: function(config) { + this.callParent(arguments); + this.createLegend(config); + }, -Ext.Loader = Ext.apply({}, { - load: function(fileList, callback, scope, preserveOrder) { - var scope = scope || this, - head = document.getElementsByTagName("head")[0], - fragment = document.createDocumentFragment(), - numFiles = fileList.length, - loadedFiles = 0, - me = this; + createLegend: function(config) { + var me = this, + index = config.yFieldIndex, + series = me.series, + seriesType = series.type, + idx = me.yFieldIndex, + legend = me.legend, + surface = me.surface, + refX = legend.x + me.x, + refY = legend.y + me.y, + bbox, z = me.zIndex, + markerConfig, label, mask, + radius, toggle = false, + seriesStyle = Ext.apply(series.seriesStyle, series.style); + + function getSeriesProp(name) { + var val = series[name]; + return (Ext.isArray(val) ? val[idx] : val); + } + + label = me.add('label', surface.add({ + type: 'text', + x: 20, + y: 0, + zIndex: z || 0, + font: legend.labelFont, + text: getSeriesProp('title') || getSeriesProp('yField') + })); + + if (seriesType === 'line' || seriesType === 'scatter') { + if(seriesType === 'line') { + me.add('line', surface.add({ + type: 'path', + path: 'M0.5,0.5L16.5,0.5', + zIndex: z, + "stroke-width": series.lineWidth, + "stroke-linejoin": "round", + "stroke-dasharray": series.dash, + stroke: seriesStyle.stroke || '#000', + style: { + cursor: 'pointer' + } + })); + } + if (series.showMarkers || seriesType === 'scatter') { + markerConfig = Ext.apply(series.markerStyle, series.markerConfig || {}); + me.add('marker', Ext.chart.Shape[markerConfig.type](surface, { + fill: markerConfig.fill, + x: 8.5, + y: 0.5, + zIndex: z, + radius: markerConfig.radius || markerConfig.size, + style: { + cursor: 'pointer' + } + })); + } + } - var loadFileIndex = function(index) { - head.appendChild( - me.buildScriptTag(fileList[index], onFileLoaded) - ); - }; + else { + me.add('box', surface.add({ + type: 'rect', + zIndex: z, + x: 0, + y: 0, + width: 12, + height: 12, + fill: series.getLegendColor(index), + style: { + cursor: 'pointer' + } + })); + } + me.setAttributes({ + hidden: false + }, true); - var onFileLoaded = function() { - loadedFiles ++; - - - if (numFiles == loadedFiles && typeof callback == 'function') { - callback.call(scope); - } else { - if (preserveOrder === true) { - loadFileIndex(loadedFiles); - } + bbox = me.getBBox(); + + mask = me.add('mask', surface.add({ + type: 'rect', + x: bbox.x, + y: bbox.y, + width: bbox.width || 20, + height: bbox.height || 20, + zIndex: (z || 0) + 1000, + fill: '#f00', + opacity: 0, + style: { + 'cursor': 'pointer' } - }; + })); + - if (preserveOrder === true) { - loadFileIndex.call(this, 0); - } else { - - Ext.each(fileList, function(file, index) { - fragment.appendChild( - this.buildScriptTag(file, onFileLoaded) - ); - }, this); - - head.appendChild(fragment); - } + me.on('mouseover', function() { + label.setStyle({ + 'font-weight': 'bold' + }); + mask.setStyle({ + 'cursor': 'pointer' + }); + series._index = index; + series.highlightItem(); + }, me); + + me.on('mouseout', function() { + label.setStyle({ + 'font-weight': 'normal' + }); + series._index = index; + series.unHighlightItem(); + }, me); + + if (!series.visibleInLegend(index)) { + toggle = true; + label.setAttributes({ + opacity: 0.5 + }, true); + } + + me.on('mousedown', function() { + if (!toggle) { + series.hideAll(); + label.setAttributes({ + opacity: 0.5 + }, true); + } else { + series.showAll(); + label.setAttributes({ + opacity: 1 + }, true); + } + toggle = !toggle; + }, me); + me.updatePosition({x:0, y:0}); }, + - - buildScriptTag: function(filename, callback) { - var script = document.createElement('script'); - script.type = "text/javascript"; - script.src = filename; - - - if (script.readyState) { - script.onreadystatechange = function() { - if (script.readyState == "loaded" || script.readyState == "complete") { - script.onreadystatechange = null; - callback(); - } - }; - } else { - script.onload = callback; - } - - return script; + updatePosition: function(relativeTo) { + var me = this, + items = me.items, + ln = items.length, + i = 0, + item; + if (!relativeTo) { + relativeTo = me.legend; + } + for (; i < ln; i++) { + item = items[i]; + switch (item.type) { + case 'text': + item.setAttributes({ + x: 20 + relativeTo.x + me.x, + y: relativeTo.y + me.y + }, true); + break; + case 'rect': + item.setAttributes({ + translate: { + x: relativeTo.x + me.x, + y: relativeTo.y + me.y - 6 + } + }, true); + break; + default: + item.setAttributes({ + translate: { + x: relativeTo.x + me.x, + y: relativeTo.y + me.y + } + }, true); + } + } } }); +Ext.define('Ext.chart.Legend', { -Ext.ns("Ext.grid", "Ext.list", "Ext.dd", "Ext.tree", "Ext.form", "Ext.menu", - "Ext.state", "Ext.layout", "Ext.app", "Ext.ux", "Ext.chart", "Ext.direct"); -Ext.apply(Ext, function(){ - var E = Ext, - idSeed = 0, - scrollWidth = null; + requires: ['Ext.chart.LegendItem'], - return { - - emptyFn : function(){}, + - - BLANK_IMAGE_URL : Ext.isIE6 || Ext.isIE7 || Ext.isAir ? - 'http:/' + '/www.extjs.com/s.gif' : - 'data:image/gif;base64,R0lGODlhAQABAID/AMDAwAAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==', + + visible: true, - extendX : function(supr, fn){ - return Ext.extend(supr, fn(supr.prototype)); - }, + + position: 'bottom', - - getDoc : function(){ - return Ext.get(document); - }, + + x: 0, - - num : function(v, defaultValue){ - v = Number(Ext.isEmpty(v) || Ext.isArray(v) || typeof v == 'boolean' || (typeof v == 'string' && v.trim().length == 0) ? NaN : v); - return isNaN(v) ? defaultValue : v; - }, + + y: 0, - - value : function(v, defaultValue, allowBlank){ - return Ext.isEmpty(v, allowBlank) ? defaultValue : v; - }, + + labelFont: '12px Helvetica, sans-serif', - - escapeRe : function(s) { - return s.replace(/([-.*+?^${}()|[\]\/\\])/g, "\\$1"); - }, + + boxStroke: '#000', - sequence : function(o, name, fn, scope){ - o[name] = o[name].createSequence(fn, scope); - }, + + boxStrokeWidth: 1, + + + boxFill: '#FFF', + + + itemSpacing: 10, + + + padding: 5, + + + width: 0, + + height: 0, + + + boxZIndex: 100, + constructor: function(config) { + var me = this; + if (config) { + Ext.apply(me, config); + } + me.items = []; - addBehaviors : function(o){ - if(!Ext.isReady){ - Ext.onReady(function(){ - Ext.addBehaviors(o); + me.isVertical = ("left|right|float".indexOf(me.position) !== -1); + + + me.origX = me.x; + me.origY = me.y; + }, + + + create: function() { + var me = this; + me.createItems(); + if (!me.created && me.isDisplayed()) { + me.createBox(); + me.created = true; + + + me.chart.series.each(function(series) { + series.on('titlechange', function() { + me.create(); + me.updatePosition(); }); - } else { - var cache = {}, - parts, - b, - s; - for (b in o) { - if ((parts = b.split('@'))[1]) { - s = parts[0]; - if(!cache[s]){ - cache[s] = Ext.select(s); - } - cache[s].on(parts[1], o[b]); - } - } - cache = null; - } - }, + }); + } + }, + + + isDisplayed: function() { + return this.visible && this.chart.series.findIndex('showInLegend', true) !== -1; + }, + + + createItems: function() { + var me = this, + chart = me.chart, + surface = chart.surface, + items = me.items, + padding = me.padding, + itemSpacing = me.itemSpacing, + spacingOffset = 2, + maxWidth = 0, + maxHeight = 0, + totalWidth = 0, + totalHeight = 0, + vertical = me.isVertical, + math = Math, + mfloor = math.floor, + mmax = math.max, + index = 0, + i = 0, + len = items ? items.length : 0, + x, y, spacing, item, bbox, height, width; - getScrollBarWidth: function(force){ - if(!Ext.isReady){ - return 0; + if (len) { + for (; i < len; i++) { + items[i].destroy(); } + } + + items.length = []; + + + chart.series.each(function(series, i) { + if (series.showInLegend) { + Ext.each([].concat(series.yField), function(field, j) { + item = Ext.create('Ext.chart.LegendItem', { + legend: this, + series: series, + surface: chart.surface, + yFieldIndex: j + }); + bbox = item.getBBox(); - if(force === true || scrollWidth === null){ - var div = Ext.getBody().createChild('
'), - child = div.child('div', true); - var w1 = child.offsetWidth; - div.setStyle('overflow', (Ext.isWebKit || Ext.isGecko) ? 'auto' : 'scroll'); - var w2 = child.offsetWidth; - div.remove(); - - scrollWidth = w1 - w2 + 2; - } - return scrollWidth; - }, + width = bbox.width; + height = bbox.height; + if (i + j === 0) { + spacing = vertical ? padding + height / 2 : padding; + } + else { + spacing = itemSpacing / (vertical ? 2 : 1); + } + + item.x = mfloor(vertical ? padding : totalWidth + spacing); + item.y = mfloor(vertical ? totalHeight + spacing : padding + height / 2); - - combine : function(){ - var as = arguments, l = as.length, r = []; - for(var i = 0; i < l; i++){ - var a = as[i]; - if(Ext.isArray(a)){ - r = r.concat(a); - }else if(a.length !== undefined && !a.substr){ - r = r.concat(Array.prototype.slice.call(a, 0)); - }else{ - r.push(a); - } - } - return r; - }, + + totalWidth += width + spacing; + totalHeight += height + spacing; + maxWidth = mmax(maxWidth, width); + maxHeight = mmax(maxHeight, height); - - copyTo : function(dest, source, names){ - if(typeof names == 'string'){ - names = names.split(/[,;\s]/); + items.push(item); + }, this); } - Ext.each(names, function(name){ - if(source.hasOwnProperty(name)){ - dest[name] = source[name]; - } - }, this); - return dest; - }, + }, me); - destroy : function(){ - Ext.each(arguments, function(arg){ - if(arg){ - if(Ext.isArray(arg)){ - this.destroy.apply(this, arg); - }else if(typeof arg.destroy == 'function'){ - arg.destroy(); - }else if(arg.dom){ - arg.remove(); - } - } - }, this); - }, + me.width = mfloor((vertical ? maxWidth : totalWidth) + padding * 2); + if (vertical && items.length === 1) { + spacingOffset = 1; + } + me.height = mfloor((vertical ? totalHeight - spacingOffset * spacing : maxHeight) + (padding * 2)); + me.itemHeight = maxHeight; + }, - - destroyMembers : function(o, arg1, arg2, etc){ - for(var i = 1, a = arguments, len = a.length; i < len; i++) { - Ext.destroy(o[a[i]]); - delete o[a[i]]; + + getBBox: function() { + var me = this; + return { + x: Math.round(me.x) - me.boxStrokeWidth / 2, + y: Math.round(me.y) - me.boxStrokeWidth / 2, + width: me.width, + height: me.height + }; + }, + + + 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.redraw(); + }, + + + updatePosition: function() { + var me = this, + x, y, + legendWidth = me.width, + legendHeight = me.height, + padding = me.padding, + chart = me.chart, + chartBBox = chart.chartBBox, + insets = chart.insetPadding, + chartWidth = chartBBox.width - (insets * 2), + chartHeight = chartBBox.height - (insets * 2), + chartX = chartBBox.x + insets, + chartY = chartBBox.y + insets, + surface = chart.surface, + mfloor = Math.floor; + + if (me.isDisplayed()) { + + switch(me.position) { + case "left": + x = insets; + y = mfloor(chartY + chartHeight / 2 - legendHeight / 2); + break; + case "right": + x = mfloor(surface.width - legendWidth) - insets; + y = mfloor(chartY + chartHeight / 2 - legendHeight / 2); + break; + case "top": + x = mfloor(chartX + chartWidth / 2 - legendWidth / 2); + y = insets; + break; + case "bottom": + x = mfloor(chartX + chartWidth / 2 - legendWidth / 2); + y = mfloor(surface.height - legendHeight) - insets; + break; + default: + x = mfloor(me.origX) + insets; + y = mfloor(me.origY) + insets; } - }, + me.x = x; + me.y = y; - - clean : function(arr){ - var ret = []; - Ext.each(arr, function(v){ - if(!!v){ - ret.push(v); - } + + Ext.each(me.items, function(item) { + item.updatePosition(); }); - return ret; - }, + + me.boxSprite.setAttributes(me.getBBox(), true); + } + } +}); - - unique : function(arr){ - var ret = [], - collect = {}; - Ext.each(arr, function(v) { - if(!collect[v]){ - ret.push(v); - } - collect[v] = true; - }); - return ret; - }, +Ext.define('Ext.chart.Chart', { - - flatten : function(arr){ - var worker = []; - function rFlatten(a) { - Ext.each(a, function(v) { - if(Ext.isArray(v)){ - rFlatten(v); - }else{ - worker.push(v); - } - }); - return worker; - } - return rFlatten(arr); - }, + - - min : function(arr, comp){ - var ret = arr[0]; - comp = comp || function(a,b){ return a < b ? -1 : 1; }; - Ext.each(arr, function(v) { - ret = comp(ret, v) == -1 ? ret : v; - }); - return ret; - }, + alias: 'widget.chart', - - max : function(arr, comp){ - var ret = arr[0]; - comp = comp || function(a,b){ return a > b ? 1 : -1; }; - Ext.each(arr, function(v) { - ret = comp(ret, v) == 1 ? ret : v; - }); - return ret; - }, + extend: 'Ext.draw.Component', + + mixins: { + themeManager: 'Ext.chart.theme.Theme', + mask: 'Ext.chart.Mask', + navigation: 'Ext.chart.Navigation' + }, - - mean : function(arr){ - return arr.length > 0 ? Ext.sum(arr) / arr.length : undefined; - }, + requires: [ + 'Ext.util.MixedCollection', + 'Ext.data.StoreManager', + 'Ext.chart.Legend', + 'Ext.util.DelayedTask' + ], - - sum : function(arr){ - var ret = 0; - Ext.each(arr, function(v) { - ret += v; - }); - return ret; - }, + - - partition : function(arr, truth){ - var ret = [[],[]]; - Ext.each(arr, function(v, i, a) { - ret[ (truth && truth(v, i, a)) || (!truth && v) ? 0 : 1].push(v); - }); - return ret; - }, + + viewBox: false, - - invoke : function(arr, methodName){ - var ret = [], - args = Array.prototype.slice.call(arguments, 2); - Ext.each(arr, function(v,i) { - if (v && typeof v[methodName] == 'function') { - ret.push(v[methodName].apply(v, args)); - } else { - ret.push(undefined); - } - }); - return ret; - }, + - - pluck : function(arr, prop){ - var ret = []; - Ext.each(arr, function(v) { - ret.push( v[prop] ); - }); - return ret; - }, + + animate: false, - - zip : function(){ - var parts = Ext.partition(arguments, function( val ){ return typeof val != 'function'; }), - arrs = parts[0], - fn = parts[1][0], - len = Ext.max(Ext.pluck(arrs, "length")), - ret = []; + + legend: false, - for (var i = 0; i < len; i++) { - ret[i] = []; - if(fn){ - ret[i] = fn.apply(fn, Ext.pluck(arrs, i)); - }else{ - for (var j = 0, aLen = arrs.length; j < aLen; j++){ - ret[i].push( arrs[j][i] ); - } - } + + insetPadding: 10, + + + enginePriority: ['Svg', 'Vml'], + + + background: false, + + + + + constructor: function(config) { + var me = this, + defaultAnim; + me.initTheme(config.theme || me.theme); + if (me.gradients) { + Ext.apply(config, { gradients: me.gradients }); + } + if (me.background) { + Ext.apply(config, { background: me.background }); + } + if (config.animate) { + defaultAnim = { + easing: 'ease', + duration: 500 + }; + if (Ext.isObject(config.animate)) { + config.animate = Ext.applyIf(config.animate, defaultAnim); } - return ret; - }, + else { + config.animate = defaultAnim; + } + } + me.mixins.mask.constructor.call(me, config); + me.mixins.navigation.constructor.call(me, config); + me.callParent([config]); + }, + + initComponent: function() { + var me = this, + axes, + series; + me.callParent(); + me.addEvents( + 'itemmousedown', + 'itemmouseup', + 'itemmouseover', + 'itemmouseout', + 'itemclick', + 'itemdoubleclick', + 'itemdragstart', + 'itemdrag', + 'itemdragend', + + 'beforerefresh', + + 'refresh' + ); + Ext.applyIf(me, { + zoom: { + width: 1, + height: 1, + x: 0, + y: 0 + } + }); + me.maxGutter = [0, 0]; + me.store = Ext.data.StoreManager.lookup(me.store); + axes = me.axes; + me.axes = Ext.create('Ext.util.MixedCollection', false, function(a) { return a.position; }); + if (axes) { + me.axes.addAll(axes); + } + series = me.series; + me.series = Ext.create('Ext.util.MixedCollection', false, function(a) { return a.seriesId || (a.seriesId = Ext.id(null, 'ext-chart-series-')); }); + if (series) { + me.series.addAll(series); + } + if (me.legend !== false) { + me.legend = Ext.create('Ext.chart.Legend', Ext.applyIf({chart:me}, me.legend)); + } + + me.on({ + mousemove: me.onMouseMove, + mouseleave: me.onMouseLeave, + mousedown: me.onMouseDown, + mouseup: me.onMouseUp, + scope: me + }); + }, + + + afterComponentLayout: function(width, height) { + var me = this; + if (Ext.isNumber(width) && Ext.isNumber(height)) { + me.curWidth = width; + me.curHeight = height; + me.redraw(true); + } + this.callParent(arguments); + }, + + redraw: function(resize) { + var me = this, + chartBBox = me.chartBBox = { + x: 0, + y: 0, + height: me.curHeight, + width: me.curWidth + }, + legend = me.legend; + me.surface.setSize(chartBBox.width, chartBBox.height); + + me.series.each(me.initializeSeries, me); + me.axes.each(me.initializeAxis, me); - getCmp : function(id){ - return Ext.ComponentMgr.get(id); - }, + + me.axes.each(function(axis) { + axis.processView(); + }); + me.axes.each(function(axis) { + axis.drawAxis(true); + }); - useShims: E.isIE6 || (E.isMac && E.isGecko2), + if (legend !== false) { + legend.create(); + } + me.alignAxes(); + - type : function(o){ - if(o === undefined || o === null){ - return false; - } - if(o.htmlElement){ - return 'element'; - } - var t = typeof o; - if(t == 'object' && o.nodeName) { - switch(o.nodeType) { - case 1: return 'element'; - case 3: return (/\S/).test(o.nodeValue) ? 'textnode' : 'whitespace'; - } - } - if(t == 'object' || t == 'function') { - switch(o.constructor) { - case Array: return 'array'; - case RegExp: return 'regexp'; - case Date: return 'date'; - } - if(typeof o.length == 'number' && typeof o.item == 'function') { - return 'nodelist'; - } - } - return t; - }, + if (me.legend !== false) { + legend.updatePosition(); + } - intercept : function(o, name, fn, scope){ - o[name] = o[name].createInterceptor(fn, scope); - }, + + me.getMaxGutter(); - callback : function(cb, scope, args, delay){ - if(typeof cb == 'function'){ - if(delay){ - cb.defer(delay, scope, args || []); - }else{ - cb.apply(scope, args || []); - } - } - } - }; -}()); + me.resizing = !!resize; + me.axes.each(me.drawAxis, me); + me.series.each(me.drawCharts, me); + me.resizing = false; + }, -Ext.apply(Function.prototype, { - createSequence : function(fcn, scope){ - var method = this; - return (typeof fcn != 'function') ? - this : - function(){ - var retval = method.apply(this || window, arguments); - fcn.apply(scope || this || window, arguments); - return retval; - }; - } -}); - + afterRender: function() { + var ref, + me = this; + this.callParent(); + if (me.categoryNames) { + me.setCategoryNames(me.categoryNames); + } -Ext.applyIf(String, { + if (me.tipRenderer) { + ref = me.getFunctionRef(me.tipRenderer); + me.setTipRenderer(ref.fn, ref.scope); + } + me.bindStore(me.store, true); + me.refresh(); + }, - escape : function(string) { - return string.replace(/('|\\)/g, "\\$1"); + getEventXY: function(e) { + var me = this, + box = this.surface.getRegion(), + pageXY = e.getXY(), + x = pageXY[0] - box.left, + y = pageXY[1] - box.top; + return [x, y]; }, - leftPad : function (val, size, ch) { - var result = String(val); - if(!ch) { - ch = " "; - } - while (result.length < size) { - result = ch + result; - } - return result; - } -}); + onClick: function(e) { + var me = this, + position = me.getEventXY(e), + item; + + + me.series.each(function(series) { + if (Ext.draw.Draw.withinBox(position[0], position[1], series.bbox)) { + if (series.getItemForPoint) { + item = series.getItemForPoint(position[0], position[1]); + if (item) { + series.fireEvent('itemclick', item); + } + } + } + }, me); + }, -String.prototype.toggle = function(value, other){ - return this == value ? other : value; -}; + + onMouseDown: function(e) { + var me = this, + position = me.getEventXY(e), + item; + if (me.mask) { + me.mixins.mask.onMouseDown.call(me, e); + } + + + me.series.each(function(series) { + if (Ext.draw.Draw.withinBox(position[0], position[1], series.bbox)) { + if (series.getItemForPoint) { + item = series.getItemForPoint(position[0], position[1]); + if (item) { + series.fireEvent('itemmousedown', item); + } + } + } + }, me); + }, -String.prototype.trim = function(){ - var re = /^\s+|\s+$/g; - return function(){ return this.replace(re, ""); }; -}(); + + onMouseUp: function(e) { + var me = this, + position = me.getEventXY(e), + item; + if (me.mask) { + me.mixins.mask.onMouseUp.call(me, e); + } + + + me.series.each(function(series) { + if (Ext.draw.Draw.withinBox(position[0], position[1], series.bbox)) { + if (series.getItemForPoint) { + item = series.getItemForPoint(position[0], position[1]); + if (item) { + series.fireEvent('itemmouseup', item); + } + } + } + }, me); + }, + + onMouseMove: function(e) { + var me = this, + position = me.getEventXY(e), + item, last, storeItem, storeField; -Date.prototype.getElapsed = function(date) { - return Math.abs((date || new Date()).getTime()-this.getTime()); -}; + if (me.mask) { + me.mixins.mask.onMouseMove.call(me, e); + } + + + me.series.each(function(series) { + if (Ext.draw.Draw.withinBox(position[0], position[1], series.bbox)) { + if (series.getItemForPoint) { + item = series.getItemForPoint(position[0], position[1]); + last = series._lastItemForPoint; + storeItem = series._lastStoreItem; + storeField = series._lastStoreField; + if (item !== last || item && (item.storeItem != storeItem || item.storeField != storeField)) { + if (last) { + series.fireEvent('itemmouseout', last); + delete series._lastItemForPoint; + delete series._lastStoreField; + delete series._lastStoreItem; + } + if (item) { + series.fireEvent('itemmouseover', item); + series._lastItemForPoint = item; + series._lastStoreItem = item.storeItem; + series._lastStoreField = item.storeField; + } + } + } + } else { + last = series._lastItemForPoint; + if (last) { + series.fireEvent('itemmouseout', last); + delete series._lastItemForPoint; + delete series._lastStoreField; + delete series._lastStoreItem; + } + } + }, me); + }, -Ext.applyIf(Number.prototype, { - constrain : function(min, max){ - return Math.min(Math.max(this, min), max); - } -}); -Ext.lib.Dom.getRegion = function(el) { - return Ext.lib.Region.getRegion(el); -}; Ext.lib.Region = function(t, r, b, l) { - var me = this; - me.top = t; - me[1] = t; - me.right = r; - me.bottom = b; - me.left = l; - me[0] = l; - }; - - Ext.lib.Region.prototype = { - contains : function(region) { - var me = this; - return ( region.left >= me.left && - region.right <= me.right && - region.top >= me.top && - region.bottom <= me.bottom ); - - }, + onMouseLeave: function(e) { + var me = this; + if (me.mask) { + me.mixins.mask.onMouseLeave.call(me, e); + } + me.series.each(function(series) { + delete series._lastItemForPoint; + }); + }, - getArea : function() { - var me = this; - return ( (me.bottom - me.top) * (me.right - me.left) ); - }, + + delayRefresh: function() { + var me = this; + if (!me.refreshTask) { + me.refreshTask = Ext.create('Ext.util.DelayedTask', me.refresh, me); + } + me.refreshTask.delay(me.refreshBuffer); + }, - intersect : function(region) { - var me = this, - t = Math.max(me.top, region.top), - r = Math.min(me.right, region.right), - b = Math.min(me.bottom, region.bottom), - l = Math.max(me.left, region.left); + + refresh: function() { + var me = this; + if (me.rendered && me.curWidth != undefined && me.curHeight != undefined) { + if (me.fireEvent('beforerefresh', me) !== false) { + me.redraw(); + me.fireEvent('refresh', me); + } + } + }, - if (b >= t && r >= l) { - return new Ext.lib.Region(t, r, b, l); + + bindStore: function(store, initial) { + var me = this; + if (!initial && me.store) { + if (store !== me.store && me.store.autoDestroy) { + me.store.destroy(); } - }, - - union : function(region) { - var me = this, - t = Math.min(me.top, region.top), - r = Math.max(me.right, region.right), - b = Math.max(me.bottom, region.bottom), - l = Math.min(me.left, region.left); + else { + me.store.un('datachanged', me.refresh, me); + me.store.un('add', me.delayRefresh, me); + me.store.un('remove', me.delayRefresh, me); + me.store.un('update', me.delayRefresh, me); + me.store.un('clear', me.refresh, me); + } + } + if (store) { + store = Ext.data.StoreManager.lookup(store); + store.on({ + scope: me, + datachanged: me.refresh, + add: me.delayRefresh, + remove: me.delayRefresh, + update: me.delayRefresh, + clear: me.refresh + }); + } + me.store = store; + if (store && !initial) { + me.refresh(); + } + }, - return new Ext.lib.Region(t, r, b, l); - }, + + initializeAxis: function(axis) { + var me = this, + chartBBox = me.chartBBox, + w = chartBBox.width, + h = chartBBox.height, + x = chartBBox.x, + y = chartBBox.y, + themeAttrs = me.themeAttrs, + config = { + chart: me + }; + if (themeAttrs) { + config.axisStyle = Ext.apply({}, themeAttrs.axis); + config.axisLabelLeftStyle = Ext.apply({}, themeAttrs.axisLabelLeft); + config.axisLabelRightStyle = Ext.apply({}, themeAttrs.axisLabelRight); + config.axisLabelTopStyle = Ext.apply({}, themeAttrs.axisLabelTop); + config.axisLabelBottomStyle = Ext.apply({}, themeAttrs.axisLabelBottom); + config.axisTitleLeftStyle = Ext.apply({}, themeAttrs.axisTitleLeft); + config.axisTitleRightStyle = Ext.apply({}, themeAttrs.axisTitleRight); + config.axisTitleTopStyle = Ext.apply({}, themeAttrs.axisTitleTop); + config.axisTitleBottomStyle = Ext.apply({}, themeAttrs.axisTitleBottom); + } + switch (axis.position) { + case 'top': + Ext.apply(config, { + length: w, + width: h, + x: x, + y: y + }); + break; + case 'bottom': + Ext.apply(config, { + length: w, + width: h, + x: x, + y: h + }); + break; + case 'left': + Ext.apply(config, { + length: h, + width: w, + x: x, + y: h + }); + break; + case 'right': + Ext.apply(config, { + length: h, + width: w, + x: w, + y: h + }); + break; + } + if (!axis.chart) { + Ext.apply(config, axis); + axis = me.axes.replace(Ext.createByAlias('axis.' + axis.type.toLowerCase(), config)); + } + else { + Ext.apply(axis, config); + } + }, - constrainTo : function(r) { - var me = this; - me.top = me.top.constrain(r.top, r.bottom); - me.bottom = me.bottom.constrain(r.top, r.bottom); - me.left = me.left.constrain(r.left, r.right); - me.right = me.right.constrain(r.left, r.right); - return me; - }, - adjust : function(t, l, b, r) { - var me = this; - me.top += t; - me.left += l; - me.right += r; - me.bottom += b; - return me; + + alignAxes: function() { + var me = this, + axes = me.axes, + legend = me.legend, + edges = ['top', 'right', 'bottom', 'left'], + chartBBox, + insetPadding = me.insetPadding, + insets = { + top: insetPadding, + right: insetPadding, + bottom: insetPadding, + left: insetPadding + }; + + function getAxis(edge) { + var i = axes.findIndex('position', edge); + return (i < 0) ? null : axes.getAt(i); } - }; - Ext.lib.Region.getRegion = function(el) { - var p = Ext.lib.Dom.getXY(el), - t = p[1], - r = p[0] + el.offsetWidth, - b = p[1] + el.offsetHeight, - l = p[0]; + + Ext.each(edges, function(edge) { + var isVertical = (edge === 'left' || edge === 'right'), + axis = getAxis(edge), + bbox; - return new Ext.lib.Region(t, r, b, l); - }; Ext.lib.Point = function(x, y) { - if (Ext.isArray(x)) { - y = x[1]; - x = x[0]; - } - var me = this; - me.x = me.right = me.left = me[0] = x; - me.y = me.top = me.bottom = me[1] = y; - }; + + if (legend !== false) { + if (legend.position === edge) { + bbox = legend.getBBox(); + insets[edge] += (isVertical ? bbox.width : bbox.height) + insets[edge]; + } + } + + + + if (axis && axis.bbox) { + bbox = axis.bbox; + insets[edge] += (isVertical ? bbox.width : bbox.height); + } + }); + + chartBBox = { + x: insets.left, + y: insets.top, + width: me.curWidth - insets.left - insets.right, + height: me.curHeight - insets.top - insets.bottom + }; + me.chartBBox = chartBBox; - Ext.lib.Point.prototype = new Ext.lib.Region(); + + + axes.each(function(axis) { + var pos = axis.position, + isVertical = (pos === 'left' || pos === 'right'); -Ext.apply(Ext.DomHelper, -function(){ - var pub, - afterbegin = 'afterbegin', - afterend = 'afterend', - beforebegin = 'beforebegin', - beforeend = 'beforeend', - confRe = /tag|children|cn|html$/i; + axis.x = (pos === 'right' ? chartBBox.x + chartBBox.width : chartBBox.x); + axis.y = (pos === 'top' ? chartBBox.y : chartBBox.y + chartBBox.height); + axis.width = (isVertical ? chartBBox.width : chartBBox.height); + axis.length = (isVertical ? chartBBox.height : chartBBox.width); + }); + }, - function doInsert(el, o, returnElement, pos, sibling, append){ - el = Ext.getDom(el); - var newNode; - if (pub.useDom) { - newNode = createDom(o, null); - if (append) { - el.appendChild(newNode); + initializeSeries: function(series, idx) { + var me = this, + themeAttrs = me.themeAttrs, + seriesObj, markerObj, seriesThemes, st, + markerThemes, colorArrayStyle = [], + i = 0, l, + config = { + chart: me, + seriesId: series.seriesId + }; + if (themeAttrs) { + seriesThemes = themeAttrs.seriesThemes; + markerThemes = themeAttrs.markerThemes; + seriesObj = Ext.apply({}, themeAttrs.series); + markerObj = Ext.apply({}, themeAttrs.marker); + config.seriesStyle = Ext.apply(seriesObj, seriesThemes[idx % seriesThemes.length]); + config.seriesLabelStyle = Ext.apply({}, themeAttrs.seriesLabel); + config.markerStyle = Ext.apply(markerObj, markerThemes[idx % markerThemes.length]); + if (themeAttrs.colors) { + config.colorArrayStyle = themeAttrs.colors; } else { - (sibling == 'firstChild' ? el : el.parentNode).insertBefore(newNode, el[sibling] || el); + colorArrayStyle = []; + for (l = seriesThemes.length; i < l; i++) { + st = seriesThemes[i]; + if (st.fill || st.stroke) { + colorArrayStyle.push(st.fill || st.stroke); + } + } + if (colorArrayStyle.length) { + config.colorArrayStyle = colorArrayStyle; + } } + config.seriesIdx = idx; + } + if (series instanceof Ext.chart.series.Series) { + Ext.apply(series, config); } else { - newNode = Ext.DomHelper.insertHtml(pos, el, Ext.DomHelper.createHtml(o)); + Ext.applyIf(config, series); + series = me.series.replace(Ext.createByAlias('series.' + series.type.toLowerCase(), config)); } - return returnElement ? Ext.get(newNode, true) : newNode; - } + if (series.initialize) { + series.initialize(); + } + }, - - function createDom(o, parentNode){ - var el, - doc = document, - useSet, - attr, - val, - cn; + getMaxGutter: function() { + var me = this, + maxGutter = [0, 0]; + me.series.each(function(s) { + var gutter = s.getGutters && s.getGutters() || [0, 0]; + maxGutter[0] = Math.max(maxGutter[0], gutter[0]); + maxGutter[1] = Math.max(maxGutter[1], gutter[1]); + }); + me.maxGutter = maxGutter; + }, - if (Ext.isArray(o)) { - el = doc.createDocumentFragment(); - for (var i = 0, l = o.length; i < l; i++) { - createDom(o[i], el); - } - } else if (typeof o == 'string') { - el = doc.createTextNode(o); - } else { - el = doc.createElement( o.tag || 'div' ); - useSet = !!el.setAttribute; - for (var attr in o) { - if(!confRe.test(attr)){ - val = o[attr]; - if(attr == 'cls'){ - el.className = val; - }else{ - if(useSet){ - el.setAttribute(attr, val); - }else{ - el[attr] = val; - } - } - } - } - Ext.DomHelper.applyStyles(el, o.style); + + drawAxis: function(axis) { + axis.drawAxis(); + }, - if ((cn = o.children || o.cn)) { - createDom(cn, el); - } else if (o.html) { - el.innerHTML = o.html; - } - } - if(parentNode){ - parentNode.appendChild(el); + + drawCharts: function(series) { + series.triggerafterrender = false; + series.drawSeries(); + if (!this.animate) { + series.fireEvent('afterrender'); } - return el; + }, + + + destroy: function() { + this.surface.destroy(); + this.bindStore(null); + this.callParent(arguments); } +}); - pub = { - - createTemplate : function(o){ - var html = Ext.DomHelper.createHtml(o); - return new Ext.Template(html); - }, - - useDom : false, +Ext.define('Ext.chart.Highlight', { - - insertBefore : function(el, o, returnElement){ - return doInsert(el, o, returnElement, beforebegin); - }, + - - insertAfter : function(el, o, returnElement){ - return doInsert(el, o, returnElement, afterend, 'nextSibling'); - }, + requires: ['Ext.fx.Anim'], - - insertFirst : function(el, o, returnElement){ - return doInsert(el, o, returnElement, afterbegin, 'firstChild'); - }, + - - append: function(el, o, returnElement){ - return doInsert(el, o, returnElement, beforeend, '', true); - }, + + highlight: false, - - createDom: createDom - }; - return pub; -}()); + highlightCfg : null, -Ext.apply(Ext.Template.prototype, { - - disableFormats : false, - + constructor: function(config) { + if (config.highlight) { + if (config.highlight !== true) { + this.highlightCfg = Ext.apply({}, config.highlight); + } + else { + this.highlightCfg = { + fill: '#fdd', + radius: 20, + lineWidth: 5, + stroke: '#f55' + }; + } + } + }, - re : /\{([\w-]+)(?:\:([\w\.]*)(?:\((.*?)?\))?)?\}/g, - argsRe : /^\s*['"](.*)["']\s*$/, - compileARe : /\\/g, - compileBRe : /(\r\n|\n)/g, - compileCRe : /'/g, - - /** - * Returns an HTML fragment of this template with the specified values applied. - * @param {Object/Array} values The template values. Can be an array if your params are numeric (i.e. {0}) or an object (i.e. {foo: 'bar'}) - * @return {String} The HTML fragment - * @hide repeat doc - */ - applyTemplate : function(values){ + highlightItem: function(item) { + if (!item) { + return; + } + var me = this, - useF = me.disableFormats !== true, - fm = Ext.util.Format, - tpl = me; - - if(me.compiled){ - return me.compiled(values); + sprite = item.sprite, + opts = me.highlightCfg, + surface = me.chart.surface, + animate = me.chart.animate, + p, + from, + to, + pi; + + if (!me.highlight || !sprite || sprite._highlighted) { + return; } - function fn(m, name, format, args){ - if (format && useF) { - if (format.substr(0, 5) == "this.") { - return tpl.call(format.substr(5), values[name], values); - } else { - if (args) { - // quoted values are required for strings in compiled templates, - // but for non compiled we need to strip them - // quoted reversed for jsmin - var re = me.argsRe; - args = args.split(','); - for(var i = 0, len = args.length; i < len; i++){ - args[i] = args[i].replace(re, "$1"); + if (sprite._anim) { + sprite._anim.paused = true; + } + sprite._highlighted = true; + if (!sprite._defaults) { + sprite._defaults = Ext.apply(sprite._defaults || {}, + sprite.attr); + from = {}; + to = {}; + for (p in opts) { + if (! (p in sprite._defaults)) { + sprite._defaults[p] = surface.availableAttrs[p]; + } + from[p] = sprite._defaults[p]; + to[p] = opts[p]; + if (Ext.isObject(opts[p])) { + from[p] = {}; + to[p] = {}; + Ext.apply(sprite._defaults[p], sprite.attr[p]); + Ext.apply(from[p], sprite._defaults[p]); + for (pi in sprite._defaults[p]) { + if (! (pi in opts[p])) { + to[p][pi] = from[p][pi]; + } else { + to[p][pi] = opts[p][pi]; + } + } + for (pi in opts[p]) { + if (! (pi in to[p])) { + to[p][pi] = opts[p][pi]; } - args = [values[name]].concat(args); - } else { - args = [values[name]]; } - return fm[format].apply(fm, args); } - } else { - return values[name] !== undefined ? values[name] : ""; } + sprite._from = from; + sprite._to = to; + } + if (animate) { + sprite._anim = Ext.create('Ext.fx.Anim', { + target: sprite, + from: sprite._from, + to: sprite._to, + duration: 150 + }); + } else { + sprite.setAttributes(sprite._to, true); } - return me.html.replace(me.re, fn); }, - /** - * Compiles the template into an internal function, eliminating the RegEx overhead. - * @return {Ext.Template} this - * @hide repeat doc - */ - compile : function(){ + + unHighlightItem: function() { + if (!this.highlight || !this.items) { + return; + } + var me = this, - fm = Ext.util.Format, - useF = me.disableFormats !== true, - sep = Ext.isGecko ? "+" : ",", - body; + items = me.items, + len = items.length, + opts = me.highlightCfg, + animate = me.chart.animate, + i = 0, + obj, + p, + sprite; - function fn(m, name, format, args){ - if(format && useF){ - args = args ? ',' + args : ""; - if(format.substr(0, 5) != "this."){ - format = "fm." + format + '('; - }else{ - format = 'this.call("'+ format.substr(5) + '", '; - args = ", values"; + for (; i < len; i++) { + if (!items[i]) { + continue; + } + sprite = items[i].sprite; + if (sprite && sprite._highlighted) { + if (sprite._anim) { + sprite._anim.paused = true; } - }else{ - args= ''; format = "(values['" + name + "'] == undefined ? '' : "; + obj = {}; + for (p in opts) { + if (Ext.isObject(sprite._defaults[p])) { + obj[p] = {}; + Ext.apply(obj[p], sprite._defaults[p]); + } + else { + obj[p] = sprite._defaults[p]; + } + } + if (animate) { + sprite._anim = Ext.create('Ext.fx.Anim', { + target: sprite, + to: obj, + duration: 150 + }); + } + else { + sprite.setAttributes(obj, true); + } + delete sprite._highlighted; + } - return "'"+ sep + format + "values['" + name + "']" + args + ")"+sep+"'"; } + }, - // branched to use + in gecko and [].join() in others - if(Ext.isGecko){ - body = "this.compiled = function(values){ return '" + - me.html.replace(me.compileARe, '\\\\').replace(me.compileBRe, '\\n').replace(me.compileCRe, "\\'").replace(me.re, fn) + - "';};"; - }else{ - body = ["this.compiled = function(values){ return ['"]; - body.push(me.html.replace(me.compileARe, '\\\\').replace(me.compileBRe, '\\n').replace(me.compileCRe, "\\'").replace(me.re, fn)); - body.push("'].join('');};"); - body = body.join(''); + cleanHighlights: function() { + if (!this.highlight) { + return; } - eval(body); - return me; - }, - // private function used to call members - call : function(fnName, value, allValues){ - return this[fnName](value, allValues); + var group = this.group, + markerGroup = this.markerGroup, + i = 0, + l; + for (l = group.getCount(); i < l; i++) { + delete group.getAt(i)._defaults; + } + if (markerGroup) { + for (l = markerGroup.getCount(); i < l; i++) { + delete markerGroup.getAt(i)._defaults; + } + } } }); -Ext.Template.prototype.apply = Ext.Template.prototype.applyTemplate; -/** - * @class Ext.util.Functions - * @singleton - */ -Ext.util.Functions = { - /** - * Creates an interceptor function. The passed function is called before the original one. If it returns false, - * the original one is not called. The resulting function returns the results of the original function. - * The passed function is called with the parameters of the original function. Example usage: - *

-var sayHi = function(name){
-    alert('Hi, ' + name);
-}
 
-sayHi('Fred'); // alerts "Hi, Fred"
+Ext.define('Ext.chart.Label', {
 
-// create a new function that validates input without
-// directly modifying the original function:
-var sayHiToFriend = Ext.createInterceptor(sayHi, function(name){
-    return name == 'Brian';
-});
+    
 
-sayHiToFriend('Fred');  // no alert
-sayHiToFriend('Brian'); // alerts "Hi, Brian"
-       
- * @param {Function} origFn The original function. - * @param {Function} newFn The function to call before the original - * @param {Object} scope (optional) The scope (this reference) in which the passed function is executed. - * If omitted, defaults to the scope in which the original function is called or the browser window. - * @return {Function} The new function - */ - createInterceptor: function(origFn, newFn, scope) { - var method = origFn; - if (!Ext.isFunction(newFn)) { - return origFn; - } - else { - return function() { - var me = this, - args = arguments; - newFn.target = me; - newFn.method = origFn; - return (newFn.apply(scope || me || window, args) !== false) ? - origFn.apply(me || window, args) : - null; - }; - } - }, + requires: ['Ext.draw.Color'], + + - /** - * Creates a delegate (callback) that sets the scope to obj. - * Call directly on any function. Example: Ext.createDelegate(this.myFunction, this, [arg1, arg2]) - * Will create a function that is automatically scoped to obj so that the this variable inside the - * callback points to obj. Example usage: - *

-var sayHi = function(name){
-    // Note this use of "this.text" here.  This function expects to
-    // execute within a scope that contains a text property.  In this
-    // example, the "this" variable is pointing to the btn object that
-    // was passed in createDelegate below.
-    alert('Hi, ' + name + '. You clicked the "' + this.text + '" button.');
-}
+    
 
-var btn = new Ext.Button({
-    text: 'Say Hi',
-    renderTo: Ext.getBody()
-});
-
-// This callback will execute in the scope of the
-// button instance. Clicking the button alerts
-// "Hi, Fred. You clicked the "Say Hi" button."
-btn.on('click', Ext.createDelegate(sayHi, btn, ['Fred']));
-       
- * @param {Function} fn The function to delegate. - * @param {Object} scope (optional) The scope (this reference) in which the function is executed. - * If omitted, defaults to the browser window. - * @param {Array} args (optional) Overrides arguments for the call. (Defaults to the arguments passed by the caller) - * @param {Boolean/Number} appendArgs (optional) if True args are appended to call args instead of overriding, - * if a number the args are inserted at the specified position - * @return {Function} The new function - */ - createDelegate: function(fn, obj, args, appendArgs) { - if (!Ext.isFunction(fn)) { - return fn; - } - return function() { - var callArgs = args || arguments; - if (appendArgs === true) { - callArgs = Array.prototype.slice.call(arguments, 0); - callArgs = callArgs.concat(args); - } - else if (Ext.isNumber(appendArgs)) { - callArgs = Array.prototype.slice.call(arguments, 0); - // copy arguments first - var applyArgs = [appendArgs, 0].concat(args); - // create method call params - Array.prototype.splice.apply(callArgs, applyArgs); - // splice them in - } - return fn.apply(obj || window, callArgs); - }; - }, + - /** - * Calls this function after the number of millseconds specified, optionally in a specific scope. Example usage: - *

-var sayHi = function(name){
-    alert('Hi, ' + name);
-}
+    
 
-// executes immediately:
-sayHi('Fred');
-
-// executes after 2 seconds:
-Ext.defer(sayHi, 2000, this, ['Fred']);
-
-// this syntax is sometimes useful for deferring
-// execution of an anonymous function:
-Ext.defer(function(){
-    alert('Anonymous');
-}, 100);
-       
- * @param {Function} fn The function to defer. - * @param {Number} millis The number of milliseconds for the setTimeout call (if less than or equal to 0 the function is executed immediately) - * @param {Object} scope (optional) The scope (this reference) in which the function is executed. - * If omitted, defaults to the browser window. - * @param {Array} args (optional) Overrides arguments for the call. (Defaults to the arguments passed by the caller) - * @param {Boolean/Number} appendArgs (optional) if True args are appended to call args instead of overriding, - * if a number the args are inserted at the specified position - * @return {Number} The timeout id that can be used with clearTimeout - */ - defer: function(fn, millis, obj, args, appendArgs) { - fn = Ext.util.Functions.createDelegate(fn, obj, args, appendArgs); - if (millis > 0) { - return setTimeout(fn, millis); - } - fn(); - return 0; - }, + + - /** - * Create a combined function call sequence of the original function + the passed function. - * The resulting function returns the results of the original function. - * The passed fcn is called with the parameters of the original function. Example usage: - * + -var sayHi = function(name){ - alert('Hi, ' + name); -} + -sayHi('Fred'); // alerts "Hi, Fred" + //@private a regex to parse url type colors. -var sayGoodbye = Ext.createSequence(sayHi, function(name){ - alert('Bye, ' + name); -}); + colorStringRe: /url\s*\(\s*#([^\/)]+)\s*\)/, + + //@private the mixin constructor. Used internally by Series. -sayGoodbye('Fred'); // both alerts show + constructor: function(config) { + var me = this; + me.label = Ext.applyIf(me.label || {}, + { + display: "none", + color: "#000", + field: "name", + minMargin: 50, + font: "11px Helvetica, sans-serif", + orientation: "horizontal", + renderer: function(v) { + return v; + } + }); - * @param {Function} origFn The original function. - * @param {Function} newFn The function to sequence - * @param {Object} scope (optional) The scope (this reference) in which the passed function is executed. - * If omitted, defaults to the scope in which the original function is called or the browser window. - * @return {Function} The new function - */ - createSequence: function(origFn, newFn, scope) { - if (!Ext.isFunction(newFn)) { - return origFn; - } - else { - return function() { - var retval = origFn.apply(this || window, arguments); - newFn.apply(scope || this || window, arguments); - return retval; - }; + if (me.label.display !== 'none') { + me.labelsGroup = me.chart.surface.getGroup(me.seriesId + '-labels'); } - } -}; - -/** - * Shorthand for {@link Ext.util.Functions#defer} - * @param {Function} fn The function to defer. - * @param {Number} millis The number of milliseconds for the setTimeout call (if less than or equal to 0 the function is executed immediately) - * @param {Object} scope (optional) The scope (this reference) in which the function is executed. - * If omitted, defaults to the browser window. - * @param {Array} args (optional) Overrides arguments for the call. (Defaults to the arguments passed by the caller) - * @param {Boolean/Number} appendArgs (optional) if True args are appended to call args instead of overriding, - * if a number the args are inserted at the specified position - * @return {Number} The timeout id that can be used with clearTimeout - * @member Ext - * @method defer - */ - -Ext.defer = Ext.util.Functions.defer; + }, -/** - * Shorthand for {@link Ext.util.Functions#createInterceptor} - * @param {Function} origFn The original function. - * @param {Function} newFn The function to call before the original - * @param {Object} scope (optional) The scope (this reference) in which the passed function is executed. - * If omitted, defaults to the scope in which the original function is called or the browser window. - * @return {Function} The new function - * @member Ext - * @method defer - */ + //@private a method to render all labels in the labelGroup -Ext.createInterceptor = Ext.util.Functions.createInterceptor; + renderLabels: function() { + var me = this, + chart = me.chart, + gradients = chart.gradients, + gradient, + items = me.items, + animate = chart.animate, + config = me.label, + display = config.display, + color = config.color, + field = [].concat(config.field), + group = me.labelsGroup, + 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, + Color = Ext.draw.Color, + colorString; + + if (display == 'none') { + return; + } -/** - * Shorthand for {@link Ext.util.Functions#createSequence} - * @param {Function} origFn The original function. - * @param {Function} newFn The function to sequence - * @param {Object} scope (optional) The scope (this reference) in which the passed function is executed. - * If omitted, defaults to the scope in which the original function is called or the browser window. - * @return {Function} The new function - * @member Ext - * @method defer - */ + 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); -Ext.createSequence = Ext.util.Functions.createSequence; + if (!item && label) { + label.hide(true); + } -/** - * Shorthand for {@link Ext.util.Functions#createDelegate} - * @param {Function} fn The function to delegate. - * @param {Object} scope (optional) The scope (this reference) in which the function is executed. - * If omitted, defaults to the browser window. - * @param {Array} args (optional) Overrides arguments for the call. (Defaults to the arguments passed by the caller) - * @param {Boolean/Number} appendArgs (optional) if True args are appended to call args instead of overriding, - * if a number the args are inserted at the specified position - * @return {Function} The new function - * @member Ext - * @method defer - */ -Ext.createDelegate = Ext.util.Functions.createDelegate; -/** - * @class Ext.util.Observable - */ -Ext.apply(Ext.util.Observable.prototype, function(){ - // this is considered experimental (along with beforeMethod, afterMethod, removeMethodListener?) - // allows for easier interceptor and sequences, including cancelling and overwriting the return value of the call - // private - function getMethodEvent(method){ - var e = (this.methodEvents = this.methodEvents || - {})[method], returnValue, v, cancel, obj = this; - - if (!e) { - this.methodEvents[method] = e = {}; - e.originalFn = this[method]; - e.methodName = method; - e.before = []; - e.after = []; - - var makeCall = function(fn, scope, args){ - if((v = fn.apply(scope || obj, args)) !== undefined){ - if (typeof v == 'object') { - if(v.returnValue !== undefined){ - returnValue = v.returnValue; - }else{ - returnValue = v; - } - cancel = !!v.cancel; + if (item && field[j]) { + if (!label) { + label = me.onCreateLabel(storeItem, item, i, display, j, count); } - else - if (v === false) { - cancel = true; + 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 (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; + } + } } else { - returnValue = v; + spriteBrightness = spriteColor.getGrayscale() / 255; } - } - }; - - this[method] = function(){ - var args = Array.prototype.slice.call(arguments, 0), - b; - returnValue = v = undefined; - cancel = false; - - for(var i = 0, len = e.before.length; i < len; i++){ - b = e.before[i]; - makeCall(b.fn, b.scope, args); - if (cancel) { - return returnValue; - } - } - - if((v = e.originalFn.apply(obj, args)) !== undefined){ - returnValue = v; - } - - for(var i = 0, len = e.after.length; i < len; i++){ - b = e.after[i]; - makeCall(b.fn, b.scope, args); - if (cancel) { - return returnValue; + 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); } } - return returnValue; - }; + count++; + } } - return e; - } - - return { - // these are considered experimental - // allows for easier interceptor and sequences, including cancelling and overwriting the return value of the call - // adds an 'interceptor' called before the original method - beforeMethod : function(method, fn, scope){ - getMethodEvent.call(this, method).before.push({ - fn: fn, - scope: scope - }); - }, + me.hideLabels(count); + }, - // adds a 'sequence' called after the original method - afterMethod : function(method, fn, scope){ - getMethodEvent.call(this, method).after.push({ - fn: fn, - scope: scope - }); - }, + //@private a method to hide labels. - removeMethodListener: function(method, fn, scope){ - var e = this.getMethodEvent(method); - for(var 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); - return; - } - } - for(var 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); - return; - } + hideLabels: function(index) { + var labelsGroup = this.labelsGroup, len; + if (labelsGroup) { + len = labelsGroup.getCount(); + while (len-->index) { + labelsGroup.getAt(len).hide(true); } - }, + } + } +}); +Ext.define('Ext.chart.MaskLayer', { + extend: 'Ext.Component', + + constructor: function(config) { + config = Ext.apply(config || {}, { + style: 'position:absolute;background-color:#888;cursor:move;opacity:0.6;border:1px solid #222;' + }); + this.callParent([config]); + }, + + initComponent: function() { + var me = this; + me.callParent(arguments); + me.addEvents( + 'mousedown', + 'mouseup', + 'mousemove', + 'mouseenter', + 'mouseleave' + ); + }, - /** - * Relays selected events from the specified Observable as if the events were fired by this. - * @param {Object} o The Observable whose events this object is to relay. - * @param {Array} events Array of event names to relay. - */ - relayEvents : function(o, events){ - var me = this; - function createHandler(ename){ - return function(){ - return me.fireEvent.apply(me, [ename].concat(Array.prototype.slice.call(arguments, 0))); - }; + initDraggable: function() { + this.callParent(arguments); + this.dd.onStart = function (e) { + var me = this, + comp = me.comp; + + + this.startPosition = comp.getPosition(true); + + + + if (comp.ghost && !comp.liveDrag) { + me.proxy = comp.ghost(); + me.dragTarget = me.proxy.header.el; } - for(var i = 0, len = events.length; i < len; i++){ - var ename = events[i]; - me.events[ename] = me.events[ename] || true; - o.on(ename, createHandler(ename), me); + + + if (me.constrain || me.constrainDelegate) { + me.constrainTo = me.calculateConstrainRegion(); } - }, + }; + } +}); + +Ext.define('Ext.chart.TipSurface', { - /** - *

Enables events fired by this Observable to bubble up an owner hierarchy by calling - * this.getBubbleTarget() if present. There is no implementation in the Observable base class.

- *

This is commonly used by Ext.Components to bubble events to owner Containers. See {@link Ext.Component.getBubbleTarget}. The default - * implementation in Ext.Component returns the Component's immediate owner. But if a known target is required, this can be overridden to - * access the required target more quickly.

- *

Example:


-Ext.override(Ext.form.Field, {
     
-    initComponent : Ext.form.Field.prototype.initComponent.createSequence(function() {
-        this.enableBubble('change');
-    }),
+
+    extend: 'Ext.draw.Component',
 
     
-    getBubbleTarget : function() {
-        if (!this.formPanel) {
-            this.formPanel = this.findParentByType('form');
+
+    spriteArray: false,
+    renderFirst: true,
+
+    constructor: function(config) {
+        this.callParent([config]);
+        if (config.sprites) {
+            this.spriteArray = [].concat(config.sprites);
+            delete config.sprites;
         }
-        return this.formPanel;
-    }
-});
+    },
 
-var myForm = new Ext.formPanel({
-    title: 'User Details',
-    items: [{
-        ...
-    }],
-    listeners: {
-        change: function() {
-            
-            myForm.header.setStyle('color', 'red');
+    onRender: function() {
+        var me = this,
+            i = 0,
+            l = 0,
+            sp,
+            sprites;
+            this.callParent(arguments);
+        sprites = me.spriteArray;
+        if (me.renderFirst && sprites) {
+            me.renderFirst = false;
+            for (l = sprites.length; i < l; i++) {
+                sp = me.surface.add(sprites[i]);
+                sp.setAttributes({
+                    hidden: false
+                },
+                true);
+            }
         }
     }
 });
-
- * @param {String/Array} events The event name to bubble, or an Array of event names. - */ - enableBubble : function(events){ - var me = this; - if(!Ext.isEmpty(events)){ - events = Ext.isArray(events) ? events : Array.prototype.slice.call(arguments, 0); - for(var i = 0, len = events.length; i < len; i++){ - var ename = events[i]; - ename = ename.toLowerCase(); - var ce = me.events[ename] || true; - if (typeof ce == 'boolean') { - ce = new Ext.util.Event(me, ename); - me.events[ename] = ce; - } - ce.bubble = true; - } - } - } - }; -}()); +Ext.define('Ext.chart.Tip', { -Ext.util.Observable.capture = function(o, fn, scope){ - o.fireEvent = o.fireEvent.createInterceptor(fn, scope); -}; + + requires: ['Ext.tip.ToolTip', 'Ext.chart.TipSurface'], + -Ext.util.Observable.observeClass = function(c, listeners){ - if(c){ - if(!c.fireEvent){ - Ext.apply(c, new Ext.util.Observable()); - Ext.util.Observable.capture(c.prototype, c.fireEvent, c); - } - if(typeof listeners == 'object'){ - c.on(listeners); - } - return c; - } -}; + constructor: function(config) { + var me = this, + surface, + sprites, + tipSurface; + if (config.tips) { + me.tipTimeout = null; + me.tipConfig = Ext.apply({}, config.tips, { + renderer: Ext.emptyFn, + constrainPosition: false + }); + me.tooltip = Ext.create('Ext.tip.ToolTip', me.tipConfig); + Ext.getBody().on('mousemove', me.tooltip.onMouseMove, me.tooltip); + if (me.tipConfig.surface) { + + surface = me.tipConfig.surface; + sprites = surface.sprites; + tipSurface = Ext.create('Ext.chart.TipSurface', { + id: 'tipSurfaceComponent', + sprites: sprites + }); + if (surface.width && surface.height) { + tipSurface.setSize(surface.width, surface.height); + } + me.tooltip.add(tipSurface); + me.spriteTip = tipSurface; + } + } + }, -Ext.apply(Ext.EventManager, function(){ - var resizeEvent, - resizeTask, - textEvent, - textSize, - D = Ext.lib.Dom, - propRe = /^(?:scope|delay|buffer|single|stopEvent|preventDefault|stopPropagation|normalized|args|delegate)$/, - curWidth = 0, - curHeight = 0, - - - - useKeydown = Ext.isWebKit ? - Ext.num(navigator.userAgent.match(/AppleWebKit\/(\d+)/)[1]) >= 525 : - !((Ext.isGecko && !Ext.isWindows) || Ext.isOpera); + showTip: function(item) { + var me = this; + if (!me.tooltip) { + return; + } + clearTimeout(me.tipTimeout); + var tooltip = me.tooltip, + spriteTip = me.spriteTip, + tipConfig = me.tipConfig, + trackMouse = tooltip.trackMouse, + sprite, surface, surfaceExt, pos, x, y; + if (!trackMouse) { + tooltip.trackMouse = true; + sprite = item.sprite; + surface = sprite.surface; + surfaceExt = Ext.get(surface.getId()); + if (surfaceExt) { + pos = surfaceExt.getXY(); + x = pos[0] + (sprite.attr.x || 0) + (sprite.attr.translation && sprite.attr.translation.x || 0); + y = pos[1] + (sprite.attr.y || 0) + (sprite.attr.translation && sprite.attr.translation.y || 0); + tooltip.targetXY = [x, y]; + } + } + if (spriteTip) { + tipConfig.renderer.call(tooltip, item.storeItem, item, spriteTip.surface); + } else { + tipConfig.renderer.call(tooltip, item.storeItem, item); + } + tooltip.show(); + tooltip.trackMouse = trackMouse; + }, - return { - - doResizeEvent: function(){ - var h = D.getViewHeight(), - w = D.getViewWidth(); + hideTip: function(item) { + var tooltip = this.tooltip; + if (!tooltip) { + return; + } + clearTimeout(this.tipTimeout); + this.tipTimeout = setTimeout(function() { + tooltip.hide(); + }, 0); + } +}); - - if(curHeight != h || curWidth != w){ - resizeEvent.fire(curWidth = w, curHeight = h); - } - }, +Ext.define('Ext.chart.axis.Abstract', { - - onWindowResize : function(fn, scope, options){ - if(!resizeEvent){ - resizeEvent = new Ext.util.Event(); - resizeTask = new Ext.util.DelayedTask(this.doResizeEvent); - Ext.EventManager.on(window, "resize", this.fireWindowResize, this); - } - resizeEvent.addListener(fn, scope, options); - }, + - - fireWindowResize : function(){ - if(resizeEvent){ - resizeTask.delay(100); - } - }, + requires: ['Ext.chart.Chart'], - - onTextResize : function(fn, scope, options){ - if(!textEvent){ - textEvent = new Ext.util.Event(); - var textEl = new Ext.Element(document.createElement('div')); - textEl.dom.className = 'x-text-resize'; - textEl.dom.innerHTML = 'X'; - textEl.appendTo(document.body); - textSize = textEl.dom.offsetHeight; - setInterval(function(){ - if(textEl.dom.offsetHeight != textSize){ - textEvent.fire(textSize, textSize = textEl.dom.offsetHeight); - } - }, this.textResizeInterval); - } - textEvent.addListener(fn, scope, options); - }, + - - removeResizeListener : function(fn, scope){ - if(resizeEvent){ - resizeEvent.removeListener(fn, scope); - } - }, + constructor: function(config) { + config = config || {}; - - fireResize : function(){ - if(resizeEvent){ - resizeEvent.fire(D.getViewWidth(), D.getViewHeight()); - } - }, + var me = this, + pos = config.position || 'left'; + pos = pos.charAt(0).toUpperCase() + pos.substring(1); - textResizeInterval : 50, + config.label = Ext.apply(config['axisLabel' + pos + 'Style'] || {}, config.label || {}); + config.axisTitleStyle = Ext.apply(config['axisTitle' + pos + 'Style'] || {}, config.labelTitle || {}); + Ext.apply(me, config); + me.fields = [].concat(me.fields); + this.callParent(); + me.labels = []; + me.getId(); + me.labelGroup = me.chart.surface.getGroup(me.axisId + "-labels"); + }, - - ieDeferSrc : false, - - - getKeyEvent : function(){ - return useKeydown ? 'keydown' : 'keypress'; - }, + alignment: null, + grid: false, + steps: 10, + x: 0, + y: 0, + minValue: 0, + maxValue: 0, - - - useKeydown: useKeydown - }; -}()); + getId: function() { + return this.axisId || (this.axisId = Ext.id(null, 'ext-axis-')); + }, -Ext.EventManager.on = Ext.EventManager.addListener; + + processView: Ext.emptyFn, + drawAxis: Ext.emptyFn, + addDisplayAndLabels: Ext.emptyFn +}); -Ext.apply(Ext.EventObjectImpl.prototype, { - - BACKSPACE: 8, - - TAB: 9, - - NUM_CENTER: 12, - - ENTER: 13, - - RETURN: 13, - - SHIFT: 16, - - CTRL: 17, - CONTROL : 17, - - ALT: 18, - - PAUSE: 19, - - CAPS_LOCK: 20, - - ESC: 27, - - SPACE: 32, - - PAGE_UP: 33, - PAGEUP : 33, - - PAGE_DOWN: 34, - PAGEDOWN : 34, - - END: 35, - - HOME: 36, - - LEFT: 37, - - UP: 38, - - RIGHT: 39, - - DOWN: 40, - - PRINT_SCREEN: 44, - - INSERT: 45, - - DELETE: 46, - - ZERO: 48, - - ONE: 49, - - TWO: 50, - - THREE: 51, - - FOUR: 52, - - FIVE: 53, - - SIX: 54, - - SEVEN: 55, - - EIGHT: 56, - - NINE: 57, - - A: 65, - - B: 66, - - C: 67, - - D: 68, - - E: 69, - - F: 70, - - G: 71, - - H: 72, - - I: 73, - - J: 74, - - K: 75, - - L: 76, - - M: 77, - - N: 78, - - O: 79, - - P: 80, - - Q: 81, - - R: 82, - - S: 83, - - T: 84, - - U: 85, - - V: 86, - - W: 87, - - X: 88, - - Y: 89, - - Z: 90, - - CONTEXT_MENU: 93, - - NUM_ZERO: 96, - - NUM_ONE: 97, - - NUM_TWO: 98, - - NUM_THREE: 99, - - NUM_FOUR: 100, - - NUM_FIVE: 101, - - NUM_SIX: 102, - - NUM_SEVEN: 103, - - NUM_EIGHT: 104, - - NUM_NINE: 105, - - NUM_MULTIPLY: 106, - - NUM_PLUS: 107, - - NUM_MINUS: 109, - - NUM_PERIOD: 110, - - NUM_DIVISION: 111, - - F1: 112, - - F2: 113, - - F3: 114, - - F4: 115, - - F5: 116, - - F6: 117, - - F7: 118, - - F8: 119, - - F9: 120, - - F10: 121, - - F11: 122, - - F12: 123, - - isNavKeyPress : function(){ - var me = this, - k = this.normalizeKey(me.keyCode); - return (k >= 33 && k <= 40) || - k == me.RETURN || - k == me.TAB || - k == me.ESC; - }, +Ext.define('Ext.chart.axis.Axis', { + + - isSpecialKey : function(){ - var k = this.normalizeKey(this.keyCode); - return (this.type == 'keypress' && this.ctrlKey) || - this.isNavKeyPress() || - (k == this.BACKSPACE) || - (k >= 16 && k <= 20) || - (k >= 44 && k <= 46); - }, + extend: 'Ext.chart.axis.Abstract', - getPoint : function(){ - return new Ext.lib.Point(this.xy[0], this.xy[1]); - }, + alternateClassName: 'Ext.chart.Axis', + + requires: ['Ext.draw.Draw'], - - hasModifier : function(){ - return ((this.ctrlKey || this.altKey) || this.shiftKey); - } -}); -Ext.Element.addMethods({ - 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; - } - me.on(eventName, fn); - return me; - }, - 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, - ni = -1; - if (Ext.Element.data(dom, 'isCleaned') && forceReclean !== true) { - return me; - } + + dashSize: 3, + + + position: 'bottom', + + + skipFirst: false, + + + length: 0, + + + width: 0, + + majorTickSteps: false, - while (n) { - var nx = n.nextSibling; - if (n.nodeType == 3 && !(/\S/.test(n.nodeValue))) { - dom.removeChild(n); - } else { - n.nodeIndex = ++ni; + + applyData: Ext.emptyFn, + + + calcEnds: function() { + var me = this, + 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, + min = isNaN(me.minimum) ? Infinity : me.minimum, + max = isNaN(me.maximum) ? -Infinity : me.maximum, + prevMin = me.prevMin, + prevMax = me.prevMax, + aggregate = false, + total = 0, + excludes = [], + outfrom, outto, + i, l, values, rec, out; + + + + for (i = 0, l = series.length; !aggregate && i < l; i++) { + aggregate = aggregate || series[i].stacked; + excludes = series[i].__excludes || excludes; + } + store.each(function(record) { + if (aggregate) { + if (!isFinite(min)) { + min = 0; + } + for (values = [0, 0], i = 0; i < ln; i++) { + if (excludes[i]) { + continue; + } + 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]); } - n = nx; + else { + for (i = 0; i < ln; i++) { + if (excludes[i]) { + continue; + } + value = record.get(fields[i]); + max = mmax(max, value); + min = mmin(min, value); + } + } + }); + if (!isFinite(max)) { + max = me.prevMax || 0; + } + if (!isFinite(min)) { + min = me.prevMin || 0; } - Ext.Element.data(dom, 'isCleaned', true); - return me; - }, - - - load : function() { - var updateManager = this.getUpdater(); - updateManager.update.apply(updateManager, arguments); + if (min != max && (max != (max >> 0))) { + max = (max >> 0) + 1; + } + out = Ext.draw.Draw.snapEnds(min, max, me.majorTickSteps !== false ? (me.majorTickSteps +1) : me.steps); + outfrom = out.from; + outto = out.to; + if (!isNaN(me.maximum)) { + + + out.to = me.maximum; + } + if (!isNaN(me.minimum)) { + + + out.from = me.minimum; + } - return this; - }, - - - getUpdater : function() { - return this.updateManager || (this.updateManager = new Ext.Updater(this)); + + out.step = (out.to - out.from) / (outto - outfrom) * out.step; + + if (me.adjustMaximumByMajorUnit) { + out.to += out.step; + } + if (me.adjustMinimumByMajorUnit) { + out.from -= out.step; + } + me.prevMin = min == max? 0 : min; + me.prevMax = max; + return out; }, - update : function(html, loadScripts, callback) { - if (!this.dom) { - return this; + drawAxis: function (init) { + var me = this, + i, j, + x = me.x, + y = me.y, + gutterX = me.chart.maxGutter[0], + gutterY = me.chart.maxGutter[1], + dashSize = me.dashSize, + subDashesX = me.minorTickSteps || 0, + subDashesY = me.minorTickSteps || 0, + length = me.length, + position = me.position, + inflections = [], + calcLabels = false, + stepCalcs = me.applyData(), + step = stepCalcs.step, + steps = stepCalcs.steps, + from = stepCalcs.from, + to = stepCalcs.to, + trueLength, + currentX, + currentY, + path, + prev, + dashesX, + dashesY, + delta; + + + + + if (me.hidden || isNaN(step) || (from == to)) { + return; } - html = html || ""; - if (loadScripts !== true) { - this.dom.innerHTML = html; - if (typeof callback == 'function') { - callback(); - } - return this; + me.from = stepCalcs.from; + me.to = stepCalcs.to; + if (position == 'left' || position == 'right') { + currentX = Math.floor(x) + 0.5; + path = ["M", currentX, y, "l", 0, -length]; + trueLength = length - (gutterY * 2); } - - var id = Ext.id(), - dom = this.dom; - - html += ''; - - Ext.lib.Event.onAvailable(id, function() { - 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]); + else { + currentY = Math.floor(y) + 0.5; + 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') { + calcLabels = true; + me.labels = [stepCalcs.from]; + } + if (position == 'right' || position == 'left') { + currentY = y - gutterY; + currentX = x - ((position == 'left') * dashSize * 2); + while (currentY >= y - gutterY - trueLength) { + path.push("M", currentX, Math.floor(currentY) + 0.5, "l", dashSize * 2 + 1, 0); + if (currentY != y - gutterY) { + for (i = 1; i < dashesY; i++) { + path.push("M", currentX + dashSize, Math.floor(currentY + delta * i / dashesY) + 0.5, "l", dashSize + 1, 0); } } + inflections.push([ Math.floor(x), Math.floor(currentY) ]); + currentY -= delta; + if (calcLabels) { + me.labels.push(me.labels[me.labels.length -1] + step); + } + if (delta === 0) { + break; + } } - - el = DOC.getElementById(id); - if (el) { - Ext.removeNode(el); + if (Math.round(currentY + delta - (y - gutterY - trueLength))) { + path.push("M", currentX, Math.floor(y - length + gutterY) + 0.5, "l", dashSize * 2 + 1, 0); + for (i = 1; i < dashesY; i++) { + path.push("M", currentX + dashSize, Math.floor(y - length + gutterY + delta * i / dashesY) + 0.5, "l", dashSize + 1, 0); + } + inflections.push([ Math.floor(x), Math.floor(currentY) ]); + if (calcLabels) { + me.labels.push(me.labels[me.labels.length -1] + step); + } } - - if (typeof callback == 'function') { - callback(); + } else { + currentX = x + gutterX; + currentY = y - ((position == 'top') * dashSize * 2); + while (currentX <= x + gutterX + trueLength) { + path.push("M", Math.floor(currentX) + 0.5, currentY, "l", 0, dashSize * 2 + 1); + if (currentX != x + gutterX) { + for (i = 1; i < dashesX; i++) { + path.push("M", Math.floor(currentX - delta * i / dashesX) + 0.5, currentY, "l", 0, dashSize + 1); + } + } + inflections.push([ Math.floor(currentX), Math.floor(y) ]); + currentX += delta; + if (calcLabels) { + me.labels.push(me.labels[me.labels.length -1] + step); + } + if (delta === 0) { + break; + } } - }); - dom.innerHTML = html.replace(/(?:)((\n|\r|.)*?)(?:<\/script>)/ig, ""); - return this; + if (Math.round(currentX - delta - (x + gutterX + trueLength))) { + path.push("M", Math.floor(x + length - gutterX) + 0.5, currentY, "l", 0, dashSize * 2 + 1); + for (i = 1; i < dashesX; i++) { + path.push("M", Math.floor(x + length - gutterX - delta * i / dashesX) + 0.5, currentY, "l", 0, dashSize + 1); + } + inflections.push([ Math.floor(currentX), Math.floor(y) ]); + if (calcLabels) { + me.labels.push(me.labels[me.labels.length -1] + step); + } + } + } + if (!me.axis) { + me.axis = me.chart.surface.add(Ext.apply({ + type: 'path', + path: path + }, me.axisStyle)); + } + me.axis.setAttributes({ + path: path + }, true); + me.inflections = inflections; + if (!init && me.grid) { + me.drawGrid(); + } + me.axisBBox = me.axis.getBBox(); + me.drawLabel(); }, - removeAllListeners : function() { - this.removeAnchor(); - Ext.EventManager.removeAll(this.dom); - return this; + drawGrid: function() { + var me = this, + surface = me.chart.surface, + grid = me.grid, + odd = grid.odd, + even = grid.even, + inflections = me.inflections, + ln = inflections.length - ((odd || even)? 0 : 1), + position = me.position, + gutter = me.chart.maxGutter, + width = me.width - 2, + vert = false, + point, prevPoint, + 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; + ln++; + } + for (; i < ln; i++) { + point = inflections[i]; + prevPoint = inflections[i - 1]; + if (odd || even) { + path = (i % 2)? oddPath : evenPath; + styles = ((i % 2)? odd : even) || {}; + 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, + "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, + "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, + "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, + "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"); + } + } else { + if (position == 'left') { + path = path.concat(["M", point[0] + 0.5, point[1] + 0.5, "l", width, 0]); + } + else if (position == 'right') { + path = path.concat(["M", point[0] - 0.5, point[1] + 0.5, "l", -width, 0]); + } + else if (position == 'top') { + path = path.concat(["M", point[0] + 0.5, point[1] + 0.5, "l", 0, width]); + } + else { + path = path.concat(["M", point[0] + 0.5, point[1] - 0.5, "l", 0, -width]); + } + } + } + if (odd || even) { + if (oddPath.length) { + if (!me.gridOdd && oddPath.length) { + me.gridOdd = surface.add({ + type: 'path', + path: oddPath + }); + } + me.gridOdd.setAttributes(Ext.apply({ + path: oddPath, + hidden: false + }, odd || {}), true); + } + if (evenPath.length) { + if (!me.gridEven) { + me.gridEven = surface.add({ + type: 'path', + path: evenPath + }); + } + me.gridEven.setAttributes(Ext.apply({ + path: evenPath, + hidden: false + }, even || {}), true); + } + } + else { + if (path.length) { + if (!me.gridLines) { + me.gridLines = me.chart.surface.add({ + type: 'path', + path: path, + "stroke-width": me.lineWidth || 1, + stroke: me.gridColor || '#ccc' + }); + } + me.gridLines.setAttributes({ + hidden: false, + path: path + }, true); + } + else if (me.gridLines) { + me.gridLines.hide(true); + } + } }, - - createProxy : function(config, renderTo, matchBox) { - config = (typeof config == 'object') ? config : {tag : "div", cls: config}; + //@private + getOrCreateLabel: function(i, text) { var me = this, - proxy = renderTo ? Ext.DomHelper.append(renderTo, config, true) : - Ext.DomHelper.insertBefore(me.dom, config, true); - - if (matchBox && me.setBox && me.getBox) { - proxy.setBox(me.getBox()); + labelGroup = me.labelGroup, + textLabel = labelGroup.getAt(i), + surface = me.chart.surface; + if (textLabel) { + if (text != textLabel.attr.text) { + textLabel.setAttributes(Ext.apply({ + text: text + }, me.label), true); + textLabel._bbox = textLabel.getBBox(); + } } - return proxy; - } -}); - -Ext.Element.prototype.getUpdateManager = Ext.Element.prototype.getUpdater; - -Ext.Element.addMethods({ - - getAnchorXY : function(anchor, local, s){ - - - anchor = (anchor || "tl").toLowerCase(); - s = s || {}; - - var me = this, - vp = me.dom == document.body || me.dom == document, - w = s.width || vp ? Ext.lib.Dom.getViewWidth() : me.getWidth(), - h = s.height || vp ? Ext.lib.Dom.getViewHeight() : me.getHeight(), - xy, - r = Math.round, - o = me.getXY(), - scroll = me.getScroll(), - extraX = vp ? scroll.left : !local ? o[0] : 0, - extraY = vp ? scroll.top : !local ? o[1] : 0, - hash = { - c : [r(w * 0.5), r(h * 0.5)], - t : [r(w * 0.5), 0], - l : [0, r(h * 0.5)], - r : [w, r(h * 0.5)], - b : [r(w * 0.5), h], - tl : [0, 0], - bl : [0, h], - br : [w, h], - tr : [w, 0] - }; - - xy = hash[anchor]; - return [xy[0] + extraX, xy[1] + extraY]; - }, - - - anchorTo : function(el, alignment, offsets, animate, monitorScroll, callback){ - var me = this, - dom = me.dom, - scroll = !Ext.isEmpty(monitorScroll), - action = function(){ - Ext.fly(dom).alignTo(el, alignment, offsets, animate); - Ext.callback(callback, Ext.fly(dom)); - }, - anchor = this.getAnchor(); + else { + textLabel = surface.add(Ext.apply({ + group: labelGroup, + type: 'text', + x: 0, + y: 0, + text: text + }, me.label)); + surface.renderItem(textLabel); + textLabel._bbox = textLabel.getBBox(); + } + + if (me.label.rotation) { + textLabel.setAttributes({ + rotation: { + degrees: 0 + } + }, true); + textLabel._ubbox = textLabel.getBBox(); + textLabel.setAttributes(me.label, true); + } else { + textLabel._ubbox = textLabel._bbox; + } + return textLabel; + }, + + rect2pointArray: function(sprite) { + var surface = this.chart.surface, + rect = surface.getBBox(sprite, true), + p1 = [rect.x, rect.y], + p1p = p1.slice(), + p2 = [rect.x + rect.width, rect.y], + p2p = p2.slice(), + p3 = [rect.x + rect.width, rect.y + rect.height], + p3p = p3.slice(), + p4 = [rect.x, rect.y + rect.height], + p4p = p4.slice(), + matrix = sprite.matrix; + + 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, + floor = Math.floor, + max = Math.max, + axes = me.chart.axes, + position = me.position, + inflections = me.inflections, + ln = inflections.length, + labels = me.labels, + labelGroup = me.labelGroup, + maxHeight = 0, + ratio, + gutterY = me.chart.maxGutter[1], + ubbox, bbox, point, prevX, prevLabel, + projectedWidth = 0, + textLabel, attr, textRight, text, + label, last, x, y, i, firstLabel; + + last = ln - 1; + + 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; + + for (i = 0; i < ln; i++) { + point = inflections[i]; + text = me.label.renderer(labels[i]); + textLabel = me.getOrCreateLabel(i, text); + bbox = textLabel._bbox; + maxHeight = max(maxHeight, bbox.height + me.dashSize + me.label.padding); + x = floor(point[0] - (ratio? bbox.height : bbox.width) / 2); + if (me.chart.maxGutter[0] == 0) { + if (i == 0 && axes.findIndex('position', 'left') == -1) { + x = point[0]; + } + else if (i == last && axes.findIndex('position', 'right') == -1) { + x = point[0] - bbox.width; + } + } + if (position == 'top') { + y = point[1] - (me.dashSize * 2) - me.label.padding - (bbox.height / 2); + } + else { + y = point[1] + (me.dashSize * 2) + me.label.padding + (bbox.height / 2); + } - - this.removeAnchor(); - Ext.apply(anchor, { - fn: action, - scroll: scroll - }); + textLabel.setAttributes({ + hidden: false, + x: x, + y: y + }, true); - Ext.EventManager.onWindowResize(action, null); - - if(scroll){ - Ext.EventManager.on(window, 'scroll', action, null, - {buffer: !isNaN(monitorScroll) ? monitorScroll : 50}); - } - action.call(me); - return me; - }, - - - removeAnchor : function(){ - var me = this, - anchor = this.getAnchor(); - if(anchor && anchor.fn){ - Ext.EventManager.removeResizeListener(anchor.fn); - if(anchor.scroll){ - Ext.EventManager.un(window, 'scroll', anchor.fn); + if (i != 0 && (me.intersect(textLabel, prevLabel) + || me.intersect(textLabel, firstLabel))) { + textLabel.hide(true); + continue; } - delete anchor.fn; + + prevLabel = textLabel; } - return me; + + return maxHeight; }, - - getAnchor : function(){ - var data = Ext.Element.data, - dom = this.dom; - if (!dom) { - return; + drawVerticalLabels: function() { + var me = this, + inflections = me.inflections, + position = me.position, + ln = inflections.length, + labels = me.labels, + maxWidth = 0, + max = Math.max, + floor = Math.floor, + ceil = Math.ceil, + axes = me.chart.axes, + gutterY = me.chart.maxGutter[1], + ubbox, bbox, point, prevLabel, + projectedWidth = 0, + textLabel, attr, textRight, text, + label, last, x, y, i; + + last = ln; + for (i = 0; i < last; i++) { + point = inflections[i]; + 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) { + if (i == last - 1 && axes.findIndex('position', 'top') == -1) { + y = me.y - me.length + ceil(bbox.height / 2); + } + else if (i == 0 && axes.findIndex('position', 'bottom') == -1) { + y = me.y - floor(bbox.height / 2); + } } - var anchor = data(dom, '_anchor'); - - if(!anchor){ - anchor = data(dom, '_anchor', {}); + if (position == 'left') { + x = point[0] - bbox.width - me.dashSize - me.label.padding - 2; + } + else { + x = point[0] + me.dashSize + me.label.padding + 2; + } + textLabel.setAttributes(Ext.apply({ + hidden: false, + x: x, + y: y + }, me.label), true); + + if (i != 0 && me.intersect(textLabel, prevLabel)) { + textLabel.hide(true); + continue; + } + prevLabel = textLabel; } - return anchor; + + return maxWidth; }, - getAlignToXY : function(el, p, o){ - el = Ext.get(el); - - if(!el || !el.dom){ - throw "Element.alignToXY with an element that doesn't exist"; - } - - o = o || [0,0]; - p = (!p || p == "?" ? "tl-bl?" : (!(/-/).test(p) && p !== "" ? "tl-" + p : p || "tl-bl")).toLowerCase(); - - var me = this, - d = me.dom, - a1, - a2, - x, - y, - - w, - h, - r, - dw = Ext.lib.Dom.getViewWidth() -10, - dh = Ext.lib.Dom.getViewHeight()-10, - p1y, - p1x, - p2y, - p2x, - swapY, - swapX, - doc = document, - docElement = doc.documentElement, - docBody = doc.body, - scrollX = (docElement.scrollLeft || docBody.scrollLeft || 0)+5, - scrollY = (docElement.scrollTop || docBody.scrollTop || 0)+5, - c = false, - p1 = "", - p2 = "", - m = p.match(/^([a-z]+)-([a-z]+)(\?)?$/); - - if(!m){ - throw "Element.alignTo with an invalid alignment " + p; + drawLabel: function() { + var me = this, + position = me.position, + labelGroup = me.labelGroup, + inflections = me.inflections, + maxWidth = 0, + maxHeight = 0, + ln, i; + + if (position == 'left' || position == 'right') { + maxWidth = me.drawVerticalLabels(); + } else { + maxHeight = me.drawHorizontalLabels(); } - - p1 = m[1]; - p2 = m[2]; - c = !!m[3]; - - a1 = me.getAnchorXY(p1, true); - a2 = el.getAnchorXY(p2, false); + ln = labelGroup.getCount(); + i = inflections.length; + for (; i < ln; i++) { + labelGroup.getAt(i).hide(true); + } - x = a2[0] - a1[0] + o[0]; - y = a2[1] - a1[1] + o[1]; + me.bbox = {}; + Ext.apply(me.bbox, me.axisBBox); + me.bbox.height = maxHeight; + me.bbox.width = maxWidth; + if (Ext.isString(me.title)) { + me.drawTitle(maxWidth, maxHeight); + } + }, - if(c){ - w = me.getWidth(); - h = me.getHeight(); - r = el.getRegion(); - - - - p1y = p1.charAt(0); - p1x = p1.charAt(p1.length-1); - p2y = p2.charAt(0); - p2x = p2.charAt(p2.length-1); - swapY = ((p1y=="t" && p2y=="b") || (p1y=="b" && p2y=="t")); - swapX = ((p1x=="r" && p2x=="l") || (p1x=="l" && p2x=="r")); - + + elipsis: function(sprite, text, desiredWidth, minWidth, center) { + var bbox, + x; - if (x + w > dw + scrollX) { - x = swapX ? r.left-w : dw+scrollX-w; - } - if (x < scrollX) { - x = swapX ? r.right : scrollX; - } - if (y + h > dh + scrollY) { - y = swapY ? r.top-h : dh+scrollY-h; + if (desiredWidth < minWidth) { + sprite.hide(true); + return false; + } + while (text.length > 4) { + text = text.substr(0, text.length - 4) + "..."; + sprite.setAttributes({ + text: text + }, true); + bbox = sprite.getBBox(); + if (bbox.width < desiredWidth) { + if (typeof center == 'number') { + sprite.setAttributes({ + x: Math.floor(center - (bbox.width / 2)) + }, true); + } + break; } - if (y < scrollY){ - y = swapY ? r.bottom : scrollY; - } } - return [x,y]; + return true; }, - alignTo : function(element, position, offsets, animate){ - var me = this; - return me.setXY(me.getAlignToXY(element, position, offsets), - me.preanim && !!animate ? me.preanim(arguments, 3) : false); - }, - - - adjustForConstraints : function(xy, parent, offsets){ - return this.getConstrainToXY(parent || document, false, offsets, xy) || xy; + setTitle: function(title) { + this.title = title; + this.drawLabel(); }, - getConstrainToXY : function(el, local, offsets, proposedXY){ - var os = {top:0, left:0, bottom:0, right: 0}; - - return function(el, local, offsets, proposedXY){ - el = Ext.get(el); - offsets = offsets ? Ext.applyIf(offsets, os) : os; + drawTitle: function(maxWidth, maxHeight) { + var me = this, + position = me.position, + surface = me.chart.surface, + displaySprite = me.displaySprite, + title = me.title, + rotate = (position == 'left' || position == 'right'), + x = me.x, + y = me.y, + base, bbox, pad; + + if (displaySprite) { + displaySprite.setAttributes({text: title}, true); + } else { + base = { + type: 'text', + x: 0, + y: 0, + text: title + }; + displaySprite = me.displaySprite = surface.add(Ext.apply(base, me.axisTitleStyle, me.labelTitle)); + surface.renderItem(displaySprite); + } + bbox = displaySprite.getBBox(); + pad = me.dashSize + me.label.padding; - var vw, vh, vx = 0, vy = 0; - if(el.dom == document.body || el.dom == document){ - vw =Ext.lib.Dom.getViewWidth(); - vh = Ext.lib.Dom.getViewHeight(); - }else{ - vw = el.dom.clientWidth; - vh = el.dom.clientHeight; - if(!local){ - var vxy = el.getXY(); - vx = vxy[0]; - vy = vxy[1]; - } + if (rotate) { + y -= ((me.length / 2) - (bbox.height / 2)); + if (position == 'left') { + x -= (maxWidth + pad + (bbox.width / 2)); } - - var s = el.getScroll(); - - vx += offsets.left + s.left; - vy += offsets.top + s.top; - - vw -= offsets.right; - vh -= offsets.bottom; - - var vr = vx + vw, - vb = vy + vh, - xy = proposedXY || (!local ? this.getXY() : [this.getLeft(true), this.getTop(true)]), - x = xy[0], y = xy[1], - offset = this.getConstrainOffset(), - w = this.dom.offsetWidth + offset, - h = this.dom.offsetHeight + offset; - - - var moved = false; - - - if((x + w) > vr){ - x = vr - w; - moved = true; + else { + x += (maxWidth + pad + bbox.width - (bbox.width / 2)); } - if((y + h) > vb){ - y = vb - h; - moved = true; + me.bbox.width += bbox.width + 10; + } + else { + x += (me.length / 2) - (bbox.width * 0.5); + if (position == 'top') { + y -= (maxHeight + pad + (bbox.height * 0.3)); } - - if(x < vx){ - x = vx; - moved = true; + else { + y += (maxHeight + pad + (bbox.height * 0.8)); } - if(y < vy){ - y = vy; - moved = true; + me.bbox.height += bbox.height + 10; + } + displaySprite.setAttributes({ + translate: { + x: x, + y: y } - return moved ? [x, y] : false; - }; - }(), - - - + }, true); + } +}); +Ext.define('Ext.chart.axis.Category', { + + extend: 'Ext.chart.axis.Axis', + alternateClassName: 'Ext.chart.CategoryAxis', + alias: 'axis.category', + + + categoryNames: null, + + calculateCategoryCount: false, + + setLabels: function() { + var store = this.chart.store, + fields = this.fields, + ln = fields.length, + i; + this.labels = []; + store.each(function(record) { + for (i = 0; i < ln; i++) { + this.labels.push(record.get(fields[i])); + } + }, this); + }, + + applyData: function() { + this.callParent(); + this.setLabels(); + var count = this.chart.store.getCount(); + return { + from: 0, + to: count, + power: 1, + step: 1, + steps: count - 1 + }; + } +}); +Ext.define('Ext.chart.axis.Gauge', { + + extend: 'Ext.chart.axis.Abstract', + + + + + + + position: 'gauge', + alias: 'axis.gauge', + drawAxis: function(init) { + var chart = this.chart, + surface = chart.surface, + bbox = chart.chartBBox, + centerX = bbox.x + (bbox.width / 2), + centerY = bbox.y + bbox.height, + margin = this.margin || 10, + rho = Math.min(bbox.width, 2 * bbox.height) /2 + margin, + sprites = [], sprite, + steps = this.steps, + i, pi = Math.PI, + cos = Math.cos, + sin = Math.sin; + if (this.sprites && !chart.resizing) { + this.drawLabel(); + return; + } + if (this.margin >= 0) { + if (!this.sprites) { + + for (i = 0; i <= steps; i++) { + sprite = surface.add({ + type: 'path', + path: ['M', centerX + (rho - margin) * cos(i / steps * pi - pi), + centerY + (rho - margin) * sin(i / steps * pi - pi), + 'L', centerX + rho * cos(i / steps * pi - pi), + centerY + rho * sin(i / steps * pi - pi), 'Z'], + stroke: '#ccc' + }); + sprite.setAttributes({ + hidden: false + }, true); + sprites.push(sprite); + } + } else { + sprites = this.sprites; + + for (i = 0; i <= steps; i++) { + sprites[i].setAttributes({ + path: ['M', centerX + (rho - margin) * cos(i / steps * pi - pi), + centerY + (rho - margin) * sin(i / steps * pi - pi), + 'L', centerX + rho * cos(i / steps * pi - pi), + centerY + rho * sin(i / steps * pi - pi), 'Z'], + stroke: '#ccc' + }, true); + } + } + } + this.sprites = sprites; + this.drawLabel(); + if (this.title) { + this.drawTitle(); + } + }, + + drawTitle: function() { + var me = this, + chart = me.chart, + surface = chart.surface, + 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 + }, me.label || {}), true); + labelBBox = labelSprite.getBBox(); + labelSprite.setAttributes({ + x: bbox.x + (bbox.width / 2) - (labelBBox.width / 2), + y: bbox.y + bbox.height - (labelBBox.height / 2) - 4 + }, true); + }, + + setTitle: function(title) { + this.title = title; + this.drawTitle(); + }, + + drawLabel: function() { + var chart = this.chart, + surface = chart.surface, + bbox = chart.chartBBox, + centerX = bbox.x + (bbox.width / 2), + centerY = bbox.y + bbox.height, + margin = this.margin || 10, + rho = Math.min(bbox.width, 2 * bbox.height) /2 + 2 * margin, + round = Math.round, + labelArray = [], label, + maxValue = this.maximum || 0, + steps = this.steps, i = 0, + adjY, + pi = Math.PI, + cos = Math.cos, + sin = Math.sin, + labelConf = this.label, + renderer = labelConf.renderer || function(v) { return v; }; + + if (!this.labelArray) { + + for (i = 0; i <= steps; i++) { + + adjY = (i === 0 || i === steps) ? 7 : 0; + label = surface.add({ + type: 'text', + text: renderer(round(i / steps * maxValue)), + x: centerX + rho * cos(i / steps * pi - pi), + y: centerY + rho * sin(i / steps * pi - pi) - adjY, + 'text-anchor': 'middle', + 'stroke-width': 0.2, + zIndex: 10, + stroke: '#333' + }); + label.setAttributes({ + hidden: false + }, true); + labelArray.push(label); + } + } + else { + labelArray = this.labelArray; + + for (i = 0; i <= steps; i++) { + + adjY = (i === 0 || i === steps) ? 7 : 0; + labelArray[i].setAttributes({ + text: renderer(round(i / steps * maxValue)), + x: centerX + rho * cos(i / steps * pi - pi), + y: centerY + rho * sin(i / steps * pi - pi) - adjY + }, true); + } + } + this.labelArray = labelArray; + } +}); +Ext.define('Ext.chart.axis.Numeric', { + + extend: 'Ext.chart.axis.Axis', + alternateClassName: 'Ext.chart.NumericAxis', + + type: 'numeric', + alias: 'axis.numeric', + constructor: function(config) { + var me = this, label, f; + 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 { + 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; + }, + + + minimum: NaN, + + maximum: NaN, + + decimals: 2, + + scale: "linear", + + position: 'left', + + adjustMaximumByMajorUnit: false, + + adjustMinimumByMajorUnit: false, + + applyData: function() { + this.callParent(); + return this.calcEnds(); + } +}); +Ext.define('Ext.chart.axis.Radial', { + + extend: 'Ext.chart.axis.Abstract', + + position: 'radial', + alias: 'axis.radial', + drawAxis: function(init) { + var chart = this.chart, + surface = chart.surface, + bbox = chart.chartBBox, + store = chart.store, + l = store.getCount(), + centerX = bbox.x + (bbox.width / 2), + centerY = bbox.y + (bbox.height / 2), + rho = Math.min(bbox.width, bbox.height) /2, + sprites = [], sprite, + steps = this.steps, + i, j, pi2 = Math.PI * 2, + cos = Math.cos, sin = Math.sin; + if (this.sprites && !chart.resizing) { + this.drawLabel(); + return; + } + if (!this.sprites) { + + for (i = 1; i <= steps; i++) { + sprite = surface.add({ + type: 'circle', + x: centerX, + y: centerY, + radius: Math.max(rho * i / steps, 0), + stroke: '#ccc' + }); + sprite.setAttributes({ + hidden: false + }, true); + sprites.push(sprite); + } + + store.each(function(rec, i) { + sprite = surface.add({ + type: 'path', + path: ['M', centerX, centerY, 'L', centerX + rho * cos(i / l * pi2), centerY + rho * sin(i / l * pi2), 'Z'], + stroke: '#ccc' + }); + sprite.setAttributes({ + hidden: false + }, true); + sprites.push(sprite); + }); + } else { + sprites = this.sprites; + + for (i = 0; i < steps; i++) { + sprites[i].setAttributes({ + x: centerX, + y: centerY, + radius: Math.max(rho * (i + 1) / steps, 0), + stroke: '#ccc' + }, true); + } + + store.each(function(rec, j) { + sprites[i + j].setAttributes({ + path: ['M', centerX, centerY, 'L', centerX + rho * cos(j / l * pi2), centerY + rho * sin(j / l * pi2), 'Z'], + stroke: '#ccc' + }, true); + }); + } + this.sprites = sprites; + + this.drawLabel(); + }, + + drawLabel: function() { + var chart = this.chart, + surface = chart.surface, + bbox = chart.chartBBox, + store = chart.store, + centerX = bbox.x + (bbox.width / 2), + centerY = bbox.y + (bbox.height / 2), + rho = Math.min(bbox.width, bbox.height) /2, + max = Math.max, round = Math.round, + labelArray = [], label, + fields = [], nfields, + categories = [], xField, + aggregate = !this.maximum, + maxValue = this.maximum || 0, + steps = this.steps, i = 0, j, dx, dy, + pi2 = Math.PI * 2, + cos = Math.cos, sin = Math.sin, + display = this.label.display, + draw = display !== 'none', + margin = 10; + + if (!draw) { + return; + } + + chart.series.each(function(series) { + fields.push(series.yField); + xField = series.xField; + }); + + + store.each(function(record, i) { + if (aggregate) { + for (i = 0, nfields = fields.length; i < nfields; i++) { + maxValue = max(+record.get(fields[i]), maxValue); + } + } + categories.push(record.get(xField)); + }); + if (!this.labelArray) { + if (display != 'categories') { + + for (i = 1; i <= steps; i++) { + label = surface.add({ + type: 'text', + text: round(i / steps * maxValue), + x: centerX, + y: centerY - rho * i / steps, + 'text-anchor': 'middle', + 'stroke-width': 0.1, + stroke: '#333' + }); + label.setAttributes({ + hidden: false + }, true); + labelArray.push(label); + } + } + if (display != 'scale') { + + for (j = 0, steps = categories.length; j < steps; j++) { + dx = cos(j / steps * pi2) * (rho + margin); + dy = sin(j / steps * pi2) * (rho + margin); + label = surface.add({ + type: 'text', + text: categories[j], + x: centerX + dx, + y: centerY + dy, + 'text-anchor': dx * dx <= 0.001? 'middle' : (dx < 0? 'end' : 'start') + }); + label.setAttributes({ + hidden: false + }, true); + labelArray.push(label); + } + } + } + else { + labelArray = this.labelArray; + if (display != 'categories') { + + for (i = 0; i < steps; i++) { + labelArray[i].setAttributes({ + text: round((i + 1) / steps * maxValue), + x: centerX, + y: centerY - rho * (i + 1) / steps, + 'text-anchor': 'middle', + 'stroke-width': 0.1, + stroke: '#333' + }, true); + } + } + if (display != 'scale') { + + for (j = 0, steps = categories.length; j < steps; j++) { + dx = cos(j / steps * pi2) * (rho + margin); + dy = sin(j / steps * pi2) * (rho + margin); + if (labelArray[i + j]) { + labelArray[i + j].setAttributes({ + type: 'text', + text: categories[j], + x: centerX + dx, + y: centerY + dy, + 'text-anchor': dx * dx <= 0.001? 'middle' : (dx < 0? 'end' : 'start') + }, true); + } + } + } + } + this.labelArray = labelArray; + } +}); +Ext.define('Ext.data.AbstractStore', { + requires: ['Ext.util.MixedCollection', 'Ext.data.Operation', 'Ext.util.Filter'], - getConstrainOffset : function(){ - return 0; + mixins: { + observable: 'Ext.util.Observable', + sortable: 'Ext.util.Sortable' }, - - getCenterXY : function(){ - return this.getAlignToXY(document, 'c-c'); + statics: { + create: function(store){ + if (!store.isStore) { + if (!store.type) { + store.type = 'store'; + } + store = Ext.createByAlias('store.' + store.type, store); + } + return store; + } }, + + remoteSort : false, + remoteFilter: false, - center : function(centerIn){ - return this.alignTo(centerIn || document, 'c-c'); - } -}); -Ext.Element.addMethods({ - select : function(selector, unique){ - return Ext.Element.select(selector, unique, this.dom); - } -}); -Ext.apply(Ext.Element.prototype, function() { - var GETDOM = Ext.getDom, - GET = Ext.get, - DH = Ext.DomHelper; - - return { - - insertSibling: function(el, where, returnDom){ - var me = this, - rt, - isAfter = (where || 'before').toLowerCase() == 'after', - insertEl; - - if(Ext.isArray(el)){ - insertEl = me; - Ext.each(el, function(e) { - rt = Ext.fly(insertEl, '_internal').insertSibling(e, where, returnDom); - if(isAfter){ - insertEl = rt; - } - }); - return rt; - } - - el = el || {}; - - if(el.nodeType || el.dom){ - rt = me.dom.parentNode.insertBefore(GETDOM(el), isAfter ? me.dom.nextSibling : me.dom); - if (!returnDom) { - rt = GET(rt); - } - }else{ - if (isAfter && !me.dom.nextSibling) { - rt = DH.append(me.dom.parentNode, el, !returnDom); - } else { - rt = DH[isAfter ? 'insertAfter' : 'insertBefore'](me.dom, el, !returnDom); - } - } - return rt; - } - }; -}()); + autoLoad: false, + + autoSync: false, -Ext.Element.boxMarkup = '
'; + + batchUpdateMode: 'operation', -Ext.Element.addMethods(function(){ - var INTERNAL = "_internal", - pxMatch = /(\d+\.?\d+)px/; - return { - - applyStyles : function(style){ - Ext.DomHelper.applyStyles(this.dom, style); - return this; - }, + + filterOnLoad: true, - - getStyles : function(){ - var ret = {}; - Ext.each(arguments, function(v) { - ret[v] = this.getStyle(v); - }, - this); - return ret; - }, + + sortOnLoad: true, - - setOverflow : function(v){ - var dom = this.dom; - if(v=='auto' && Ext.isMac && Ext.isGecko2){ - dom.style.overflow = 'hidden'; - (function(){dom.style.overflow = 'auto';}).defer(1); - }else{ - dom.style.overflow = v; - } - }, + + implicitModel: false, - - boxWrap : function(cls){ - cls = cls || 'x-box'; - var el = Ext.get(this.insertHtml("beforeBegin", "
" + String.format(Ext.Element.boxMarkup, cls) + "
")); - Ext.DomQuery.selectNode('.' + cls + '-mc', el.dom).appendChild(this.dom); - return el; - }, + + defaultProxyType: 'memory', - - setSize : function(width, height, animate){ - var me = this; - if(typeof width == 'object'){ - height = width.height; - width = width.width; - } - width = me.adjustWidth(width); - height = me.adjustHeight(height); - if(!animate || !me.anim){ - me.dom.style.width = me.addUnits(width); - me.dom.style.height = me.addUnits(height); - }else{ - me.anim({width: {to: width}, height: {to: height}}, me.preanim(arguments, 2)); - } - return me; - }, + + isDestroyed: false, - - getComputedHeight : function(){ - var me = this, - h = Math.max(me.dom.offsetHeight, me.dom.clientHeight); - if(!h){ - h = parseFloat(me.getStyle('height')) || 0; - if(!me.isBorderBox()){ - h += me.getFrameWidth('tb'); - } - } - return h; - }, + isStore: true, + + + + + sortRoot: 'data', + + + constructor: function(config) { + var me = this; - getComputedWidth : function(){ - var w = Math.max(this.dom.offsetWidth, this.dom.clientWidth); - if(!w){ - w = parseFloat(this.getStyle('width')) || 0; - if(!this.isBorderBox()){ - w += this.getFrameWidth('lr'); - } - } - return w; - }, + me.addEvents( + + 'add', + + + 'remove', + + + 'update', + + + 'datachanged', + + + 'beforeload', + + + 'load', + + 'beforesync', + + 'clear' + ); - getFrameWidth : function(sides, onlyContentBox){ - return onlyContentBox && this.isBorderBox() ? 0 : (this.getPadding(sides) + this.getBorderWidth(sides)); - }, + Ext.apply(me, config); - addClassOnOver : function(className){ - this.hover( - function(){ - Ext.fly(this, INTERNAL).addClass(className); - }, - function(){ - Ext.fly(this, INTERNAL).removeClass(className); - } - ); - return this; - }, + me.removed = []; + + me.mixins.observable.constructor.apply(me, arguments); + me.model = Ext.ModelManager.getModel(config.model || me.model); - addClassOnFocus : function(className){ - this.on("focus", function(){ - Ext.fly(this, INTERNAL).addClass(className); - }, this.dom); - this.on("blur", function(){ - Ext.fly(this, INTERNAL).removeClass(className); - }, this.dom); - return this; - }, + Ext.applyIf(me, { + modelDefaults: {} + }); - addClassOnClick : function(className){ - var dom = this.dom; - this.on("mousedown", function(){ - Ext.fly(dom, INTERNAL).addClass(className); - var d = Ext.getDoc(), - fn = function(){ - Ext.fly(dom, INTERNAL).removeClass(className); - d.removeListener("mouseup", fn); - }; - d.on("mouseup", fn); + if (!me.model && me.fields) { + me.model = Ext.define('Ext.data.Store.ImplicitModel-' + (me.storeId || Ext.id()), { + extend: 'Ext.data.Model', + fields: me.fields, + proxy: me.proxy || me.defaultProxyType }); - return this; - }, - + delete me.fields; - getViewSize : function(){ - var doc = document, - d = this.dom, - isDoc = (d == doc || d == doc.body); + me.implicitModel = true; + } - - if (isDoc) { - var extdom = Ext.lib.Dom; - return { - width : extdom.getViewWidth(), - height : extdom.getViewHeight() - }; + + me.setProxy(config.proxy || me.proxy || me.model.getProxy()); - - } else { - return { - width : d.clientWidth, - height : d.clientHeight - }; - } - }, + if (me.id && !me.storeId) { + me.storeId = me.id; + delete me.id; + } + if (me.storeId) { + Ext.data.StoreManager.register(me); + } + me.mixins.sortable.initSortable.call(me); + + + me.filters = Ext.create('Ext.util.MixedCollection'); + me.filters.addAll(me.decodeFilters(config.filters)); + }, - getStyleSize : function(){ - var me = this, - w, h, - doc = document, - d = this.dom, - isDoc = (d == doc || d == doc.body), - s = d.style; - - - if (isDoc) { - var extdom = Ext.lib.Dom; - return { - width : extdom.getViewWidth(), - height : extdom.getViewHeight() + + setProxy: function(proxy) { + var me = this; + + if (proxy instanceof Ext.data.proxy.Proxy) { + proxy.setModel(me.model); + } else { + if (Ext.isString(proxy)) { + proxy = { + type: proxy }; } + Ext.applyIf(proxy, { + model: me.model + }); - if(s.width && s.width != 'auto'){ - w = parseFloat(s.width); - if(me.isBorderBox()){ - w -= me.getFrameWidth('lr'); - } - } - - if(s.height && s.height != 'auto'){ - h = parseFloat(s.height); - if(me.isBorderBox()){ - h -= me.getFrameWidth('tb'); - } - } - - return {width: w || me.getWidth(true), height: h || me.getHeight(true)}; - }, - + proxy = Ext.createByAlias('proxy.' + proxy.type, proxy); + } - getSize : function(contentSize){ - return {width: this.getWidth(contentSize), height: this.getHeight(contentSize)}; - }, - + me.proxy = proxy; - repaint : function(){ - var dom = this.dom; - this.addClass("x-repaint"); - setTimeout(function(){ - Ext.fly(dom).removeClass("x-repaint"); - }, 1); - return this; - }, + return me.proxy; + }, + + + getProxy: function() { + return this.proxy; + }, + + create: function(data, options) { + var me = this, + instance = Ext.ModelManager.create(Ext.applyIf(data, me.modelDefaults), me.model.modelName), + operation; - unselectable : function(){ - this.dom.unselectable = "on"; - return this.swallowEvent("selectstart", true). - applyStyles("-moz-user-select:none;-khtml-user-select:none;"). - addClass("x-unselectable"); - }, + options = options || {}; + Ext.applyIf(options, { + action : 'create', + records: [instance] + }); + + operation = Ext.create('Ext.data.Operation', options); + + me.proxy.create(operation, me.onProxyWrite, me); - getMargins : function(side){ - var me = this, - key, - hash = {t:"top", l:"left", r:"right", b: "bottom"}, - o = {}; + return instance; + }, - if (!side) { - for (key in me.margins){ - o[hash[key]] = parseFloat(me.getStyle(me.margins[key])) || 0; - } - return o; - } else { - return me.addStyles.call(me, side, me.margins); - } - } - }; -}()); + read: function() { + return this.load.apply(this, arguments); + }, -Ext.Element.addMethods({ - - setBox : function(box, adjust, animate){ + onProxyRead: Ext.emptyFn, + + update: function(options) { var me = this, - w = box.width, - h = box.height; - if((adjust && !me.autoBoxAdjust) && !me.isBorderBox()){ - w -= (me.getBorderWidth("lr") + me.getPadding("lr")); - h -= (me.getBorderWidth("tb") + me.getPadding("tb")); - } - me.setBounds(box.x, box.y, w, h, me.animTest.call(me, arguments, animate, 2)); - return me; + operation; + options = options || {}; + + Ext.applyIf(options, { + action : 'update', + records: me.getUpdatedRecords() + }); + + operation = Ext.create('Ext.data.Operation', options); + + return me.proxy.update(operation, me.onProxyWrite, me); }, - getBox : function(contentBox, local) { - var me = this, - xy, - left, - top, - getBorderWidth = me.getBorderWidth, - getPadding = me.getPadding, - l, - r, - t, - b; - if(!local){ - xy = me.getXY(); - }else{ - left = parseInt(me.getStyle("left"), 10) || 0; - top = parseInt(me.getStyle("top"), 10) || 0; - xy = [left, top]; + onProxyWrite: function(operation) { + var me = this, + success = operation.wasSuccessful(), + records = operation.getRecords(); + + switch (operation.action) { + case 'create': + me.onCreateRecords(records, operation, success); + break; + case 'update': + me.onUpdateRecords(records, operation, success); + break; + case 'destroy': + me.onDestroyRecords(records, operation, success); + break; } - var el = me.dom, w = el.offsetWidth, h = el.offsetHeight, bx; - if(!contentBox){ - bx = {x: xy[0], y: xy[1], 0: xy[0], 1: xy[1], width: w, height: h}; - }else{ - l = getBorderWidth.call(me, "l") + getPadding.call(me, "l"); - r = getBorderWidth.call(me, "r") + getPadding.call(me, "r"); - t = getBorderWidth.call(me, "t") + getPadding.call(me, "t"); - b = getBorderWidth.call(me, "b") + getPadding.call(me, "b"); - bx = {x: xy[0]+l, y: xy[1]+t, 0: xy[0]+l, 1: xy[1]+t, width: w-(l+r), height: h-(t+b)}; + + if (success) { + me.fireEvent('write', me, operation); + me.fireEvent('datachanged', me); } - bx.right = bx.x + bx.width; - bx.bottom = bx.y + bx.height; - return bx; - }, - - - move : function(direction, distance, animate){ - var me = this, - xy = me.getXY(), - x = xy[0], - y = xy[1], - left = [x - distance, y], - right = [x + distance, y], - top = [x, y - distance], - bottom = [x, y + distance], - hash = { - l : left, - left : left, - r : right, - right : right, - t : top, - top : top, - up : top, - b : bottom, - bottom : bottom, - down : bottom - }; - - direction = direction.toLowerCase(); - me.moveTo(hash[direction][0], hash[direction][1], me.animTest.call(me, arguments, animate, 2)); - }, - - - setLeftTop : function(left, top){ - var me = this, - style = me.dom.style; - style.left = me.addUnits(left); - style.top = me.addUnits(top); - return me; + + Ext.callback(operation.callback, operation.scope || me, [records, operation, success]); }, + + - - getRegion : function(){ - return Ext.lib.Dom.getRegion(this.dom); + destroy: function(options) { + var me = this, + operation; + + options = options || {}; + + Ext.applyIf(options, { + action : 'destroy', + records: me.getRemovedRecords() + }); + + operation = Ext.create('Ext.data.Operation', options); + + return me.proxy.destroy(operation, me.onProxyWrite, me); }, + - - setBounds : function(x, y, width, height, animate){ - var me = this; - if (!animate || !me.anim) { - me.setSize(width, height); - me.setLocation(x, y); - } else { - me.anim({points: {to: [x, y]}, - width: {to: me.adjustWidth(width)}, - height: {to: me.adjustHeight(height)}}, - me.preanim(arguments, 4), - 'motion'); - } - return me; + onBatchOperationComplete: function(batch, operation) { + return this.onProxyWrite(operation); }, - setRegion : function(region, animate) { - return this.setBounds(region.left, region.top, region.right-region.left, region.bottom-region.top, this.animTest.call(this, arguments, animate, 1)); - } -}); -Ext.Element.addMethods({ - - scrollTo : function(side, value, animate) { - - var top = /top/i.test(side), - me = this, - dom = me.dom, - prop; - if (!animate || !me.anim) { - - prop = 'scroll' + (top ? 'Top' : 'Left'); - dom[prop] = value; - } - else { - - prop = 'scroll' + (top ? 'Left' : 'Top'); - me.anim({scroll: {to: top ? [dom[prop], value] : [value, dom[prop]]}}, me.preanim(arguments, 2), 'scroll'); + onBatchComplete: function(batch, operation) { + var me = this, + operations = batch.operations, + length = operations.length, + i; + + me.suspendEvents(); + + for (i = 0; i < length; i++) { + me.onProxyWrite(operations[i]); } - return me; + + me.resumeEvents(); + + me.fireEvent('datachanged', me); }, - - - scrollIntoView : function(container, hscroll) { - var c = Ext.getDom(container) || Ext.getBody().dom, - el = this.dom, - o = this.getOffsetsTo(c), - l = o[0] + c.scrollLeft, - t = o[1] + c.scrollTop, - b = t + el.offsetHeight, - r = l + el.offsetWidth, - ch = c.clientHeight, - ct = parseInt(c.scrollTop, 10), - cl = parseInt(c.scrollLeft, 10), - cb = ct + ch, - cr = cl + c.clientWidth; - if (el.offsetHeight > ch || t < ct) { - c.scrollTop = t; - } - else if (b > cb) { - c.scrollTop = b-ch; - } + onBatchException: function(batch, operation) { + + + - c.scrollTop = c.scrollTop; + + }, - if (hscroll !== false) { - if (el.offsetWidth > c.clientWidth || l < cl) { - c.scrollLeft = l; - } - else if (r > cr) { - c.scrollLeft = r - c.clientWidth; - } - c.scrollLeft = c.scrollLeft; - } - return this; + + filterNew: function(item) { + + return item.phantom === true && item.isValid(); }, - scrollChildIntoView : function(child, hscroll) { - Ext.fly(child, '_scrollChildIntoView').scrollIntoView(this, hscroll); + getNewRecords: function() { + return []; }, + + getUpdatedRecords: function() { + return []; + }, + - scroll : function(direction, distance, animate) { - if (!this.isScrollable()) { - return false; - } - var el = this.dom, - l = el.scrollLeft, t = el.scrollTop, - w = el.scrollWidth, h = el.scrollHeight, - cw = el.clientWidth, ch = el.clientHeight, - scrolled = false, v, - hash = { - l: Math.min(l + distance, w-cw), - r: v = Math.max(l - distance, 0), - t: Math.max(t - distance, 0), - b: Math.min(t + distance, h-ch) - }; - hash.d = hash.b; - hash.u = hash.t; + filterUpdated: function(item) { - direction = direction.substr(0, 1); - if ((v = hash[direction]) > -1) { - scrolled = true; - this.scrollTo(direction == 'l' || direction == 'r' ? 'left' : 'top', v, this.preanim(arguments, 2)); - } - return scrolled; - } -}); -Ext.Element.addMethods( - function() { - var VISIBILITY = "visibility", - DISPLAY = "display", - HIDDEN = "hidden", - NONE = "none", - XMASKED = "x-masked", - XMASKEDRELATIVE = "x-masked-relative", - data = Ext.Element.data; + return item.dirty === true && item.phantom !== true && item.isValid(); + }, - return { - - isVisible : function(deep) { - var vis = !this.isStyle(VISIBILITY, HIDDEN) && !this.isStyle(DISPLAY, NONE), - p = this.dom.parentNode; - - if (deep !== true || !vis) { - return vis; - } - - while (p && !(/^body/i.test(p.tagName))) { - if (!Ext.fly(p, '_isVisible').isVisible()) { - return false; - } - p = p.parentNode; - } - return true; - }, + + getRemovedRecords: function() { + return this.removed; + }, - - isDisplayed : function() { - return !this.isStyle(DISPLAY, NONE); - }, + filter: function(filters, value) { + + }, - - enableDisplayMode : function(display) { - this.setVisibilityMode(Ext.Element.DISPLAY); - - if (!Ext.isEmpty(display)) { - data(this.dom, 'originalDisplay', display); - } - - return this; - }, + + decodeFilters: function(filters) { + if (!Ext.isArray(filters)) { + if (filters === undefined) { + filters = []; + } else { + filters = [filters]; + } + } - - mask : function(msg, msgCls) { - var me = this, - dom = me.dom, - dh = Ext.DomHelper, - EXTELMASKMSG = "ext-el-mask-msg", - el, - mask; + var length = filters.length, + Filter = Ext.util.Filter, + config, i; - if (!(/^body/i.test(dom.tagName) && me.getStyle('position') == 'static')) { - me.addClass(XMASKEDRELATIVE); - } - if (el = data(dom, 'maskMsg')) { - el.remove(); - } - if (el = data(dom, 'mask')) { - el.remove(); - } + for (i = 0; i < length; i++) { + config = filters[i]; - mask = dh.append(dom, {cls : "ext-el-mask"}, true); - data(dom, 'mask', mask); + if (!(config instanceof Filter)) { + Ext.apply(config, { + root: 'data' + }); - me.addClass(XMASKED); - mask.setDisplayed(true); - if (typeof msg == 'string') { - var mm = dh.append(dom, {cls : EXTELMASKMSG, cn:{tag:'div'}}, true); - data(dom, 'maskMsg', mm); - mm.dom.className = msgCls ? EXTELMASKMSG + " " + msgCls : EXTELMASKMSG; - mm.dom.firstChild.innerHTML = msg; - mm.setDisplayed(true); - mm.center(me); + if (config.fn) { + config.filterFn = config.fn; } + - - if (Ext.isIE && !(Ext.isIE7 && Ext.isStrict) && me.getStyle('height') == 'auto') { - mask.setSize(undefined, me.getHeight()); + if (typeof config == 'function') { + config = { + filterFn: config + }; } - - return mask; - }, - - unmask : function() { - var me = this, - dom = me.dom, - mask = data(dom, 'mask'), - maskMsg = data(dom, 'maskMsg'); + filters[i] = new Filter(config); + } + } - if (mask) { - if (maskMsg) { - maskMsg.remove(); - data(dom, 'maskMsg', undefined); - } - - mask.remove(); - data(dom, 'mask', undefined); - me.removeClass([XMASKED, XMASKEDRELATIVE]); - } - }, + return filters; + }, - - isMasked : function() { - var m = data(this.dom, 'mask'); - return m && m.isVisible(); - }, + clearFilter: function(supressEvent) { + + }, + + isFiltered: function() { - - createShim : function() { - var el = document.createElement('iframe'), - shim; - - el.frameBorder = '0'; - el.className = 'ext-shim'; - el.src = Ext.SSL_SECURE_URL; - shim = Ext.get(this.dom.parentNode.insertBefore(el, this.dom)); - shim.autoBoxAdjust = false; - return shim; - } - }; - }() -); -Ext.Element.addMethods({ - - addKeyListener : function(key, fn, scope){ - var config; - if(typeof key != 'object' || Ext.isArray(key)){ - config = { - key: key, - fn: fn, - scope: scope - }; - }else{ - config = { - key : key.key, - shift : key.shift, - ctrl : key.ctrl, - alt : key.alt, - fn: fn, - scope: scope - }; - } - return new Ext.KeyMap(this, config); }, + filterBy: function(fn, scope) { + + }, - addKeyMap : function(config){ - return new Ext.KeyMap(this, config); - } -}); + + sync: function() { + var me = this, + options = {}, + toCreate = me.getNewRecords(), + toUpdate = me.getUpdatedRecords(), + toDestroy = me.getRemovedRecords(), + needsSync = false; + if (toCreate.length > 0) { + options.create = toCreate; + needsSync = true; + } + if (toUpdate.length > 0) { + options.update = toUpdate; + needsSync = true; + } -Ext.CompositeElementLite.importElementMethods(); -Ext.apply(Ext.CompositeElementLite.prototype, { - addElements : function(els, root){ - if(!els){ - return this; + if (toDestroy.length > 0) { + options.destroy = toDestroy; + needsSync = true; } - if(typeof els == "string"){ - els = Ext.Element.selectorFunction(els, root); + + if (needsSync && me.fireEvent('beforesync', options) !== false) { + me.proxy.batch(options, me.getBatchListeners()); } - var yels = this.elements; - Ext.each(els, function(e) { - yels.push(Ext.get(e)); - }); - return this; }, - - first : function(){ - return this.item(0); - }, - last : function(){ - return this.item(this.getCount()-1); + getBatchListeners: function() { + var me = this, + listeners = { + scope: me, + exception: me.onBatchException + }; + + if (me.batchUpdateMode == 'operation') { + listeners.operationcomplete = me.onBatchOperationComplete; + } else { + listeners.complete = me.onBatchComplete; + } + + return listeners; }, - contains : function(el){ - return this.indexOf(el) != -1; + save: function() { + return this.sync.apply(this, arguments); }, - removeElement : function(keys, removeDom){ + load: function(options) { var me = this, - els = this.elements, - el; - Ext.each(keys, function(val){ - if ((el = (els[val] || els[val = me.indexOf(val)]))) { - if(removeDom){ - if(el.dom){ - el.remove(); - }else{ - Ext.removeNode(el); - } - } - els.splice(val, 1); - } + operation; + + options = options || {}; + + Ext.applyIf(options, { + action : 'read', + filters: me.filters.items, + sorters: me.getSorters() }); - return this; - } -}); + + operation = Ext.create('Ext.data.Operation', options); + + if (me.fireEvent('beforeload', me, operation) !== false) { + me.loading = true; + me.proxy.read(operation, me.onProxyLoad, me); + } + + return me; + }, -Ext.CompositeElement = Ext.extend(Ext.CompositeElementLite, { - constructor : function(els, root){ - this.elements = []; - this.add(els, root); + afterEdit : function(record) { + var me = this; + + if (me.autoSync) { + me.sync(); + } + + me.fireEvent('update', me, record, Ext.data.Model.EDIT); }, + + afterReject : function(record) { + this.fireEvent('update', this, record, Ext.data.Model.REJECT); + }, + - getElement : function(el){ + afterCommit : function(record) { + this.fireEvent('update', this, record, Ext.data.Model.COMMIT); + }, + + clearData: Ext.emptyFn, + + destroyStore: function() { + var me = this; - return el; + if (!me.isDestroyed) { + if (me.storeId) { + Ext.data.StoreManager.unregister(me); + } + me.clearData(); + me.data = null; + me.tree = null; + + me.reader = me.writer = null; + me.clearListeners(); + me.isDestroyed = true; + + if (me.implicitModel) { + Ext.destroy(me.model); + } + } }, + doSort: function(sorterFn) { + var me = this; + if (me.remoteSort) { + + me.load(); + } else { + me.data.sortBy(sorterFn); + me.fireEvent('datachanged', me); + } + }, + + getCount: Ext.emptyFn, + + getById: Ext.emptyFn, - transformElement : function(el){ - return Ext.get(el); - } + + removeAll: Ext.emptyFn, + + + + + isLoading: function() { + return this.loading; + } +}); + + + +Ext.define('Ext.util.Grouper', { + extend: 'Ext.util.Sorter', + + getGroupString: function(instance) { + return instance.get(this.property); + } }); +Ext.define('Ext.data.Store', { + extend: 'Ext.data.AbstractStore', -Ext.Element.select = function(selector, unique, root){ - var els; - if(typeof selector == "string"){ - els = Ext.Element.selectorFunction(selector, root); - }else if(selector.length !== undefined){ - els = selector; - }else{ - throw "Invalid selector"; - } + alias: 'store.store', - return (unique === true) ? new Ext.CompositeElement(els) : new Ext.CompositeElementLite(els); -}; + requires: ['Ext.ModelManager', 'Ext.data.Model', 'Ext.util.Grouper'], + uses: ['Ext.data.proxy.Memory'], + + remoteSort: false, -Ext.select = Ext.Element.select; -Ext.UpdateManager = Ext.Updater = Ext.extend(Ext.util.Observable, -function() { - var BEFOREUPDATE = "beforeupdate", - UPDATE = "update", - FAILURE = "failure"; + + remoteFilter: false, + + + remoteGroup : false, - function processSuccess(response){ - var me = this; - me.transaction = null; - if (response.argument.form && response.argument.reset) { - try { - response.argument.form.reset(); - } catch(e){} - } - if (me.loadScripts) { - me.renderer.render(me.el, response, me, - updateComplete.createDelegate(me, [response])); - } else { - me.renderer.render(me.el, response, me); - updateComplete.call(me, response); - } - } - function updateComplete(response, type, success){ - this.fireEvent(type || UPDATE, this.el, response); - if(Ext.isFunction(response.argument.callback)){ - response.argument.callback.call(response.argument.scope, this.el, Ext.isEmpty(success) ? true : false, response, response.argument.options); - } - } - function processFailure(response){ - updateComplete.call(this, response, FAILURE, !!(this.transaction = null)); - } - return { - constructor: function(el, forceNew){ - var me = this; - el = Ext.get(el); - if(!forceNew && el.updateManager){ - return el.updateManager; - } - - me.el = el; - - me.defaultUrl = null; + + groupField: undefined, - me.addEvents( - - BEFOREUPDATE, - - UPDATE, - - FAILURE - ); + + groupDir: "ASC", - Ext.apply(me, Ext.Updater.defaults); - - - - - - + + pageSize: 25, + + + currentPage: 1, + + + clearOnPageLoad: true, + + + loading: false, + + + sortOnFilter: true, + + + buffered: false, + + + purgePageCount: 5, + + isStore: true, + + + constructor: function(config) { + config = config || {}; + var me = this, + groupers = config.groupers, + proxy, + data; - me.transaction = null; + if (config.buffered || me.buffered) { + me.prefetchData = Ext.create('Ext.util.MixedCollection', false, function(record) { + return record.index; + }); + me.pendingRequests = []; + me.pagesRequested = []; - me.refreshDelegate = me.refresh.createDelegate(me); + me.sortOnLoad = false; + me.filterOnLoad = false; + } - me.updateDelegate = me.update.createDelegate(me); + me.addEvents( - me.formUpdateDelegate = (me.formUpdate || function(){}).createDelegate(me); - + 'beforeprefetch', - me.renderer = me.renderer || me.getDefaultRenderer(); - - Ext.Updater.superclass.constructor.call(me); - }, + 'groupchange', + + 'prefetch' + ); + data = config.data || me.data; - setRenderer : function(renderer){ - this.renderer = renderer; - }, + me.data = Ext.create('Ext.util.MixedCollection', false, function(record) { + return record.internalId; + }); + if (data) { + me.inlineData = data; + delete config.data; + } - getRenderer : function(){ - return this.renderer; - }, - + if (!groupers && config.groupField) { + groupers = [{ + property : config.groupField, + direction: config.groupDir + }]; + } + delete config.groupers; - getDefaultRenderer: function() { - return new Ext.Updater.BasicRenderer(); - }, - - setDefaultUrl : function(defaultUrl){ - this.defaultUrl = defaultUrl; - }, + me.groupers = Ext.create('Ext.util.MixedCollection'); + me.groupers.addAll(me.decodeGroupers(groupers)); + this.callParent([config]); - getEl : function(){ - return this.el; - }, + if (me.groupers.items.length) { + me.sort(me.groupers.items, 'prepend', false); + } - - update : function(url, params, callback, discardUrl){ - var me = this, - cfg, - callerScope; - - if(me.fireEvent(BEFOREUPDATE, me.el, url, params) !== false){ - if(Ext.isObject(url)){ - cfg = url; - url = cfg.url; - params = params || cfg.params; - callback = callback || cfg.callback; - discardUrl = discardUrl || cfg.discardUrl; - callerScope = cfg.scope; - if(!Ext.isEmpty(cfg.nocache)){me.disableCaching = cfg.nocache;}; - if(!Ext.isEmpty(cfg.text)){me.indicatorText = '
'+cfg.text+"
";}; - if(!Ext.isEmpty(cfg.scripts)){me.loadScripts = cfg.scripts;}; - if(!Ext.isEmpty(cfg.timeout)){me.timeout = cfg.timeout;}; - } - me.showLoading(); - - if(!discardUrl){ - me.defaultUrl = url; - } - if(Ext.isFunction(url)){ - url = url.call(me); - } - - var o = Ext.apply({}, { - url : url, - params: (Ext.isFunction(params) && callerScope) ? params.createDelegate(callerScope) : params, - success: processSuccess, - failure: processFailure, - scope: me, - callback: undefined, - timeout: (me.timeout*1000), - disableCaching: me.disableCaching, - argument: { - "options": cfg, - "url": url, - "form": null, - "callback": callback, - "scope": callerScope || window, - "params": params - } - }, cfg); + proxy = me.proxy; + data = me.inlineData; - me.transaction = Ext.Ajax.request(o); + if (data) { + if (proxy instanceof Ext.data.proxy.Memory) { + proxy.data = data; + me.read(); + } else { + me.add.apply(me, data); } - }, - - formUpdate : function(form, url, reset, callback){ - var me = this; - if(me.fireEvent(BEFOREUPDATE, me.el, form, url) !== false){ - if(Ext.isFunction(url)){ - url = url.call(me); - } - form = Ext.getDom(form); - me.transaction = Ext.Ajax.request({ - form: form, - url:url, - success: processSuccess, - failure: processFailure, - scope: me, - timeout: (me.timeout*1000), - argument: { - "url": url, - "form": form, - "callback": callback, - "reset": reset - } - }); - me.showLoading.defer(1, me); + me.sort(); + delete me.inlineData; + } else if (me.autoLoad) { + Ext.defer(me.load, 10, me, [typeof me.autoLoad === 'object' ? me.autoLoad: undefined]); + + + } + }, + + onBeforeSort: function() { + this.sort(this.groupers.items, 'prepend', false); + }, + + + decodeGroupers: function(groupers) { + if (!Ext.isArray(groupers)) { + if (groupers === undefined) { + groupers = []; + } else { + groupers = [groupers]; } - }, + } - - startAutoRefresh : function(interval, url, params, callback, refreshNow){ - var me = this; - if(refreshNow){ - me.update(url || me.defaultUrl, params, callback, true); - } - if(me.autoRefreshProcId){ - clearInterval(me.autoRefreshProcId); - } - me.autoRefreshProcId = setInterval(me.update.createDelegate(me, [url || me.defaultUrl, params, callback, true]), interval * 1000); - }, + var length = groupers.length, + Grouper = Ext.util.Grouper, + config, i; - - stopAutoRefresh : function(){ - if(this.autoRefreshProcId){ - clearInterval(this.autoRefreshProcId); - delete this.autoRefreshProcId; + for (i = 0; i < length; i++) { + config = groupers[i]; + + if (!(config instanceof Grouper)) { + if (Ext.isString(config)) { + config = { + property: config + }; + } + + Ext.applyIf(config, { + root : 'data', + direction: "ASC" + }); + + + if (config.fn) { + config.sorterFn = config.fn; + } + + + if (typeof config == 'function') { + config = { + sorterFn: config + }; + } + + groupers[i] = new Grouper(config); } - }, + } + return groupers; + }, + + + group: function(groupers, direction) { + var me = this, + grouper, + newGroupers; + + if (Ext.isArray(groupers)) { + newGroupers = groupers; + } else if (Ext.isObject(groupers)) { + newGroupers = [groupers]; + } else if (Ext.isString(groupers)) { + grouper = me.groupers.get(groupers); + + if (!grouper) { + grouper = { + property : groupers, + direction: direction + }; + newGroupers = [grouper]; + } else if (direction === undefined) { + grouper.toggle(); + } else { + grouper.setDirection(direction); + } + } - isAutoRefreshing : function(){ - return !!this.autoRefreshProcId; - }, - + if (newGroupers && newGroupers.length) { + 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); + } + }, + + + clearGrouping: function(){ + var me = this; - showLoading : function(){ - if(this.showLoadIndicator){ - this.el.dom.innerHTML = this.indicatorText; + me.groupers.each(function(grouper){ + me.sorters.remove(grouper); + }); + me.groupers.clear(); + if (me.remoteGroup) { + me.load({ + scope: me, + callback: me.fireGroupChange + }); + } else { + me.sort(); + me.fireEvent('groupchange', me, me.groupers); + } + }, + + + isGrouped: function() { + return this.groupers.getCount() > 0; + }, + + + fireGroupChange: function(){ + this.fireEvent('groupchange', this, this.groupers); + }, + + + getGroups: function(requestGroupString) { + var records = this.data.items, + length = records.length, + groups = [], + pointers = {}, + record, + groupStr, + group, + i; + + for (i = 0; i < length; i++) { + record = records[i]; + groupStr = this.getGroupString(record); + group = pointers[groupStr]; + + if (group === undefined) { + group = { + name: groupStr, + children: [] + }; + + groups.push(group); + pointers[groupStr] = group; } - }, - - abort : function(){ - if(this.transaction){ - Ext.Ajax.abort(this.transaction); + group.children.push(record); + } + + return requestGroupString ? pointers[requestGroupString] : groups; + }, + + + getGroupsForGrouper: function(records, grouper) { + var length = records.length, + groups = [], + oldValue, + newValue, + record, + group, + i; + + for (i = 0; i < length; i++) { + record = records[i]; + newValue = grouper.getGroupString(record); + + if (newValue !== oldValue) { + group = { + name: newValue, + grouper: grouper, + records: [] + }; + groups.push(group); } - }, - - isUpdating : function(){ - return this.transaction ? Ext.Ajax.isLoading(this.transaction) : false; - }, + group.records.push(record); - - refresh : function(callback){ - if(this.defaultUrl){ - this.update(this.defaultUrl, null, callback, true); + oldValue = newValue; + } + + return groups; + }, + + + getGroupsForGrouperIndex: function(records, grouperIndex) { + var me = this, + groupers = me.groupers, + grouper = groupers.getAt(grouperIndex), + groups = me.getGroupsForGrouper(records, grouper), + length = groups.length, + i; + + if (grouperIndex + 1 < groupers.length) { + for (i = 0; i < length; i++) { + groups[i].children = me.getGroupsForGrouperIndex(groups[i].records, grouperIndex + 1); } } - }; -}()); + for (i = 0; i < length; i++) { + groups[i].depth = grouperIndex; + } + + return groups; + }, -Ext.Updater.defaults = { - - timeout : 30, - disableCaching : false, + getGroupData: function(sort) { + var me = this; + if (sort !== false) { + me.sort(); + } + + return me.getGroupsForGrouperIndex(me.data.items, 0); + }, + - showLoadIndicator : true, + getGroupString: function(instance) { + var group = this.groupers.first(); + if (group) { + return instance.get(group.property); + } + return ''; + }, - indicatorText : '
Loading...
', - - loadScripts : false, + insert: function(index, records) { + var me = this, + sync = false, + i, + record, + len; + + records = [].concat(records); + for (i = 0, len = records.length; i < len; i++) { + record = me.createModel(records[i]); + record.set(me.modelDefaults); + + records[i] = record; + + me.data.insert(index + i, record); + record.join(me); + + sync = sync || record.phantom === true; + } + + if (me.snapshot) { + me.snapshot.addAll(records); + } + + me.fireEvent('add', me, records, index); + me.fireEvent('datachanged', me); + if (me.autoSync && sync) { + me.sync(); + } + }, + - sslBlankUrl : Ext.SSL_SECURE_URL -}; + add: function(records) { + + if (!Ext.isArray(records)) { + records = Array.prototype.slice.apply(arguments); + } + + var me = this, + i = 0, + length = records.length, + record; + for (; i < length; i++) { + record = me.createModel(records[i]); + + records[i] = record; + } + me.insert(me.data.length, records); -Ext.Updater.updateElement = function(el, url, params, options){ - var um = Ext.get(el).getUpdater(); - Ext.apply(um, options); - um.update(url, params, options ? options.callback : null); -}; + return records; + }, + + createModel: function(record) { + if (!record.isModel) { + record = Ext.ModelManager.create(record, this.model); + } -Ext.Updater.BasicRenderer = function(){}; + return record; + }, -Ext.Updater.BasicRenderer.prototype = { - render : function(el, response, updateManager, callback){ - el.update(response.responseText, updateManager.loadScripts, callback); - } -}; + each: function(fn, scope) { + this.data.each(fn, scope); + }, + + remove: function(records, isMove) { + if (!Ext.isArray(records)) { + records = [records]; + } + + isMove = isMove === true; + var me = this, + sync = false, + i = 0, + length = records.length, + isPhantom, + index, + record; -(function() { + for (; i < length; i++) { + record = records[i]; + index = me.data.indexOf(record); + + if (me.snapshot) { + me.snapshot.remove(record); + } + + if (index > -1) { + isPhantom = record.phantom === true; + if (!isMove && !isPhantom) { + + me.removed.push(record); + } + record.unjoin(me); + me.data.remove(record); + sync = sync || !isPhantom; -Date.useStrict = false; + me.fireEvent('remove', me, record, index); + } + } + me.fireEvent('datachanged', me); + if (!isMove && me.autoSync && sync) { + me.sync(); + } + }, + + removeAt: function(index) { + var record = this.getAt(index); + if (record) { + this.remove(record); + } + }, + + load: function(options) { + var me = this; + + options = options || {}; -function xf(format) { - var args = Array.prototype.slice.call(arguments, 1); - return format.replace(/\{(\d+)\}/g, function(m, i) { - return args[i]; - }); -} + if (Ext.isFunction(options)) { + options = { + callback: options + }; + } + Ext.applyIf(options, { + groupers: me.groupers.items, + page: me.currentPage, + start: (me.currentPage - 1) * me.pageSize, + limit: me.pageSize, + addRecords: false + }); + return me.callParent([options]); + }, -Date.formatCodeToRegex = function(character, currentGroup) { - var p = Date.parseCodes[character]; + onProxyLoad: function(operation) { + var me = this, + resultSet = operation.getResultSet(), + records = operation.getRecords(), + successful = operation.wasSuccessful(); - if (p) { - p = typeof p == 'function'? p() : p; - Date.parseCodes[character] = p; - } + if (resultSet) { + me.totalCount = resultSet.total; + } - return p ? Ext.applyIf({ - c: p.c ? xf(p.c, currentGroup || "{0}") : p.c - }, p) : { - g:0, - c:null, - s:Ext.escapeRe(character) - }; -}; + if (successful) { + me.loadRecords(records, operation); + } + me.loading = false; + me.fireEvent('load', me, records, successful); -var $f = Date.formatCodeToRegex; + + + me.fireEvent('read', me, records, operation.wasSuccessful()); -Ext.apply(Date, { + + Ext.callback(operation.callback, operation.scope || me, [records, operation, successful]); + }, - parseFunctions: { - "M$": function(input, strict) { - + + onCreateRecords: function(records, operation, success) { + if (success) { + var i = 0, + data = this.data, + snapshot = this.snapshot, + length = records.length, + originalRecords = operation.records, + record, + original, + index; + - var re = new RegExp('\\/Date\\(([-+])?(\\d+)(?:[+-]\\d{4})?\\)\\/'); - var r = (input || '').match(re); - return r? new Date(((r[1] || '') + r[2]) * 1) : null; + for (; i < length; ++i) { + record = records[i]; + original = originalRecords[i]; + if (original) { + index = data.indexOf(original); + if (index > -1) { + data.removeAt(index); + data.insert(index, record); + } + if (snapshot) { + index = snapshot.indexOf(original); + if (index > -1) { + snapshot.removeAt(index); + snapshot.insert(index, record); + } + } + record.phantom = false; + record.join(this); + } + } } }, - parseRegexes: [], - formatFunctions: { - "M$": function() { - - return '\\/Date(' + this.getTime() + ')\\/'; + 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 = []; } }, - y2kYear : 50, - - MILLI : "ms", + getNewRecords: function() { + return this.data.filterBy(this.filterNew).items; + }, - SECOND : "s", + getUpdatedRecords: function() { + return this.data.filterBy(this.filterUpdated).items; + }, - MINUTE : "mi", + filter: function(filters, value) { + if (Ext.isString(filters)) { + filters = { + property: filters, + value: value + }; + } - - HOUR : "h", + var me = this, + decoded = me.decodeFilters(filters), + i = 0, + doLocalSort = me.sortOnFilter && !me.remoteSort, + length = decoded.length; - - DAY : "d", + for (; i < length; i++) { + me.filters.replace(decoded[i]); + } - - MONTH : "mo", + 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); - - YEAR : "y", + if (doLocalSort) { + me.sort(); + } + + if (!doLocalSort || me.sorters.length < 1) { + me.fireEvent('datachanged', me); + } + } + } + }, - defaults: {}, + clearFilter: function(suppressEvent) { + var me = this; - - dayNames : [ - "Sunday", - "Monday", - "Tuesday", - "Wednesday", - "Thursday", - "Friday", - "Saturday" - ], + me.filters.clear(); - - monthNames : [ - "January", - "February", - "March", - "April", - "May", - "June", - "July", - "August", - "September", - "October", - "November", - "December" - ], + if (me.remoteFilter) { + me.load(); + } else if (me.isFiltered()) { + me.data = me.snapshot.clone(); + delete me.snapshot; - - monthNumbers : { - Jan:0, - Feb:1, - Mar:2, - Apr:3, - May:4, - Jun:5, - Jul:6, - Aug:7, - Sep:8, - Oct:9, - Nov:10, - Dec:11 + if (suppressEvent !== true) { + me.fireEvent('datachanged', me); + } + } }, - getShortMonthName : function(month) { - return Date.monthNames[month].substring(0, 3); + isFiltered: function() { + var snapshot = this.snapshot; + return !! snapshot && snapshot !== this.data; }, - getShortDayName : function(day) { - return Date.dayNames[day].substring(0, 3); + 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); }, - getMonthNumber : function(name) { - - return Date.monthNumbers[name.substring(0, 1).toUpperCase() + name.substring(1, 3).toLowerCase()]; + queryBy: function(fn, scope) { + var me = this, + data = me.snapshot || me.data; + return data.filterBy(fn, scope || me); }, - formatCodes : { - d: "String.leftPad(this.getDate(), 2, '0')", - D: "Date.getShortDayName(this.getDay())", - j: "this.getDate()", - l: "Date.dayNames[this.getDay()]", - N: "(this.getDay() ? this.getDay() : 7)", - S: "this.getSuffix()", - w: "this.getDay()", - z: "this.getDayOfYear()", - W: "String.leftPad(this.getWeekOfYear(), 2, '0')", - F: "Date.monthNames[this.getMonth()]", - m: "String.leftPad(this.getMonth() + 1, 2, '0')", - M: "Date.getShortMonthName(this.getMonth())", - n: "(this.getMonth() + 1)", - t: "this.getDaysInMonth()", - L: "(this.isLeapYear() ? 1 : 0)", - o: "(this.getFullYear() + (this.getWeekOfYear() == 1 && this.getMonth() > 0 ? +1 : (this.getWeekOfYear() >= 52 && this.getMonth() < 11 ? -1 : 0)))", - Y: "String.leftPad(this.getFullYear(), 4, '0')", - y: "('' + this.getFullYear()).substring(2, 4)", - a: "(this.getHours() < 12 ? 'am' : 'pm')", - A: "(this.getHours() < 12 ? 'AM' : 'PM')", - g: "((this.getHours() % 12) ? this.getHours() % 12 : 12)", - G: "this.getHours()", - h: "String.leftPad((this.getHours() % 12) ? this.getHours() % 12 : 12, 2, '0')", - H: "String.leftPad(this.getHours(), 2, '0')", - i: "String.leftPad(this.getMinutes(), 2, '0')", - s: "String.leftPad(this.getSeconds(), 2, '0')", - u: "String.leftPad(this.getMilliseconds(), 3, '0')", - O: "this.getGMTOffset()", - P: "this.getGMTOffset(true)", - T: "this.getTimezone()", - Z: "(this.getTimezoneOffset() * -60)", + loadData: function(data, append) { + var model = this.model, + length = data.length, + i, + record; - c: function() { - for (var c = "Y-m-dTH:i:sP", code = [], i = 0, l = c.length; i < l; ++i) { - var e = c.charAt(i); - code.push(e == "T" ? "'T'" : Date.getFormatCode(e)); - } - return code.join(" + "); - }, + for (i = 0; i < length; i++) { + record = data[i]; - U: "Math.round(this.getTime() / 1000)" + if (! (record instanceof Ext.data.Model)) { + data[i] = Ext.ModelManager.create(record, model); + } + } + + this.loadRecords(data, {addRecords: append}); }, - isValid : function(y, m, d, h, i, s, ms) { - - h = h || 0; - i = i || 0; - s = s || 0; - ms = ms || 0; + loadRecords: function(records, options) { + var me = this, + i = 0, + length = records.length; - - var dt = new Date(y < 100 ? 100 : y, m - 1, d, h, i, s, ms).add(Date.YEAR, y < 100 ? y - 100 : 0); + options = options || {}; - return y == dt.getFullYear() && - m == dt.getMonth() + 1 && - d == dt.getDate() && - h == dt.getHours() && - i == dt.getMinutes() && - s == dt.getSeconds() && - ms == dt.getMilliseconds(); - }, - - parseDate : function(input, format, strict) { - var p = Date.parseFunctions; - if (p[format] == null) { - Date.createParser(format); + if (!options.addRecords) { + delete me.snapshot; + me.data.clear(); } - return p[format](input, Ext.isDefined(strict) ? strict : Date.useStrict); - }, - - getFormatCode : function(character) { - var f = Date.formatCodes[character]; + me.data.addAll(records); - if (f) { - f = typeof f == 'function'? f() : f; - Date.formatCodes[character] = f; + + for (; i < length; i++) { + if (options.start !== undefined) { + records[i].index = options.start + i; + + } + records[i].join(me); } - return f || ("'" + String.escape(character) + "'"); - }, + me.suspendEvents(); - - createFormat : function(format) { - var code = [], - special = false, - ch = ''; + if (me.filterOnLoad && !me.remoteFilter) { + me.filter(); + } - for (var i = 0; i < format.length; ++i) { - ch = format.charAt(i); - if (!special && ch == "\\") { - special = true; - } else if (special) { - special = false; - code.push("'" + String.escape(ch) + "'"); - } else { - code.push(Date.getFormatCode(ch)); - } + if (me.sortOnLoad && !me.remoteSort) { + me.sort(); } - Date.formatFunctions[format] = new Function("return " + code.join('+')); + + me.resumeEvents(); + me.fireEvent('datachanged', me, records); }, - createParser : function() { - var code = [ - "var dt, y, m, d, h, i, s, ms, o, z, zz, u, v,", - "def = Date.defaults,", - "results = String(input).match(Date.parseRegexes[{0}]);", - - "if(results){", - "{1}", - - "if(u != null){", - "v = new Date(u * 1000);", - "}else{", - - - - "dt = (new Date()).clearTime();", - - - "y = Ext.num(y, Ext.num(def.y, dt.getFullYear()));", - "m = Ext.num(m, Ext.num(def.m - 1, dt.getMonth()));", - "d = Ext.num(d, Ext.num(def.d, dt.getDate()));", + + loadPage: function(page) { + var me = this; - - "h = Ext.num(h, Ext.num(def.h, dt.getHours()));", - "i = Ext.num(i, Ext.num(def.i, dt.getMinutes()));", - "s = Ext.num(s, Ext.num(def.s, dt.getSeconds()));", - "ms = Ext.num(ms, Ext.num(def.ms, dt.getMilliseconds()));", + me.currentPage = page; - "if(z >= 0 && y >= 0){", - - + me.read({ + page: page, + start: (page - 1) * me.pageSize, + limit: me.pageSize, + addRecords: !me.clearOnPageLoad + }); + }, - - - "v = new Date(y < 100 ? 100 : y, 0, 1, h, i, s, ms).add(Date.YEAR, y < 100 ? y - 100 : 0);", + + nextPage: function() { + this.loadPage(this.currentPage + 1); + }, - - "v = !strict? v : (strict === true && (z <= 364 || (v.isLeapYear() && z <= 365))? v.add(Date.DAY, z) : null);", - "}else if(strict === true && !Date.isValid(y, m + 1, d, h, i, s, ms)){", - "v = null;", - "}else{", - - - "v = new Date(y < 100 ? 100 : y, m, d, h, i, s, ms).add(Date.YEAR, y < 100 ? y - 100 : 0);", - "}", - "}", - "}", + + previousPage: function() { + this.loadPage(this.currentPage - 1); + }, - "if(v){", - - "if(zz != null){", - - "v = v.add(Date.SECOND, -v.getTimezoneOffset() * 60 - zz);", - "}else if(o){", - - "v = v.add(Date.MINUTE, -v.getTimezoneOffset() + (sn == '+'? -1 : 1) * (hr * 60 + mn));", - "}", - "}", + + clearData: function() { + this.data.each(function(record) { + record.unjoin(); + }); - "return v;" - ].join('\n'); + this.data.clear(); + }, + + + + prefetch: function(options) { + var me = this, + operation, + requestId = me.getRequestId(); - return function(format) { - var regexNum = Date.parseRegexes.length, - currentGroup = 1, - calc = [], - regex = [], - special = false, - ch = "", - i = 0, - obj, - last; + options = options || {}; - for (; i < format.length; ++i) { - ch = format.charAt(i); - if (!special && ch == "\\") { - special = true; - } else if (special) { - special = false; - regex.push(String.escape(ch)); - } else { - obj = $f(ch, currentGroup); - currentGroup += obj.g; - regex.push(obj.s); - if (obj.g && obj.c) { - if (obj.calcLast) { - last = obj.c; - } else { - calc.push(obj.c); - } - } - } - } - - if (last) { - calc.push(last); - } + Ext.applyIf(options, { + action : 'read', + filters: me.filters.items, + sorters: me.sorters.items, + requestId: requestId + }); + me.pendingRequests.push(requestId); - Date.parseRegexes[regexNum] = new RegExp("^" + regex.join('') + "$", 'i'); - Date.parseFunctions[format] = new Function("input", "strict", xf(code, regexNum, calc.join(''))); - }; - }(), + operation = Ext.create('Ext.data.Operation', options); - - parseCodes : { - d: { - g:1, - c:"d = parseInt(results[{0}], 10);\n", - s:"(\\d{2})" - }, - j: { - g:1, - c:"d = parseInt(results[{0}], 10);\n", - s:"(\\d{1,2})" - }, - D: function() { - for (var a = [], i = 0; i < 7; a.push(Date.getShortDayName(i)), ++i); - return { - g:0, - c:null, - s:"(?:" + a.join("|") +")" - }; - }, - l: function() { - return { - g:0, - c:null, - s:"(?:" + Date.dayNames.join("|") + ")" - }; - }, - N: { - g:0, - c:null, - s:"[1-7]" - }, - S: { - g:0, - c:null, - s:"(?:st|nd|rd|th)" - }, - w: { - g:0, - c:null, - s:"[0-6]" - }, - z: { - g:1, - c:"z = parseInt(results[{0}], 10);\n", - s:"(\\d{1,3})" - }, - W: { - g:0, - c:null, - s:"(?:\\d{2})" - }, - F: function() { - return { - g:1, - c:"m = parseInt(Date.getMonthNumber(results[{0}]), 10);\n", - s:"(" + Date.monthNames.join("|") + ")" - }; - }, - M: function() { - for (var a = [], i = 0; i < 12; a.push(Date.getShortMonthName(i)), ++i); - return Ext.applyIf({ - s:"(" + a.join("|") + ")" - }, $f("F")); - }, - m: { - g:1, - c:"m = parseInt(results[{0}], 10) - 1;\n", - s:"(\\d{2})" - }, - n: { - g:1, - c:"m = parseInt(results[{0}], 10) - 1;\n", - s:"(\\d{1,2})" - }, - t: { - g:0, - c:null, - s:"(?:\\d{2})" - }, - L: { - g:0, - c:null, - s:"(?:1|0)" - }, - o: function() { - return $f("Y"); - }, - Y: { - g:1, - c:"y = parseInt(results[{0}], 10);\n", - s:"(\\d{4})" - }, - y: { - g:1, - c:"var ty = parseInt(results[{0}], 10);\n" - + "y = ty > Date.y2kYear ? 1900 + ty : 2000 + ty;\n", - s:"(\\d{1,2})" - }, - a: function(){ - return $f("A"); - }, - A: { - - calcLast: true, - g:1, - c:"if (/(am)/i.test(results[{0}])) {\n" - + "if (!h || h == 12) { h = 0; }\n" - + "} else { if (!h || h < 12) { h = (h || 0) + 12; }}", - s:"(AM|PM|am|pm)" - }, - g: function() { - return $f("G"); - }, - G: { - g:1, - c:"h = parseInt(results[{0}], 10);\n", - s:"(\\d{1,2})" - }, - h: function() { - return $f("H"); - }, - H: { - g:1, - c:"h = parseInt(results[{0}], 10);\n", - s:"(\\d{2})" - }, - i: { - g:1, - c:"i = parseInt(results[{0}], 10);\n", - s:"(\\d{2})" - }, - s: { - g:1, - c:"s = parseInt(results[{0}], 10);\n", - s:"(\\d{2})" - }, - u: { - g:1, - c:"ms = results[{0}]; ms = parseInt(ms, 10)/Math.pow(10, ms.length - 3);\n", - s:"(\\d+)" - }, - O: { - g:1, - c:[ - "o = results[{0}];", - "var sn = o.substring(0,1),", - "hr = o.substring(1,3)*1 + Math.floor(o.substring(3,5) / 60),", - "mn = o.substring(3,5) % 60;", - "o = ((-12 <= (hr*60 + mn)/60) && ((hr*60 + mn)/60 <= 14))? (sn + String.leftPad(hr, 2, '0') + String.leftPad(mn, 2, '0')) : null;\n" - ].join("\n"), - s: "([+\-]\\d{4})" - }, - P: { - g:1, - c:[ - "o = results[{0}];", - "var sn = o.substring(0,1),", - "hr = o.substring(1,3)*1 + Math.floor(o.substring(4,6) / 60),", - "mn = o.substring(4,6) % 60;", - "o = ((-12 <= (hr*60 + mn)/60) && ((hr*60 + mn)/60 <= 14))? (sn + String.leftPad(hr, 2, '0') + String.leftPad(mn, 2, '0')) : null;\n" - ].join("\n"), - s: "([+\-]\\d{2}:\\d{2})" - }, - T: { - g:0, - c:null, - s:"[A-Z]{1,4}" - }, - Z: { - g:1, - c:"zz = results[{0}] * 1;\n" - + "zz = (-43200 <= zz && zz <= 50400)? zz : null;\n", - s:"([+\-]?\\d{1,5})" - }, - c: function() { - var calc = [], - arr = [ - $f("Y", 1), - $f("m", 2), - $f("d", 3), - $f("h", 4), - $f("i", 5), - $f("s", 6), - {c:"ms = results[7] || '0'; ms = parseInt(ms, 10)/Math.pow(10, ms.length - 3);\n"}, - {c:[ - "if(results[8]) {", - "if(results[8] == 'Z'){", - "zz = 0;", - "}else if (results[8].indexOf(':') > -1){", - $f("P", 8).c, - "}else{", - $f("O", 8).c, - "}", - "}" - ].join('\n')} - ]; - - for (var i = 0, l = arr.length; i < l; ++i) { - calc.push(arr[i].c); - } - - return { - g:1, - c:calc.join(""), - s:[ - arr[0].s, - "(?:", "-", arr[1].s, - "(?:", "-", arr[2].s, - "(?:", - "(?:T| )?", - arr[3].s, ":", arr[4].s, - "(?::", arr[5].s, ")?", - "(?:(?:\\.|,)(\\d+))?", - "(Z|(?:[-+]\\d{2}(?::)?\\d{2}))?", - ")?", - ")?", - ")?" - ].join("") - }; - }, - U: { - g:1, - c:"u = parseInt(results[{0}], 10);\n", - s:"(-?\\d+)" + + + if (me.fireEvent('beforeprefetch', me, operation) !== false) { + me.loading = true; + me.proxy.read(operation, me.onProxyPrefetch, me); } - } -}); - -}()); - -Ext.apply(Date.prototype, { + + return me; + }, - dateFormat : function(format) { - if (Date.formatFunctions[format] == null) { - Date.createFormat(format); + + prefetchPage: function(page, options) { + var me = this, + pageSize = me.pageSize, + start = (page - 1) * me.pageSize, + end = start + pageSize; + + + if (Ext.Array.indexOf(me.pagesRequested, page) === -1 && !me.rangeSatisfied(start, end)) { + options = options || {}; + me.pagesRequested.push(page); + Ext.applyIf(options, { + page : page, + start: start, + limit: pageSize, + callback: me.onWaitForGuarantee, + scope: me + }); + + me.prefetch(options); } - return Date.formatFunctions[format].call(this); + }, - - getTimezone : function() { + + 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; + if (end - i > me.pageSize) { + Ext.Error.raise("A single page prefetch could never satisfy this request."); + } + 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; + + if (start > end) { + Ext.Error.raise("Start (" + start + ") was greater than end (" + 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) { + Ext.Error.raise("Record was not found and store said it was guaranteed"); + } + 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) { + 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" + }); + } + } + 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 + }); + } - return this.toString().replace(/^.* (?:\((.*)\)|([A-Z]{1,4})(?:[\-+][0-9]{4})?(?: -?\d+)?)$/, "$1$2").replace(/[^A-Z]/g, ""); + } else { + me.onGuaranteedRange(); + } }, - - getGMTOffset : function(colon) { - return (this.getTimezoneOffset() > 0 ? "-" : "+") - + String.leftPad(Math.floor(Math.abs(this.getTimezoneOffset()) / 60), 2, "0") - + (colon ? ":" : "") - + String.leftPad(Math.abs(this.getTimezoneOffset() % 60), 2, "0"); + + + 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); + } }, - getDayOfYear: function() { - var num = 0, - d = this.clone(), - m = this.getMonth(), - i; - - for (i = 0, d.setDate(1), d.setMonth(0); i < m; d.setMonth(++i)) { - num += d.getDaysInMonth(); + + + 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.fireEvent('datachanged', me); } - return num + this.getDate() - 1; }, - - getWeekOfYear : function() { - - var ms1d = 864e5, - ms7d = 7 * ms1d; + + 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; + }, - return function() { - var DC3 = Date.UTC(this.getFullYear(), this.getMonth(), this.getDate() + 3) / ms1d, - AWN = Math.floor(DC3 / 7), - Wyr = new Date(AWN * ms7d).getUTCFullYear(); + + findRecord: function() { + var me = this, + index = me.find.apply(me, arguments); + return index !== -1 ? me.getAt(index) : null; + }, - return AWN - Math.floor(Date.UTC(Wyr, 0, 7) / ms7d) + 1; + + 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]); }; - }(), + }, - isLeapYear : function() { - var year = this.getFullYear(); - return !!((year & 3) == 0 && (year % 100 || (year % 400 == 0 && year))); + findExact: function(property, value, start) { + return this.data.findIndexBy(function(rec) { + return rec.get(property) === value; + }, + this, start); }, - getFirstDayOfMonth : function() { - var day = (this.getDay() - (this.getDate() - 1)) % 7; - return (day < 0) ? (day + 7) : day; + findBy: function(fn, scope, start) { + return this.data.findIndexBy(fn, scope, start); }, - getLastDayOfMonth : function() { - return this.getLastDateOfMonth().getDay(); - }, + collect: function(dataIndex, allowNull, bypassFilter) { + var me = this, + data = (bypassFilter === true && me.snapshot) ? me.snapshot: me.data; + return data.collect(dataIndex, 'data', allowNull); + }, - getFirstDateOfMonth : function() { - return new Date(this.getFullYear(), this.getMonth(), 1); + getCount: function() { + return this.data.length || 0; }, - getLastDateOfMonth : function() { - return new Date(this.getFullYear(), this.getMonth(), this.getDaysInMonth()); + getTotalCount: function() { + return this.totalCount; }, - getDaysInMonth: function() { - var daysInMonth = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]; - - return function() { - var m = this.getMonth(); - - return m == 1 && this.isLeapYear() ? 29 : daysInMonth[m]; - }; - }(), + getAt: function(index) { + return this.data.getAt(index); + }, - getSuffix : function() { - switch (this.getDate()) { - case 1: - case 21: - case 31: - return "st"; - case 2: - case 22: - return "nd"; - case 3: - case 23: - return "rd"; - default: - return "th"; - } + getRange: function(start, end) { + return this.data.getRange(start, end); }, - clone : function() { - return new Date(this.getTime()); + getById: function(id) { + return (this.snapshot || this.data).findBy(function(record) { + return record.getId() === id; + }); }, - isDST : function() { - - - return new Date(this.getFullYear(), 0, 1).getTimezoneOffset() != this.getTimezoneOffset(); + indexOf: function(record) { + return this.data.indexOf(record); }, + - clearTime : function(clone) { - if (clone) { - return this.clone().clearTime(); - } + indexOfTotal: function(record) { + return record.index || this.indexOf(record); + }, + + indexOfId: function(id) { + return this.data.indexOfKey(id); + }, - var d = this.getDate(); + + removeAll: function(silent) { + var me = this; - - this.setHours(0); - this.setMinutes(0); - this.setSeconds(0); - this.setMilliseconds(0); + me.clearData(); + if (me.snapshot) { + me.snapshot.clear(); + } + if (silent !== true) { + me.fireEvent('clear', me); + } + }, - if (this.getDate() != d) { - - + - - for (var hr = 1, c = this.add(Date.HOUR, hr); c.getDate() != d; hr++, c = this.add(Date.HOUR, hr)); + + first: function(grouped) { + var me = this; - this.setDate(d); - this.setHours(c.getHours()); + if (grouped && me.isGrouped()) { + return me.aggregate(function(records) { + return records.length ? records[0] : undefined; + }, me, true); + } else { + return me.data.first(); } - - return this; }, - add : function(interval, value) { - var d = this.clone(); - if (!interval || value === 0) return d; + last: function(grouped) { + var me = this; - switch(interval.toLowerCase()) { - case Date.MILLI: - d.setMilliseconds(this.getMilliseconds() + value); - break; - case Date.SECOND: - d.setSeconds(this.getSeconds() + value); - break; - case Date.MINUTE: - d.setMinutes(this.getMinutes() + value); - break; - case Date.HOUR: - d.setHours(this.getHours() + value); - break; - case Date.DAY: - d.setDate(this.getDate() + value); - break; - case Date.MONTH: - var day = this.getDate(); - if (day > 28) { - day = Math.min(day, this.getFirstDateOfMonth().add('mo', value).getLastDateOfMonth().getDate()); - } - d.setDate(day); - d.setMonth(this.getMonth() + value); - break; - case Date.YEAR: - d.setFullYear(this.getFullYear() + value); - break; + 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(); } - return d; }, - between : function(start, end) { - var t = this.getTime(); - return start.getTime() <= t && t <= end.getTime(); - } -}); - - - -Date.prototype.format = Date.prototype.dateFormat; - - - -if (Ext.isSafari && (navigator.userAgent.match(/WebKit\/(\d+)/)[1] || NaN) < 420) { - Ext.apply(Date.prototype, { - _xMonth : Date.prototype.setMonth, - _xDate : Date.prototype.setDate, - - - - setMonth : function(num) { - if (num <= -1) { - var n = Math.ceil(-num), - back_year = Math.ceil(n / 12), - month = (n % 12) ? 12 - n % 12 : 0; + sum: function(field, grouped) { + var me = this; - this.setFullYear(this.getFullYear() - back_year); + if (grouped && me.isGrouped()) { + return me.aggregate(me.getSum, me, true, [field]); + } else { + return me.getSum(me.data.items, field); + } + }, - return this._xMonth(month); - } else { - return this._xMonth(num); - } - }, + + getSum: function(records, field) { + var total = 0, + i = 0, + len = records.length; - - - - setDate : function(d) { - - - return this.setTime(this.getTime() - (this.getDate() - d) * 864e5); + for (; i < len; ++i) { + total += records[i].get(field); } - }); -} - + return total; + }, + + count: function(grouped) { + var me = this; + if (grouped && me.isGrouped()) { + return me.aggregate(function(records) { + return records.length; + }, me, true); + } else { + return me.getCount(); + } + }, -Ext.util.MixedCollection = function(allowFunctions, keyFn){ - this.items = []; - this.map = {}; - this.keys = []; - this.length = 0; - this.addEvents( - - 'clear', - - 'add', - - 'replace', - - 'remove', - 'sort' - ); - this.allowFunctions = allowFunctions === true; - if(keyFn){ - this.getKey = keyFn; - } - Ext.util.MixedCollection.superclass.constructor.call(this); -}; + + min: function(field, grouped) { + var me = this; -Ext.extend(Ext.util.MixedCollection, Ext.util.Observable, { + if (grouped && me.isGrouped()) { + return me.aggregate(me.getMin, me, true, [field]); + } else { + return me.getMin(me.data.items, field); + } + }, - allowFunctions : false, + getMin: function(records, field){ + var i = 1, + len = records.length, + value, min; - - add : function(key, o){ - if(arguments.length == 1){ - o = arguments[0]; - key = this.getKey(o); + if (len > 0) { + min = records[0].get(field); } - if(typeof key != 'undefined' && key !== null){ - var old = this.map[key]; - if(typeof old != 'undefined'){ - return this.replace(key, o); + + for (; i < len; ++i) { + value = records[i].get(field); + if (value < min) { + min = value; } - this.map[key] = o; } - this.length++; - this.items.push(o); - this.keys.push(key); - this.fireEvent('add', this.length-1, o, key); - return o; + return min; }, - getKey : function(o){ - return o.id; - }, + max: function(field, grouped) { + var me = this; - - replace : function(key, o){ - if(arguments.length == 1){ - o = arguments[0]; - key = this.getKey(o); - } - var old = this.map[key]; - if(typeof key == 'undefined' || key === null || typeof old == 'undefined'){ - return this.add(key, o); + if (grouped && me.isGrouped()) { + return me.aggregate(me.getMax, me, true, [field]); + } else { + return me.getMax(me.data.items, field); } - var index = this.indexOfKey(key); - this.items[index] = o; - this.map[key] = o; - this.fireEvent('replace', key, old, o); - return o; }, - addAll : function(objs){ - if(arguments.length > 1 || Ext.isArray(objs)){ - var args = arguments.length > 1 ? arguments : objs; - for(var i = 0, len = args.length; i < len; i++){ - this.add(args[i]); - } - }else{ - for(var key in objs){ - if(this.allowFunctions || typeof objs[key] != 'function'){ - this.add(key, objs[key]); - } - } + getMax: function(records, field) { + var i = 1, + len = records.length, + value, + max; + + if (len > 0) { + max = records[0].get(field); } - }, - - each : function(fn, scope){ - var items = [].concat(this.items); - for(var i = 0, len = items.length; i < len; i++){ - if(fn.call(scope || items[i], items[i], i, len) === false){ - break; + for (; i < len; ++i) { + value = records[i].get(field); + if (value > max) { + max = value; } } + return max; }, - eachKey : function(fn, scope){ - for(var i = 0, len = this.keys.length; i < len; i++){ - fn.call(scope || window, this.keys[i], this.items[i], i, len); + 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); } }, - find : function(fn, scope){ - for(var i = 0, len = this.items.length; i < len; i++){ - if(fn.call(scope || window, this.items[i], this.keys[i])){ - return this.items[i]; + getAverage: function(records, field) { + var i = 0, + len = records.length, + sum = 0; + + if (records.length > 0) { + for (; i < len; ++i) { + sum += records[i].get(field); } + return sum / len; } - return null; + return 0; }, - insert : function(index, key, o){ - if(arguments.length == 2){ - o = arguments[1]; - key = this.getKey(o); - } - if(this.containsKey(key)){ - this.suspendEvents(); - this.removeKey(key); - this.resumeEvents(); - } - if(index >= this.length){ - return this.add(key, o); - } - this.length++; - this.items.splice(index, 0, o); - if(typeof key != 'undefined' && key !== null){ - this.map[key] = o; + 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)); } - this.keys.splice(index, 0, key); - this.fireEvent('add', index, o, key); - return o; - }, + } +}); - - remove : function(o){ - return this.removeAt(this.indexOf(o)); - }, - - removeAt : function(index){ - if(index < this.length && index >= 0){ - this.length--; - var o = this.items[index]; - this.items.splice(index, 1); - var key = this.keys[index]; - if(typeof key != 'undefined'){ - delete this.map[key]; - } - this.keys.splice(index, 1); - this.fireEvent('remove', o, key); - return o; - } - return false; - }, +Ext.define('Ext.data.JsonStore', { + extend: 'Ext.data.Store', + alias: 'store.json', - removeKey : function(key){ - return this.removeAt(this.indexOfKey(key)); - }, + constructor: function(config) { + config = config || {}; - - getCount : function(){ - return this.length; - }, + Ext.applyIf(config, { + proxy: { + type : 'ajax', + reader: 'json', + writer: 'json' + } + }); - - indexOf : function(o){ - return this.items.indexOf(o); - }, + this.callParent([config]); + } +}); - - indexOfKey : function(key){ - return this.keys.indexOf(key); - }, - - item : function(key){ - var mk = this.map[key], - item = mk !== undefined ? mk : (typeof key == 'number') ? this.items[key] : undefined; - return typeof item != 'function' || this.allowFunctions ? item : null; - }, +Ext.define('Ext.chart.axis.Time', { - itemAt : function(index){ - return this.items[index]; - }, - - key : function(key){ - return this.map[key]; - }, + extend: 'Ext.chart.axis.Category', - - contains : function(o){ - return this.indexOf(o) != -1; - }, + alternateClassName: 'Ext.chart.TimeAxis', - - containsKey : function(key){ - return typeof this.map[key] != 'undefined'; - }, + alias: 'axis.time', - - clear : function(){ - this.length = 0; - this.items = []; - this.keys = []; - this.map = {}; - this.fireEvent('clear'); - }, + requires: ['Ext.data.Store', 'Ext.data.JsonStore'], - first : function(){ - return this.items[0]; - }, + + calculateByLabelSize: true, - last : function(){ - return this.items[this.length-1]; + + dateFormat: false, + + + groupBy: 'year,month,day', + + + aggregateOp: 'sum', + + + fromDate: false, + + + toDate: false, + + + step: [Ext.Date.DAY, 1], + + + constrain: false, + + + dateMethods: { + 'year': function(date) { + return date.getFullYear(); + }, + 'month': function(date) { + return date.getMonth() + 1; + }, + 'day': function(date) { + return date.getDate(); + }, + 'hour': function(date) { + return date.getHours(); + }, + 'minute': function(date) { + return date.getMinutes(); + }, + 'second': function(date) { + return date.getSeconds(); + }, + 'millisecond': function(date) { + return date.getMilliseconds(); + } }, - - _sort : function(property, dir, fn){ - var i, len, - dsc = String(dir).toUpperCase() == 'DESC' ? -1 : 1, - - - c = [], - keys = this.keys, - items = this.items; - - - fn = fn || function(a, b) { - return a - b; + + 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]; + } + for (; i < l; i++) { + acum += list[i]; + } + return acum / l; + } }; - + })(), + + + 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 + }); - for(i = 0, len = items.length; i < len; i++){ - c[c.length] = { - key : keys[i], - value: items[i], - index: i + var getRecordByDate = (function() { + var index = 0, l = store.getCount(); + return function(date) { + var rec, recDate; + for (; index < l; index++) { + rec = store.getAt(index); + recDate = rec.get(field); + if (+recDate > +date) { + return false; + } else if (+recDate == +date) { + return rec; + } + } + return false; }; + })(); + + if (!this.constrain) { + this.chart.filteredStore = this.chart.store; + return; } - - c.sort(function(a, b){ - var v = fn(a[property], b[property]) * dsc; - if(v === 0){ - v = (a.index < b.index ? -1 : 1); + while(+fromDate <= +toDate) { + record = getRecordByDate(fromDate); + recObj = {}; + if (record) { + newStore.add(record.data); + } else { + newStore.model.prototype.fields.each(function(f) { + recObj[f.name] = false; + }); + recObj.date = fromDate; + newStore.add(recObj); + } + fromDate = Ext.Date.add(fromDate, step[0], step[1]); + } + + this.chart.filteredStore = newStore; + }, + + + aggregate: function() { + var aggStore = {}, + aggKeys = [], key, value, + op = this.aggregateOp, + field = this.fields, i, + fields = this.groupBy.split(','), + curField, + recFields = [], + recFieldsLen = 0, + obj, + dates = [], + json = [], + l = fields.length, + dateMethods = this.dateMethods, + aggregateFn = this.aggregateFn, + store = this.chart.filteredStore || this.chart.store; + + store.each(function(rec) { + + if (!recFields.length) { + rec.fields.each(function(f) { + recFields.push(f.name); + }); + recFieldsLen = recFields.length; + } + + value = rec.get(field); + + for (i = 0; i < l; i++) { + if (i == 0) { + key = String(dateMethods[fields[i]](value)); + } else { + key += '||' + dateMethods[fields[i]](value); + } + } + + if (key in aggStore) { + obj = aggStore[key]; + } else { + obj = aggStore[key] = {}; + aggKeys.push(key); + dates.push(value); + } + + 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)); + } } - return v; }); - - for(i = 0, len = c.length; i < len; i++){ - items[i] = c[i].value; - keys[i] = c[i].key; + for (key in aggStore) { + obj = aggStore[key]; + for (i = 0; i < recFieldsLen; i++) { + curField = recFields[i]; + obj[curField] = aggregateFn[op](obj[curField]); + } + json.push(obj); } + this.chart.substore = Ext.create('Ext.data.JsonStore', { + fields: recFields, + data: json + }); + + this.dates = dates; + }, + + + setLabels: function() { + var store = this.chart.substore, + fields = this.fields, + format = this.dateFormat, + labels, i, dates = this.dates, + formatFn = Ext.Date.format; + this.labels = labels = []; + store.each(function(record, i) { + if (!format) { + labels.push(record.get(fields)); + } else { + labels.push(formatFn(dates[i], format)); + } + }, this); + }, - this.fireEvent('sort', this); + processView: function() { + + if (this.constrain) { + this.constrainDates(); + this.aggregate(); + this.chart.substore = this.chart.filteredStore; + } else { + this.aggregate(); + } }, + + applyData: function() { + this.setLabels(); + var count = this.chart.substore.getCount(); + return { + from: 0, + to: count, + steps: count - 1, + step: 1 + }; + } + }); + + + +Ext.define('Ext.chart.series.Series', { + - sort : function(dir, fn){ - this._sort('value', dir, fn); + + mixins: { + observable: 'Ext.util.Observable', + labels: 'Ext.chart.Label', + highlights: 'Ext.chart.Highlight', + tips: 'Ext.chart.Tip', + callouts: 'Ext.chart.Callout' }, - reorder: function(mapping) { - this.suspendEvents(); - - var items = this.items, - index = 0, - length = items.length, - order = [], - remaining = [], - oldIndex; - - for (oldIndex in mapping) { - order[mapping[oldIndex]] = items[oldIndex]; - } + - for (index = 0; index < length; index++) { - if (mapping[index] == undefined) { - remaining.push(items[index]); - } - } + - for (index = 0; index < length; index++) { - if (order[index] == undefined) { - order[index] = remaining.shift(); - } - } + + type: null, - this.clear(); - this.addAll(order); + + title: null, - this.resumeEvents(); - this.fireEvent('sort', this); - }, + + showInLegend: true, - keySort : 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); - }); + renderer: function(sprite, record, attributes, index, store) { + return attributes; }, - getRange : function(start, end){ - var items = this.items; - if(items.length < 1){ - return []; - } - start = start || 0; - end = Math.min(typeof end == 'undefined' ? this.length-1 : end, this.length-1); - var i, r = []; - if(start <= end){ - for(i = start; i <= end; i++) { - r[r.length] = items[i]; - } - }else{ - for(i = start; i >= end; i--) { - r[r.length] = items[i]; - } - } - return r; - }, + shadowAttributes: null, + + //@private triggerdrawlistener flag + + triggerAfterDraw: false, - filter : function(property, value, anyMatch, caseSensitive){ - if(Ext.isEmpty(value, false)){ - return this.clone(); + + constructor: function(config) { + var me = this; + if (config) { + Ext.apply(me, config); } - value = this.createValueMatcher(value, anyMatch, caseSensitive); - return this.filterBy(function(o){ - return o && value.test(o[property]); + + me.shadowGroups = []; + + me.mixins.labels.constructor.call(me, config); + me.mixins.highlights.constructor.call(me, config); + me.mixins.tips.constructor.call(me, config); + me.mixins.callouts.constructor.call(me, config); + + me.addEvents({ + scope: me, + itemmouseover: true, + itemmouseout: true, + itemmousedown: true, + itemmouseup: true, + mouseleave: true, + afterdraw: true, + + + titlechange: true + }); + + me.mixins.observable.constructor.call(me, config); + + me.on({ + scope: me, + itemmouseover: me.onItemMouseOver, + itemmouseout: me.onItemMouseOut, + mouseleave: me.onMouseLeave }); }, - filterBy : function(fn, scope){ - var r = new Ext.util.MixedCollection(); - r.getKey = this.getKey; - var k = this.keys, it = this.items; - for(var i = 0, len = it.length; i < len; i++){ - if(fn.call(scope||this, it[i], k[i])){ - r.add(k[i], it[i]); - } - } - return r; + 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; }, - findIndex : function(property, value, start, anyMatch, caseSensitive){ - if(Ext.isEmpty(value, false)){ - return -1; + 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'); + } + } + })); } - value = this.createValueMatcher(value, anyMatch, caseSensitive); - return this.findIndexBy(function(o){ - return o && value.test(o[property]); - }, null, start); + }, + + + getGutters: function() { + return [0, 0]; }, - findIndexBy : function(fn, scope, start){ - var k = this.keys, it = this.items; - for(var i = (start||0), len = it.length; i < len; i++){ - if(fn.call(scope||this, it[i], k[i])){ - return i; + onItemMouseOver: function(item) { + var me = this; + if (item.series === me) { + if (me.highlight) { + me.highlightItem(item); + } + if (me.tooltip) { + me.showTip(item); } } - return -1; }, - createValueMatcher : function(value, anyMatch, caseSensitive, exactMatch) { - if (!value.exec) { - var er = Ext.escapeRe; - value = String(value); - - if (anyMatch === true) { - value = er(value); - } else { - value = '^' + er(value); - if (exactMatch === true) { - value += '$'; - } + onItemMouseOut: function(item) { + var me = this; + if (item.series === me) { + me.unHighlightItem(); + if (me.tooltip) { + me.hideTip(item); } - value = new RegExp(value, caseSensitive ? '' : 'i'); - } - return value; + } }, - clone : function(){ - var r = new Ext.util.MixedCollection(); - var k = this.keys, it = this.items; - for(var i = 0, len = it.length; i < len; i++){ - r.add(k[i], it[i]); + onMouseLeave: function() { + var me = this; + me.unHighlightItem(); + if (me.tooltip) { + me.hideTip(); } - r.getKey = this.getKey; - return r; - } -}); - -Ext.util.MixedCollection.prototype.get = Ext.util.MixedCollection.prototype.item; + }, -Ext.AbstractManager = Ext.extend(Object, { - typeName: 'type', - constructor: function(config) { - Ext.apply(this, config || {}); + 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; - this.all = new Ext.util.MixedCollection(); - - this.types = {}; - }, - - - get : function(id){ - return this.all.get(id); + 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 null; }, - - register: function(item) { - this.all.add(item); + isItemInPoint: function(x, y, item, i) { + return false; }, + - - unregister: function(item) { - this.all.remove(item); + 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); + } + } }, + - - registerType : function(type, cls){ - this.types[type] = cls; - cls[this.typeName] = type; + 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; }, - isRegistered : function(type){ - return this.types[type] !== undefined; + 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'; }, - create: function(config, defaultType) { - var type = config[this.typeName] || config.type || defaultType, - Constructor = this.types[type]; - - if (Constructor == undefined) { - throw new Error(String.format("The '{0}' type has not been registered with this manager", type)); + visibleInLegend: function(index){ + var excludes = this.__excludes; + if (excludes) { + return !excludes[index]; } - - return new Constructor(config); + return !this.seriesIsHidden; }, + - - onAvailable : function(id, fn, scope){ - var all = this.all; - - all.on("add", function(index, o){ - if (o.id == id) { - fn.call(scope || o, o); - all.un("add", fn, scope); - } - }); + 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); } }); -Ext.util.Format = function() { - var trimRe = /^\s+|\s+$/g, - stripTagsRE = /<\/?[^>]+>/gi, - stripScriptsRe = /(?:)((\n|\r|.)*?)(?:<\/script>)/ig, - nl2brRe = /\r?\n/g; - return { - - ellipsis : function(value, len, word) { - if (value && value.length > len) { - if (word) { - var vs = value.substr(0, len - 2), - index = Math.max(vs.lastIndexOf(' '), vs.lastIndexOf('.'), vs.lastIndexOf('!'), vs.lastIndexOf('?')); - if (index == -1 || index < (len - 15)) { - return value.substr(0, len - 3) + "..."; - } else { - return vs.substr(0, index) + "..."; - } - } else { - return value.substr(0, len - 3) + "..."; - } - } - return value; - }, - - undef : function(value) { - return value !== undefined ? value : ""; - }, +Ext.define('Ext.chart.series.Cartesian', { - - defaultValue : function(value, defaultValue) { - return value !== undefined && value !== '' ? value : defaultValue; - }, + - - htmlEncode : function(value) { - return !value ? value : String(value).replace(/&/g, "&").replace(/>/g, ">").replace(/").replace(/</g, "<").replace(/"/g, '"').replace(/&/g, "&"); - }, + alternateClassName: ['Ext.chart.CartesianSeries', 'Ext.chart.CartesianChart'], - - trim : function(value) { - return String(value).replace(trimRe, ""); - }, + - - substr : function(value, start, length) { - return String(value).substr(start, length); - }, + + xField: null, - - lowercase : function(value) { - return String(value).toLowerCase(); - }, + + yField: null, - - uppercase : function(value) { - return String(value).toUpperCase(); - }, + + axis: 'left' +}); - - capitalize : function(value) { - return !value ? value : value.charAt(0).toUpperCase() + value.substr(1).toLowerCase(); - }, - - call : function(value, fn) { - if (arguments.length > 2) { - var args = Array.prototype.slice.call(arguments, 2); - args.unshift(value); - return eval(fn).apply(window, args); - } else { - return eval(fn).call(window, value); - } - }, +Ext.define('Ext.chart.series.Area', { - - usMoney : function(v) { - v = (Math.round((v-0)*100))/100; - v = (v == Math.floor(v)) ? v + ".00" : ((v*10 == Math.floor(v*10)) ? v + "0" : v); - v = String(v); - var ps = v.split('.'), - whole = ps[0], - sub = ps[1] ? '.'+ ps[1] : '.00', - r = /(\d+)(\d{3})/; - while (r.test(whole)) { - whole = whole.replace(r, '$1' + ',' + '$2'); - } - v = whole + sub; - if (v.charAt(0) == '-') { - return '-$' + v.substr(1); - } - return "$" + v; - }, + - - date : function(v, format) { - if (!v) { - return ""; - } - if (!Ext.isDate(v)) { - v = new Date(Date.parse(v)); - } - return v.dateFormat(format || "m/d/Y"); - }, + extend: 'Ext.chart.series.Cartesian', + + alias: 'series.area', - - dateRenderer : function(format) { - return function(v) { - return Ext.util.Format.date(v, format); - }; - }, + requires: ['Ext.chart.axis.Axis', 'Ext.draw.Color', 'Ext.fx.Anim'], - - stripTags : function(v) { - return !v ? v : String(v).replace(stripTagsRE, ""); - }, + - - stripScripts : function(v) { - return !v ? v : String(v).replace(stripScriptsRe, ""); - }, + type: 'area', - - fileSize : function(size) { - if (size < 1024) { - return size + " bytes"; - } else if (size < 1048576) { - return (Math.round(((size*10) / 1024))/10) + " KB"; - } else { - return (Math.round(((size*10) / 1048576))/10) + " MB"; - } - }, + + stacked: true, - - math : function(){ - var fns = {}; - - return function(v, a){ - if (!fns[a]) { - fns[a] = new Function('v', 'return v ' + a + ';'); - } - return fns[a](v); - }; - }(), + + style: {}, - - round : function(value, precision) { - var result = Number(value); - if (typeof precision == 'number') { - precision = Math.pow(10, precision); - result = Math.round(value * precision) / precision; + 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' } - return result; - }, + }); + 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); + }, + + 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 = []; - number: function(v, format) { - if (!format) { - return v; + 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]; } - v = Ext.num(v, NaN); - if (isNaN(v)) { - return ''; + if (i % ratio == 0) { + + xRes.push(xSum/ratio); + for (j = 0; j < yCompLen; ++j) { + ySum[j] /= ratio; + } + yRes.push(ySum); + + xSum = 0; + for (j = 0, ySum = []; j < yCompLen; ++j) { + ySum[j] = 0; + } } - var comma = ',', - dec = '.', - i18n = false, - neg = v < 0; + } + return { + x: xRes, + y: yRes + }; + }, - v = Math.abs(v); - if (format.substr(format.length - 2) == '/i') { - format = format.substr(0, format.length - 2); - i18n = true; - comma = '.'; - dec = ','; - } + + getBounds: function() { + var me = this, + chart = me.chart, + store = chart.substore || chart.store, + 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 (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); + } + } + + 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); + } - var hasComma = format.indexOf(comma) != -1, - psplit = (i18n ? format.replace(/[^\d\,]/g, '') : format.replace(/[^\d\.]/g, '')).split(dec); + if (!Ext.isNumber(minY)) { + minY = 0; + } + if (!Ext.isNumber(maxY)) { + maxY = 0; + } - if (1 < psplit.length) { - v = v.toFixed(psplit[1].length); - } else if(2 < psplit.length) { - throw ('NumberFormatException: invalid format, formats should have no more than 1 period: ' + format); - } else { - v = v.toFixed(0); + store.each(function(record, i) { + xValue = record.get(me.xField); + yValue = []; + if (typeof xValue != 'number') { + xValue = i; + } + 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); - var fnum = v.toString(); + xScale = bbox.width / (maxX - minX); + yScale = bbox.height / (maxY - minY); - psplit = fnum.split('.'); + ln = xValues.length; + if ((ln > bbox.width) && me.areas) { + sumValues = me.shrink(xValues, yValues, bbox.width); + xValues = sumValues.x; + yValues = sumValues.y; + } - if (hasComma) { - var cnum = psplit[0], - parr = [], - j = cnum.length, - m = Math.floor(j / 3), - n = cnum.length % 3 || 3, - i; + return { + bbox: bbox, + minX: minX, + minY: minY, + xValues: xValues, + yValues: yValues, + xScale: xScale, + yScale: yScale, + areasLen: areasLen + }; + }, - for (i = 0; i < j; i += n) { - if (i != 0) { - n = 3; - } - - parr[parr.length] = cnum.substr(i, n); - m -= 1; + + getPaths: function() { + var me = this, + chart = me.chart, + store = chart.substore || chart.store, + 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; } - fnum = parr.join(comma); - if (psplit[1]) { - fnum += dec + psplit[1]; + if (!componentPaths[areaIndex]) { + componentPaths[areaIndex] = []; } - } else { - if (psplit[1]) { - fnum = psplit[0] + dec + psplit[1]; + areaElem = yValue[areaIndex]; + acumY += areaElem; + y = bbox.y + bbox.height - (acumY - bounds.minY) * bounds.yScale; + if (!paths[areaIndex]) { + paths[areaIndex] = ['M', x, y]; + componentPaths[areaIndex].push(['L', x, y]); + } else { + paths[areaIndex].push('L', x, y); + componentPaths[areaIndex].push(['L', x, y]); + } + if (!items[areaIndex]) { + items[areaIndex] = { + pointsUp: [], + pointsDown: [], + series: me + }; } + items[areaIndex].pointsUp.push([x, y]); } - - return (neg ? '-' : '') + format.replace(/[\d,?\.?]+/, fnum); - }, - - - numberRenderer : function(format) { - return function(v) { - return Ext.util.Format.number(v, format); - }; - }, - + } - plural : function(v, s, p) { - return v +' ' + (v == 1 ? s : (p ? p : s+'s')); - }, - - nl2br : function(v) { - return Ext.isEmpty(v) ? '' : v.replace(nl2brRe, '
'); + for (areaIndex = 0; areaIndex < bounds.areasLen; areaIndex++) { + + if (me.__excludes[areaIndex]) { + continue; + } + path = paths[areaIndex]; + + if (areaIndex == 0 || first) { + first = false; + path.push('L', x, bbox.y + bbox.height, + 'L', bbox.x, bbox.y + bbox.height, + 'Z'); + } + + 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'); + } + prevAreaIndex = areaIndex; } - }; -}(); - -Ext.XTemplate = function(){ - Ext.XTemplate.superclass.constructor.apply(this, arguments); - - var me = this, - s = me.html, - re = /]*>((?:(?=([^<]+))\2|<(?!tpl\b[^>]*>))*?)<\/tpl>/, - nameRe = /^]*?for="(.*?)"/, - ifRe = /^]*?if="(.*?)"/, - execRe = /^]*?exec="(.*?)"/, - m, - id = 0, - tpls = [], - VALUES = 'values', - PARENT = 'parent', - XINDEX = 'xindex', - XCOUNT = 'xcount', - RETURN = 'return ', - WITHVALUES = 'with(values){ '; - - s = ['', s, ''].join(''); - - while((m = s.match(re))){ - var m2 = m[0].match(nameRe), - m3 = m[0].match(ifRe), - m4 = m[0].match(execRe), - exp = null, - fn = null, - exec = null, - name = m2 && m2[1] ? m2[1] : ''; - - if (m3) { - exp = m3 && m3[1] ? m3[1] : null; - if(exp){ - fn = new Function(VALUES, PARENT, XINDEX, XCOUNT, WITHVALUES + RETURN +(Ext.util.Format.htmlDecode(exp))+'; }'); - } - } - if (m4) { - exp = m4 && m4[1] ? m4[1] : null; - if(exp){ - exec = new Function(VALUES, PARENT, XINDEX, XCOUNT, WITHVALUES +(Ext.util.Format.htmlDecode(exp))+'; }'); - } - } - if(name){ - switch(name){ - case '.': name = new Function(VALUES, PARENT, WITHVALUES + RETURN + VALUES + '; }'); break; - case '..': name = new Function(VALUES, PARENT, WITHVALUES + RETURN + PARENT + '; }'); break; - default: name = new Function(VALUES, PARENT, WITHVALUES + RETURN + name + '; }'); - } - } - tpls.push({ - id: id, - target: name, - exec: exec, - test: fn, - body: m[1]||'' - }); - s = s.replace(m[0], '{xtpl'+ id + '}'); - ++id; - } - for(var i = tpls.length-1; i >= 0; --i){ - me.compileTpl(tpls[i]); - } - me.master = tpls[tpls.length-1]; - me.tpls = tpls; -}; -Ext.extend(Ext.XTemplate, Ext.Template, { - - re : /\{([\w-\.\#]+)(?:\:([\w\.]*)(?:\((.*?)?\))?)?(\s?[\+\-\*\\]\s?[\d\.\+\-\*\\\(\)]+)?\}/g, - - codeRe : /\{\[((?:\\\]|.|\n)*?)\]\}/g, + return { + paths: paths, + areasLen: bounds.areasLen + }; + }, - applySubTemplate : function(id, values, parent, xindex, xcount){ + drawSeries: function() { var me = this, - len, - t = me.tpls[id], - vs, - buf = []; - if ((t.test && !t.test.call(me, values, parent, xindex, xcount)) || - (t.exec && t.exec.call(me, values, parent, xindex, xcount))) { - return ''; - } - vs = t.target ? t.target.call(me, values, parent) : values; - len = vs.length; - parent = t.target ? values : parent; - if(t.target && Ext.isArray(vs)){ - for(var i = 0, len = vs.length; i < len; i++){ - buf[buf.length] = t.compiled.call(me, vs[i], parent, i+1, len); - } - return buf.join(''); + chart = me.chart, + store = chart.substore || chart.store, + surface = chart.surface, + animate = chart.animate, + group = me.group, + endLineStyle = Ext.apply(me.seriesStyle, me.style), + colorArrayStyle = me.colorArrayStyle, + colorArrayLength = colorArrayStyle && colorArrayStyle.length || 0, + areaIndex, areaElem, paths, path, rendererAttributes; + + me.unHighlightItem(); + me.cleanHighlights(); + + if (!store || !store.getCount()) { + return; } - return t.compiled.call(me, vs, parent, xindex, xcount); - }, + + paths = me.getPaths(); - - compileTpl : function(tpl){ - var fm = Ext.util.Format, - useF = this.disableFormats !== true, - sep = Ext.isGecko ? "+" : ",", - body; + if (!me.areas) { + me.areas = []; + } - function fn(m, name, format, args, math){ - if(name.substr(0, 4) == 'xtpl'){ - return "'"+ sep +'this.applySubTemplate('+name.substr(4)+', values, parent, xindex, xcount)'+sep+"'"; - } - var v; - if(name === '.'){ - v = 'values'; - }else if(name === '#'){ - v = 'xindex'; - }else if(name.indexOf('.') != -1){ - v = name; - }else{ - v = "values['" + name + "']"; + for (areaIndex = 0; areaIndex < paths.areasLen; areaIndex++) { + + if (me.__excludes[areaIndex]) { + continue; } - if(math){ - v = '(' + v + math + ')'; + 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 || {})); } - if (format && useF) { - args = args ? ',' + args : ""; - if(format.substr(0, 5) != "this."){ - format = "fm." + format + '('; - }else{ - format = 'this.call("'+ format.substr(5) + '", '; - args = ", values"; - } + 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 { - args= ''; format = "("+v+" === undefined ? '' : "; + 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); } - return "'"+ sep + format + v + args + ")"+sep+"'"; - } - - function codeFn(m, code){ - - return "'" + sep + '(' + code.replace(/\\'/g, "'") + ')' + sep + "'"; - } - - - if(Ext.isGecko){ - body = "tpl.compiled = function(values, parent, xindex, xcount){ return '" + - tpl.body.replace(/(\r\n|\n)/g, '\\n').replace(/'/g, "\\'").replace(this.re, fn).replace(this.codeRe, codeFn) + - "';};"; - }else{ - body = ["tpl.compiled = function(values, parent, xindex, xcount){ return ['"]; - body.push(tpl.body.replace(/(\r\n|\n)/g, '\\n').replace(/'/g, "\\'").replace(this.re, fn).replace(this.codeRe, codeFn)); - body.push("'].join('');};"); - body = body.join(''); } - eval(body); - return this; + me.renderLabels(); + me.renderCallouts(); }, - applyTemplate : function(values){ - return this.master.compiled.call(this, values, {}, 1, 1); + onAnimate: function(sprite, attr) { + sprite.show(); + return this.callParent(arguments); }, - compile : function(){return this;} - - - - - -}); - -Ext.XTemplate.prototype.apply = Ext.XTemplate.prototype.applyTemplate; - - -Ext.XTemplate.from = function(el){ - el = Ext.getDom(el); - return new Ext.XTemplate(el.value || el.innerHTML); -}; - -Ext.util.CSS = function(){ - var rules = null; - var doc = document; - - var camelRe = /(-[a-z])/gi; - var camelFn = function(m, a){ return a.charAt(1).toUpperCase(); }; - - return { - - createStyleSheet : function(cssText, id){ - var ss; - var head = doc.getElementsByTagName("head")[0]; - var rules = doc.createElement("style"); - rules.setAttribute("type", "text/css"); - if(id){ - rules.setAttribute("id", id); - } - if(Ext.isIE){ - head.appendChild(rules); - ss = rules.styleSheet; - ss.cssText = cssText; - }else{ - try{ - rules.appendChild(doc.createTextNode(cssText)); - }catch(e){ - rules.cssText = cssText; - } - head.appendChild(rules); - ss = rules.styleSheet ? rules.styleSheet : (rules.sheet || doc.styleSheets[doc.styleSheets.length-1]); - } - this.cacheStyleSheet(ss); - return ss; - }, - - - removeStyleSheet : function(id){ - var existing = doc.getElementById(id); - if(existing){ - existing.parentNode.removeChild(existing); - } - }, + onCreateLabel: function(storeItem, item, i, display) { + var me = this, + group = me.labelsGroup, + config = me.label, + bbox = me.bbox, + endLabelStyle = Ext.apply(config, me.seriesLabelStyle); - - swapStyleSheet : function(id, url){ - this.removeStyleSheet(id); - var ss = doc.createElement("link"); - ss.setAttribute("rel", "stylesheet"); - ss.setAttribute("type", "text/css"); - ss.setAttribute("id", id); - ss.setAttribute("href", url); - doc.getElementsByTagName("head")[0].appendChild(ss); - }, - - - refreshCache : function(){ - return this.getRules(true); - }, + 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 || {})); + }, - - cacheStyleSheet : function(ss){ - if(!rules){ - rules = {}; - } - try{ - var ssRules = ss.cssRules || ss.rules; - for(var j = ssRules.length-1; j >= 0; --j){ - rules[ssRules[j].selectorText.toLowerCase()] = ssRules[j]; - } - }catch(e){} - }, - - - getRules : function(refreshCache){ - if(rules === null || refreshCache){ - rules = {}; - var ds = doc.styleSheets; - for(var i =0, len = ds.length; i < len; i++){ - try{ - this.cacheStyleSheet(ds[i]); - }catch(e){} - } - } - return rules; - }, - - - getRule : function(selector, refreshCache){ - var rs = this.getRules(refreshCache); - if(!Ext.isArray(selector)){ - return rs[selector.toLowerCase()]; - } - for(var i = 0; i < selector.length; i++){ - if(rs[selector[i]]){ - return rs[selector[i].toLowerCase()]; - } - } - return null; - }, - - - - updateRule : function(selector, property, value){ - if(!Ext.isArray(selector)){ - var rule = this.getRule(selector); - if(rule){ - rule.style[property.replace(camelRe, camelFn)] = value; - return true; - } - }else{ - for(var i = 0; i < selector.length; i++){ - if(this.updateRule(selector[i], property, value)){ - return true; - } - } - } - return false; - } - }; -}(); -Ext.util.ClickRepeater = Ext.extend(Ext.util.Observable, { - constructor : function(el, config){ - this.el = Ext.get(el); - this.el.unselectable(); + 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; + + 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; + y = (y + height > bbox.y + bbox.height) ? (y - (y + height - bbox.y - bbox.height)) : y; + + if (me.chart.animate && !me.chart.resizing) { + label.show(true); + me.onAnimate(label, { + to: { + x: x, + y: y + } + }); + } else { + label.setAttributes({ + x: x, + y: y + }, true); + if (resizing) { + me.animation.on('afteranimate', function() { + label.show(true); + }); + } else { + label.show(true); + } + } + }, - Ext.apply(this, config); + + 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; - this.addEvents( - "mousedown", + 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]); - "click", + norm = Math.sqrt(1 + a * a); + dir = [1 / norm, a / norm]; + normal = [-dir[1], dir[0]]; - "mouseup" - ); - - if(!this.disabled){ - this.disabled = true; - this.enable(); + + 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; } - if(this.handler){ - this.on("click", this.handler, this.scope || this); + 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])) { + normal[0] *= -1; + } + if (boxy < clipRect[1] || (boxy + boxh) > (clipRect[1] + clipRect[3])) { + normal[1] *= -1; } - Ext.util.ClickRepeater.superclass.constructor.call(this); + + 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"] + }, 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); + } }, - interval : 20, - delay: 250, - preventDefault : true, - stopDefault : false, - timer : 0, + 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])) { + dist = abs(x - point[0]); + } else { + point = pointsUp[p -1]; + if (y >= point[1] && (!pointsDown.length || y <= (pointsDown[p -1][1]))) { + item.storeIndex = p -1; + item.storeField = me.yField[i]; + item.storeItem = me.chart.store.getAt(p -1); + item._points = pointsDown.length? [point, pointsDown[p -1]] : [point]; + return true; + } else { + break; + } + } + } + return false; + }, - enable: function(){ - if(this.disabled){ - this.el.on('mousedown', this.handleMouseDown, this); - if (Ext.isIE){ - this.el.on('dblclick', this.handleDblClick, this); + highlightSeries: function() { + var area, to, fillColor; + if (this._index !== undefined) { + area = this.areas[this._index]; + if (area.__highlightAnim) { + area.__highlightAnim.paused = true; } - if(this.preventDefault || this.stopDefault){ - this.el.on('click', this.eventOptions, this); + 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); } } - this.disabled = false; }, - disable: function( force){ - if(force || !this.disabled){ - clearTimeout(this.timer); - if(this.pressClass){ - this.el.removeClass(this.pressClass); + 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 + } + }); } - Ext.getDoc().un('mouseup', this.handleMouseUp, this); - this.el.removeAllListeners(); } - this.disabled = true; }, - setDisabled: function(disabled){ - this[disabled ? 'disable' : 'enable'](); + 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); }, - eventOptions: function(e){ - if(this.preventDefault){ - e.preventDefault(); + + unHighlightItem: function(item) { + if (!item) { + this.unHighlightSeries(); } - if(this.stopDefault){ - e.stopEvent(); + + if (this.highlightSprite) { + this.highlightSprite.hide(true); } }, - destroy : function() { - this.disable(true); - Ext.destroy(this.el); - this.purgeListeners(); - }, - - handleDblClick : function(e){ - clearTimeout(this.timer); - this.el.blur(); - - this.fireEvent("mousedown", this, e); - this.fireEvent("click", this, e); + hideAll: function() { + if (!isNaN(this._index)) { + this.__excludes[this._index] = true; + this.areas[this._index].hide(true); + this.drawSeries(); + } }, - handleMouseDown : function(e){ - clearTimeout(this.timer); - this.el.blur(); - if(this.pressClass){ - this.el.addClass(this.pressClass); + showAll: function() { + if (!isNaN(this._index)) { + this.__excludes[this._index] = false; + this.areas[this._index].show(true); + this.drawSeries(); } - this.mousedownTime = new Date(); + }, - Ext.getDoc().on("mouseup", this.handleMouseUp, this); - this.el.on("mouseout", this.handleMouseOut, this); + + getLegendColor: function(index) { + var me = this; + return me.colorArrayStyle[index % me.colorArrayStyle.length]; + } +}); - this.fireEvent("mousedown", this, e); - this.fireEvent("click", this, e); - - if (this.accelerate) { - this.delay = 400; - } - this.timer = this.click.defer(this.delay || this.interval, this, [e]); - }, +Ext.define('Ext.chart.series.Bar', { - click : function(e){ - this.fireEvent("click", this, e); - this.timer = this.click.defer(this.accelerate ? - this.easeOutExpo(this.mousedownTime.getElapsed(), - 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; - }, + extend: 'Ext.chart.series.Cartesian', - - handleMouseOut : function(){ - clearTimeout(this.timer); - if(this.pressClass){ - this.el.removeClass(this.pressClass); - } - this.el.on("mouseover", this.handleMouseReturn, this); - }, + alternateClassName: ['Ext.chart.BarSeries', 'Ext.chart.BarChart', 'Ext.chart.StackedBarChart'], - - handleMouseReturn : function(){ - this.el.un("mouseover", this.handleMouseReturn, this); - if(this.pressClass){ - this.el.addClass(this.pressClass); - } - this.click(); - }, + requires: ['Ext.chart.axis.Axis', 'Ext.fx.Anim'], - 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); - this.el.removeClass(this.pressClass); - this.fireEvent("mouseup", this, e); - } -}); -Ext.KeyNav = function(el, config){ - this.el = Ext.get(el); - Ext.apply(this, config); - if(!this.disabled){ - this.disabled = true; - this.enable(); - } -}; -Ext.KeyNav.prototype = { + type: 'bar', + + alias: 'series.bar', - disabled : false, + column: false, - defaultEventAction: "stopEvent", - forceKeyDown : false, - + style: {}, + - relay : function(e){ - var k = e.getKey(), - h = this.keyToHandler[k]; - if(h && this[h]){ - if(this.doRelay(e, this[h], h) !== true){ - e[this.defaultEventAction](); - } - } - }, + gutter: 38.2, - doRelay : function(e, h, hname){ - return h.call(this.scope || this, e, hname); - }, + groupGutter: 38.2, - enter : false, - left : false, - right : false, - up : false, - down : false, - tab : false, - esc : false, - pageUp : false, - pageDown : false, - del : false, - home : false, - end : false, + xPadding: 0, - keyToHandler : { - 37 : "left", - 39 : "right", - 38 : "up", - 40 : "down", - 33 : "pageUp", - 34 : "pageDown", - 46 : "del", - 36 : "home", - 35 : "end", - 13 : "enter", - 27 : "esc", - 9 : "tab" - }, - - stopKeyUp: function(e) { - var k = e.getKey(); + yPadding: 10, - if (k >= 37 && k <= 40) { - + constructor: function(config) { + this.callParent(arguments); + var me = this, + surface = me.chart.surface, + shadow = me.chart.shadow, + i, l; + Ext.apply(me, config, { + highlightCfg: { + lineWidth: 3, + stroke: '#55c', + opacity: 0.8, + color: '#f00' + }, - e.stopEvent(); + shadowAttributes: [{ + "stroke-width": 6, + "stroke-opacity": 0.05, + stroke: 'rgb(200, 200, 200)', + translate: { + x: 1.2, + y: 1.2 + } + }, { + "stroke-width": 4, + "stroke-opacity": 0.1, + stroke: 'rgb(150, 150, 150)', + translate: { + x: 0.9, + y: 0.9 + } + }, { + "stroke-width": 2, + "stroke-opacity": 0.15, + stroke: 'rgb(100, 100, 100)', + translate: { + x: 0.6, + y: 0.6 + } + }] + }); + me.group = surface.getGroup(me.seriesId + '-bars'); + if (shadow) { + for (i = 0, l = me.shadowAttributes.length; i < l; i++) { + me.shadowGroups.push(surface.getGroup(me.seriesId + '-shadows' + i)); + } } }, + + getBarGirth: function() { + var me = this, + store = me.chart.store, + 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); + }, + - destroy: function(){ - this.disable(); + getGutters: function() { + var me = this, + column = me.column, + gutter = Math.ceil(me[column ? 'xPadding' : 'yPadding'] + me.getBarGirth() / 2); + return me.column ? [gutter, 0] : [0, gutter]; }, - - enable: function() { - if (this.disabled) { - if (Ext.isSafari2) { - - this.el.on('keyup', this.stopKeyUp, this); + + getBounds: function() { + var me = this, + chart = me.chart, + store = chart.substore || chart.store, + bars = [].concat(me.yField), + barsLen = bars.length, + groupBarsLen = barsLen, + groupGutter = me.groupGutter / 100, + column = me.column, + xPadding = me.xPadding, + yPadding = me.yPadding, + stacked = me.stacked, + barWidth = me.getBarGirth(), + math = Math, + mmax = math.max, + mabs = math.abs, + groupBarWidth, bbox, minY, maxY, axis, out, + scale, zero, total, rec, j, plus, minus; + + me.setBBox(true); + bbox = me.bbox; + + + if (me.__excludes) { + for (j = 0, total = me.__excludes.length; j < total; j++) { + if (me.__excludes[j]) { + groupBarsLen--; + } } - - this.el.on(this.isKeydown()? 'keydown' : 'keypress', this.relay, this); - this.disabled = false; } - }, - - disable: function() { - if (!this.disabled) { - if (Ext.isSafari2) { - - this.el.un('keyup', this.stopKeyUp, this); + 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); } + } - this.el.un(this.isKeydown()? 'keydown' : 'keypress', this.relay, this); - this.disabled = true; + 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); } - }, - - - setDisabled : function(disabled){ - this[disabled ? "disable" : "enable"](); - }, - - - isKeydown: function(){ - return this.forceKeyDown || Ext.EventManager.useKeydown; - } -}; -Ext.KeyMap = function(el, config, eventName){ - this.el = Ext.get(el); - this.eventName = eventName || "keydown"; - this.bindings = []; - if(config){ - this.addBinding(config); - } - this.enable(); -}; + if (!Ext.isNumber(minY)) { + minY = 0; + } + if (!Ext.isNumber(maxY)) { + maxY = 0; + } + scale = (column ? bbox.height - yPadding * 2 : bbox.width - xPadding * 2) / (maxY - minY); + groupBarWidth = barWidth / ((stacked ? 1 : groupBarsLen) * (groupGutter + 1) - groupGutter); + zero = (column) ? bbox.y + bbox.height - yPadding : bbox.x + xPadding; -Ext.KeyMap.prototype = { - - stopEvent : false, + if (stacked) { + total = [[], []]; + store.each(function(record, i) { + total[0][i] = total[0][i] || 0; + total[1][i] = total[1][i] || 0; + for (j = 0; j < barsLen; j++) { + if (me.__excludes && me.__excludes[j]) { + continue; + } + rec = record.get(bars[j]); + total[+(rec > 0)][i] += mabs(rec); + } + }); + total[+(maxY > 0)].push(mabs(maxY)); + total[+(minY > 0)].push(mabs(minY)); + minus = mmax.apply(math, total[0]); + plus = mmax.apply(math, total[1]); + scale = (column ? bbox.height - yPadding * 2 : bbox.width - xPadding * 2) / (plus + minus); + zero = zero + minus * scale * (column ? -1 : 1); + } + else if (minY / maxY < 0) { + zero = zero - minY * scale * (column ? -1 : 1); + } + return { + bars: bars, + bbox: bbox, + barsLen: barsLen, + groupBarsLen: groupBarsLen, + barWidth: barWidth, + groupBarWidth: groupBarWidth, + scale: scale, + zero: zero, + xPadding: xPadding, + yPadding: yPadding, + signed: minY / maxY < 0, + minY: minY, + maxY: maxY + }; + }, - addBinding : function(config){ - if(Ext.isArray(config)){ - Ext.each(config, function(c){ - this.addBinding(c); - }, this); - return; - } - var keyCode = config.key, - fn = config.fn || config.handler, - scope = config.scope; - - if (config.stopEvent) { - this.stopEvent = config.stopEvent; - } - - if(typeof keyCode == "string"){ - var ks = []; - var keyString = keyCode.toUpperCase(); - for(var j = 0, len = keyString.length; j < len; j++){ - ks.push(keyString.charCodeAt(j)); - } - keyCode = ks; - } - var keyArray = Ext.isArray(keyCode); - - var handler = function(e){ - if(this.checkModifiers(config, e)){ - var k = e.getKey(); - if(keyArray){ - for(var i = 0, len = keyCode.length; i < len; i++){ - if(keyCode[i] == k){ - if(this.stopEvent){ - e.stopEvent(); - } - fn.call(scope || window, k, e); - return; - } + getPaths: function() { + var me = this, + chart = me.chart, + store = chart.substore || chart.store, + bounds = me.bounds = me.getBounds(), + items = me.items = [], + gutter = me.gutter / 100, + groupGutter = me.groupGutter / 100, + animate = chart.animate, + column = me.column, + group = me.group, + enableShadows = chart.shadow, + shadowGroups = me.shadowGroups, + shadowAttributes = me.shadowAttributes, + shadowGroupsLn = shadowGroups.length, + bbox = bounds.bbox, + xPadding = me.xPadding, + yPadding = me.yPadding, + stacked = me.stacked, + barsLen = bounds.barsLen, + colors = me.colorArrayStyle, + colorLength = colors && colors.length || 0, + math = Math, + mmax = math.max, + mmin = math.min, + mabs = math.abs, + j, yValue, height, totalDim, totalNegDim, bottom, top, hasShadow, barAttr, attrs, counter, + shadowIndex, shadow, sprite, offset, floorY; + + store.each(function(record, i, total) { + bottom = bounds.zero; + top = bounds.zero; + totalDim = 0; + totalNegDim = 0; + 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); + barAttr = { + fill: colors[(barsLen > 1 ? j : 0) % colorLength] + }; + if (column) { + Ext.apply(barAttr, { + height: height, + width: mmax(bounds.groupBarWidth, 0), + x: (bbox.x + xPadding + i * bounds.barWidth * (1 + gutter) + counter * bounds.groupBarWidth * (1 + groupGutter) * !stacked), + y: bottom - height + }); + } + else { + + offset = (total - 1) - i; + Ext.apply(barAttr, { + height: mmax(bounds.groupBarWidth, 0), + width: height + (bottom == bounds.zero), + x: bottom + (bottom != bounds.zero), + y: (bbox.y + yPadding + offset * bounds.barWidth * (1 + gutter) + counter * bounds.groupBarWidth * (1 + groupGutter) * !stacked + 1) + }); + } + if (height < 0) { + if (column) { + barAttr.y = top; + barAttr.height = mabs(height); + } else { + barAttr.x = top + height; + barAttr.width = mabs(height); } - }else{ - if(k == keyCode){ - if(this.stopEvent){ - e.stopEvent(); + } + if (stacked) { + if (height < 0) { + top += height * (column ? -1 : 1); + } else { + bottom += height * (column ? -1 : 1); + } + totalDim += mabs(height); + if (height < 0) { + totalNegDim += mabs(height); + } + } + barAttr.x = Math.floor(barAttr.x) + 1; + floorY = Math.floor(barAttr.y); + if (!Ext.isIE9 && barAttr.y > floorY) { + floorY--; + } + barAttr.y = floorY; + barAttr.width = Math.floor(barAttr.width); + barAttr.height = Math.floor(barAttr.height); + items.push({ + series: me, + storeItem: record, + value: [record.get(me.xField), yValue], + attr: barAttr, + point: column ? [barAttr.x + barAttr.width / 2, yValue >= 0 ? barAttr.y : barAttr.y + barAttr.height] : + [yValue >= 0 ? barAttr.x + barAttr.width : barAttr.x, barAttr.y + barAttr.height / 2] + }); + + if (animate && chart.resizing) { + attrs = column ? { + x: barAttr.x, + y: bounds.zero, + width: barAttr.width, + height: 0 + } : { + x: bounds.zero, + y: barAttr.y, + width: 0, + height: barAttr.height + }; + if (enableShadows && (stacked && !hasShadow || !stacked)) { + hasShadow = true; + + for (shadowIndex = 0; shadowIndex < shadowGroupsLn; shadowIndex++) { + shadow = shadowGroups[shadowIndex].getAt(stacked ? i : (i * barsLen + j)); + if (shadow) { + shadow.setAttributes(attrs, true); + } } - fn.call(scope || window, k, e); + } + + sprite = group.getAt(i * barsLen + j); + if (sprite) { + sprite.setAttributes(attrs, true); } } + counter++; } - }; - this.bindings.push(handler); - }, - - - checkModifiers: function(config, e){ - var val, key, keys = ['shift', 'ctrl', 'alt']; - for (var i = 0, len = keys.length; i < len; ++i){ - key = keys[i]; - val = config[key]; - if(!(val === undefined || (val === e[key + 'Key']))){ - return false; + if (stacked && items.length) { + items[i * counter].totalDim = totalDim; + items[i * counter].totalNegDim = totalNegDim; } - } - return true; + }, me); }, - on : function(key, fn, scope){ - var keyCode, shift, ctrl, alt; - if(typeof key == "object" && !Ext.isArray(key)){ - keyCode = key.key; - shift = key.shift; - ctrl = key.ctrl; - alt = key.alt; - }else{ - keyCode = key; + renderShadows: function(i, barAttr, baseAttrs, bounds) { + var me = this, + chart = me.chart, + surface = chart.surface, + animate = chart.animate, + stacked = me.stacked, + shadowGroups = me.shadowGroups, + shadowAttributes = me.shadowAttributes, + shadowGroupsLn = shadowGroups.length, + store = chart.substore || chart.store, + column = me.column, + items = me.items, + shadows = [], + zero = bounds.zero, + shadowIndex, shadowBarAttr, shadow, totalDim, totalNegDim, j, rendererAttributes; + + if ((stacked && (i % bounds.groupBarsLen === 0)) || !stacked) { + j = i / bounds.groupBarsLen; + + for (shadowIndex = 0; shadowIndex < shadowGroupsLn; shadowIndex++) { + shadowBarAttr = Ext.apply({}, shadowAttributes[shadowIndex]); + shadow = shadowGroups[shadowIndex].getAt(stacked ? j : i); + Ext.copyTo(shadowBarAttr, barAttr, 'x,y,width,height'); + if (!shadow) { + shadow = surface.add(Ext.apply({ + type: 'rect', + group: shadowGroups[shadowIndex] + }, Ext.apply({}, baseAttrs, shadowBarAttr))); + } + if (stacked) { + totalDim = items[i].totalDim; + totalNegDim = items[i].totalNegDim; + if (column) { + shadowBarAttr.y = zero - totalNegDim; + shadowBarAttr.height = totalDim; + } + else { + shadowBarAttr.x = zero - totalNegDim; + shadowBarAttr.width = totalDim; + } + } + if (animate) { + if (!stacked) { + rendererAttributes = me.renderer(shadow, store.getAt(j), shadowBarAttr, i, store); + me.onAnimate(shadow, { to: rendererAttributes }); + } + else { + rendererAttributes = me.renderer(shadow, store.getAt(j), Ext.apply(shadowBarAttr, { hidden: true }), i, store); + shadow.setAttributes(rendererAttributes, true); + } + } + else { + rendererAttributes = me.renderer(shadow, store.getAt(j), Ext.apply(shadowBarAttr, { hidden: false }), i, store); + shadow.setAttributes(rendererAttributes, true); + } + shadows.push(shadow); + } } - this.addBinding({ - key: keyCode, - shift: shift, - ctrl: ctrl, - alt: alt, - fn: fn, - scope: scope - }); + return shadows; }, - handleKeyDown : function(e){ - if(this.enabled){ - var b = this.bindings; - for(var i = 0, len = b.length; i < len; i++){ - b[i].call(this, e); - } - } - }, - - - isEnabled : function(){ - return this.enabled; - }, + drawSeries: function() { + var me = this, + chart = me.chart, + store = chart.substore || chart.store, + surface = chart.surface, + animate = chart.animate, + stacked = me.stacked, + column = me.column, + enableShadows = chart.shadow, + shadowGroups = me.shadowGroups, + shadowGroupsLn = shadowGroups.length, + group = me.group, + 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); + me.unHighlightItem(); + me.cleanHighlights(); - - enable: function(){ - if(!this.enabled){ - this.el.on(this.eventName, this.handleKeyDown, this); - this.enabled = true; - } - }, + me.getPaths(); + bounds = me.bounds; + items = me.items; - - disable: function(){ - if(this.enabled){ - this.el.removeListener(this.eventName, this.handleKeyDown, this); - this.enabled = false; - } - }, - - - setDisabled : function(disabled){ - this[disabled ? "disable" : "enable"](); - } -}; -Ext.util.TextMetrics = function(){ - var shared; - return { + baseAttrs = column ? { + y: bounds.zero, + height: 0 + } : { + x: bounds.zero, + width: 0 + }; + ln = items.length; - measure : function(el, text, fixedWidth){ - if(!shared){ - shared = Ext.util.TextMetrics.Instance(el, fixedWidth); + for (i = 0; i < ln; i++) { + sprite = group.getAt(i); + barAttr = items[i].attr; + + if (enableShadows) { + items[i].shadows = me.renderShadows(i, barAttr, baseAttrs, bounds); } - shared.bind(el); - shared.setFixedWidth(fixedWidth || 'auto'); - return shared.getSize(text); - }, - - createInstance : function(el, fixedWidth){ - return Ext.util.TextMetrics.Instance(el, fixedWidth); + + if (!sprite) { + attrs = Ext.apply({}, baseAttrs, barAttr); + attrs = Ext.apply(attrs, endSeriesStyle || {}); + sprite = surface.add(Ext.apply({}, { + type: 'rect', + group: group + }, attrs)); + } + if (animate) { + rendererAttributes = me.renderer(sprite, store.getAt(i), barAttr, i, store); + sprite._to = rendererAttributes; + anim = me.onAnimate(sprite, { to: Ext.apply(rendererAttributes, endSeriesStyle) }); + if (enableShadows && stacked && (i % bounds.barsLen === 0)) { + j = i / bounds.barsLen; + for (shadowIndex = 0; shadowIndex < shadowGroupsLn; shadowIndex++) { + anim.on('afteranimate', function() { + this.show(true); + }, shadowGroups[shadowIndex].getAt(j)); + } + } + } + else { + rendererAttributes = me.renderer(sprite, store.getAt(i), Ext.apply(barAttr, { hidden: false }), i, store); + sprite.setAttributes(Ext.apply(rendererAttributes, endSeriesStyle), true); + } + items[i].sprite = sprite; } - }; -}(); -Ext.util.TextMetrics.Instance = function(bindTo, fixedWidth){ - var ml = new Ext.Element(document.createElement('div')); - document.body.appendChild(ml.dom); - ml.position('absolute'); - ml.setLeftTop(-1000, -1000); - ml.hide(); - - if(fixedWidth){ - ml.setWidth(fixedWidth); - } - - var instance = { - getSize : function(text){ - ml.update(text); - var s = ml.getSize(); - ml.update(''); - return s; - }, - + ln = group.getCount(); + for (j = i; j < ln; j++) { + group.getAt(j).hide(true); + } - bind : function(el){ - ml.setStyle( - Ext.fly(el).getStyles('font-size','font-style', 'font-weight', 'font-family','line-height', 'text-transform', 'letter-spacing') - ); - }, - + if (enableShadows) { + for (shadowIndex = 0; shadowIndex < shadowGroupsLn; shadowIndex++) { + shadowGroup = shadowGroups[shadowIndex]; + ln = shadowGroup.getCount(); + for (j = i; j < ln; j++) { + shadowGroup.getAt(j).hide(true); + } + } + } + me.renderLabels(); + }, + + + onCreateLabel: function(storeItem, item, i, display) { + var me = this, + surface = me.chart.surface, + group = me.labelsGroup, + config = me.label, + endLabelStyle = Ext.apply({}, config, me.seriesLabelStyle || {}), + sprite; + return surface.add(Ext.apply({ + type: 'text', + group: group + }, endLabelStyle || {})); + }, + + + onPlaceLabel: function(label, storeItem, item, i, display, animate, index) { - setFixedWidth : function(width){ - ml.setWidth(width); - }, - - getWidth : function(text){ - ml.dom.style.width = 'auto'; - return this.getSize(text).width; - }, + var me = this, + opt = me.bounds, + groupBarWidth = opt.groupBarWidth, + column = me.column, + chart = me.chart, + chartBBox = chart.chartBBox, + resizing = chart.resizing, + xValue = item.value[0], + yValue = item.value[1], + attr = item.attr, + config = me.label, + rotate = config.orientation == 'vertical', + field = [].concat(config.field), + format = config.renderer, + text = format(storeItem.get(field[index])), + size = me.getLabelSize(text), + width = size.width, + height = size.height, + zero = opt.zero, + outside = 'outside', + insideStart = 'insideStart', + insideEnd = 'insideEnd', + offsetX = 10, + offsetY = 6, + signed = opt.signed, + x, y, finalAttr; + + label.setAttributes({ + text: text + }); + if (column) { + if (display == outside) { + if (height + offsetY + attr.height > (yValue >= 0 ? zero - chartBBox.y : chartBBox.y + chartBBox.height - zero)) { + display = insideEnd; + } + } else { + if (height + offsetY > attr.height) { + display = outside; + } + } + x = attr.x + groupBarWidth / 2; + y = display == insideStart ? + (zero + ((height / 2 + 3) * (yValue >= 0 ? -1 : 1))) : + (yValue >= 0 ? (attr.y + ((height / 2 + 3) * (display == outside ? -1 : 1))) : + (attr.y + attr.height + ((height / 2 + 3) * (display === outside ? 1 : -1)))); + } + else { + if (display == outside) { + if (width + offsetX + attr.width > (yValue >= 0 ? chartBBox.x + chartBBox.width - zero : zero - chartBBox.x)) { + display = insideEnd; + } + } + else { + if (width + offsetX > attr.width) { + display = outside; + } + } + x = display == insideStart ? + (zero + ((width / 2 + 5) * (yValue >= 0 ? 1 : -1))) : + (yValue >= 0 ? (attr.x + attr.width + ((width / 2 + 5) * (display === outside ? 1 : -1))) : + (attr.x + ((width / 2 + 5) * (display === outside ? -1 : 1)))); + y = attr.y + groupBarWidth / 2; + } - getHeight : function(text){ - return this.getSize(text).height; + finalAttr = { + x: x, + y: y + }; + + if (rotate) { + finalAttr.rotate = { + x: x, + y: y, + degrees: 270 + }; } - }; + + if (animate && resizing) { + if (column) { + x = attr.x + attr.width / 2; + y = zero; + } else { + x = zero; + y = attr.y + attr.height / 2; + } + label.setAttributes({ + x: x, + y: y + }, true); + if (rotate) { + label.setAttributes({ + rotate: { + x: x, + y: y, + degrees: 270 + } + }, true); + } + } + + if (animate) { + me.onAnimate(label, { to: finalAttr }); + } + else { + label.setAttributes(Ext.apply(finalAttr, { + hidden: false + }), true); + } + }, - instance.bind(bindTo); + + getLabelSize: function(value) { + var tester = this.testerLabel, + config = this.label, + endLabelStyle = Ext.apply({}, config, this.seriesLabelStyle || {}), + rotated = config.orientation === 'vertical', + bbox, w, h, + undef; + if (!tester) { + tester = this.testerLabel = this.chart.surface.add(Ext.apply({ + type: 'text', + opacity: 0 + }, endLabelStyle)); + } + tester.setAttributes({ + text: value + }, true); - return instance; -}; + + bbox = tester.getBBox(); + w = bbox.width; + h = bbox.height; + return { + width: rotated ? h : w, + height: rotated ? w : h + }; + }, -Ext.Element.addMethods({ - getTextWidth : function(text, min, max){ - return (Ext.util.TextMetrics.measure(this.dom, Ext.value(text, this.dom.innerHTML, true)).width).constrain(min || 0, max || 1000000); - } -}); - -Ext.util.Cookies = { + onAnimate: function(sprite, attr) { + sprite.show(); + return this.callParent(arguments); + }, - set : function(name, value){ - var argv = arguments; - var argc = arguments.length; - var expires = (argc > 2) ? argv[2] : null; - var path = (argc > 3) ? argv[3] : '/'; - var domain = (argc > 4) ? argv[4] : null; - var secure = (argc > 5) ? argv[5] : false; - document.cookie = name + "=" + escape(value) + ((expires === null) ? "" : ("; expires=" + expires.toGMTString())) + ((path === null) ? "" : ("; path=" + path)) + ((domain === null) ? "" : ("; domain=" + domain)) + ((secure === true) ? "; secure" : ""); + 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; }, - - get : function(name){ - var arg = name + "="; - var alen = arg.length; - var clen = document.cookie.length; - var i = 0; - var j = 0; - while(i < clen){ - j = i + alen; - if(document.cookie.substring(i, j) == arg){ - return Ext.util.Cookies.getCookieVal(j); - } - i = document.cookie.indexOf(" ", i) + 1; - if(i === 0){ - break; + + hideAll: function() { + var axes = this.chart.axes; + if (!isNaN(this._index)) { + if (!this.__excludes) { + this.__excludes = []; } + this.__excludes[this._index] = true; + this.drawSeries(); + axes.each(function(axis) { + axis.drawAxis(); + }); } - return null; }, - clear : function(name){ - if(Ext.util.Cookies.get(name)){ - document.cookie = name + "=" + "; expires=Thu, 01-Jan-70 00:00:01 GMT"; + showAll: function() { + var axes = this.chart.axes; + if (!isNaN(this._index)) { + if (!this.__excludes) { + this.__excludes = []; + } + this.__excludes[this._index] = false; + this.drawSeries(); + axes.each(function(axis) { + axis.drawAxis(); + }); } }, - getCookieVal : function(offset){ - var endstr = document.cookie.indexOf(";", offset); - if(endstr == -1){ - endstr = document.cookie.length; - } - return unescape(document.cookie.substring(offset, endstr)); + + getLegendColor: function(index) { + var me = this; + return me.colorArrayStyle[index % me.colorArrayStyle.length]; } -}; -Ext.handleError = function(e) { - throw e; -}; +}); -Ext.Error = function(message) { - - this.message = (this.lang[message]) ? this.lang[message] : message; -}; +Ext.define('Ext.chart.series.Column', { -Ext.Error.prototype = new Error(); -Ext.apply(Ext.Error.prototype, { - lang: {}, - name: 'Ext.Error', + alternateClassName: ['Ext.chart.ColumnSeries', 'Ext.chart.ColumnChart', 'Ext.chart.StackedColumnChart'], + + extend: 'Ext.chart.series.Bar', + - getName : function() { - return this.name; - }, + + type: 'column', + alias: 'series.column', + + column: true, + - getMessage : function() { - return this.message; - }, + xPadding: 10, + - toJson : function() { - return Ext.encode(this); - } + yPadding: 0 }); -Ext.ComponentMgr = function(){ - var all = new Ext.util.MixedCollection(); - var types = {}; - var ptypes = {}; - - return { - - register : function(c){ - all.add(c); - }, +Ext.define('Ext.chart.series.Gauge', { - - unregister : function(c){ - all.remove(c); - }, + - - get : function(id){ - return all.get(id); - }, + extend: 'Ext.chart.series.Series', - - onAvailable : function(id, fn, scope){ - all.on("add", function(index, o){ - if(o.id == id){ - fn.call(scope || o, o); - all.un("add", fn, scope); - } - }); - }, + - - all : all, - - - types : types, - - - ptypes: ptypes, - - - isRegistered : function(xtype){ - return types[xtype] !== undefined; - }, - - - isPluginRegistered : function(ptype){ - return ptypes[ptype] !== undefined; - }, + type: "gauge", + alias: 'series.gauge', - - registerType : function(xtype, cls){ - types[xtype] = cls; - cls.xtype = xtype; - }, + rad: Math.PI / 180, - - create : function(config, defaultType){ - return config.render ? config : new types[config.xtype || defaultType](config); - }, + + highlightDuration: 150, - - registerPlugin : function(ptype, cls){ - ptypes[ptype] = cls; - cls.ptype = ptype; - }, + + angleField: false, - - createPlugin : function(config, defaultType){ - var PluginCls = ptypes[config.ptype || defaultType]; - if (PluginCls.init) { - return PluginCls; - } else { - return new PluginCls(config); - } - } - }; -}(); + + needle: false, + + + donut: false, + + showInLegend: false, -Ext.reg = Ext.ComponentMgr.registerType; + + style: {}, + + constructor: function(config) { + this.callParent(arguments); + var me = this, + chart = me.chart, + surface = chart.surface, + store = chart.store, + shadow = chart.shadow, i, l, cfg; + Ext.apply(me, config, { + shadowAttributes: [{ + "stroke-width": 6, + "stroke-opacity": 1, + stroke: 'rgb(200, 200, 200)', + translate: { + x: 1.2, + y: 2 + } + }, + { + "stroke-width": 4, + "stroke-opacity": 1, + stroke: 'rgb(150, 150, 150)', + translate: { + x: 0.9, + y: 1.5 + } + }, + { + "stroke-width": 2, + "stroke-opacity": 1, + stroke: 'rgb(100, 100, 100)', + translate: { + x: 0.6, + y: 1 + } + }] + }); + me.group = surface.getGroup(me.seriesId); + if (shadow) { + for (i = 0, l = me.shadowAttributes.length; i < l; i++) { + me.shadowGroups.push(surface.getGroup(me.seriesId + '-shadows' + i)); + } + } + surface.customAttributes.segment = function(opt) { + return me.getSegment(opt); + }; + }, + + //@private updates some onbefore render parameters. -Ext.preg = Ext.ComponentMgr.registerPlugin; + initialize: function() { + var me = this, + store = me.chart.substore || me.chart.store; + + me.yField = []; + if (me.label.field) { + store.each(function(rec) { + me.yField.push(rec.get(me.label.field)); + }); + } + }, -Ext.create = Ext.ComponentMgr.create; -Ext.Component = function(config){ - config = config || {}; - if(config.initialConfig){ - if(config.isAction){ - this.baseAction = config; + + getSegment: function(opt) { + var me = this, + 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, + 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); + + x1 = x + opt.startRho * cos(a1); + y1 = y + opt.startRho * sin(a1); + + x2 = x + opt.endRho * cos(a1); + y2 = y + opt.endRho * sin(a1); + + x3 = x + opt.startRho * cos(a2); + y3 = y + opt.startRho * sin(a2); + + x4 = x + opt.endRho * cos(a2); + y4 = y + opt.endRho * sin(a2); + + if (abs(x1 - x3) <= delta && abs(y1 - y3) <= delta) { + singleSlice = true; + } + + if (singleSlice) { + return { + path: [ + ["M", x1, y1], + ["L", x2, y2], + ["A", opt.endRho, opt.endRho, 0, +flag, 1, x4, y4], + ["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"]] + }; } - config = config.initialConfig; - }else if(config.tagName || config.dom || Ext.isString(config)){ - config = {applyTo: config, id: config.id || config}; - } + }, - this.initialConfig = config; + calcMiddle: function(item) { + var me = this, + rad = me.rad, + slice = item.slice, + x = me.centerX, + y = me.centerY, + startAngle = slice.startAngle, + endAngle = slice.endAngle, + radius = Math.max(('rho' in slice) ? slice.rho: me.radius, me.label.minMargin), + 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); + + item.middle = { + x: xm, + y: ym + }; + }, - Ext.apply(this, config); - this.addEvents( - - 'added', - - 'disable', - - 'enable', - - 'beforeshow', - - 'show', - - 'beforehide', - - 'hide', - - 'removed', - - 'beforerender', - - 'render', - - 'afterrender', - - 'beforedestroy', + + drawSeries: function() { + var me = this, + chart = me.chart, + store = chart.substore || chart.store, + group = me.group, + animate = me.chart.animate, + axis = me.chart.axes.get(0), + minimum = axis && axis.minimum || me.minimum || 0, + maximum = axis && axis.maximum || me.maximum || 0, + field = me.angleField || me.field || me.xField, + surface = chart.surface, + chartBBox = chart.chartBBox, + rad = me.rad, + donut = +me.donut, + values = {}, + items = [], + seriesStyle = me.seriesStyle, + seriesLabelStyle = me.seriesLabelStyle, + colorArrayStyle = me.colorArrayStyle, + colorArrayLength = colorArrayStyle && colorArrayStyle.length || 0, + gutterX = chart.maxGutter[0], + gutterY = chart.maxGutter[1], + cos = Math.cos, + sin = Math.sin, + rendererAttributes, centerX, centerY, slice, slices, sprite, value, + item, ln, record, i, j, startAngle, endAngle, middleAngle, sliceLength, path, + p, spriteOptions, bbox, splitAngle, sliceA, sliceB; + + Ext.apply(seriesStyle, me.style || {}); + + me.setBBox(); + bbox = me.bbox; + + + if (me.colorSet) { + colorArrayStyle = me.colorSet; + colorArrayLength = colorArrayStyle.length; + } + + + if (!store || !store.getCount()) { + return; + } - 'destroy', + centerX = me.centerX = chartBBox.x + (chartBBox.width / 2); + centerY = me.centerY = chartBBox.y + chartBBox.height; + me.radius = Math.min(centerX - chartBBox.x, centerY - chartBBox.y); + me.slices = slices = []; + me.items = items = []; - 'beforestaterestore', + if (!me.value) { + record = store.getAt(0); + me.value = record.get(field); + } - 'staterestore', + value = me.value; + if (me.needle) { + sliceA = { + series: me, + value: value, + startAngle: -180, + endAngle: 0, + rho: me.radius + }; + splitAngle = -180 * (1 - (value - minimum) / (maximum - minimum)); + slices.push(sliceA); + } else { + splitAngle = -180 * (1 - (value - minimum) / (maximum - minimum)); + sliceA = { + series: me, + value: value, + startAngle: -180, + endAngle: splitAngle, + rho: me.radius + }; + sliceB = { + series: me, + value: me.maximum - value, + startAngle: splitAngle, + endAngle: 0, + rho: me.radius + }; + slices.push(sliceA, sliceB); + } - 'beforestatesave', - 'statesave' - ); - this.getId(); - Ext.ComponentMgr.register(this); - Ext.Component.superclass.constructor.call(this); - - if(this.baseAction){ - this.baseAction.addComponent(this); - } - - this.initComponent(); + for (i = 0, ln = slices.length; i < ln; i++) { + slice = slices[i]; + sprite = group.getAt(i); + + rendererAttributes = Ext.apply({ + segment: { + startAngle: slice.startAngle, + endAngle: slice.endAngle, + margin: 0, + rho: slice.rho, + startRho: slice.rho * +donut / 100, + endRho: slice.rho + } + }, Ext.apply(seriesStyle, colorArrayStyle && { fill: colorArrayStyle[i % colorArrayLength] } || {})); - if(this.plugins){ - if(Ext.isArray(this.plugins)){ - for(var i = 0, len = this.plugins.length; i < len; i++){ - this.plugins[i] = this.initPlugin(this.plugins[i]); + item = Ext.apply({}, + rendererAttributes.segment, { + slice: slice, + series: me, + storeItem: record, + index: i + }); + items[i] = item; + + if (!sprite) { + spriteOptions = Ext.apply({ + type: "path", + group: group + }, Ext.apply(seriesStyle, colorArrayStyle && { fill: colorArrayStyle[i % colorArrayLength] } || {})); + sprite = surface.add(Ext.apply(spriteOptions, rendererAttributes)); + } + slice.sprite = slice.sprite || []; + item.sprite = sprite; + slice.sprite.push(sprite); + if (animate) { + rendererAttributes = me.renderer(sprite, record, rendererAttributes, i, store); + sprite._to = rendererAttributes; + me.onAnimate(sprite, { + to: rendererAttributes + }); + } else { + rendererAttributes = me.renderer(sprite, record, Ext.apply(rendererAttributes, { + hidden: false + }), i, store); + sprite.setAttributes(rendererAttributes, true); } - }else{ - this.plugins = this.initPlugin(this.plugins); } - } - - if(this.stateful !== false){ - this.initState(); - } - - if(this.applyTo){ - this.applyToMarkup(this.applyTo); - delete this.applyTo; - }else if(this.renderTo){ - this.render(this.renderTo); - delete this.renderTo; - } -}; - - -Ext.Component.AUTO_ID = 1000; - -Ext.extend(Ext.Component, Ext.util.Observable, { - - - - - + + if (me.needle) { + splitAngle = splitAngle * Math.PI / 180; + + if (!me.needleSprite) { + me.needleSprite = me.chart.surface.add({ + type: 'path', + path: ['M', centerX + (me.radius * +donut / 100) * cos(splitAngle), + centerY + -Math.abs((me.radius * +donut / 100) * sin(splitAngle)), + 'L', centerX + me.radius * cos(splitAngle), + centerY + -Math.abs(me.radius * sin(splitAngle))], + 'stroke-width': 4, + 'stroke': '#222' + }); + } else { + if (animate) { + me.onAnimate(me.needleSprite, { + to: { + path: ['M', centerX + (me.radius * +donut / 100) * cos(splitAngle), + centerY + -Math.abs((me.radius * +donut / 100) * sin(splitAngle)), + 'L', centerX + me.radius * cos(splitAngle), + centerY + -Math.abs(me.radius * sin(splitAngle))] + } + }); + } else { + me.needleSprite.setAttributes({ + type: 'path', + path: ['M', centerX + (me.radius * +donut / 100) * cos(splitAngle), + centerY + -Math.abs((me.radius * +donut / 100) * sin(splitAngle)), + 'L', centerX + me.radius * cos(splitAngle), + centerY + -Math.abs(me.radius * sin(splitAngle))] + }); + } + } + me.needleSprite.setAttributes({ + hidden: false + }, true); + } + + delete me.value; + }, + setValue: function (value) { + this.value = value; + this.drawSeries(); + }, + onCreateLabel: function(storeItem, item, i, display) {}, + + onPlaceLabel: function(label, storeItem, item, i, display, animate, index) {}, + + onPlaceCallout: function() {}, + + onAnimate: function(sprite, attr) { + sprite.show(); + return this.callParent(arguments); + }, + + isItemInPoint: function(x, y, item, i) { + return false; + }, + showAll: function() { + if (!isNaN(this._index)) { + this.__excludes[this._index] = false; + this.drawSeries(); + } + }, + getLegendColor: function(index) { + var me = this; + return me.colorArrayStyle[index % me.colorArrayStyle.length]; + } +}); + + + + +Ext.define('Ext.chart.series.Line', { + - disabled : false, - - hidden : false, - - - - - - - - autoEl : 'div', + + extend: 'Ext.chart.series.Cartesian', + + alternateClassName: ['Ext.chart.LineSeries', 'Ext.chart.LineChart'], + + requires: ['Ext.chart.axis.Axis', 'Ext.chart.Shape', 'Ext.draw.Draw', 'Ext.fx.Anim'], - disabledClass : 'x-item-disabled', + + type: 'line', - allowDomMove : true, + alias: 'series.line', + - autoShow : false, + selectionTolerance: 20, - hideMode : 'display', - hideParent : false, + showMarkers: true, + + markerConfig: {}, + + style: {}, + smooth: false, + - rendered : false, + fill: false, + constructor: function(config) { + this.callParent(arguments); + var me = this, + surface = me.chart.surface, + shadow = me.chart.shadow, + i, l; + Ext.apply(me, config, { + highlightCfg: { + 'stroke-width': 3 + }, + shadowAttributes: [{ + "stroke-width": 6, + "stroke-opacity": 0.05, + stroke: 'rgb(0, 0, 0)', + translate: { + x: 1, + y: 1 + } + }, { + "stroke-width": 4, + "stroke-opacity": 0.1, + stroke: 'rgb(0, 0, 0)', + translate: { + x: 1, + y: 1 + } + }, { + "stroke-width": 2, + "stroke-opacity": 0.15, + stroke: 'rgb(0, 0, 0)', + translate: { + x: 1, + y: 1 + } + }] + }); + me.group = surface.getGroup(me.seriesId); + if (me.showMarkers) { + me.markerGroup = surface.getGroup(me.seriesId + '-markers'); + } + if (shadow) { + for (i = 0, l = this.shadowAttributes.length; i < l; i++) { + me.shadowGroups.push(surface.getGroup(me.seriesId + '-shadows' + i)); + } + } + }, + shrink: function(xValues, yValues, size) { + + var len = xValues.length, + ratio = Math.floor(len / size), + i = 1, + xSum = 0, + ySum = 0, + xRes = [xValues[0]], + yRes = [yValues[0]]; + + for (; i < len; ++i) { + xSum += xValues[i] || 0; + ySum += yValues[i] || 0; + if (i % ratio == 0) { + xRes.push(xSum/ratio); + yRes.push(ySum/ratio); + xSum = 0; + ySum = 0; + } + } + return { + x: xRes, + y: yRes + }; + }, + drawSeries: function() { + var me = this, + chart = me.chart, + store = chart.substore || chart.store, + surface = chart.surface, + chartBBox = chart.chartBBox, + 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, + lnsh = shadowGroups.length, + dummyPath = ["M"], + path = ["M"], + markerIndex = chart.markerIndex, + axes = [].concat(me.axis), + shadowGroup, + shadowBarAttr, + xValues = [], + yValues = [], + onbreak = false, + markerStyle = me.markerStyle, + seriesStyle = me.seriesStyle, + seriesLabelStyle = me.seriesLabelStyle, + 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, + yValue, coords, xScale, yScale, minX, maxX, minY, maxY, line, animation, endMarkerStyle, + endLineStyle, type, props, firstMarker; + + + if (!store || !store.getCount()) { + return; + } + + + endMarkerStyle = Ext.apply(markerStyle, me.markerConfig); + type = endMarkerStyle.type; + delete endMarkerStyle.type; + endLineStyle = Ext.apply(seriesStyle, me.style); + + + if (!endLineStyle['stroke-width']) { + endLineStyle['stroke-width'] = 0.5; + } + + + if (markerIndex && markerGroup && markerGroup.getCount()) { + for (i = 0; i < markerIndex; i++) { + marker = markerGroup.getAt(i); + markerGroup.remove(marker); + markerGroup.add(marker); + markerAux = markerGroup.getAt(markerGroup.getCount() - 2); + marker.setAttributes({ + x: 0, + y: 0, + translate: { + x: markerAux.attr.translation.x, + y: markerAux.attr.translation.y + } + }, true); + } + } + + me.unHighlightItem(); + me.cleanHighlights(); - - tplWriteMode : 'overwrite', + me.setBBox(); + bbox = me.bbox; - - - - bubbleEvents: [], + 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]); + if (axis) { + ends = axis.calcEnds(); + if (axis.position == 'top' || axis.position == 'bottom') { + minX = ends.from; + maxX = ends.to; + } + else { + minY = ends.from; + maxY = ends.to; + } + } + } + + + + if (me.xField && !Ext.isNumber(minX) + && (me.axis == 'bottom' || me.axis == 'top')) { + axis = Ext.create('Ext.chart.axis.Axis', { + chart: chart, + fields: [].concat(me.xField) + }).calcEnds(); + minX = axis.from; + maxX = axis.to; + } + if (me.yField && !Ext.isNumber(minY) + && (me.axis == 'right' || me.axis == 'left')) { + axis = Ext.create('Ext.chart.axis.Axis', { + chart: chart, + fields: [].concat(me.yField) + }).calcEnds(); + minY = axis.from; + maxY = axis.to; + } - - ctype : 'Ext.Component', + if (isNaN(minX)) { + minX = 0; + xScale = bbox.width / (store.getCount() - 1); + } + else { + xScale = bbox.width / (maxX - minX); + } - - actionMode : 'el', + if (isNaN(minY)) { + minY = 0; + yScale = bbox.height / (store.getCount() - 1); + } + else { + yScale = bbox.height / (maxY - minY); + } - - getActionEl : function(){ - return this[this.actionMode]; - }, + store.each(function(record, i) { + xValue = record.get(me.xField); + 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' + + || (me.axis != 'left' && me.axis != 'right')) { + yValue = i; + } + xValues.push(xValue); + yValues.push(yValue); + }, me); + + ln = xValues.length; + if (ln > bbox.width) { + coords = me.shrink(xValues, yValues, bbox.width); + xValues = coords.x; + yValues = coords.y; + } + + me.items = []; + + ln = xValues.length; + for (i = 0; i < ln; i++) { + xValue = xValues[i]; + yValue = yValues[i]; + if (yValue === false) { + if (path.length == 1) { + path = []; + } + onbreak = true; + me.items.push(false); + continue; + } else { + x = (bbox.x + (xValue - minX) * xScale).toFixed(2); + y = ((bbox.y + bbox.height) - (yValue - minY) * yScale).toFixed(2); + if (onbreak) { + onbreak = false; + path.push('M'); + } + path = path.concat([x, y]); + } + if ((typeof firstY == 'undefined') && (typeof y != 'undefined')) { + firstY = y; + } + + if (!me.line || chart.resizing) { + dummyPath = dummyPath.concat([x, bbox.y + bbox.height / 2]); + } - initPlugin : function(p){ - if(p.ptype && !Ext.isFunction(p.init)){ - p = Ext.ComponentMgr.createPlugin(p); - }else if(Ext.isString(p)){ - p = Ext.ComponentMgr.createPlugin({ - ptype: p + + if (chart.animate && chart.resizing && me.line) { + me.line.setAttributes({ + path: dummyPath + }, true); + if (me.fillPath) { + me.fillPath.setAttributes({ + path: dummyPath, + opacity: 0.2 + }, true); + } + if (me.line.shadows) { + shadows = me.line.shadows; + for (j = 0, lnsh = shadows.length; j < lnsh; j++) { + shadow = shadows[j]; + shadow.setAttributes({ + path: dummyPath + }, true); + } + } + } + if (showMarkers) { + marker = markerGroup.getAt(i); + if (!marker) { + marker = Ext.chart.Shape[type](surface, Ext.apply({ + group: [group, markerGroup], + x: 0, y: 0, + translate: { + x: prevX || x, + y: prevY || (bbox.y + bbox.height / 2) + }, + value: '"' + xValue + ', ' + yValue + '"' + }, endMarkerStyle)); + marker._to = { + translate: { + x: x, + y: y + } + }; + } else { + marker.setAttributes({ + value: '"' + xValue + ', ' + yValue + '"', + x: 0, y: 0, + hidden: false + }, true); + marker._to = { + translate: { + x: x, y: y + } + }; + } + } + me.items.push({ + series: me, + value: [xValue, yValue], + point: [x, y], + sprite: marker, + storeItem: store.getAt(i) }); + prevX = x; + prevY = y; } - p.init(this); - return p; - }, - - - initComponent : function(){ - if(this.listeners){ - this.on(this.listeners); - delete this.listeners; + if (path.length <= 1) { + + return; + } + + if (me.smooth) { + path = Ext.draw.Draw.smooth(path, 6); + } + + + if (chart.markerIndex && me.previousPath) { + fromPath = me.previousPath; + fromPath.splice(1, 2); + } else { + fromPath = path; } - this.enableBubble(this.bubbleEvents); - }, - - render : function(container, position){ - if(!this.rendered && this.fireEvent('beforerender', this) !== false){ - if(!container && this.el){ - this.el = Ext.get(this.el); - container = this.el.dom.parentNode; - this.allowDomMove = false; - } - this.container = Ext.get(container); - if(this.ctCls){ - this.container.addClass(this.ctCls); + + if (!me.line) { + me.line = surface.add(Ext.apply({ + type: 'path', + group: group, + path: dummyPath, + stroke: endLineStyle.stroke || endLineStyle.fill + }, endLineStyle || {})); + + me.line.setAttributes({ + fill: 'none' + }); + if (!endLineStyle.stroke && colorArrayLength) { + me.line.setAttributes({ + stroke: colorArrayStyle[seriesIdx % colorArrayLength] + }, true); } - this.rendered = true; - if(position !== undefined){ - if(Ext.isNumber(position)){ - position = this.container.dom.childNodes[position]; - }else{ - position = Ext.getDom(position); + if (enableShadows) { + + 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({}, { + type: 'path', + group: shadowGroups[shindex] + }, shadowBarAttr)); + shadows.push(shadow); } } - this.onRender(this.container, position || null); - if(this.autoShow){ - this.el.removeClass(['x-hidden','x-hide-' + this.hideMode]); - } - if(this.cls){ - this.el.addClass(this.cls); - delete this.cls; - } - if(this.style){ - this.el.applyStyles(this.style); - delete this.style; - } - if(this.overCls){ - this.el.addClassOnOver(this.overCls); + } + if (me.fill) { + fillPath = path.concat([ + ["L", x, bbox.y + bbox.height], + ["L", bbox.x, bbox.y + bbox.height], + ["L", bbox.x, firstY] + ]); + if (!me.fillPath) { + me.fillPath = surface.add({ + group: group, + type: 'path', + opacity: endLineStyle.opacity || 0.3, + fill: colorArrayStyle[seriesIdx % colorArrayLength] || endLineStyle.fill, + path: dummyPath + }); } - this.fireEvent('render', this); - - + } + markerCount = showMarkers && markerGroup.getCount(); + if (chart.animate) { + fill = me.fill; + line = me.line; + rendererAttributes = me.renderer(line, false, { path: path }, i, store); + Ext.apply(rendererAttributes, endLineStyle || {}, { + stroke: endLineStyle.stroke || endLineStyle.fill + }); + + delete rendererAttributes.fill; + if (chart.markerIndex && me.previousPath) { + me.animation = animation = me.onAnimate(line, { + to: rendererAttributes, + from: { + path: fromPath + } + }); + } else { + me.animation = animation = me.onAnimate(line, { + to: rendererAttributes + }); + } - var contentTarget = this.getContentTarget(); - if (this.html){ - contentTarget.update(Ext.DomHelper.markup(this.html)); - delete this.html; + if (enableShadows) { + shadows = line.shadows; + for(j = 0; j < lnsh; j++) { + if (chart.markerIndex && me.previousPath) { + me.onAnimate(shadows[j], { + to: { path: path }, + from: { path: fromPath } + }); + } else { + me.onAnimate(shadows[j], { + to: { path: path } + }); + } + } } - if (this.contentEl){ - var ce = Ext.getDom(this.contentEl); - Ext.fly(ce).removeClass(['x-hidden', 'x-hide-display']); - contentTarget.appendChild(ce); + + if (fill) { + me.onAnimate(me.fillPath, { + to: Ext.apply({}, { + path: fillPath, + fill: colorArrayStyle[seriesIdx % colorArrayLength] || endLineStyle.fill + }, endLineStyle || {}) + }); } - if (this.tpl) { - if (!this.tpl.compile) { - this.tpl = new Ext.XTemplate(this.tpl); + + if (showMarkers) { + for(i = 0; i < ln; i++) { + item = markerGroup.getAt(i); + if (item) { + if (me.items[i]) { + 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); + } + } } - if (this.data) { - this.tpl[this.tplWriteMode](contentTarget, this.data); - delete this.data; + for(; i < markerCount; i++) { + item = markerGroup.getAt(i); + item.hide(true); } - } - this.afterRender(this.container); - if(this.hidden){ - - this.doHide(); + + } - if(this.disabled){ - - this.disable(true); + } else { + rendererAttributes = me.renderer(me.line, false, { path: path, hidden: false }, i, store); + Ext.apply(rendererAttributes, endLineStyle || {}, { + stroke: endLineStyle.stroke || endLineStyle.fill + }); + + delete rendererAttributes.fill; + me.line.setAttributes(rendererAttributes, true); + + if (enableShadows) { + shadows = me.line.shadows; + for(j = 0; j < lnsh; j++) { + shadows[j].setAttributes({ + path: path + }, true); + } } - - if(this.stateful !== false){ - this.initStateEvents(); + if (me.fill) { + me.fillPath.setAttributes({ + path: fillPath + }, true); + } + if (showMarkers) { + for(i = 0; i < ln; i++) { + item = markerGroup.getAt(i); + if (item) { + if (me.items[i]) { + rendererAttributes = me.renderer(item, store.getAt(i), item._to, i, store); + item.setAttributes(Ext.apply(endMarkerStyle || {}, rendererAttributes || {}), true); + } else { + item.hide(true); + } + } + } + for(; i < markerCount; i++) { + item = markerGroup.getAt(i); + item.hide(true); + } } - this.fireEvent('afterrender', this); } - return this; - }, - - - update: function(htmlOrData, loadScripts, cb) { - var contentTarget = this.getContentTarget(); - if (this.tpl && typeof htmlOrData !== "string") { - this.tpl[this.tplWriteMode](contentTarget, htmlOrData || {}); - } else { - var html = Ext.isObject(htmlOrData) ? Ext.DomHelper.markup(htmlOrData) : htmlOrData; - contentTarget.update(html, loadScripts, cb); + if (chart.markerIndex) { + path.splice(1, 0, path[1], path[2]); + me.previousPath = path; } + me.renderLabels(); + me.renderCallouts(); }, - - - onAdded : function(container, pos) { - this.ownerCt = container; - this.initRef(); - this.fireEvent('added', this, container, pos); - }, - - onRemoved : function() { - this.removeRef(); - this.fireEvent('removed', this, this.ownerCt); - delete this.ownerCt; - }, + 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 || {})); + }, + - initRef : function() { + onPlaceLabel: function(label, storeItem, item, i, display, animate) { + 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], + radius = item.sprite.attr.radius, + bb, width, height; + + label.setAttributes({ + text: format(storeItem.get(field)), + hidden: true + }, true); - if(this.ref && !this.refOwner){ - var levels = this.ref.split('/'), - last = levels.length, - i = 0, - t = this; - - while(t && i < last){ - t = t.ownerCt; - ++i; - } - if(t){ - t[this.refName = levels[--i]] = this; - - this.refOwner = t; + if (display == 'rotate') { + label.setAttributes({ + 'text-anchor': 'start', + 'rotation': { + x: x, + y: y, + degrees: -45 + } + }, true); + + bb = label.getBBox(); + width = bb.width; + height = bb.height; + 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(); + bb.width = bb.width || (radius * 2); + bb.height = bb.height || (radius * 2); + y = y + (display == 'over'? -bb.height : bb.height); + + 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; + y = (y + height > bbox.y + bbox.height) ? (y - (y + height - bbox.y - bbox.height)) : y; + } + + if (me.chart.animate && !me.chart.resizing) { + label.show(true); + me.onAnimate(label, { + to: { + x: x, + y: y + } + }); + } else { + label.setAttributes({ + x: x, + y: y + }, true); + if (resizing) { + me.animation.on('afteranimate', function() { + label.show(true); + }); + } else { + label.show(true); } } }, - removeRef : function() { - if (this.refOwner && this.refName) { - delete this.refOwner[this.refName]; - delete this.refOwner; + //@private Overriding highlights.js highlightItem method. + + 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 (this.line.__anim) { + this.line.__anim.paused = true; + } + this.line.__anim = Ext.create('Ext.fx.Anim', { + target: this.line, + to: { + 'stroke-width': this.line.__strokeWidth + 3 + } + }); + this.highlighted = true; } }, - - initState : function(){ - if(Ext.state.Manager){ - var id = this.getStateId(); - if(id){ - var state = Ext.state.Manager.get(id); - if(state){ - if(this.fireEvent('beforestaterestore', this, state) !== false){ - this.applyState(Ext.apply({}, state)); - this.fireEvent('staterestore', this, state); - } + //@private Overriding highlights.js unHighlightItem method. + + unHighlightItem: function() { + var me = this; + me.callParent(arguments); + if (this.line && this.highlighted) { + this.line.__anim = Ext.create('Ext.fx.Anim', { + target: this.line, + to: { + 'stroke-width': this.line.__strokeWidth } - } + }); + this.highlighted = false; } }, - - getStateId : function(){ - return this.stateId || ((/^(ext-comp-|ext-gen)/).test(String(this.id)) ? null : this.id); - }, + //@private called when a callout needs to be placed. - - initStateEvents : function(){ - if(this.stateEvents){ - for(var i = 0, e; e = this.stateEvents[i]; i++){ - this.on(e, this.saveState, this, {delay:100}); - } + onPlaceCallout : function(callout, storeItem, item, i, display, animate, index) { + if (!display) { + return; } - }, + + 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[0], +item.point[1]], + dir, norm, normal, a, aprev, anext, + offsetFromViz = config.offsetFromViz || 30, + offsetToSide = config.offsetToSide || 10, + offsetBox = config.offsetBox || 3, + boxx, boxy, boxw, boxh, + p, clipRect = me.clipRect, + bbox = { + width: config.styles.width || 10, + height: config.styles.height || 10 + }, + x, y; - - applyState : function(state){ - if(state){ - Ext.apply(this, state); + + 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]); + + 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; + } + + x = cur[0] + normal[0] * offsetFromViz; + y = cur[1] + normal[1] * offsetFromViz; - - getState : function(){ - return null; - }, + + boxx = x + (normal[0] > 0? 0 : -(bbox.width + 2 * offsetBox)); + boxy = y - bbox.height /2 - offsetBox; + boxw = bbox.width + 2 * offsetBox; + boxh = bbox.height + 2 * offsetBox; + + + + if (boxx < clipRect[0] || (boxx + boxw) > (clipRect[0] + clipRect[2])) { + normal[0] *= -1; + } + if (boxy < clipRect[1] || (boxy + boxh) > (clipRect[1] + clipRect[3])) { + normal[1] *= -1; + } - - saveState : function(){ - if(Ext.state.Manager && this.stateful !== false){ - var id = this.getStateId(); - if(id){ - var state = this.getState(); - if(this.fireEvent('beforestatesave', this, state) !== false){ - Ext.state.Manager.set(id, state); - this.fireEvent('statesave', this, state); + + 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, { + to: { + path: ["M", cur[0], cur[1], "L", x, y, "Z"] } + }); + + if (callout.panel) { + callout.panel.setPosition(boxx, boxy, true); } } - }, - - - applyToMarkup : function(el){ - this.allowDomMove = false; - this.el = Ext.get(el); - this.render(this.el.dom.parentNode); - }, - - - addClass : function(cls){ - if(this.el){ - this.el.addClass(cls); - }else{ - this.cls = this.cls ? this.cls + ' ' + cls : cls; + else { + + callout.lines.setAttributes({ + path: ["M", cur[0], cur[1], "L", x, y, "Z"] + }, true); + + if (callout.panel) { + callout.panel.setPosition(boxx, boxy); + } + } + for (p in callout) { + callout[p].show(true); } - return this; }, - - removeClass : function(cls){ - if(this.el){ - this.el.removeClass(cls); - }else if(this.cls){ - this.cls = this.cls.split(' ').remove(cls).join(' '); + isItemInPoint: function(x, y, item, i) { + var me = this, + items = me.items, + tolerance = me.selectionTolerance, + result = null, + prevItem, + nextItem, + prevPoint, + nextPoint, + ln, + x1, + y1, + x2, + y2, + xIntersect, + 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]; + } + prevPoint = prevItem && prevItem.point; + nextPoint = nextItem && nextItem.point; + x1 = prevItem ? prevPoint[0] : nextPoint[0] - tolerance; + y1 = prevItem ? prevPoint[1] : nextPoint[1]; + x2 = nextItem ? nextPoint[0] : prevPoint[0] + tolerance; + y2 = nextItem ? nextPoint[1] : prevPoint[1]; + 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 this; + return false; }, - - onRender : function(ct, position){ - if(!this.el && this.autoEl){ - if(Ext.isString(this.autoEl)){ - this.el = document.createElement(this.autoEl); - }else{ - var div = document.createElement('div'); - Ext.DomHelper.overwrite(div, this.autoEl); - this.el = div.firstChild; - } - if (!this.el.id) { - this.el.id = this.getId(); - } + toggleAll: function(show) { + var me = this, + i, ln, shadow, shadows; + if (!show) { + Ext.chart.series.Line.superclass.hideAll.call(me); } - if(this.el){ - this.el = Ext.get(this.el); - if(this.allowDomMove !== false){ - ct.dom.insertBefore(this.el.dom, position); - if (div) { - Ext.removeNode(div); - div = null; + else { + Ext.chart.series.Line.superclass.showAll.call(me); + } + if (me.line) { + me.line.setAttributes({ + hidden: !show + }, true); + + if (me.line.shadows) { + for (i = 0, shadows = me.line.shadows, ln = shadows.length; i < ln; i++) { + shadow = shadows[i]; + shadow.setAttributes({ + hidden: !show + }, true); } } } - }, - - - getAutoCreate : function(){ - var cfg = Ext.isObject(this.autoCreate) ? - this.autoCreate : Ext.apply({}, this.defaultAutoCreate); - if(this.id && !cfg.id){ - cfg.id = this.id; + if (me.fillPath) { + me.fillPath.setAttributes({ + hidden: !show + }, true); } - return cfg; }, - - afterRender : Ext.emptyFn, - - destroy : function(){ - if(!this.isDestroyed){ - if(this.fireEvent('beforedestroy', this) !== false){ - this.destroying = true; - this.beforeDestroy(); - if(this.ownerCt && this.ownerCt.remove){ - this.ownerCt.remove(this, false); - } - if(this.rendered){ - this.el.remove(); - if(this.actionMode == 'container' || this.removeMode == 'container'){ - this.container.remove(); - } - } - - if(this.focusTask && this.focusTask.cancel){ - this.focusTask.cancel(); - } - this.onDestroy(); - Ext.ComponentMgr.unregister(this); - this.fireEvent('destroy', this); - this.purgeListeners(); - this.destroying = false; - this.isDestroyed = true; - } - } + hideAll: function() { + this.toggleAll(false); }, + + + showAll: function() { + this.toggleAll(true); + } +}); - deleteMembers : function(){ - var args = arguments; - for(var i = 0, len = args.length; i < len; ++i){ - delete this[args[i]]; - } - }, +Ext.define('Ext.chart.series.Pie', { - beforeDestroy : Ext.emptyFn, - - onDestroy : Ext.emptyFn, + alternateClassName: ['Ext.chart.PieSeries', 'Ext.chart.PieChart'], - - getEl : function(){ - return this.el; - }, + extend: 'Ext.chart.series.Series', - getContentTarget : function(){ - return this.el; - }, + type: "pie", - getId : function(){ - return this.id || (this.id = 'ext-comp-' + (++Ext.Component.AUTO_ID)); - }, + alias: 'series.pie', - - getItemId : function(){ - return this.itemId || this.getId(); - }, + rad: Math.PI / 180, - focus : function(selectText, delay){ - if(delay){ - this.focusTask = new Ext.util.DelayedTask(this.focus, this, [selectText, false]); - this.focusTask.delay(Ext.isNumber(delay) ? delay : 10); - return this; - } - if(this.rendered && !this.isDestroyed){ - this.el.focus(); - if(selectText === true){ - this.el.dom.select(); - } - } - return this; - }, + highlightDuration: 150, - blur : function(){ - if(this.rendered){ - this.el.blur(); - } - return this; - }, + angleField: false, - disable : function( silent){ - if(this.rendered){ - this.onDisable(); - } - this.disabled = true; - if(silent !== true){ - this.fireEvent('disable', this); - } - return this; - }, + lengthField: false, - onDisable : function(){ - this.getActionEl().addClass(this.disabledClass); - this.el.dom.disabled = true; - }, + donut: false, - enable : function(){ - if(this.rendered){ - this.onEnable(); - } - this.disabled = false; - this.fireEvent('enable', this); - return this; - }, + showInLegend: false, - onEnable : function(){ - this.getActionEl().removeClass(this.disabledClass); - this.el.dom.disabled = false; - }, - - setDisabled : function(disabled){ - return this[disabled ? 'disable' : 'enable'](); - }, - - show : function(){ - if(this.fireEvent('beforeshow', this) !== false){ - this.hidden = false; - if(this.autoRender){ - this.render(Ext.isBoolean(this.autoRender) ? Ext.getBody() : this.autoRender); + style: {}, + + constructor: function(config) { + this.callParent(arguments); + var me = this, + chart = me.chart, + surface = chart.surface, + store = chart.store, + shadow = chart.shadow, i, l, cfg; + Ext.applyIf(me, { + highlightCfg: { + segment: { + margin: 20 + } } - if(this.rendered){ - this.onShow(); + }); + Ext.apply(me, config, { + shadowAttributes: [{ + "stroke-width": 6, + "stroke-opacity": 1, + stroke: 'rgb(200, 200, 200)', + translate: { + x: 1.2, + y: 2 + } + }, + { + "stroke-width": 4, + "stroke-opacity": 1, + stroke: 'rgb(150, 150, 150)', + translate: { + x: 0.9, + y: 1.5 + } + }, + { + "stroke-width": 2, + "stroke-opacity": 1, + stroke: 'rgb(100, 100, 100)', + translate: { + x: 0.6, + y: 1 + } + }] + }); + me.group = surface.getGroup(me.seriesId); + if (shadow) { + for (i = 0, l = me.shadowAttributes.length; i < l; i++) { + me.shadowGroups.push(surface.getGroup(me.seriesId + '-shadows' + i)); } - this.fireEvent('show', this); } - return this; + surface.customAttributes.segment = function(opt) { + return me.getSegment(opt); + }; }, - - onShow : function(){ - this.getVisibilityEl().removeClass('x-hide-' + this.hideMode); - }, + //@private updates some onbefore render parameters. - - hide : function(){ - if(this.fireEvent('beforehide', this) !== false){ - this.doHide(); - this.fireEvent('hide', this); + initialize: function() { + var me = this, + store = me.chart.substore || me.chart.store; + + me.yField = []; + if (me.label.field) { + store.each(function(rec) { + me.yField.push(rec.get(me.label.field)); + }); } - return this; }, - doHide: function(){ - this.hidden = true; - if(this.rendered){ - this.onHide(); + getSegment: function(opt) { + var me = this, + 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, + 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); + + x1 = x + opt.startRho * cos(a1); + y1 = y + opt.startRho * sin(a1); + + x2 = x + opt.endRho * cos(a1); + y2 = y + opt.endRho * sin(a1); + + x3 = x + opt.startRho * cos(a2); + y3 = y + opt.startRho * sin(a2); + + x4 = x + opt.endRho * cos(a2); + y4 = y + opt.endRho * sin(a2); + + if (abs(x1 - x3) <= delta && abs(y1 - y3) <= delta) { + singleSlice = true; + } + + if (singleSlice) { + return { + path: [ + ["M", x1, y1], + ["L", x2, y2], + ["A", opt.endRho, opt.endRho, 0, +flag, 1, x4, y4], + ["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"]] + }; } }, - onHide : function(){ - this.getVisibilityEl().addClass('x-hide-' + this.hideMode); + calcMiddle: function(item) { + var me = this, + rad = me.rad, + slice = item.slice, + x = me.centerX, + y = me.centerY, + 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); + + item.middle = { + x: xm, + y: ym + }; }, - getVisibilityEl : function(){ - return this.hideParent ? this.container : this.getActionEl(); - }, + drawSeries: function() { + var me = this, + store = me.chart.substore || me.chart.store, + group = me.group, + animate = me.chart.animate, + field = me.angleField || me.field || me.xField, + lenField = [].concat(me.lengthField), + totalLenField = 0, + colors = me.colorSet, + chart = me.chart, + surface = chart.surface, + chartBBox = chart.chartBBox, + enableShadows = chart.shadow, + shadowGroups = me.shadowGroups, + shadowAttributes = me.shadowAttributes, + lnsh = shadowGroups.length, + rad = me.rad, + layers = lenField.length, + rhoAcum = 0, + donut = +me.donut, + layerTotals = [], + values = {}, + fieldLength, + items = [], + passed = false, + totalField = 0, + maxLenField = 0, + cut = 9, + defcut = true, + angle = 0, + seriesStyle = me.seriesStyle, + seriesLabelStyle = me.seriesLabelStyle, + colorArrayStyle = me.colorArrayStyle, + colorArrayLength = colorArrayStyle && colorArrayStyle.length || 0, + gutterX = chart.maxGutter[0], + gutterY = chart.maxGutter[1], + rendererAttributes, + shadowGroup, + shadowAttr, + shadows, + shadow, + shindex, + centerX, + centerY, + deltaRho, + first = 0, + slice, + slices, + sprite, + value, + item, + lenValue, + ln, + record, + i, + j, + startAngle, + endAngle, + middleAngle, + sliceLength, + path, + p, + spriteOptions, bbox; + + Ext.apply(seriesStyle, me.style || {}); - - setVisible : function(visible){ - return this[visible ? 'show' : 'hide'](); - }, + me.setBBox(); + bbox = me.bbox; - - isVisible : function(){ - return this.rendered && this.getVisibilityEl().isVisible(); - }, + + if (me.colorSet) { + colorArrayStyle = me.colorSet; + colorArrayLength = colorArrayStyle.length; + } + + + if (!store || !store.getCount()) { + return; + } + + me.unHighlightItem(); + me.cleanHighlights(); - - cloneConfig : function(overrides){ - overrides = overrides || {}; - var id = overrides.id || Ext.id(); - var cfg = Ext.applyIf(overrides, this.initialConfig); - cfg.id = id; - return new this.constructor(cfg); + centerX = me.centerX = chartBBox.x + (chartBBox.width / 2); + centerY = me.centerY = chartBBox.y + (chartBBox.height / 2); + me.radius = Math.min(centerX - chartBBox.x, centerY - chartBBox.y); + me.slices = slices = []; + me.items = items = []; + + store.each(function(record, i) { + if (this.__excludes && this.__excludes[i]) { + + return; + } + totalField += +record.get(field); + if (lenField[0]) { + for (j = 0, totalLenField = 0; j < layers; j++) { + totalLenField += +record.get(lenField[j]); + } + layerTotals[i] = totalLenField; + maxLenField = Math.max(maxLenField, totalLenField); + } + }, this); + + 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; + } + + if (!i || first == 0) { + angle = 360 - middleAngle; + me.firstAngle = angle; + middleAngle = angle - 360 * value / totalField / 2; + } + endAngle = angle - 360 * value / totalField; + slice = { + series: me, + value: value, + startAngle: angle, + endAngle: endAngle, + storeItem: record + }; + if (lenField[0]) { + lenValue = layerTotals[i]; + slice.rho = me.radius * (lenValue / maxLenField); + } else { + 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++) { + sprite = group.getAt(i * layers + j); + deltaRho = lenField[j] ? store.getAt(i).get(lenField[j]) / layerTotals[i] * slice.rho: slice.rho; + + rendererAttributes = { + segment: { + startAngle: slice.startAngle, + endAngle: slice.endAngle, + margin: 0, + rho: slice.rho, + startRho: rhoAcum + (deltaRho * donut / 100), + endRho: rhoAcum + deltaRho + } + }; + + for (shindex = 0, shadows = []; shindex < lnsh; shindex++) { + shadowAttr = shadowAttributes[shindex]; + shadow = shadowGroups[shindex].getAt(i); + if (!shadow) { + shadow = chart.surface.add(Ext.apply({}, + { + type: 'path', + group: shadowGroups[shindex], + strokeLinejoin: "round" + }, + rendererAttributes, shadowAttr)); + } + if (animate) { + rendererAttributes = me.renderer(shadow, store.getAt(i), Ext.apply({}, + rendererAttributes, shadowAttr), i, store); + me.onAnimate(shadow, { + to: rendererAttributes + }); + } else { + rendererAttributes = me.renderer(shadow, store.getAt(i), Ext.apply(shadowAttr, { + hidden: false + }), i, store); + shadow.setAttributes(rendererAttributes, true); + } + shadows.push(shadow); + } + slice.shadowAttrs[j] = shadows; + } + } + } + + 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); + deltaRho = lenField[j] ? store.getAt(i).get(lenField[j]) / layerTotals[i] * slice.rho: slice.rho; + + rendererAttributes = Ext.apply({ + segment: { + startAngle: slice.startAngle, + endAngle: slice.endAngle, + margin: 0, + rho: slice.rho, + startRho: rhoAcum + (deltaRho * donut / 100), + endRho: rhoAcum + deltaRho + } + }, Ext.apply(seriesStyle, colorArrayStyle && { fill: colorArrayStyle[(layers > 1? j : i) % colorArrayLength] } || {})); + item = Ext.apply({}, + rendererAttributes.segment, { + slice: slice, + series: me, + storeItem: slice.storeItem, + index: i + }); + me.calcMiddle(item); + if (enableShadows) { + item.shadows = slice.shadowAttrs[j]; + } + items[i] = item; + + if (!sprite) { + spriteOptions = Ext.apply({ + type: "path", + group: group, + middle: item.middle + }, Ext.apply(seriesStyle, colorArrayStyle && { fill: colorArrayStyle[(layers > 1? j : i) % colorArrayLength] } || {})); + sprite = surface.add(Ext.apply(spriteOptions, rendererAttributes)); + } + slice.sprite = slice.sprite || []; + item.sprite = sprite; + slice.sprite.push(sprite); + slice.point = [item.middle.x, item.middle.y]; + if (animate) { + rendererAttributes = me.renderer(sprite, store.getAt(i), rendererAttributes, i, store); + sprite._to = rendererAttributes; + sprite._animating = true; + me.onAnimate(sprite, { + to: rendererAttributes, + listeners: { + afteranimate: { + fn: function() { + this._animating = false; + }, + scope: sprite + } + } + }); + } else { + rendererAttributes = me.renderer(sprite, store.getAt(i), Ext.apply(rendererAttributes, { + hidden: false + }), i, store); + sprite.setAttributes(rendererAttributes, true); + } + rhoAcum += deltaRho; + } + } + + + ln = group.getCount(); + for (i = 0; i < ln; i++) { + if (!slices[(i / layers) >> 0] && group.getAt(i)) { + group.getAt(i).hide(true); + } + } + if (enableShadows) { + lnsh = shadowGroups.length; + for (shindex = 0; shindex < ln; shindex++) { + if (!slices[(shindex / layers) >> 0]) { + for (j = 0; j < lnsh; j++) { + if (shadowGroups[j].getAt(shindex)) { + shadowGroups[j].getAt(shindex).hide(true); + } + } + } + } + } + me.renderLabels(); + me.renderCallouts(); }, - getXType : function(){ - return this.constructor.xtype; + onCreateLabel: function(storeItem, item, i, display) { + var me = this, + group = me.labelsGroup, + config = me.label, + centerX = me.centerX, + centerY = me.centerY, + middle = item.middle, + endLabelStyle = Ext.apply(me.seriesLabelStyle || {}, config || {}); + + return me.chart.surface.add(Ext.apply({ + 'type': 'text', + 'text-anchor': 'middle', + 'group': group, + 'x': middle.x, + 'y': middle.y + }, endLabelStyle)); }, - isXType : function(xtype, shallow){ + 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 = [].concat(config.field), + centerX = me.centerX, + centerY = me.centerY, + middle = item.middle, + opt = { + x: middle.x, + y: middle.y + }, + x = middle.x - centerX, + y = middle.y - centerY, + from = {}, + rho = 1, + theta = Math.atan2(y, x || 1), + dg = theta * 180 / Math.PI, + prevDg; - if (Ext.isFunction(xtype)){ - xtype = xtype.xtype; - }else if (Ext.isObject(xtype)){ - xtype = xtype.constructor.xtype; + function fixAngle(a) { + if (a < 0) a += 360; + return a % 360; } - return !shallow ? ('/' + this.getXTypes() + '/').indexOf('/' + xtype + '/') != -1 : this.constructor.xtype == xtype; - }, + label.setAttributes({ + text: format(storeItem.get(field[index])) + }, true); - - getXTypes : function(){ - var tc = this.constructor; - if(!tc.xtypes){ - var c = [], sc = this; - while(sc && sc.constructor.xtype){ - c.unshift(sc.constructor.xtype); - sc = sc.constructor.superclass; + switch (display) { + case 'outside': + rho = Math.sqrt(x * x + y * y) * 2; + + opt.x = rho * Math.cos(theta) + centerX; + opt.y = rho * Math.sin(theta) + centerY; + break; + + case 'rotate': + dg = fixAngle(dg); + dg = (dg > 90 && dg < 270) ? dg + 180: dg; + + prevDg = label.attr.rotation.degrees; + if (prevDg != null && Math.abs(prevDg - dg) > 180) { + if (dg > prevDg) { + dg -= 360; + } else { + dg += 360; + } + dg = dg % 360; + } else { + dg = fixAngle(dg); } - tc.xtypeChain = c; - tc.xtypes = c.join('/'); + + opt.rotate = { + degrees: dg, + x: opt.x, + y: opt.y + }; + break; + + default: + break; } - return tc.xtypes; + + opt.translate = { + x: 0, y: 0 + }; + if (animate && !resizing && (display != 'rotate' || prevDg != null)) { + me.onAnimate(label, { + to: opt + }); + } else { + label.setAttributes(opt, true); + } + label._from = from; }, - findParentBy : function(fn) { - for (var p = this.ownerCt; (p != null) && !fn(p, this); p = p.ownerCt); - return p || null; - }, + onPlaceCallout: function(callout, storeItem, item, i, display, animate, index) { + var me = this, + chart = me.chart, + resizing = chart.resizing, + config = me.callouts, + centerX = me.centerX, + centerY = me.centerY, + middle = item.middle, + opt = { + x: middle.x, + y: middle.y + }, + x = middle.x - centerX, + y = middle.y - centerY, + rho = 1, + rhoCenter, + theta = Math.atan2(y, x || 1), + bbox = callout.label.getBBox(), + offsetFromViz = 20, + offsetToSide = 10, + offsetBox = 10, + p; - - findParentByType : function(xtype, shallow){ - return this.findParentBy(function(c){ - return c.isXType(xtype, shallow); - }); - }, - - - bubble : function(fn, scope, args){ - var p = this; - while(p){ - if(fn.apply(scope || p, args || [p]) === false){ - break; - } - p = p.ownerCt; + + rho = item.endRho + offsetFromViz; + rhoCenter = (item.endRho + item.startRho) / 2 + (item.endRho - item.startRho) / 3; + + opt.x = rho * Math.cos(theta) + centerX; + opt.y = rho * Math.sin(theta) + centerY; + + x = rhoCenter * Math.cos(theta); + y = rhoCenter * Math.sin(theta); + + if (chart.animate) { + + me.onAnimate(callout.lines, { + to: { + path: ["M", x + centerX, y + centerY, "L", opt.x, opt.y, "Z", "M", opt.x, opt.y, "l", x > 0 ? offsetToSide: -offsetToSide, 0, "z"] + } + }); + + me.onAnimate(callout.box, { + to: { + x: opt.x + (x > 0 ? offsetToSide: -(offsetToSide + bbox.width + 2 * offsetBox)), + y: opt.y + (y > 0 ? ( - bbox.height - offsetBox / 2) : ( - bbox.height - offsetBox / 2)), + width: bbox.width + 2 * offsetBox, + height: bbox.height + 2 * offsetBox + } + }); + + me.onAnimate(callout.label, { + to: { + x: opt.x + (x > 0 ? (offsetToSide + offsetBox) : -(offsetToSide + bbox.width + offsetBox)), + y: opt.y + (y > 0 ? -bbox.height / 4: -bbox.height / 4) + } + }); + } else { + + callout.lines.setAttributes({ + path: ["M", x + centerX, y + centerY, "L", opt.x, opt.y, "Z", "M", opt.x, opt.y, "l", x > 0 ? offsetToSide: -offsetToSide, 0, "z"] + }, + true); + + callout.box.setAttributes({ + x: opt.x + (x > 0 ? offsetToSide: -(offsetToSide + bbox.width + 2 * offsetBox)), + y: opt.y + (y > 0 ? ( - bbox.height - offsetBox / 2) : ( - bbox.height - offsetBox / 2)), + width: bbox.width + 2 * offsetBox, + height: bbox.height + 2 * offsetBox + }, + true); + + callout.label.setAttributes({ + x: opt.x + (x > 0 ? (offsetToSide + offsetBox) : -(offsetToSide + bbox.width + offsetBox)), + y: opt.y + (y > 0 ? -bbox.height / 4: -bbox.height / 4) + }, + true); + } + for (p in callout) { + callout[p].show(true); } - return this; }, - getPositionEl : function(){ - return this.positionEl || this.el; + onAnimate: function(sprite, attr) { + sprite.show(); + return this.callParent(arguments); }, - - purgeListeners : function(){ - Ext.Component.superclass.purgeListeners.call(this); - if(this.mons){ - this.on('beforedestroy', this.clearMons, this, {single: true}); + isItemInPoint: function(x, y, item, i) { + var me = this, + cx = me.centerX, + cy = me.centerY, + abs = Math.abs, + dx = abs(x - cx), + dy = abs(y - cy), + startAngle = item.startAngle, + endAngle = item.endAngle, + rho = Math.sqrt(dx * dx + dy * dy), + angle = Math.atan2(y - cy, x - cx) / me.rad + 360; + + + if (angle > me.firstAngle) { + angle -= 360; + } + return (angle <= startAngle && angle > endAngle + && rho >= item.startRho && rho <= item.endRho); + }, + + + hideAll: function() { + var i, l, shadow, shadows, sh, lsh, sprite; + if (!isNaN(this._index)) { + this.__excludes = this.__excludes || []; + this.__excludes[this._index] = true; + sprite = this.slices[this._index].sprite; + for (sh = 0, lsh = sprite.length; sh < lsh; sh++) { + sprite[sh].setAttributes({ + hidden: true + }, true); + } + if (this.slices[this._index].shadowAttrs) { + for (i = 0, shadows = this.slices[this._index].shadowAttrs, l = shadows.length; i < l; i++) { + shadow = shadows[i]; + for (sh = 0, lsh = shadow.length; sh < lsh; sh++) { + shadow[sh].setAttributes({ + hidden: true + }, true); + } + } + } + this.drawSeries(); } }, - - clearMons : function(){ - Ext.each(this.mons, function(m){ - m.item.un(m.ename, m.fn, m.scope); - }, this); - this.mons = []; - }, - - createMons: function(){ - if(!this.mons){ - this.mons = []; - this.on('beforedestroy', this.clearMons, this, {single: true}); + showAll: function() { + if (!isNaN(this._index)) { + this.__excludes[this._index] = false; + this.drawSeries(); } }, - mon : function(item, ename, fn, scope, opt){ - this.createMons(); - if(Ext.isObject(ename)){ - var propRe = /^(?:scope|delay|buffer|single|stopEvent|preventDefault|stopPropagation|normalized|args|delegate)$/; + highlightItem: function(item) { + var me = this, + rad = me.rad; + item = item || this.items[this._index]; + + + + + + this.unHighlightItem(); + + if (!item || item.sprite && item.sprite._animating) { + return; + } + me.callParent([item]); + if (!me.highlight) { + return; + } + if ('segment' in me.highlightCfg) { + var highlightSegment = me.highlightCfg.segment, + animate = me.chart.animate, + attrs, i, shadows, shadow, ln, to, itemHighlightSegment, prop; + + if (me.labelsGroup) { + var group = me.labelsGroup, + display = me.label.display, + label = group.getAt(item.index), + middle = (item.startAngle + item.endAngle) / 2 * rad, + r = highlightSegment.margin || 0, + x = r * Math.cos(middle), + y = r * Math.sin(middle); - var o = ename; - for(var e in o){ - if(propRe.test(e)){ - continue; + + + + + + if (Math.abs(x) < 1e-10) { + x = 0; } - if(Ext.isFunction(o[e])){ - - this.mons.push({ - item: item, ename: e, fn: o[e], scope: o.scope - }); - item.on(e, o[e], o.scope, o); - }else{ - - this.mons.push({ - item: item, ename: e, fn: o[e], scope: o.scope + if (Math.abs(y) < 1e-10) { + y = 0; + } + + if (animate) { + label.stopAnimation(); + label.animate({ + to: { + translate: { + x: x, + y: y + } + }, + duration: me.highlightDuration }); - item.on(e, o[e]); + } + else { + label.setAttributes({ + translate: { + x: x, + y: y + } + }, true); } } - return; - } - - this.mons.push({ - item: item, ename: ename, fn: fn, scope: scope - }); - item.on(ename, fn, scope, opt); - }, - - - mun : function(item, ename, fn, scope){ - var found, mon; - this.createMons(); - for(var i = 0, len = this.mons.length; i < len; ++i){ - mon = this.mons[i]; - if(item === mon.item && ename == mon.ename && fn === mon.fn && scope === mon.scope){ - this.mons.splice(i, 1); - item.un(ename, fn, scope); - found = true; - break; + + if (me.chart.shadow && item.shadows) { + i = 0; + shadows = item.shadows; + ln = shadows.length; + for (; i < ln; i++) { + shadow = shadows[i]; + to = {}; + itemHighlightSegment = item.sprite._from.segment; + for (prop in itemHighlightSegment) { + if (! (prop in highlightSegment)) { + to[prop] = itemHighlightSegment[prop]; + } + } + attrs = { + segment: Ext.applyIf(to, me.highlightCfg.segment) + }; + if (animate) { + shadow.stopAnimation(); + shadow.animate({ + to: attrs, + duration: me.highlightDuration + }); + } + else { + shadow.setAttributes(attrs, true); + } + } } } - return found; }, - nextSibling : function(){ - if(this.ownerCt){ - var index = this.ownerCt.items.indexOf(this); - if(index != -1 && index+1 < this.ownerCt.items.getCount()){ - return this.ownerCt.items.itemAt(index+1); - } + unHighlightItem: function() { + var me = this; + if (!me.highlight) { + return; } - return null; - }, - - previousSibling : function(){ - if(this.ownerCt){ - var index = this.ownerCt.items.indexOf(this); - if(index > 0){ - return this.ownerCt.items.itemAt(index-1); + if (('segment' in me.highlightCfg) && me.items) { + var items = me.items, + animate = me.chart.animate, + shadowsEnabled = !!me.chart.shadow, + group = me.labelsGroup, + len = items.length, + i = 0, + j = 0, + display = me.label.display, + shadowLen, p, to, ihs, hs, sprite, shadows, shadow, item, label, attrs; + + for (; i < len; i++) { + item = items[i]; + if (!item) { + continue; + } + sprite = item.sprite; + if (sprite && sprite._highlighted) { + + if (group) { + label = group.getAt(item.index); + attrs = Ext.apply({ + translate: { + x: 0, + y: 0 + } + }, + display == 'rotate' ? { + rotate: { + x: label.attr.x, + y: label.attr.y, + degrees: label.attr.rotation.degrees + } + }: {}); + if (animate) { + label.stopAnimation(); + label.animate({ + to: attrs, + duration: me.highlightDuration + }); + } + else { + label.setAttributes(attrs, true); + } + } + if (shadowsEnabled) { + shadows = item.shadows; + shadowLen = shadows.length; + for (; j < shadowLen; j++) { + to = {}; + ihs = item.sprite._to.segment; + hs = item.sprite._from.segment; + Ext.apply(to, hs); + for (p in ihs) { + if (! (p in hs)) { + to[p] = ihs[p]; + } + } + shadow = shadows[j]; + if (animate) { + shadow.stopAnimation(); + shadow.animate({ + to: { + segment: to + }, + duration: me.highlightDuration + }); + } + else { + shadow.setAttributes({ segment: to }, true); + } + } + } + } } } - return null; + me.callParent(arguments); }, - - getBubbleTarget : function(){ - return this.ownerCt; + + getLegendColor: function(index) { + var me = this; + return me.colorArrayStyle[index % me.colorArrayStyle.length]; } }); -Ext.reg('component', Ext.Component); -Ext.Action = Ext.extend(Object, { - - - - - - - - constructor : function(config){ - this.initialConfig = config; - this.itemId = config.itemId = (config.itemId || config.id || Ext.id()); - this.items = []; - }, - - - isAction : true, +Ext.define('Ext.chart.series.Radar', { - setText : function(text){ - this.initialConfig.text = text; - this.callEach('setText', [text]); - }, - - getText : function(){ - return this.initialConfig.text; - }, + extend: 'Ext.chart.series.Series', - - setIconClass : function(cls){ - this.initialConfig.iconCls = cls; - this.callEach('setIconClass', [cls]); - }, + requires: ['Ext.chart.Shape', 'Ext.fx.Anim'], - getIconClass : function(){ - return this.initialConfig.iconCls; - }, - - setDisabled : function(v){ - this.initialConfig.disabled = v; - this.callEach('setDisabled', [v]); - }, + type: "radar", + alias: 'series.radar', - enable : function(){ - this.setDisabled(false); - }, + rad: Math.PI / 180, - - disable : function(){ - this.setDisabled(true); - }, + showInLegend: false, - isDisabled : function(){ - return this.initialConfig.disabled; - }, - + style: {}, - setHidden : function(v){ - this.initialConfig.hidden = v; - this.callEach('setVisible', [!v]); + constructor: function(config) { + this.callParent(arguments); + var me = this, + surface = me.chart.surface, i, l; + me.group = surface.getGroup(me.seriesId); + if (me.showMarkers) { + me.markerGroup = surface.getGroup(me.seriesId + '-markers'); + } }, - show : function(){ - this.setHidden(false); - }, + drawSeries: function() { + var me = this, + store = me.chart.substore || me.chart.store, + group = me.group, + sprite, + chart = me.chart, + animate = chart.animate, + field = me.field || me.yField, + surface = chart.surface, + chartBBox = chart.chartBBox, + rendererAttributes, + centerX, centerY, + items, + radius, + maxValue = 0, + fields = [], + max = Math.max, + cos = Math.cos, + sin = Math.sin, + pi2 = Math.PI * 2, + l = store.getCount(), + startPath, path, x, y, rho, + i, nfields, + seriesStyle = me.seriesStyle, + seriesLabelStyle = me.seriesLabelStyle, + 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(); + centerX = me.centerX = chartBBox.x + (chartBBox.width / 2); + centerY = me.centerY = chartBBox.y + (chartBBox.height / 2); + me.radius = radius = Math.min(chartBBox.width, chartBBox.height) /2; + me.items = items = []; + + if (aggregate) { + + chart.series.each(function(series) { + fields.push(series.yField); + }); + + store.each(function(record, i) { + for (i = 0, nfields = fields.length; i < nfields; i++) { + maxValue = max(+record.get(fields[i]), maxValue); + } + }); + } + + maxValue = maxValue || 1; + + startPath = []; path = []; + store.each(function(record, i) { + rho = radius * record.get(field) / maxValue; + x = rho * cos(i / l * pi2); + y = rho * sin(i / l * pi2); + if (i == 0) { + path.push('M', x + centerX, y + centerY); + startPath.push('M', 0.01 * x + centerX, 0.01 * y + centerY); + } else { + path.push('L', x + centerX, y + centerY); + startPath.push('L', 0.01 * x + centerX, 0.01 * y + centerY); + } + items.push({ + sprite: false, + point: [centerX + x, centerY + y], + series: me + }); + }); + path.push('Z'); + + if (!me.radar) { + me.radar = surface.add(Ext.apply({ + type: 'path', + group: group, + path: startPath + }, seriesStyle || {})); + } + + if (chart.resizing) { + me.radar.setAttributes({ + path: startPath + }, true); + } + + if (chart.animate) { + me.onAnimate(me.radar, { + to: Ext.apply({ + path: path + }, seriesStyle || {}) + }); + } else { + me.radar.setAttributes(Ext.apply({ + path: path + }, seriesStyle || {}), true); + } + + if (me.showMarkers) { + me.drawMarkers(); + } + me.renderLabels(); + me.renderCallouts(); + }, - hide : function(){ - this.setHidden(true); + + drawMarkers: function() { + var me = this, + chart = me.chart, + surface = chart.surface, + markerStyle = Ext.apply({}, me.markerStyle || {}), + endMarkerStyle = Ext.apply(markerStyle, me.markerConfig), + 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); + if (!marker) { + marker = Ext.chart.Shape[type](surface, Ext.apply({ + group: markerGroup, + x: 0, + y: 0, + translate: { + x: centerX, + y: centerY + } + }, endMarkerStyle)); + } + else { + marker.show(); + } + if (chart.resizing) { + marker.setAttributes({ + x: 0, + y: 0, + translate: { + x: centerX, + y: centerY + } + }, true); + } + marker._to = { + translate: { + x: item.point[0], + y: item.point[1] + } + }; + + if (chart.animate) { + me.onAnimate(marker, { + to: marker._to + }); + } + else { + marker.setAttributes(Ext.apply(marker._to, endMarkerStyle || {}), true); + } + } }, - - isHidden : function(){ - return this.initialConfig.hidden; + isItemInPoint: function(x, y, item) { + var point, + tolerance = 10, + abs = Math.abs; + point = item.point; + return (abs(point[0] - x) <= tolerance && + abs(point[1] - y) <= tolerance); }, - setHandler : function(fn, scope){ - this.initialConfig.handler = fn; - this.initialConfig.scope = scope; - this.callEach('setHandler', [fn, scope]); + onCreateLabel: function(storeItem, item, i, display) { + var me = this, + group = me.labelsGroup, + config = me.label, + centerX = me.centerX, + centerY = me.centerY, + point = item.point, + endLabelStyle = Ext.apply(me.seriesLabelStyle || {}, config); + + return me.chart.surface.add(Ext.apply({ + 'type': 'text', + 'text-anchor': 'middle', + 'group': group, + 'x': centerX, + 'y': centerY + }, config || {})); }, - each : function(fn, scope){ - Ext.each(this.items, fn, scope); + onPlaceLabel: function(label, storeItem, item, i, display, animate) { + var me = this, + chart = me.chart, + resizing = chart.resizing, + config = me.label, + format = config.renderer, + field = config.field, + centerX = me.centerX, + centerY = me.centerY, + opt = { + x: item.point[0], + y: item.point[1] + }, + x = opt.x - centerX, + y = opt.y - centerY; + + label.setAttributes({ + text: format(storeItem.get(field)), + hidden: true + }, + true); + + if (resizing) { + label.setAttributes({ + x: centerX, + y: centerY + }, true); + } + + if (animate) { + label.show(true); + me.onAnimate(label, { + to: opt + }); + } else { + label.setAttributes(opt, true); + label.show(true); + } }, - 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); + toggleAll: function(show) { + var me = this, + i, ln, shadow, shadows; + if (!show) { + Ext.chart.series.Radar.superclass.hideAll.call(me); + } + else { + Ext.chart.series.Radar.superclass.showAll.call(me); + } + if (me.radar) { + me.radar.setAttributes({ + hidden: !show + }, true); + + if (me.radar.shadows) { + for (i = 0, shadows = me.radar.shadows, ln = shadows.length; i < ln; i++) { + shadow = shadows[i]; + shadow.setAttributes({ + hidden: !show + }, true); + } + } } }, - - addComponent : function(comp){ - this.items.push(comp); - comp.on('destroy', this.removeComponent, this); + + hideAll: function() { + this.toggleAll(false); + this.hideMarkers(0); }, - - removeComponent : function(comp){ - this.items.remove(comp); + + showAll: function() { + this.toggleAll(true); }, - - execute : function(){ - this.initialConfig.handler.apply(this.initialConfig.scope || window, arguments); + + hideMarkers: function(index) { + var me = this, + count = me.markerGroup && me.markerGroup.getCount() || 0, + i = index || 0; + for (; i < count; i++) { + me.markerGroup.getAt(i).hide(true); + } } }); -(function(){ -Ext.Layer = function(config, existingEl){ - config = config || {}; - var dh = Ext.DomHelper, - cp = config.parentEl, pel = cp ? Ext.getDom(cp) : document.body; - - if (existingEl) { - this.dom = Ext.getDom(existingEl); - } - if(!this.dom){ - var o = config.dh || {tag: 'div', cls: 'x-layer'}; - this.dom = dh.append(pel, o); - } - if(config.cls){ - this.addClass(config.cls); - } - this.constrain = config.constrain !== false; - this.setVisibilityMode(Ext.Element.VISIBILITY); - if(config.id){ - this.id = this.dom.id = config.id; - }else{ - this.id = Ext.id(this.dom); - } - this.zindex = config.zindex || this.getZIndex(); - this.position('absolute', this.zindex); - if(config.shadow){ - this.shadowOffset = config.shadowOffset || 4; - this.shadow = new Ext.Shadow({ - offset : this.shadowOffset, - mode : config.shadow - }); - }else{ - this.shadowOffset = 0; - } - this.useShim = config.shim !== false && Ext.useShims; - this.useDisplay = config.useDisplay; - this.hide(); -}; -var supr = Ext.Element.prototype; +Ext.define('Ext.chart.series.Scatter', { -var shims = []; + -Ext.extend(Ext.Layer, Ext.Element, { + extend: 'Ext.chart.series.Cartesian', - getZIndex : function(){ - return this.zindex || parseInt((this.getShim() || this).getStyle('z-index'), 10) || 11000; - }, + requires: ['Ext.chart.axis.Axis', 'Ext.chart.Shape', 'Ext.fx.Anim'], - getShim : function(){ - if(!this.useShim){ - return null; + + + type: 'scatter', + alias: 'series.scatter', + + + + + + constructor: function(config) { + this.callParent(arguments); + var me = this, + shadow = me.chart.shadow, + surface = me.chart.surface, i, l; + Ext.apply(me, config, { + style: {}, + markerConfig: {}, + shadowAttributes: [{ + "stroke-width": 6, + "stroke-opacity": 0.05, + stroke: 'rgb(0, 0, 0)' + }, { + "stroke-width": 4, + "stroke-opacity": 0.1, + stroke: 'rgb(0, 0, 0)' + }, { + "stroke-width": 2, + "stroke-opacity": 0.15, + stroke: 'rgb(0, 0, 0)' + }] + }); + me.group = surface.getGroup(me.seriesId); + if (shadow) { + for (i = 0, l = me.shadowAttributes.length; i < l; i++) { + me.shadowGroups.push(surface.getGroup(me.seriesId + '-shadows' + i)); + } } - if(this.shim){ - return this.shim; + }, + + + getBounds: function() { + var me = this, + chart = me.chart, + store = chart.substore || chart.store, + 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++) { + axis = chart.axes.get(axes[i]); + if (axis) { + ends = axis.calcEnds(); + if (axis.position == 'top' || axis.position == 'bottom') { + minX = ends.from; + maxX = ends.to; + } + else { + minY = ends.from; + maxY = ends.to; + } + } } - var shim = shims.shift(); - if(!shim){ - shim = this.createShim(); - shim.enableDisplayMode('block'); - shim.dom.style.display = 'none'; - shim.dom.style.visibility = 'visible'; + + if (me.xField && !Ext.isNumber(minX)) { + axis = Ext.create('Ext.chart.axis.Axis', { + chart: chart, + fields: [].concat(me.xField) + }).calcEnds(); + minX = axis.from; + maxX = axis.to; } - var pn = this.dom.parentNode; - if(shim.dom.parentNode != pn){ - pn.insertBefore(shim.dom, this.dom); + if (me.yField && !Ext.isNumber(minY)) { + axis = Ext.create('Ext.chart.axis.Axis', { + chart: chart, + fields: [].concat(me.yField) + }).calcEnds(); + minY = axis.from; + maxY = axis.to; } - shim.setStyle('z-index', this.getZIndex()-2); - this.shim = shim; - return shim; - }, - hideShim : function(){ - if(this.shim){ - this.shim.setDisplayed(false); - shims.push(this.shim); - delete this.shim; + if (isNaN(minX)) { + minX = 0; + maxX = store.getCount() - 1; + xScale = bbox.width / (store.getCount() - 1); } - }, - - disableShadow : function(){ - if(this.shadow){ - this.shadowDisabled = true; - this.shadow.hide(); - this.lastShadowOffset = this.shadowOffset; - this.shadowOffset = 0; + else { + xScale = bbox.width / (maxX - minX); } - }, - enableShadow : function(show){ - if(this.shadow){ - this.shadowDisabled = false; - this.shadowOffset = this.lastShadowOffset; - delete this.lastShadowOffset; - if(show){ - this.sync(true); - } + if (isNaN(minY)) { + minY = 0; + maxY = store.getCount() - 1; + yScale = bbox.height / (store.getCount() - 1); + } + else { + yScale = bbox.height / (maxY - minY); } + + return { + bbox: bbox, + minX: minX, + minY: minY, + xScale: xScale, + yScale: yScale + }; }, - - - sync : function(doShow){ - var shadow = this.shadow; - if(!this.updating && this.isVisible() && (shadow || this.useShim)){ - var shim = this.getShim(), - w = this.getWidth(), - h = this.getHeight(), - l = this.getLeft(true), - t = this.getTop(true); - - if(shadow && !this.shadowDisabled){ - if(doShow && !shadow.isVisible()){ - shadow.show(this); - }else{ - shadow.realign(l, t, w, h); + getPaths: function() { + var me = this, + chart = me.chart, + enableShadows = chart.shadow, + store = chart.substore || chart.store, + group = me.group, + bounds = me.bounds = me.getBounds(), + bbox = me.bbox, + xScale = bounds.xScale, + yScale = bounds.yScale, + minX = bounds.minX, + minY = bounds.minY, + boxX = bbox.x, + boxY = bbox.y, + boxHeight = bbox.height, + items = me.items = [], + attrs = [], + x, y, xValue, yValue, sprite; + + store.each(function(record, i) { + xValue = record.get(me.xField); + 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); } - if(shim){ - if(doShow){ - shim.show(); + return; + } + + if (typeof xValue == 'string' || typeof xValue == 'object') { + xValue = i; + } + if (typeof yValue == 'string' || typeof yValue == 'object') { + yValue = i; + } + x = boxX + (xValue - minX) * xScale; + y = boxY + boxHeight - (yValue - minY) * yScale; + attrs.push({ + x: x, + y: y + }); + + me.items.push({ + series: me, + value: [xValue, yValue], + point: [x, y], + storeItem: record + }); + + + if (chart.animate && chart.resizing) { + sprite = group.getAt(i); + if (sprite) { + me.resetPoint(sprite); + if (enableShadows) { + me.resetShadow(sprite); } - - var shadowAdj = shadow.el.getXY(), shimStyle = shim.dom.style, - shadowSize = shadow.el.getSize(); - shimStyle.left = (shadowAdj[0])+'px'; - shimStyle.top = (shadowAdj[1])+'px'; - shimStyle.width = (shadowSize.width)+'px'; - shimStyle.height = (shadowSize.height)+'px'; - } - }else if(shim){ - if(doShow){ - shim.show(); } - shim.setSize(w, h); - shim.setLeftTop(l, t); } - } + }); + return attrs; }, - destroy : function(){ - this.hideShim(); - if(this.shadow){ - this.shadow.hide(); - } - this.removeAllListeners(); - Ext.removeNode(this.dom); - delete this.dom; - }, - - remove : function(){ - this.destroy(); + resetPoint: function(sprite) { + var bbox = this.bbox; + sprite.setAttributes({ + translate: { + x: (bbox.x + bbox.width) / 2, + y: (bbox.y + bbox.height) / 2 + } + }, true); }, - beginUpdate : function(){ - this.updating = true; + resetShadow: function(sprite) { + var me = this, + shadows = sprite.shadows, + shadowAttributes = me.shadowAttributes, + ln = me.shadowGroups.length, + bbox = me.bbox, + i, attr; + for (i = 0; i < ln; i++) { + attr = Ext.apply({}, shadowAttributes[i]); + if (attr.translate) { + attr.translate.x += (bbox.x + bbox.width) / 2; + attr.translate.y += (bbox.y + bbox.height) / 2; + } + else { + attr.translate = { + x: (bbox.x + bbox.width) / 2, + y: (bbox.y + bbox.height) / 2 + }; + } + shadows[i].setAttributes(attr, true); + } }, - endUpdate : function(){ - this.updating = false; - this.sync(true); + createPoint: function(attr, type) { + var me = this, + chart = me.chart, + group = me.group, + bbox = me.bbox; + + return Ext.chart.Shape[type](chart.surface, Ext.apply({}, { + x: 0, + y: 0, + group: group, + translate: { + x: (bbox.x + bbox.width) / 2, + y: (bbox.y + bbox.height) / 2 + } + }, attr)); }, - hideUnders : function(negOffset){ - if(this.shadow){ - this.shadow.hide(); + createShadow: function(sprite, endMarkerStyle, type) { + var me = this, + chart = me.chart, + shadowGroups = me.shadowGroups, + shadowAttributes = me.shadowAttributes, + lnsh = shadowGroups.length, + bbox = me.bbox, + i, shadow, shadows, attr; + + sprite.shadows = shadows = []; + + for (i = 0; i < lnsh; i++) { + attr = Ext.apply({}, shadowAttributes[i]); + if (attr.translate) { + attr.translate.x += (bbox.x + bbox.width) / 2; + attr.translate.y += (bbox.y + bbox.height) / 2; + } + else { + Ext.apply(attr, { + translate: { + x: (bbox.x + bbox.width) / 2, + y: (bbox.y + bbox.height) / 2 + } + }); + } + Ext.apply(attr, endMarkerStyle); + shadow = Ext.chart.Shape[type](chart.surface, Ext.apply({}, { + x: 0, + y: 0, + group: shadowGroups[i] + }, attr)); + shadows.push(shadow); } - this.hideShim(); }, - constrainXY : function(){ - if(this.constrain){ - var vw = Ext.lib.Dom.getViewWidth(), - vh = Ext.lib.Dom.getViewHeight(); - var s = Ext.getDoc().getScroll(); + drawSeries: function() { + var me = this, + chart = me.chart, + store = chart.substore || chart.store, + group = me.group, + enableShadows = chart.shadow, + shadowGroups = me.shadowGroups, + shadowAttributes = me.shadowAttributes, + lnsh = shadowGroups.length, + sprite, attrs, attr, ln, i, endMarkerStyle, shindex, type, shadows, + rendererAttributes, shadowAttribute; + + endMarkerStyle = Ext.apply(me.markerStyle, me.markerConfig); + type = endMarkerStyle.type; + delete endMarkerStyle.type; + + + if (!store || !store.getCount()) { + return; + } + + me.unHighlightItem(); + me.cleanHighlights(); + + attrs = me.getPaths(); + ln = attrs.length; + for (i = 0; i < ln; i++) { + attr = attrs[i]; + sprite = group.getAt(i); + Ext.apply(attr, endMarkerStyle); - var xy = this.getXY(); - var x = xy[0], y = xy[1]; - var so = this.shadowOffset; - var w = this.dom.offsetWidth+so, h = this.dom.offsetHeight+so; - - var moved = false; - - if((x + w) > vw+s.left){ - x = vw - w - so; - moved = true; - } - if((y + h) > vh+s.top){ - y = vh - h - so; - moved = true; - } - if(x < s.left){ - x = s.left; - moved = true; + if (!sprite) { + sprite = me.createPoint(attr, type); + if (enableShadows) { + me.createShadow(sprite, endMarkerStyle, type); + } } - if(y < s.top){ - y = s.top; - moved = true; + + shadows = sprite.shadows; + if (chart.animate) { + rendererAttributes = me.renderer(sprite, store.getAt(i), { translate: attr }, i, store); + sprite._to = rendererAttributes; + me.onAnimate(sprite, { + to: rendererAttributes + }); + + for (shindex = 0; shindex < lnsh; shindex++) { + shadowAttribute = Ext.apply({}, shadowAttributes[shindex]); + rendererAttributes = me.renderer(shadows[shindex], store.getAt(i), Ext.apply({}, { + 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 }); + } } - if(moved){ - if(this.avoidY){ - var ay = this.avoidY; - if(y <= ay && (y+h) >= ay){ - y = ay-h-5; - } + else { + rendererAttributes = me.renderer(sprite, store.getAt(i), Ext.apply({ translate: attr }, { hidden: false }), i, store); + 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), i, store); + shadows[shindex].setAttributes(rendererAttributes, true); } - xy = [x, y]; - this.storeXY(xy); - supr.setXY.call(this, xy); - this.sync(); } + me.items[i].sprite = sprite; } - return this; - }, - - getConstrainOffset : function(){ - return this.shadowOffset; - }, - - isVisible : function(){ - return this.visible; - }, - - showAction : function(){ - this.visible = true; - if(this.useDisplay === true){ - this.setDisplayed(''); - }else if(this.lastXY){ - supr.setXY.call(this, this.lastXY); - }else if(this.lastLT){ - supr.setLeftTop.call(this, this.lastLT[0], this.lastLT[1]); + + ln = group.getCount(); + for (i = attrs.length; i < ln; i++) { + group.getAt(i).hide(true); } + me.renderLabels(); + me.renderCallouts(); }, - - hideAction : function(){ - this.visible = false; - if(this.useDisplay === true){ - this.setDisplayed(false); - }else{ - this.setLeftTop(-10000,-10000); - } + + onCreateLabel: function(storeItem, item, i, display) { + var me = this, + group = me.labelsGroup, + config = me.label, + endLabelStyle = Ext.apply({}, config, me.seriesLabelStyle), + bbox = me.bbox; + + return me.chart.surface.add(Ext.apply({ + type: 'text', + group: group, + x: item.point[0], + y: bbox.y + bbox.height / 2 + }, endLabelStyle)); }, - - setVisible : function(v, a, d, c, e){ - if(v){ - this.showAction(); + + onPlaceLabel: function(label, storeItem, item, i, display, animate) { + 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], + 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', + 'rotation': { + x: x, + y: y, + degrees: -45 + } + }, true); + + bb = label.getBBox(); + width = bb.width; + height = bb.height; + 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(); + bb.width = bb.width || (radius * 2); + bb.height = bb.height || (radius * 2); + y = y + (display == 'over'? -bb.height : bb.height); + + 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; + y = (y + height > bbox.y + bbox.height) ? (y - (y + height - bbox.y - bbox.height)) : y; + } + + if (!chart.animate) { + label.setAttributes({ + x: x, + y: y + }, true); + label.show(true); } - if(a && v){ - var cb = function(){ - this.sync(true); - if(c){ - c(); + else { + if (resizing) { + anim = item.sprite.getActiveAnimation(); + if (anim) { + anim.on('afteranimate', function() { + label.setAttributes({ + x: x, + y: y + }, true); + label.show(true); + }); + } + else { + label.show(true); } - }.createDelegate(this); - supr.setVisible.call(this, true, true, d, cb, e); - }else{ - if(!v){ - this.hideUnders(true); } - var cb = c; - if(a){ - cb = function(){ - this.hideAction(); - if(c){ - c(); + else { + me.onAnimate(label, { + to: { + x: x, + y: y } - }.createDelegate(this); - } - supr.setVisible.call(this, v, a, d, cb, e); - if(v){ - this.sync(true); - }else if(!a){ - this.hideAction(); + }); } } - return this; - }, - - storeXY : function(xy){ - delete this.lastLT; - this.lastXY = xy; }, - - storeLeftTop : function(left, top){ - delete this.lastXY; - this.lastLT = [left, top]; - }, - - beforeFx : function(){ - this.beforeAction(); - return Ext.Layer.superclass.beforeFx.apply(this, arguments); - }, - - afterFx : function(){ - Ext.Layer.superclass.afterFx.apply(this, arguments); - this.sync(this.isVisible()); - }, - + 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, + cur = item.point, + normal, + bbox = callout.label.getBBox(), + offsetFromViz = 30, + offsetToSide = 10, + offsetBox = 3, + boxx, boxy, boxw, boxh, + p, clipRect = me.bbox, + x, y; - beforeAction : function(){ - if(!this.updating && this.shadow){ - this.shadow.hide(); + + 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])) { + normal[0] *= -1; + } + if (boxy < clipRect[1] || (boxy + boxh) > (clipRect[1] + clipRect[3])) { + normal[1] *= -1; } - }, - - setLeft : function(left){ - this.storeLeftTop(left, this.getTop(true)); - supr.setLeft.apply(this, arguments); - this.sync(); - return this; + + 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, { + to: { + path: ["M", cur[0], cur[1], "L", x, y, "Z"] + } + }, true); + + me.onAnimate(callout.box, { + to: { + x: boxx, + y: boxy, + width: boxw, + height: boxh + } + }, true); + + me.onAnimate(callout.label, { + to: { + x: x + (normal[0] > 0? offsetBox : -(bbox.width + offsetBox)), + y: y + } + }, true); + } else { + + 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); + } }, - setTop : function(top){ - this.storeLeftTop(this.getLeft(true), top); - supr.setTop.apply(this, arguments); - this.sync(); - return this; + + onAnimate: function(sprite, attr) { + sprite.show(); + return this.callParent(arguments); }, - setLeftTop : function(left, top){ - this.storeLeftTop(left, top); - supr.setLeftTop.apply(this, arguments); - this.sync(); - return this; - }, + isItemInPoint: function(x, y, item) { + var point, + tolerance = 10, + abs = Math.abs; - setXY : function(xy, a, d, c, e){ - this.fixDisplay(); - this.beforeAction(); - this.storeXY(xy); - var cb = this.createCB(c); - supr.setXY.call(this, xy, a, d, cb, e); - if(!a){ - cb(); + function dist(point) { + var dx = abs(point[0] - x), + dy = abs(point[1] - y); + return Math.sqrt(dx * dx + dy * dy); } - return this; - }, + point = item.point; + return (point[0] - tolerance <= x && point[0] + tolerance >= x && + point[1] - tolerance <= y && point[1] + tolerance >= y); + } +}); - - createCB : function(c){ - var el = this; - return function(){ - el.constrainXY(); - el.sync(true); - if(c){ - c(); - } - }; - }, - - setX : function(x, a, d, c, e){ - this.setXY([x, this.getY()], a, d, c, e); - return this; - }, - - setY : function(y, a, d, c, e){ - this.setXY([this.getX(), y], a, d, c, e); - return this; - }, +Ext.define('Ext.chart.theme.Base', { - setSize : function(w, h, a, d, c, e){ - this.beforeAction(); - var cb = this.createCB(c); - supr.setSize.call(this, w, h, a, d, cb, e); - if(!a){ - cb(); - } - return this; - }, - - setWidth : function(w, a, d, c, e){ - this.beforeAction(); - var cb = this.createCB(c); - supr.setWidth.call(this, w, a, d, cb, e); - if(!a){ - cb(); - } - return this; - }, + requires: ['Ext.chart.theme.Theme'], - setHeight : function(h, a, d, c, e){ - this.beforeAction(); - var cb = this.createCB(c); - supr.setHeight.call(this, h, a, d, cb, e); - if(!a){ - cb(); - } - return this; - }, + constructor: function(config) { + Ext.chart.theme.call(this, config, { + background: false, + axis: { + stroke: '#444', + 'stroke-width': 1 + }, + axisLabelTop: { + fill: '#444', + font: '12px Arial, Helvetica, sans-serif', + spacing: 2, + padding: 5, + renderer: function(v) { return v; } + }, + axisLabelRight: { + fill: '#444', + font: '12px Arial, Helvetica, sans-serif', + spacing: 2, + padding: 5, + renderer: function(v) { return v; } + }, + axisLabelBottom: { + fill: '#444', + font: '12px Arial, Helvetica, sans-serif', + spacing: 2, + padding: 5, + renderer: function(v) { return v; } + }, + axisLabelLeft: { + fill: '#444', + font: '12px Arial, Helvetica, sans-serif', + spacing: 2, + padding: 5, + renderer: function(v) { return v; } + }, + axisTitleTop: { + font: 'bold 18px Arial', + fill: '#444' + }, + axisTitleRight: { + font: 'bold 18px Arial', + fill: '#444', + rotate: { + x:0, y:0, + degrees: 270 + } + }, + axisTitleBottom: { + font: 'bold 18px Arial', + fill: '#444' + }, + axisTitleLeft: { + font: 'bold 18px Arial', + fill: '#444', + rotate: { + x:0, y:0, + degrees: 270 + } + }, + series: { + 'stroke-width': 0 + }, + seriesLabel: { + font: '12px Arial', + fill: '#333' + }, + marker: { + stroke: '#555', + fill: '#000', + radius: 3, + size: 3 + }, + colors: [ "#94ae0a", "#115fa6","#a61120", "#ff8809", "#ffd13e", "#a61187", "#24ad9a", "#7c7474", "#a66111"], + seriesThemes: [{ + fill: "#115fa6" + }, { + fill: "#94ae0a" + }, { + fill: "#a61120" + }, { + fill: "#ff8809" + }, { + fill: "#ffd13e" + }, { + fill: "#a61187" + }, { + fill: "#24ad9a" + }, { + fill: "#7c7474" + }, { + fill: "#a66111" + }], + markerThemes: [{ + fill: "#115fa6", + type: 'circle' + }, { + fill: "#94ae0a", + type: 'cross' + }, { + fill: "#a61120", + type: 'plus' + }] + }); + } +}, function() { + var palette = ['#b1da5a', '#4ce0e7', '#e84b67', '#da5abd', '#4d7fe6', '#fec935'], + names = ['Green', 'Sky', 'Red', 'Purple', 'Blue', 'Yellow'], + i = 0, j = 0, l = palette.length, themes = Ext.chart.theme, + categories = [['#f0a50a', '#c20024', '#2044ba', '#810065', '#7eae29'], + ['#6d9824', '#87146e', '#2a9196', '#d39006', '#1e40ac'], + ['#fbbc29', '#ce2e4e', '#7e0062', '#158b90', '#57880e'], + ['#ef5773', '#fcbd2a', '#4f770d', '#1d3eaa', '#9b001f'], + ['#7eae29', '#fdbe2a', '#910019', '#27b4bc', '#d74dbc'], + ['#44dce1', '#0b2592', '#996e05', '#7fb325', '#b821a1']], + cats = categories.length; + + + for (; i < l; i++) { + themes[names[i]] = (function(color) { + return Ext.extend(themes.Base, { + constructor: function(config) { + themes.Base.prototype.constructor.call(this, Ext.apply({ + baseColor: color + }, config)); + } + }); + })(palette[i]); + } - setBounds : function(x, y, w, h, a, d, c, e){ - this.beforeAction(); - var cb = this.createCB(c); - if(!a){ - this.storeXY([x, y]); - supr.setXY.call(this, [x, y]); - supr.setSize.call(this, w, h, a, d, cb, e); - cb(); - }else{ - supr.setBounds.call(this, x, y, w, h, a, d, cb, e); - } - return this; - }, - - setZIndex : function(zindex){ - this.zindex = zindex; - this.setStyle('z-index', zindex + 2); - if(this.shadow){ - this.shadow.setZIndex(zindex + 1); - } - if(this.shim){ - this.shim.setStyle('z-index', zindex); - } - return this; + for (i = 0; i < cats; i++) { + themes['Category' + (i + 1)] = (function(category) { + return Ext.extend(themes.Base, { + constructor: function(config) { + themes.Base.prototype.constructor.call(this, Ext.apply({ + colors: category + }, config)); + } + }); + })(categories[i]); } }); -})(); - -Ext.Shadow = function(config) { - Ext.apply(this, config); - if (typeof this.mode != "string") { - this.mode = this.defaultMode; - } - var o = this.offset, - a = { - h: 0 - }, - rad = Math.floor(this.offset / 2); - switch (this.mode.toLowerCase()) { - - case "drop": - a.w = 0; - a.l = a.t = o; - a.t -= 1; - if (Ext.isIE) { - a.l -= this.offset + rad; - a.t -= this.offset + rad; - a.w -= rad; - a.h -= rad; - a.t += 1; - } - break; - case "sides": - a.w = (o * 2); - a.l = -o; - a.t = o - 1; - if (Ext.isIE) { - a.l -= (this.offset - rad); - a.t -= this.offset + rad; - a.l += 1; - a.w -= (this.offset - rad) * 2; - a.w -= rad + 1; - a.h -= 1; - } - break; - case "frame": - a.w = a.h = (o * 2); - a.l = a.t = -o; - a.t += 1; - a.h -= 2; - if (Ext.isIE) { - a.l -= (this.offset - rad); - a.t -= (this.offset - rad); - a.l += 1; - a.w -= (this.offset + rad + 1); - a.h -= (this.offset + rad); - a.h += 1; - } - break; - }; - this.adjusts = a; -}; -Ext.Shadow.prototype = { - - - offset: 4, +Ext.define('Ext.data.ArrayStore', { + extend: 'Ext.data.Store', + alias: 'store.array', + uses: ['Ext.data.reader.Array'], - defaultMode: "drop", + constructor: function(config) { + config = config || {}; - - show: function(target) { - target = Ext.get(target); - if (!this.el) { - this.el = Ext.Shadow.Pool.pull(); - if (this.el.dom.nextSibling != target.dom) { - this.el.insertBefore(target); + Ext.applyIf(config, { + proxy: { + type: 'memory', + reader: 'array' } - } - this.el.setStyle("z-index", this.zIndex || parseInt(target.getStyle("z-index"), 10) - 1); - if (Ext.isIE) { - this.el.dom.style.filter = "progid:DXImageTransform.Microsoft.alpha(opacity=50) progid:DXImageTransform.Microsoft.Blur(pixelradius=" + (this.offset) + ")"; - } - this.realign( - target.getLeft(true), - target.getTop(true), - target.getWidth(), - target.getHeight() - ); - this.el.dom.style.display = "block"; - }, + }); - - isVisible: function() { - return this.el ? true: false; + this.callParent([config]); }, - - realign: function(l, t, w, h) { - if (!this.el) { - return; - } - var a = this.adjusts, - d = this.el.dom, - s = d.style, - iea = 0, - sw = (w + a.w), - sh = (h + a.h), - sws = sw + "px", - shs = sh + "px", - cn, - sww; - s.left = (l + a.l) + "px"; - s.top = (t + a.t) + "px"; - if (s.width != sws || s.height != shs) { - s.width = sws; - s.height = shs; - if (!Ext.isIE) { - cn = d.childNodes; - sww = Math.max(0, (sw - 12)) + "px"; - cn[0].childNodes[1].style.width = sww; - cn[1].childNodes[1].style.width = sww; - cn[2].childNodes[1].style.width = sww; - cn[1].style.height = Math.max(0, (sh - 12)) + "px"; + loadData: function(data, append) { + if (this.expandData === true) { + var r = [], + i = 0, + ln = data.length; + + for (; i < ln; i++) { + r[r.length] = [data[i]]; } - } - }, - - hide: function() { - if (this.el) { - this.el.dom.style.display = "none"; - Ext.Shadow.Pool.push(this.el); - delete this.el; + data = r; } - }, - - setZIndex: function(z) { - this.zIndex = z; - if (this.el) { - this.el.setStyle("z-index", z); - } + this.callParent([data, append]); } -}; - - -Ext.Shadow.Pool = function() { - var p = [], - markup = Ext.isIE ? - '
': - '
'; - return { - pull: function() { - var sh = p.shift(); - if (!sh) { - sh = Ext.get(Ext.DomHelper.insertHtml("beforeBegin", document.body.firstChild, markup)); - sh.autoBoxAdjust = false; - } - return sh; - }, +}, function() { + + Ext.data.SimpleStore = Ext.data.ArrayStore; + +}); - push: function(sh) { - p.push(sh); - } - }; -}(); -Ext.BoxComponent = Ext.extend(Ext.Component, { +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) { + 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); + } else { + me.fireEvent('operationcomplete', me, operation); + } + + if (hasException && me.pauseOnException) { + me.pause(); + } else { + operation.setCompleted(); + me.runNextOperation(); + } + }; + + operation.setStarted(); + + me.proxy[operation.action](operation, onProxyReturn, me); + } + } +}); + +Ext.define('Ext.data.BelongsToAssociation', { + extend: 'Ext.data.Association', + + alias: 'association.belongsto', + + + - + constructor: function(config) { + this.callParent(arguments); + + var me = this, + ownerProto = me.ownerModel.prototype, + associatedName = me.associatedName, + getterName = me.getterName || 'get' + associatedName, + setterName = me.setterName || 'set' + associatedName; + + Ext.applyIf(me, { + name : associatedName, + foreignKey : associatedName.toLowerCase() + "_id", + instanceName: associatedName + 'BelongsToInstance', + associationKey: associatedName.toLowerCase() + }); - - initComponent : function(){ - Ext.BoxComponent.superclass.initComponent.call(this); - this.addEvents( - - 'resize', - - 'move' - ); + ownerProto[getterName] = me.createGetter(); + ownerProto[setterName] = me.createSetter(); }, - boxReady : false, - - deferHeight: false, - - - setSize : function(w, h){ + createSetter: function() { + var me = this, + ownerModel = me.ownerModel, + associatedModel = me.associatedModel, + foreignKey = me.foreignKey, + primaryKey = me.primaryKey; - if(typeof w == 'object'){ - h = w.height; - w = w.width; - } - if (Ext.isDefined(w) && Ext.isDefined(this.boxMinWidth) && (w < this.boxMinWidth)) { - w = this.boxMinWidth; - } - if (Ext.isDefined(h) && Ext.isDefined(this.boxMinHeight) && (h < this.boxMinHeight)) { - h = this.boxMinHeight; - } - if (Ext.isDefined(w) && Ext.isDefined(this.boxMaxWidth) && (w > this.boxMaxWidth)) { - w = this.boxMaxWidth; - } - if (Ext.isDefined(h) && Ext.isDefined(this.boxMaxHeight) && (h > this.boxMaxHeight)) { - h = this.boxMaxHeight; - } - - if(!this.boxReady){ - this.width = w; - this.height = h; - return this; - } + return function(value, options, scope) { + this.set(foreignKey, value); - - if(this.cacheSizes !== false && this.lastSize && this.lastSize.width == w && this.lastSize.height == h){ - return this; - } - this.lastSize = {width: w, height: h}; - var adj = this.adjustSize(w, h), - aw = adj.width, - ah = adj.height, - rz; - if(aw !== undefined || ah !== undefined){ - rz = this.getResizeEl(); - if(!this.deferHeight && aw !== undefined && ah !== undefined){ - rz.setSize(aw, ah); - }else if(!this.deferHeight && ah !== undefined){ - rz.setHeight(ah); - }else if(aw !== undefined){ - rz.setWidth(aw); - } - this.onResize(aw, ah, w, h); - this.fireEvent('resize', this, aw, ah, w, h); - } - return this; - }, + if (typeof options == 'function') { + options = { + callback: options, + scope: scope || this + }; + } - - setWidth : function(width){ - return this.setSize(width); + if (Ext.isObject(options)) { + return this.save(options); + } + }; }, - setHeight : function(height){ - return this.setSize(undefined, height); - }, + createGetter: function() { + var me = this, + ownerModel = me.ownerModel, + associatedName = me.associatedName, + associatedModel = me.associatedModel, + foreignKey = me.foreignKey, + primaryKey = me.primaryKey, + instanceName = me.instanceName; - - getSize : function(){ - return this.getResizeEl().getSize(); + + return function(options, scope) { + options = options || {}; + + var foreignKeyId = this.get(foreignKey), + instance, callbackFn; + + if (this[instanceName] === undefined) { + instance = Ext.ModelManager.create({}, associatedName); + instance.set(primaryKey, foreignKeyId); + + if (typeof options == 'function') { + options = { + callback: options, + scope: scope || this + }; + } + + associatedModel.load(foreignKeyId, options); + } else { + instance = this[instanceName]; + + + + + 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); + } + + return instance; + } + }; }, - getWidth : function(){ - return this.getResizeEl().getWidth(); - }, + read: function(record, reader, associationData){ + record[this.instanceName] = reader.read([associationData]).records[0]; + } +}); + +Ext.define('Ext.data.BufferStore', { + extend: 'Ext.data.Store', + alias: 'store.buffer', + sortOnLoad: false, + filterOnLoad: false, - getHeight : function(){ - return this.getResizeEl().getHeight(); - }, + constructor: function() { + Ext.Error.raise('The BufferStore class has been deprecated. Instead, specify the buffered config option on Ext.data.Store'); + } +}); + +Ext.define('Ext.direct.Manager', { - getOuterSize : function(){ - var el = this.getResizeEl(); - return {width: el.getWidth() + el.getMargins('lr'), - height: el.getHeight() + el.getMargins('tb')}; + + singleton: true, + + mixins: { + observable: 'Ext.util.Observable' }, - - getPosition : function(local){ - var el = this.getPositionEl(); - if(local === true){ - return [el.getLeft(true), el.getTop(true)]; + requires: ['Ext.util.MixedCollection'], + + statics: { + exceptions: { + TRANSPORT: 'xhr', + PARSE: 'parse', + LOGIN: 'login', + SERVER: 'exception' } - return this.xy || el.getXY(); }, - - getBox : function(local){ - var pos = this.getPosition(local); - var s = this.getSize(); - s.x = pos[0]; - s.y = pos[1]; - return s; - }, - - updateBox : function(box){ - this.setSize(box.width, box.height); - this.setPagePosition(box.x, box.y); - return this; + + constructor: function(){ + var me = this; + + me.addEvents( + + 'event', + + 'exception' + ); + me.transactions = Ext.create('Ext.util.MixedCollection'); + me.providers = Ext.create('Ext.util.MixedCollection'); + + me.mixins.observable.constructor.call(me); }, - - getResizeEl : function(){ - return this.resizeEl || this.el; - }, - - setAutoScroll : function(scroll){ - if(this.rendered){ - this.getContentTarget().setOverflow(scroll ? 'auto' : ''); + 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]); + } + return; } - this.autoScroll = scroll; - return this; - }, - - setPosition : function(x, y){ - if(x && typeof x[1] == 'number'){ - y = x[1]; - x = x[0]; - } - this.x = x; - this.y = y; - if(!this.boxReady){ - return this; + + if (!provider.isProvider) { + provider = Ext.create('direct.' + provider.type + 'provider', provider); } - var adj = this.adjustPosition(x, y); - var ax = adj.x, ay = adj.y; + me.providers.add(provider); + provider.on('data', me.onProviderData, me); - var el = this.getPositionEl(); - if(ax !== undefined || ay !== undefined){ - if(ax !== undefined && ay !== undefined){ - el.setLeftTop(ax, ay); - }else if(ax !== undefined){ - el.setLeft(ax); - }else if(ay !== undefined){ - el.setTop(ay); - } - this.onPosition(ax, ay); - this.fireEvent('move', this, ax, ay); + + if (!provider.isConnected()) { + provider.connect(); } - return this; - }, + return provider; + }, - setPagePosition : function(x, y){ - if(x && typeof x[1] == 'number'){ - y = x[1]; - x = x[0]; - } - this.pageX = x; - this.pageY = y; - if(!this.boxReady){ - return; - } - if(x === undefined || y === undefined){ - return; - } - var p = this.getPositionEl().translatePoints(x, y); - this.setPosition(p.left, p.top); - return this; + + getProvider : function(id){ + return id.isProvider ? id : this.providers.get(id); }, - - afterRender : function(){ - Ext.BoxComponent.superclass.afterRender.call(this); - if(this.resizeEl){ - this.resizeEl = Ext.get(this.resizeEl); - } - if(this.positionEl){ - this.positionEl = Ext.get(this.positionEl); - } - this.boxReady = true; - Ext.isDefined(this.autoScroll) && this.setAutoScroll(this.autoScroll); - this.setSize(this.width, this.height); - if(this.x || this.y){ - this.setPosition(this.x, this.y); - }else if(this.pageX || this.pageY){ - this.setPagePosition(this.pageX, this.pageY); + + removeProvider : function(provider){ + var me = this, + providers = me.providers, + provider = provider.isProvider ? provider : providers.get(provider); + + if (provider) { + provider.un('data', me.onProviderData, me); + providers.remove(provider); + return provider; } + return null; }, - - syncSize : function(){ - delete this.lastSize; - this.setSize(this.autoWidth ? undefined : this.getResizeEl().getWidth(), this.autoHeight ? undefined : this.getResizeEl().getHeight()); - return this; + + addTransaction: function(transaction){ + this.transactions.add(transaction); + return transaction; }, - onResize : function(adjWidth, adjHeight, rawWidth, rawHeight){ + removeTransaction: function(transaction){ + transaction = this.getTransaction(transaction); + this.transactions.remove(transaction); + return transaction; }, - onPosition : function(x, y){ - + getTransaction: function(transaction){ + return transaction.isTransaction ? transaction : this.transactions.get(transaction); }, - - adjustSize : function(w, h){ - if(this.autoWidth){ - w = 'auto'; + 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]); + } + return; } - if(this.autoHeight){ - h = 'auto'; + if (event.name && event.name != 'event' && event.name != 'exception') { + me.fireEvent(event.name, event); + } else if (event.type == 'exception') { + me.fireEvent('exception', event); } - return {width : w, height: h}; - }, - - - adjustPosition : function(x, y){ - return {x : x, y: y}; + me.fireEvent('event', event, provider); } +}, function(){ + + Ext.Direct = Ext.direct.Manager; }); -Ext.reg('box', Ext.BoxComponent); - -Ext.Spacer = Ext.extend(Ext.BoxComponent, { - autoEl:'div' -}); -Ext.reg('spacer', Ext.Spacer); -Ext.SplitBar = function(dragElement, resizingElement, orientation, placement, existingProxy){ - +Ext.define('Ext.data.proxy.Direct', { - this.el = Ext.get(dragElement, true); - this.el.dom.unselectable = "on"; - this.resizingEl = Ext.get(resizingElement, true); - + extend: 'Ext.data.proxy.Server', + alternateClassName: 'Ext.data.DirectProxy', - this.orientation = orientation || Ext.SplitBar.HORIZONTAL; - + alias: 'proxy.direct', + requires: ['Ext.direct.Manager'], - this.minSize = 0; - - this.maxSize = 2000; + + + paramOrder: undefined, - this.animate = false; + paramsAsHash: true, - this.useShim = false; - + directFn : undefined, - this.shim = null; - - if(!existingProxy){ - - this.proxy = Ext.SplitBar.createProxy(this.orientation); - }else{ - this.proxy = Ext.get(existingProxy).dom; - } - this.dd = new Ext.dd.DDProxy(this.el.dom.id, "XSplitBars", {dragElId : this.proxy.id}); - - this.dd.b4StartDrag = this.onStartProxyDrag.createDelegate(this); - - this.dd.endDrag = this.onEndProxyDrag.createDelegate(this); - - this.dragSpecs = {}; - - this.adapter = new Ext.SplitBar.BasicLayoutAdapter(); - this.adapter.init(this); - - if(this.orientation == Ext.SplitBar.HORIZONTAL){ - - this.placement = placement || (this.el.getX() > this.resizingEl.getX() ? Ext.SplitBar.LEFT : Ext.SplitBar.RIGHT); - this.el.addClass("x-splitbar-h"); - }else{ - - this.placement = placement || (this.el.getY() > this.resizingEl.getY() ? Ext.SplitBar.TOP : Ext.SplitBar.BOTTOM); - this.el.addClass("x-splitbar-v"); - } - - this.addEvents( - - "resize", - - "moved", + paramOrderRe: /[\s,|]/, + + constructor: function(config){ + var me = this; - "beforeresize", - - "beforeapply" - ); - - Ext.SplitBar.superclass.constructor.call(this); -}; - -Ext.extend(Ext.SplitBar, Ext.util.Observable, { - onStartProxyDrag : function(x, y){ - this.fireEvent("beforeresize", this); - this.overlay = Ext.DomHelper.append(document.body, {cls: "x-drag-overlay", html: " "}, true); - this.overlay.unselectable(); - this.overlay.setSize(Ext.lib.Dom.getViewWidth(true), Ext.lib.Dom.getViewHeight(true)); - this.overlay.show(); - Ext.get(this.proxy).setDisplayed("block"); - var size = this.adapter.getElementSize(this); - this.activeMinSize = this.getMinimumSize(); - this.activeMaxSize = this.getMaximumSize(); - var c1 = size - this.activeMinSize; - var c2 = Math.max(this.activeMaxSize - size, 0); - if(this.orientation == Ext.SplitBar.HORIZONTAL){ - this.dd.resetConstraints(); - this.dd.setXConstraint( - this.placement == Ext.SplitBar.LEFT ? c1 : c2, - this.placement == Ext.SplitBar.LEFT ? c2 : c1, - this.tickSize - ); - this.dd.setYConstraint(0, 0); - }else{ - this.dd.resetConstraints(); - this.dd.setXConstraint(0, 0); - this.dd.setYConstraint( - this.placement == Ext.SplitBar.TOP ? c1 : c2, - this.placement == Ext.SplitBar.TOP ? c2 : c1, - this.tickSize - ); - } - this.dragSpecs.startSize = size; - this.dragSpecs.startPoint = [x, y]; - Ext.dd.DDProxy.prototype.b4StartDrag.call(this.dd, x, y); + Ext.apply(me, config); + if (Ext.isString(me.paramOrder)) { + me.paramOrder = me.paramOrder.split(me.paramOrderRe); + } + me.callParent(arguments); }, - - onEndProxyDrag : function(e){ - Ext.get(this.proxy).setDisplayed(false); - var endPoint = Ext.lib.Event.getXY(e); - if(this.overlay){ - Ext.destroy(this.overlay); - delete this.overlay; + doRequest: function(operation, callback, scope) { + var me = this, + writer = me.getWriter(), + request = me.buildRequest(operation, callback, scope), + fn = me.api[request.action] || me.directFn, + args = [], + params = request.params, + paramOrder = me.paramOrder, + method, + i = 0, + len; + + if (!fn) { + Ext.Error.raise('No direct function specified for this proxy'); } - var newSize; - if(this.orientation == Ext.SplitBar.HORIZONTAL){ - newSize = this.dragSpecs.startSize + - (this.placement == Ext.SplitBar.LEFT ? - endPoint[0] - this.dragSpecs.startPoint[0] : - this.dragSpecs.startPoint[0] - endPoint[0] - ); - }else{ - newSize = this.dragSpecs.startSize + - (this.placement == Ext.SplitBar.TOP ? - endPoint[1] - this.dragSpecs.startPoint[1] : - this.dragSpecs.startPoint[1] - endPoint[1] - ); + + if (operation.allowWrite()) { + request = writer.write(request); } - newSize = Math.min(Math.max(newSize, this.activeMinSize), this.activeMaxSize); - if(newSize != this.dragSpecs.startSize){ - if(this.fireEvent('beforeapply', this, newSize) !== false){ - this.adapter.setElementSize(this, newSize); - this.fireEvent("moved", this, newSize); - this.fireEvent("resize", this, newSize); + + if (operation.action == 'read') { + + method = fn.directCfg.method; + + if (method.ordered) { + if (method.len > 0) { + if (paramOrder) { + for (len = paramOrder.length; i < len; ++i) { + args.push(params[paramOrder[i]]); + } + } else if (me.paramsAsHash) { + args.push(params); + } + } + } else { + args.push(params); } + } else { + args.push(request.jsonData); } + + Ext.apply(request, { + args: args, + directFn: fn + }); + args.push(me.createRequestCallback(request, operation, callback, scope), me); + fn.apply(window, args); }, - - getAdapter : function(){ - return this.adapter; - }, - - setAdapter : function(adapter){ - this.adapter = adapter; - this.adapter.init(this); + applyEncoding: function(value){ + return value; }, - - getMinimumSize : function(){ - return this.minSize; + createRequestCallback: function(request, operation, callback, scope){ + var me = this; + + return function(data, event){ + me.processResponse(event.status, operation, request, event, callback, scope); + }; }, - - setMinimumSize : function(minSize){ - this.minSize = minSize; - }, - - getMaximumSize : function(){ - return this.maxSize; + extractResponseData: function(response){ + return Ext.isDefined(response.result) ? response.result : response.data; }, - - setMaximumSize : function(maxSize){ - this.maxSize = maxSize; - }, - - setCurrentSize : function(size){ - var oldAnimate = this.animate; - this.animate = false; - this.adapter.setElementSize(this, size); - this.animate = oldAnimate; + setException: function(operation, response) { + operation.setException(response.message); }, - - destroy : function(removeEl){ - Ext.destroy(this.shim, Ext.get(this.proxy)); - this.dd.unreg(); - if(removeEl){ - this.el.remove(); - } - this.purgeListeners(); + + buildUrl: function(){ + return ''; } }); -Ext.SplitBar.createProxy = function(dir){ - var proxy = new Ext.Element(document.createElement("div")); - document.body.appendChild(proxy.dom); - proxy.unselectable(); - var cls = 'x-splitbar-proxy'; - proxy.addClass(cls + ' ' + (dir == Ext.SplitBar.HORIZONTAL ? cls +'-h' : cls + '-v')); - return proxy.dom; -}; - - -Ext.SplitBar.BasicLayoutAdapter = function(){ -}; -Ext.SplitBar.BasicLayoutAdapter.prototype = { +Ext.define('Ext.data.DirectStore', { - init : function(s){ - - }, - getElementSize : function(s){ - if(s.orientation == Ext.SplitBar.HORIZONTAL){ - return s.resizingEl.getWidth(); - }else{ - return s.resizingEl.getHeight(); - } - }, - + extend: 'Ext.data.Store', - setElementSize : function(s, newSize, onComplete){ - if(s.orientation == Ext.SplitBar.HORIZONTAL){ - if(!s.animate){ - s.resizingEl.setWidth(newSize); - if(onComplete){ - onComplete(s, newSize); - } - }else{ - s.resizingEl.setWidth(newSize, true, .1, onComplete, 'easeOut'); - } - }else{ - - if(!s.animate){ - s.resizingEl.setHeight(newSize); - if(onComplete){ - onComplete(s, newSize); + alias: 'store.direct', + + requires: ['Ext.data.proxy.Direct'], + + + + constructor : function(config){ + config = Ext.apply({}, config); + if (!config.proxy) { + var proxy = { + type: 'direct', + reader: { + type: 'json' } - }else{ - s.resizingEl.setHeight(newSize, true, .1, onComplete, 'easeOut'); - } - } - } -}; - - -Ext.SplitBar.AbsoluteLayoutAdapter = function(container){ - this.basic = new Ext.SplitBar.BasicLayoutAdapter(); - this.container = Ext.get(container); -}; - -Ext.SplitBar.AbsoluteLayoutAdapter.prototype = { - init : function(s){ - this.basic.init(s); - }, - - getElementSize : function(s){ - return this.basic.getElementSize(s); - }, - - setElementSize : function(s, newSize, onComplete){ - this.basic.setElementSize(s, newSize, this.moveSplitter.createDelegate(this, [s])); - }, - - moveSplitter : function(s){ - var yes = Ext.SplitBar; - switch(s.placement){ - case yes.LEFT: - s.el.setX(s.resizingEl.getRight()); - break; - case yes.RIGHT: - s.el.setStyle("right", (this.container.getWidth() - s.resizingEl.getLeft()) + "px"); - break; - case yes.TOP: - s.el.setY(s.resizingEl.getBottom()); - break; - case yes.BOTTOM: - s.el.setY(s.resizingEl.getTop() - s.el.getHeight()); - break; + }; + Ext.copyTo(proxy, config, 'paramOrder,paramsAsHash,directFn,api,simpleSortMode'); + Ext.copyTo(proxy.reader, config, 'totalProperty,root,idProperty'); + config.proxy = proxy; } - } -}; - - -Ext.SplitBar.VERTICAL = 1; - - -Ext.SplitBar.HORIZONTAL = 2; - - -Ext.SplitBar.LEFT = 1; - + this.callParent([config]); + } +}); -Ext.SplitBar.RIGHT = 2; -Ext.SplitBar.TOP = 3; +Ext.define('Ext.util.Inflector', { + -Ext.SplitBar.BOTTOM = 4; + singleton: true, -Ext.Container = Ext.extend(Ext.BoxComponent, { + + plurals: [ + [(/(quiz)$/i), "$1zes" ], + [(/^(ox)$/i), "$1en" ], + [(/([m|l])ouse$/i), "$1ice" ], + [(/(matr|vert|ind)ix|ex$/i), "$1ices" ], + [(/(x|ch|ss|sh)$/i), "$1es" ], + [(/([^aeiouy]|qu)y$/i), "$1ies" ], + [(/(hive)$/i), "$1s" ], + [(/(?:([^f])fe|([lr])f)$/i), "$1$2ves"], + [(/sis$/i), "ses" ], + [(/([ti])um$/i), "$1a" ], + [(/(buffal|tomat|potat)o$/i), "$1oes" ], + [(/(bu)s$/i), "$1ses" ], + [(/(alias|status|sex)$/i), "$1es" ], + [(/(octop|vir)us$/i), "$1i" ], + [(/(ax|test)is$/i), "$1es" ], + [(/^person$/), "people" ], + [(/^man$/), "men" ], + [(/^(child)$/), "$1ren" ], + [(/s$/i), "s" ], + [(/$/), "s" ] + ], - bufferResize: 50, - + singulars: [ + [(/(quiz)zes$/i), "$1" ], + [(/(matr)ices$/i), "$1ix" ], + [(/(vert|ind)ices$/i), "$1ex" ], + [(/^(ox)en/i), "$1" ], + [(/(alias|status)es$/i), "$1" ], + [(/(octop|vir)i$/i), "$1us" ], + [(/(cris|ax|test)es$/i), "$1is" ], + [(/(shoe)s$/i), "$1" ], + [(/(o)es$/i), "$1" ], + [(/(bus)es$/i), "$1" ], + [(/([m|l])ice$/i), "$1ouse" ], + [(/(x|ch|ss|sh)es$/i), "$1" ], + [(/(m)ovies$/i), "$1ovie" ], + [(/(s)eries$/i), "$1eries"], + [(/([^aeiouy]|qu)ies$/i), "$1y" ], + [(/([lr])ves$/i), "$1f" ], + [(/(tive)s$/i), "$1" ], + [(/(hive)s$/i), "$1" ], + [(/([^f])ves$/i), "$1fe" ], + [(/(^analy)ses$/i), "$1sis" ], + [(/((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)ses$/i), "$1$2sis"], + [(/([ti])a$/i), "$1um" ], + [(/(n)ews$/i), "$1ews" ], + [(/people$/i), "person" ], + [(/s$/i), "" ] + ], + uncountable: [ + "sheep", + "fish", + "series", + "species", + "money", + "rice", + "information", + "equipment", + "grass", + "mud", + "offspring", + "deer", + "means" + ], - - - autoDestroy : true, - + singular: function(matcher, replacer) { + this.singulars.unshift([matcher, replacer]); + }, - forceLayout: false, - + plural: function(matcher, replacer) { + this.plurals.unshift([matcher, replacer]); + }, - defaultType : 'panel', - - resizeEvent: 'resize', - + clearSingulars: function() { + this.singulars = []; + }, - bubbleEvents: ['add', 'remove'], - - initComponent : function(){ - Ext.Container.superclass.initComponent.call(this); - - this.addEvents( - - 'afterlayout', - - 'beforeadd', - - 'beforeremove', - - 'add', - - 'remove' - ); - - - var items = this.items; - if(items){ - delete this.items; - this.add(items); - } + clearPlurals: function() { + this.plurals = []; }, - - initItems : function(){ - if(!this.items){ - this.items = new Ext.util.MixedCollection(false, this.getComponentId); - this.getLayout(); - } + + isTransnumeral: function(word) { + return Ext.Array.indexOf(this.uncountable, word) != -1; }, - setLayout : function(layout){ - if(this.layout && this.layout != layout){ - this.layout.setContainer(null); + pluralize: function(word) { + if (this.isTransnumeral(word)) { + return word; } - this.layout = layout; - this.initItems(); - layout.setContainer(this); - }, - afterRender: function(){ - + var plurals = this.plurals, + length = plurals.length, + tuple, regex, i; - Ext.Container.superclass.afterRender.call(this); - if(!this.layout){ - this.layout = 'auto'; - } - if(Ext.isObject(this.layout) && !this.layout.layout){ - this.layoutConfig = this.layout; - this.layout = this.layoutConfig.type; - } - if(Ext.isString(this.layout)){ - this.layout = new Ext.Container.LAYOUTS[this.layout.toLowerCase()](this.layoutConfig); + 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]); + } } - this.setLayout(this.layout); - - if(this.activeItem !== undefined && this.layout.setActiveItem){ - var item = this.activeItem; - delete this.activeItem; - this.layout.setActiveItem(item); + return word; + }, + + + singularize: function(word) { + if (this.isTransnumeral(word)) { + return word; } + var singulars = this.singulars, + length = singulars.length, + tuple, regex, i; - if(!this.ownerCt){ - this.doLayout(false, true); + 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]); + } } - - - if(this.monitorResize === true){ - Ext.EventManager.onWindowResize(this.doLayout, this, [false]); - } + return word; }, - - getLayoutTarget : function(){ - return this.el; - }, - - getComponentId : function(comp){ - return comp.getItemId(); + classify: function(word) { + return Ext.String.capitalize(this.singularize(word)); }, - - add : function(comp){ - this.initItems(); - var args = arguments.length > 1; - if(args || Ext.isArray(comp)){ - var result = []; - Ext.each(args ? arguments : comp, function(c){ - result.push(this.add(c)); - }, this); - return result; - } - var c = this.lookupComponent(this.applyDefaults(comp)); - var index = this.items.length; - if(this.fireEvent('beforeadd', this, c, index) !== false && this.onBeforeAdd(c) !== false){ - this.items.add(c); - - c.onAdded(this, index); - this.onAdd(c); - this.fireEvent('add', this, c, index); - } - return c; - }, - - onAdd : function(c){ - - }, - - onAdded : function(container, pos) { + ordinalize: function(number) { + var parsed = parseInt(number, 10), + mod10 = parsed % 10, + mod100 = parsed % 100; - this.ownerCt = container; - this.initRef(); - this.cascade(function(c){ - c.initRef(); - }); - this.fireEvent('added', this, container, pos); - }, + if (11 <= mod100 && mod100 <= 13) { + return number + "th"; + } else { + switch(mod10) { + case 1 : return number + "st"; + case 2 : return number + "nd"; + case 3 : return number + "rd"; + default: return number + "th"; + } + } + } +}, function() { + + var irregulars = { + alumnus: 'alumni', + cactus : 'cacti', + focus : 'foci', + nucleus: 'nuclei', + radius: 'radii', + stimulus: 'stimuli', + ellipsis: 'ellipses', + paralysis: 'paralyses', + oasis: 'oases', + appendix: 'appendices', + index: 'indexes', + beau: 'beaux', + bureau: 'bureaux', + tableau: 'tableaux', + woman: 'women', + child: 'children', + man: 'men', + corpus: 'corpora', + criterion: 'criteria', + curriculum: 'curricula', + genus: 'genera', + memorandum: 'memoranda', + phenomenon: 'phenomena', + foot: 'feet', + goose: 'geese', + tooth: 'teeth', + antenna: 'antennae', + formula: 'formulae', + nebula: 'nebulae', + vertebra: 'vertebrae', + vita: 'vitae' + }, + singular; + + for (singular in irregulars) { + this.plural(singular, irregulars[singular]); + this.singular(irregulars[singular], singular); + } +}); + +Ext.define('Ext.data.HasManyAssociation', { + extend: 'Ext.data.Association', + requires: ['Ext.util.Inflector'], + + alias: 'association.hasmany', - insert : function(index, comp) { - var args = arguments, - length = args.length, - result = [], - i, c; - - this.initItems(); + + + + + + + + + + + + constructor: function(config) { + var me = this, + ownerProto, + name; + + me.callParent(arguments); - if (length > 2) { - for (i = length - 1; i >= 1; --i) { - result.push(this.insert(index, args[i])); - } - return result; - } + me.name = me.name || Ext.util.Inflector.pluralize(me.associatedName.toLowerCase()); - c = this.lookupComponent(this.applyDefaults(comp)); - index = Math.min(index, this.items.length); + ownerProto = me.ownerModel.prototype; + name = me.name; - if (this.fireEvent('beforeadd', this, c, index) !== false && this.onBeforeAdd(c) !== false) { - if (c.ownerCt == this) { - this.items.remove(c); - } - this.items.insert(index, c); - c.onAdded(this, index); - this.onAdd(c); - this.fireEvent('add', this, c, index); - } + Ext.applyIf(me, { + storeName : name + "Store", + foreignKey: me.ownerName.toLowerCase() + "_id" + }); - return c; + ownerProto[name] = me.createStore(); }, - - applyDefaults : function(c){ - var d = this.defaults; - if(d){ - if(Ext.isFunction(d)){ - d = d.call(this, c); - } - if(Ext.isString(c)){ - c = Ext.ComponentMgr.get(c); - Ext.apply(c, d); - }else if(!c.events){ - Ext.applyIf(c.isAction ? c.initialConfig : c, d); - }else{ - Ext.apply(c, d); + + createStore: function() { + var that = this, + associatedModel = that.associatedModel, + storeName = that.storeName, + foreignKey = that.foreignKey, + primaryKey = that.primaryKey, + filterProperty = that.filterProperty, + autoLoad = that.autoLoad, + storeConfig = that.storeConfig || {}; + + return function() { + var me = this, + config, filter, + modelDefaults = {}; + + if (me[storeName] === undefined) { + if (filterProperty) { + filter = { + property : filterProperty, + value : me.get(filterProperty), + exactMatch: true + }; + } else { + filter = { + property : foreignKey, + value : me.get(primaryKey), + exactMatch: true + }; + } + + modelDefaults[foreignKey] = me.get(primaryKey); + + config = Ext.apply({}, storeConfig, { + model : associatedModel, + filters : [filter], + remoteFilter : false, + modelDefaults: modelDefaults + }); + + me[storeName] = Ext.create('Ext.data.Store', config); + if (autoLoad) { + me[storeName].load(); + } } - } - return c; + + return me[storeName]; + }; }, - - onBeforeAdd : function(item){ - if(item.ownerCt){ - item.ownerCt.remove(item, false); - } - if(this.hideBorders === true){ - item.border = (item.border === true); - } - }, - - remove : function(comp, autoDestroy){ - this.initItems(); - var c = this.getComponent(comp); - if(c && this.fireEvent('beforeremove', this, c) !== false){ - this.doRemove(c, autoDestroy); - this.fireEvent('remove', this, c); - } - return c; - }, - - onRemove: function(c){ - - }, - + read: function(record, reader, associationData){ + var store = record[this.name](), + inverse; - doRemove: function(c, autoDestroy){ - var l = this.layout, - hasLayout = l && this.rendered; - - if(hasLayout){ - l.onRemove(c); - } - this.items.remove(c); - c.onRemoved(); - this.onRemove(c); - if(autoDestroy === true || (autoDestroy !== false && this.autoDestroy)){ - c.destroy(); - } - if(hasLayout){ - l.afterRemove(c); - } - }, - + store.add(reader.read(associationData).records); - removeAll: function(autoDestroy){ - this.initItems(); - var item, rem = [], items = []; - this.items.each(function(i){ - rem.push(i); + + + inverse = this.associatedModel.prototype.associations.findBy(function(assoc){ + return assoc.type === 'belongsTo' && assoc.associatedName === record.$className; }); - for (var i = 0, len = rem.length; i < len; ++i){ - item = rem[i]; - this.remove(item, autoDestroy); - if(item.ownerCt !== this){ - items.push(item); - } - } - return items; - }, - - getComponent : function(comp){ - if(Ext.isObject(comp)){ - comp = comp.getItemId(); + + if (inverse) { + store.data.each(function(associatedRecord){ + associatedRecord[inverse.instanceName] = record; + }); } - return this.items.get(comp); - }, + } +}); +Ext.define('Ext.data.JsonP', { - lookupComponent : function(comp){ - if(Ext.isString(comp)){ - return Ext.ComponentMgr.get(comp); - }else if(!comp.events){ - return this.createComponent(comp); - } - return comp; + + + singleton: true, + + statics: { + requestCount: 0, + requests: {} }, - - createComponent : function(config, defaultType){ - if (config.render) { - return config; + + + + 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), + url = options.url, + request, + script; + + params[callbackKey] = 'Ext.data.JsonP.' + callbackName; + if (disableCaching) { + params[cacheParam] = new Date().getTime(); } + script = me.createScript(url, params); + + me.statics().requests[id] = request = { + url: url, + params: params, + script: script, + id: id, + scope: options.scope, + success: options.success, + failure: options.failure, + callback: options.callback, + callbackName: callbackName + }; + + if (timeout > 0) { + request.timeout = setTimeout(Ext.bind(me.handleTimeout, me, [request]), timeout); + } - var c = Ext.create(Ext.apply({ - ownerCt: this - }, config), defaultType || this.defaultType); - delete c.initialConfig.ownerCt; - delete c.ownerCt; - return c; + me.setupErrorHandling(request); + me[callbackName] = Ext.bind(me.handleResponse, me, [request], true); + Ext.getHead().appendChild(script); + return request; }, - - canLayout : function() { - var el = this.getVisibilityEl(); - return el && el.dom && !el.isStyle("display", "none"); - }, - - - doLayout : function(shallow, force){ - var rendered = this.rendered, - forceLayout = force || this.forceLayout; - - if(this.collapsed || !this.canLayout()){ - this.deferLayout = this.deferLayout || !shallow; - if(!forceLayout){ - return; + abort: function(request){ + var requests = this.statics().requests, + key; + + if (request) { + if (!request.id) { + request = requests[request]; } - shallow = shallow && !this.deferLayout; + this.abort(request); } else { - delete this.deferLayout; - } - if(rendered && this.layout){ - this.layout.layout(); - } - if(shallow !== true && this.items){ - var cs = this.items.items; - for(var i = 0, len = cs.length; i < len; i++){ - var c = cs[i]; - if(c.doLayout){ - c.doLayout(false, forceLayout); + for (key in requests) { + if (requests.hasOwnProperty(key)) { + this.abort(requests[key]); } } } - if(rendered){ - this.onLayout(shallow, forceLayout); - } - - this.hasLayout = true; - delete this.forceLayout; }, - - onLayout : Ext.emptyFn, - - shouldBufferLayout: function(){ - - var hl = this.hasLayout; - if(this.ownerCt){ - - return hl ? !this.hasLayoutPending() : false; - } - - return hl; + + setupErrorHandling: function(request){ + request.script.onerror = Ext.bind(this.handleError, this, [request]); }, - - hasLayoutPending: function(){ - - var pending = false; - this.ownerCt.bubble(function(c){ - if(c.layoutPending){ - pending = true; - return false; - } - }); - return pending; + + handleAbort: function(request){ + request.errorType = 'abort'; + this.handleResponse(null, request); }, - - onShow : function(){ - - Ext.Container.superclass.onShow.call(this); - - if(Ext.isDefined(this.deferLayout)){ - delete this.deferLayout; - this.doLayout(true); - } + + + handleError: function(request){ + request.errorType = 'error'; + this.handleResponse(null, request); }, - + - getLayout : function(){ - if(!this.layout){ - var layout = new Ext.layout.AutoLayout(this.layoutConfig); - this.setLayout(layout); - } - return this.layout; + cleanupErrorHandling: function(request){ + request.script.onerror = null; }, - + - beforeDestroy : function(){ - var c; - if(this.items){ - while(c = this.items.first()){ - this.doRemove(c, true); - } - } - if(this.monitorResize){ - Ext.EventManager.removeResizeListener(this.doLayout, this); - } - Ext.destroy(this.layout); - Ext.Container.superclass.beforeDestroy.call(this); + handleTimeout: function(request){ + request.errorType = 'timeout'; + this.handleResponse(null, request); }, - + - cascade : function(fn, scope, args){ - if(fn.apply(scope || this, args || [this]) !== false){ - if(this.items){ - var cs = this.items.items; - for(var i = 0, len = cs.length; i < len; i++){ - if(cs[i].cascade){ - cs[i].cascade(fn, scope, args); - }else{ - fn.apply(scope || cs[i], args || [cs[i]]); - } - } - } + handleResponse: function(result, request){ + + var success = true; + + if (request.timeout) { + clearTimeout(request.timeout); } - return this; + delete this[request.callbackName]; + 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]); + } else { + Ext.callback(request.success, request.scope, [result]); + } + Ext.callback(request.callback, request.scope, [success, result, request.errorType]); }, - - findById : function(id){ - var m = null, - ct = this; - this.cascade(function(c){ - if(ct != c && c.id === id){ - m = c; - return false; - } - }); - return m; - }, - - findByType : function(xtype, shallow){ - return this.findBy(function(c){ - return c.isXType(xtype, shallow); - }); - }, + createScript: function(url, params) { + var script = document.createElement('script'); + script.setAttribute("src", Ext.urlAppend(url, Ext.Object.toQueryString(params))); + script.setAttribute("async", true); + script.setAttribute("type", "text/javascript"); + return script; + } +}); - - find : function(prop, value){ - return this.findBy(function(c){ - return c[prop] === value; - }); - }, - - findBy : function(fn, scope){ - var m = [], ct = this; - this.cascade(function(c){ - if(ct != c && fn.call(scope || c, c, ct) === true){ - m.push(c); - } - }); - return m; - }, +Ext.define('Ext.data.JsonPStore', { + extend: 'Ext.data.Store', + alias : 'store.jsonp', - get : function(key){ - return this.getComponent(key); + constructor: function(config) { + this.callParent(Ext.apply(config, { + reader: Ext.create('Ext.data.reader.Json', config), + proxy : Ext.create('Ext.data.proxy.JsonP', config) + })); } }); -Ext.Container.LAYOUTS = {}; -Ext.reg('container', Ext.Container); -Ext.layout.ContainerLayout = Ext.extend(Object, { - +Ext.define('Ext.data.NodeInterface', { + requires: ['Ext.data.Field'], + statics: { + + decorate: function(record) { + if (!record.isNode) { + + + var mgr = Ext.ModelManager, + 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; - + + 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} + ]); + + jln = 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; + } + } + } + } + + Ext.applyIf(record, { + firstChild: null, + lastChild: null, + parentNode: null, + previousSibling: null, + nextSibling: null, + childNodes: [] + }); + + record.commit(true); + + record.enableBubble([ + + "append", - - monitorResize:false, - - activeItem : null, + + "remove", - constructor : function(config){ - this.id = Ext.id(null, 'ext-layout-'); - Ext.apply(this, config); - }, + + "move", - type: 'container', + + "insert", - - IEMeasureHack : function(target, viewFlag) { - var tChildren = target.dom.childNodes, tLen = tChildren.length, c, d = [], e, i, ret; - for (i = 0 ; i < tLen ; i++) { - c = tChildren[i]; - e = Ext.get(c); - if (e) { - d[i] = e.getStyle('display'); - e.setStyle({display: 'none'}); - } - } - ret = target ? target.getViewSize(viewFlag) : {}; - for (i = 0 ; i < tLen ; i++) { - c = tChildren[i]; - e = Ext.get(c); - if (e) { - e.setStyle({display: d[i]}); + + "beforeappend", + + + "beforeremove", + + + "beforemove", + + + "beforeinsert", + + + "expand", + + + "collapse", + + + "beforeexpand", + + + "beforecollapse", + + + "sort" + ]); + + return record; + }, + + applyFields: function(modelClass, addFields) { + var modelPrototype = modelClass.prototype, + fields = modelPrototype.fields, + keys = fields.keys, + 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 ret; - }, + + return newFields; + }, + + getPrototypeBody: function() { + return { + isNode: true, - - getLayoutTargetSize : Ext.EmptyFn, + + createNode: function(node) { + if (Ext.isObject(node) && !node.isModel) { + node = Ext.ModelManager.create(node, this.modelName); + } + + return Ext.data.NodeInterface.decorate(node); + }, + + + isLeaf : function() { + return this.get('leaf') === true; + }, - - layout : function(){ - var ct = this.container, target = ct.getLayoutTarget(); - if(!(this.hasLayout || Ext.isEmpty(this.targetCls))){ - target.addClass(this.targetCls); - } - this.onLayout(ct, target); - ct.fireEvent('afterlayout', ct, this); - }, + + setFirstChild : function(node) { + this.firstChild = node; + }, - - onLayout : function(ct, target){ - this.renderAll(ct, target); - }, + + setLastChild : function(node) { + this.lastChild = node; + }, - - isValidParent : function(c, target){ - return target && c.getPositionEl().dom.parentNode == (target.dom || target); - }, + + updateInfo: function(silent) { + var me = this, + isRoot = me.isRoot(), + parentNode = me.parentNode, + isFirst = (!parentNode ? true : parentNode.firstChild == me), + isLast = (!parentNode ? true : parentNode.lastChild == me), + depth = 0, + parent = me, + children = me.childNodes, + len = children.length, + i = 0; + + while (parent.parentNode) { + ++depth; + parent = parent.parentNode; + } + + me.beginEdit(); + me.set({ + isFirst: isFirst, + isLast: isLast, + depth: depth, + index: parentNode ? parentNode.indexOf(me) : 0, + parentId: parentNode ? parentNode.getId() : null + }); + me.endEdit(silent); + if (silent) { + me.commit(); + } + + for (i = 0; i < len; i++) { + children[i].updateInfo(silent); + } + }, - - renderAll : function(ct, target){ - var items = ct.items.items, i, c, len = items.length; - for(i = 0; i < len; i++) { - c = items[i]; - if(c && (!c.rendered || !this.isValidParent(c, target))){ - this.renderItem(c, i, target); - } - } - }, + + isLast : function() { + return this.get('isLast'); + }, - - renderItem : function(c, position, target){ - if (c) { - if (!c.rendered) { - c.render(target, position); - this.configureItem(c); - } else if (!this.isValidParent(c, target)) { - if (Ext.isNumber(position)) { - position = target.dom.childNodes[position]; - } - target.dom.insertBefore(c.getPositionEl().dom, position || null); - c.container = target; - this.configureItem(c); - } - } - }, + isFirst : function() { + return this.get('isFirst'); + }, - - - getRenderedItems: function(ct){ - var t = ct.getLayoutTarget(), cti = ct.items.items, len = cti.length, i, c, items = []; - for (i = 0; i < len; i++) { - if((c = cti[i]).rendered && this.isValidParent(c, t) && c.shouldLayout !== false){ - items.push(c); - } - }; - return items; - }, + + hasChildNodes : function() { + return !this.isLeaf() && this.childNodes.length > 0; + }, - - configureItem: function(c){ - if (this.extraCls) { - var t = c.getPositionEl ? c.getPositionEl() : c; - t.addClass(this.extraCls); - } - - - if (c.doLayout && this.forceLayout) { - c.doLayout(); - } - if (this.renderHidden && c != this.activeItem) { - c.hide(); - } - }, + + isExpandable : function() { + return this.get('expandable') || this.hasChildNodes(); + }, - onRemove: function(c){ - if(this.activeItem == c){ - delete this.activeItem; - } - if(c.rendered && this.extraCls){ - var t = c.getPositionEl ? c.getPositionEl() : c; - t.removeClass(this.extraCls); - } - }, + + appendChild : function(node, suppressEvents, suppressNodeUpdate) { + var me = this, + i, ln, + index, + oldParent, + ps; - afterRemove: function(c){ - if(c.removeRestore){ - c.removeMode = 'container'; - delete c.removeRestore; - } - }, + + if (Ext.isArray(node)) { + for (i = 0, ln = node.length; i < ln; i++) { + me.appendChild(node[i]); + } + } else { + + node = me.createNode(node); + + if (suppressEvents !== true && me.fireEvent("beforeappend", me, node) === false) { + return false; + } - - onResize: function(){ - var ct = this.container, - b; - if(ct.collapsed){ - return; - } - if(b = ct.bufferResize && ct.shouldBufferLayout()){ - if(!this.resizeTask){ - this.resizeTask = new Ext.util.DelayedTask(this.runLayout, this); - this.resizeBuffer = Ext.isNumber(b) ? b : 50; - } - ct.layoutPending = true; - this.resizeTask.delay(this.resizeBuffer); - }else{ - this.runLayout(); - } - }, + index = me.childNodes.length; + oldParent = node.parentNode; - runLayout: function(){ - var ct = this.container; - this.layout(); - ct.onLayout(); - delete ct.layoutPending; - }, + + if (oldParent) { + if (suppressEvents !== true && node.fireEvent("beforemove", node, oldParent, me, index) === false) { + return false; + } + oldParent.removeChild(node, null, false, true); + } - - setContainer : function(ct){ - - if(this.monitorResize && ct != this.container){ - var old = this.container; - if(old){ - old.un(old.resizeEvent, this.onResize, this); - } - if(ct){ - ct.on(ct.resizeEvent, this.onResize, this); - } - } - this.container = ct; - }, + index = me.childNodes.length; + if (index === 0) { + me.setFirstChild(node); + } - - parseMargins : function(v){ - if (Ext.isNumber(v)) { - v = v.toString(); - } - var ms = v.split(' '), - len = ms.length; - - if (len == 1) { - ms[1] = ms[2] = ms[3] = ms[0]; - } else if(len == 2) { - ms[2] = ms[0]; - ms[3] = ms[1]; - } else if(len == 3) { - ms[3] = ms[1]; - } - - return { - top :parseInt(ms[0], 10) || 0, - right :parseInt(ms[1], 10) || 0, - bottom:parseInt(ms[2], 10) || 0, - left :parseInt(ms[3], 10) || 0 - }; - }, + me.childNodes.push(node); + node.parentNode = me; + node.nextSibling = null; + + me.setLastChild(node); + + ps = me.childNodes[index - 1]; + if (ps) { + node.previousSibling = ps; + ps.nextSibling = node; + ps.updateInfo(suppressNodeUpdate); + } else { + node.previousSibling = null; + } - - fieldTpl: (function() { - var t = new Ext.Template( - '
', - '', - '
', - '
', - '
' - ); - t.disableFormats = true; - return t.compile(); - })(), + node.updateInfo(suppressNodeUpdate); + + + if (!me.isLoaded()) { + me.set('loaded', true); + } + + else if (me.childNodes.length === 1) { + me.set('loaded', me.isLoaded()); + } + + if (suppressEvents !== true) { + me.fireEvent("append", me, node, index); - - destroy : function(){ - - if(this.resizeTask && this.resizeTask.cancel){ - this.resizeTask.cancel(); - } - if(this.container) { - this.container.un(this.container.resizeEvent, this.onResize, this); - } - if(!Ext.isEmpty(this.targetCls)){ - var target = this.container.getLayoutTarget(); - if(target){ - target.removeClass(this.targetCls); - } - } - } -}); -Ext.layout.AutoLayout = Ext.extend(Ext.layout.ContainerLayout, { - type: 'auto', + if (oldParent) { + node.fireEvent("move", node, oldParent, me, index); + } + } - monitorResize: true, + return node; + } + }, + + + getBubbleTarget: function() { + return this.parentNode; + }, - onLayout : function(ct, target){ - Ext.layout.AutoLayout.superclass.onLayout.call(this, ct, target); - var cs = this.getRenderedItems(ct), len = cs.length, i, c; - for(i = 0; i < len; i++){ - c = cs[i]; - if (c.doLayout){ - c.doLayout(true); - } - } - } -}); + 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; + } -Ext.Container.LAYOUTS['auto'] = Ext.layout.AutoLayout; + + me.childNodes.splice(index, 1); -Ext.layout.FitLayout = Ext.extend(Ext.layout.ContainerLayout, { - - monitorResize:true, + + if (me.firstChild == node) { + me.setFirstChild(node.nextSibling); + } + if (me.lastChild == node) { + me.setLastChild(node.previousSibling); + } + + + if (node.previousSibling) { + node.previousSibling.nextSibling = node.nextSibling; + node.previousSibling.updateInfo(suppressNodeUpdate); + } + if (node.nextSibling) { + node.nextSibling.previousSibling = node.previousSibling; + node.nextSibling.updateInfo(suppressNodeUpdate); + } - type: 'fit', + if (suppressEvents !== true) { + me.fireEvent("remove", me, node); + } + + + + if (!me.childNodes.length) { + me.set('loaded', me.isLoaded()); + } + + if (destroy) { + node.destroy(true); + } else { + node.clear(); + } - getLayoutTargetSize : function() { - var target = this.container.getLayoutTarget(); - if (!target) { - return {}; - } - - return target.getStyleSize(); - }, + return node; + }, - - onLayout : function(ct, target){ - Ext.layout.FitLayout.superclass.onLayout.call(this, ct, target); - if(!ct.collapsed){ - this.setItemSize(this.activeItem || ct.items.itemAt(0), this.getLayoutTargetSize()); - } - }, + + copy: function(newId, deep) { + var me = this, + result = me.callOverridden(arguments), + len = me.childNodes ? me.childNodes.length : 0, + i; - - setItemSize : function(item, size){ - if(item && size.height > 0){ - item.setSize(size); - } - } -}); -Ext.Container.LAYOUTS['fit'] = Ext.layout.FitLayout; -Ext.layout.CardLayout = Ext.extend(Ext.layout.FitLayout, { - - deferredRender : false, + + if (deep) { + for (i = 0; i < len; i++) { + result.appendChild(me.childNodes[i].copy(true)); + } + } + return result; + }, - - layoutOnCardChange : false, + + clear : function(destroy) { + var me = this; + + + me.parentNode = me.previousSibling = me.nextSibling = null; + if (destroy) { + me.firstChild = me.lastChild = null; + } + }, - - - renderHidden : true, + + destroy : function(silent) { + + var me = this; + + if (silent === true) { + me.clear(true); + Ext.each(me.childNodes, function(n) { + n.destroy(true); + }); + me.childNodes = null; + } else { + me.remove(true); + } - type: 'card', + me.callOverridden(); + }, - - setActiveItem : function(item){ - var ai = this.activeItem, - ct = this.container; - item = ct.getComponent(item); + + insertBefore : function(node, refNode, suppressEvents) { + var me = this, + index = me.indexOf(refNode), + oldParent = node.parentNode, + refIndex = index, + ps; + + if (!refNode) { + return me.appendChild(node); + } + + + if (node == refNode) { + return false; + } - - if(item && ai != item){ + + node = me.createNode(node); + + if (suppressEvents !== true && me.fireEvent("beforeinsert", me, node, refNode) === false) { + return false; + } + + + if (oldParent == me && me.indexOf(node) < index) { + refIndex--; + } - - if(ai){ - ai.hide(); - if (ai.hidden !== true) { - return false; - } - ai.fireEvent('deactivate', ai); - } + + if (oldParent) { + if (suppressEvents !== true && node.fireEvent("beforemove", node, oldParent, me, index, refNode) === false) { + return false; + } + oldParent.removeChild(node); + } - var layout = item.doLayout && (this.layoutOnCardChange || !item.rendered); + if (refIndex === 0) { + me.setFirstChild(node); + } - - this.activeItem = item; + me.childNodes.splice(refIndex, 0, node); + node.parentNode = me; + + node.nextSibling = refNode; + refNode.previousSibling = node; + + ps = me.childNodes[refIndex - 1]; + if (ps) { + node.previousSibling = ps; + ps.nextSibling = node; + ps.updateInfo(); + } else { + node.previousSibling = null; + } + + node.updateInfo(); + + if (!me.isLoaded()) { + me.set('loaded', true); + } + + else if (me.childNodes.length === 1) { + me.set('loaded', me.isLoaded()); + } - - - delete item.deferLayout; + if (suppressEvents !== true) { + me.fireEvent("insert", me, node, refNode); - - item.show(); + if (oldParent) { + node.fireEvent("move", node, oldParent, me, refIndex, refNode); + } + } - this.layout(); + return node; + }, + + + insertChild: function(index, node) { + var sibling = this.childNodes[index]; + if (sibling) { + return this.insertBefore(node, sibling); + } + else { + return this.appendChild(node); + } + }, - if(layout){ - item.doLayout(); - } - item.fireEvent('activate', item); - } - }, + + remove : function(destroy, suppressEvents) { + var parentNode = this.parentNode; - - renderAll : function(ct, target){ - if(this.deferredRender){ - this.renderItem(this.activeItem, undefined, target); - }else{ - Ext.layout.CardLayout.superclass.renderAll.call(this, ct, target); - } - } -}); -Ext.Container.LAYOUTS['card'] = Ext.layout.CardLayout; + if (parentNode) { + parentNode.removeChild(this, destroy, suppressEvents, true); + } + return this; + }, -Ext.layout.AnchorLayout = Ext.extend(Ext.layout.ContainerLayout, { - + + removeAll : function(destroy, suppressEvents) { + var cn = this.childNodes, + n; - - monitorResize : true, + while ((n = cn[0])) { + this.removeChild(n, destroy, suppressEvents); + } + return this; + }, - type : 'anchor', + + getChildAt : function(index) { + return this.childNodes[index]; + }, - - defaultAnchor : '100%', + + replaceChild : function(newChild, oldChild, suppressEvents) { + var s = oldChild ? oldChild.nextSibling : null; + + this.removeChild(oldChild, suppressEvents); + this.insertBefore(newChild, s, suppressEvents); + return oldChild; + }, - parseAnchorRE : /^(r|right|b|bottom)$/i, + + indexOf : function(child) { + return Ext.Array.indexOf(this.childNodes, child); + }, + + getDepth : function() { + return this.get('depth'); + }, - getLayoutTargetSize : function() { - var target = this.container.getLayoutTarget(), ret = {}; - if (target) { - ret = target.getViewSize(); + + bubble : function(fn, scope, args) { + var p = this; + while (p) { + if (fn.apply(scope || p, args || [p]) === false) { + break; + } + p = p.parentNode; + } + }, - - - - if (Ext.isIE && Ext.isStrict && ret.width == 0){ - ret = target.getStyleSize(); - } - ret.width -= target.getPadding('lr'); - ret.height -= target.getPadding('tb'); - } - return ret; - }, + cascade: function() { + if (Ext.isDefined(Ext.global.console)) { + Ext.global.console.warn('Ext.data.Node: cascade has been deprecated. Please use cascadeBy instead.'); + } + return this.cascadeBy.apply(this, arguments); + }, - - onLayout : function(container, target) { - Ext.layout.AnchorLayout.superclass.onLayout.call(this, container, target); + + cascadeBy : function(fn, scope, args) { + if (fn.apply(scope || this, args || [this]) !== false) { + var childNodes = this.childNodes, + length = childNodes.length, + i; + + for (i = 0; i < length; i++) { + childNodes[i].cascadeBy(fn, scope, args); + } + } + }, - var size = this.getLayoutTargetSize(), - containerWidth = size.width, - containerHeight = size.height, - overflow = target.getStyle('overflow'), - components = this.getRenderedItems(container), - len = components.length, - boxes = [], - box, - anchorWidth, - anchorHeight, - component, - anchorSpec, - calcWidth, - calcHeight, - anchorsArray, - totalHeight = 0, - i, - el; + + eachChild : function(fn, scope, args) { + var childNodes = this.childNodes, + length = childNodes.length, + i; - if(containerWidth < 20 && containerHeight < 20){ - return; - } + for (i = 0; i < length; i++) { + if (fn.apply(scope || this, args || [childNodes[i]]) === false) { + break; + } + } + }, - - if(container.anchorSize) { - if(typeof container.anchorSize == 'number') { - anchorWidth = container.anchorSize; - } else { - anchorWidth = container.anchorSize.width; - anchorHeight = container.anchorSize.height; - } - } else { - anchorWidth = container.initialConfig.width; - anchorHeight = container.initialConfig.height; - } + + findChild : function(attribute, value, deep) { + return this.findChildBy(function() { + return this.get(attribute) == value; + }, null, deep); + }, - for(i = 0; i < len; i++) { - component = components[i]; - el = component.getPositionEl(); + + findChildBy : function(fn, scope, deep) { + var cs = this.childNodes, + len = cs.length, + i = 0, n, res; + + for (; i < len; i++) { + n = cs[i]; + if (fn.call(scope || n, n) === true) { + return n; + } + else if (deep) { + res = n.findChildBy(fn, scope, deep); + if (res !== null) { + return res; + } + } + } - - if (!component.anchor && component.items && !Ext.isNumber(component.width) && !(Ext.isIE6 && Ext.isStrict)){ - component.anchor = this.defaultAnchor; - } + return null; + }, - if(component.anchor) { - anchorSpec = component.anchorSpec; - if(!anchorSpec){ - anchorsArray = component.anchor.split(' '); - component.anchorSpec = anchorSpec = { - right: this.parseAnchor(anchorsArray[0], component.initialConfig.width, anchorWidth), - bottom: this.parseAnchor(anchorsArray[1], component.initialConfig.height, anchorHeight) - }; - } - calcWidth = anchorSpec.right ? this.adjustWidthAnchor(anchorSpec.right(containerWidth) - el.getMargins('lr'), component) : undefined; - calcHeight = anchorSpec.bottom ? this.adjustHeightAnchor(anchorSpec.bottom(containerHeight) - el.getMargins('tb'), component) : undefined; + contains : function(node) { + return node.isAncestor(this); + }, - if(calcWidth || calcHeight) { - boxes.push({ - component: component, - width: calcWidth || undefined, - height: calcHeight || undefined - }); - } - } - } - for (i = 0, len = boxes.length; i < len; i++) { - box = boxes[i]; - box.component.setSize(box.width, box.height); - } + + isAncestor : function(node) { + var p = this.parentNode; + while (p) { + if (p == node) { + return true; + } + p = p.parentNode; + } + return false; + }, + + + sort : function(sortFn, recursive, suppressEvent) { + 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(); + } + if (i == ln - 1) { + this.setLastChild(n); + n.updateInfo(); + } + if (recursive && !n.isLeaf()) { + 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) { + if (!parent.isExpanded()) { + return false; + } + parent = parent.parentNode; + } + return true; + }, + + + expand: function(recursive, callback, scope) { + var me = this; + + + + + + if (!me.isLeaf()) { + + if (!me.isLoading() && !me.isExpanded()) { + + + + + me.fireEvent('beforeexpand', me, function(records) { + 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]); + } - if (overflow && overflow != 'hidden' && !this.adjustmentPass) { - var newTargetSize = this.getLayoutTargetSize(); - if (newTargetSize.width != size.width || newTargetSize.height != size.height){ - this.adjustmentPass = true; - this.onLayout(container, target); - } - } + + + + } + + else { + Ext.callback(callback, scope || me); + } + }, + + + expandChildren: function(recursive, callback, scope) { + var me = this, + i = 0, + nodes = me.childNodes, + ln = nodes.length, + node, + expanding = 0; + + for (; i < ln; ++i) { + node = nodes[i]; + if (!node.isLeaf() && !node.isExpanded()) { + expanding++; + nodes[i].expand(recursive, function () { + expanding--; + if (callback && !expanding) { + Ext.callback(callback, scope || me, me.childNodes); + } + }); + } + } + + if (!expanding && callback) { + Ext.callback(callback, scope || me, me.childNodes); + } + }, - delete this.adjustmentPass; - }, + + collapse: function(recursive, callback, scope) { + var me = this; - - parseAnchor : function(a, start, cstart) { - if (a && a != 'none') { - var last; - - if (this.parseAnchorRE.test(a)) { - var diff = cstart - start; - return function(v){ - if(v !== last){ - last = v; - return v - diff; + + if (!me.isLeaf()) { + + if (!me.collapsing && me.isExpanded()) { + me.fireEvent('beforecollapse', me, function(records) { + 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]); + } + }, me); + } + + else if (recursive) { + me.collapseChildren(true, callback, scope); + } } - }; - - } else if(a.indexOf('%') != -1) { - var ratio = parseFloat(a.replace('%', ''))*.01; - return function(v){ - if(v !== last){ - last = v; - return Math.floor(v*ratio); + + else { + Ext.callback(callback, scope || me, me.childNodes); } - }; - - } else { - a = parseInt(a, 10); - if (!isNaN(a)) { - return function(v) { - if (v !== last) { - last = v; - return v + a; + }, + + + collapseChildren: function(recursive, callback, scope) { + var me = this, + i = 0, + nodes = me.childNodes, + ln = nodes.length, + node, + collapsing = 0; + + for (; i < ln; ++i) { + node = nodes[i]; + if (!node.isLeaf() && node.isExpanded()) { + collapsing++; + nodes[i].collapse(recursive, function () { + collapsing--; + if (callback && !collapsing) { + Ext.callback(callback, scope || me, me.childNodes); + } + }); } - }; + } + + if (!collapsing && callback) { + Ext.callback(callback, scope || me, me.childNodes); + } } - } + }; } - return false; - }, + } +}); +Ext.define('Ext.data.NodeStore', { + extend: 'Ext.data.Store', + alias: 'store.node', + requires: ['Ext.data.NodeInterface'], - adjustWidthAnchor : function(value, comp){ - return value; - }, - - adjustHeightAnchor : function(value, comp){ - return value; - } - + node: null, -}); -Ext.Container.LAYOUTS['anchor'] = Ext.layout.AnchorLayout; - -Ext.layout.ColumnLayout = Ext.extend(Ext.layout.ContainerLayout, { - monitorResize:true, - - type: 'column', - - extraCls: 'x-column', - - scrollOffset : 0, - + recursive: false, + + + rootVisible: false, + constructor: function(config) { + var me = this, + node; + + 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."); + } - targetCls: 'x-column-layout-ct', + config.proxy = {type: 'proxy'}; + me.callParent([config]); - isValidParent : function(c, target){ - return this.innerCt && c.getPositionEl().dom.parentNode == this.innerCt.dom; + me.addEvents('expand', 'collapse', 'beforeexpand', 'beforecollapse'); + + node = me.node; + if (node) { + me.node = null; + me.setNode(node); + } }, - - getLayoutTargetSize : function() { - var target = this.container.getLayoutTarget(), ret; - if (target) { - ret = target.getViewSize(); - - - + + setNode: function(node) { + var me = this; + + if (me.node && me.node != node) { - if (Ext.isIE && Ext.isStrict && ret.width == 0){ - ret = target.getStyleSize(); + me.mun(me.node, { + expand: me.onNodeExpand, + collapse: me.onNodeCollapse, + append: me.onNodeAppend, + insert: me.onNodeInsert, + remove: me.onNodeRemove, + sort: me.onNodeSort, + scope: me + }); + me.node = null; + } + + if (node) { + Ext.data.NodeInterface.decorate(node); + me.removeAll(); + if (me.rootVisible) { + me.add(node); + } + me.mon(node, { + expand: me.onNodeExpand, + collapse: me.onNodeCollapse, + append: me.onNodeAppend, + insert: me.onNodeInsert, + remove: me.onNodeRemove, + sort: me.onNodeSort, + scope: me + }); + me.node = node; + if (node.isExpanded() && node.isLoaded()) { + me.onNodeExpand(node, node.childNodes, true); } - - ret.width -= target.getPadding('lr'); - ret.height -= target.getPadding('tb'); } - return ret; }, - - renderAll : function(ct, target) { - if(!this.innerCt){ - - - this.innerCt = target.createChild({cls:'x-column-inner'}); - this.innerCt.createChild({cls:'x-clear'}); + + onNodeSort: function(node, childNodes) { + var me = this; + + if ((me.indexOf(node) !== -1 || (node === me.node && !me.rootVisible) && node.isExpanded())) { + me.onNodeCollapse(node, childNodes, true); + me.onNodeExpand(node, childNodes, true); } - Ext.layout.ColumnLayout.superclass.renderAll.call(this, ct, this.innerCt); }, - - onLayout : function(ct, target){ - var cs = ct.items.items, - len = cs.length, - c, - i, - m, - margins = []; - - this.renderAll(ct, target); - - var size = this.getLayoutTargetSize(); - - if(size.width < 1 && size.height < 1){ + onNodeExpand: function(parent, records, suppressEvent) { + var me = this, + insertIndex = me.indexOf(parent) + 1, + ln = records ? records.length : 0, + i, record; + + if (!me.recursive && parent !== me.node) { return; } - - var w = size.width - this.scrollOffset, - h = size.height, - pw = w; - - this.innerCt.setWidth(w); - - - - for(i = 0; i < len; i++){ - c = cs[i]; - m = c.getPositionEl().getMargins('lr'); - margins[i] = m; - if(!c.columnWidth){ - pw -= (c.getWidth() + m); - } + if (!me.isVisible(parent)) { + return; } - pw = pw < 0 ? 0 : pw; - - for(i = 0; i < len; i++){ - c = cs[i]; - m = margins[i]; - if(c.columnWidth){ - c.setSize(Math.floor(c.columnWidth * pw) - m); - } + if (!suppressEvent && me.fireEvent('beforeexpand', parent, records, insertIndex) === false) { + return; } - - - if (Ext.isIE) { - if (i = target.getStyle('overflow') && i != 'hidden' && !this.adjustmentPass) { - var ts = this.getLayoutTargetSize(); - if (ts.width != size.width){ - this.adjustmentPass = true; - this.onLayout(ct, target); + if (ln) { + me.insert(insertIndex, records); + for (i = 0; i < ln; i++) { + record = records[i]; + if (record.isExpanded()) { + if (record.isLoaded()) { + + me.onNodeExpand(record, record.childNodes, true); + } + else { + record.set('expanded', false); + record.expand(); + } } } } - delete this.adjustmentPass; - } - - -}); - -Ext.Container.LAYOUTS['column'] = Ext.layout.ColumnLayout; - -Ext.layout.BorderLayout = Ext.extend(Ext.layout.ContainerLayout, { - - monitorResize:true, - - rendered : false, - - type: 'border', - - targetCls: 'x-border-layout-ct', - - getLayoutTargetSize : function() { - var target = this.container.getLayoutTarget(); - return target ? target.getViewSize() : {}; - }, - - onLayout : function(ct, target){ - var collapsed, i, c, pos, items = ct.items.items, len = items.length; - if(!this.rendered){ - collapsed = []; - for(i = 0; i < len; i++) { - c = items[i]; - pos = c.region; - if(c.collapsed){ - collapsed.push(c); - } - c.collapsed = false; - if(!c.rendered){ - c.render(target, i); - c.getPositionEl().addClass('x-border-panel'); - } - this[pos] = pos != 'center' && c.split ? - new Ext.layout.BorderLayout.SplitRegion(this, c.initialConfig, pos) : - new Ext.layout.BorderLayout.Region(this, c.initialConfig, pos); - this[pos].render(target, c); - } - this.rendered = true; + if (!suppressEvent) { + me.fireEvent('expand', parent, records); } + }, - var size = this.getLayoutTargetSize(); - if(size.width < 20 || size.height < 20){ - if(collapsed){ - this.restoreCollapsed = collapsed; - } + onNodeCollapse: function(parent, records, suppressEvent) { + var me = this, + ln = records.length, + collapseIndex = me.indexOf(parent) + 1, + i, record; + + if (!me.recursive && parent !== me.node) { return; - }else if(this.restoreCollapsed){ - collapsed = this.restoreCollapsed; - delete this.restoreCollapsed; - } - - var w = size.width, h = size.height, - centerW = w, centerH = h, centerY = 0, centerX = 0, - n = this.north, s = this.south, west = this.west, e = this.east, c = this.center, - b, m, totalWidth, totalHeight; - if(!c && Ext.layout.BorderLayout.WARN !== false){ - throw 'No center region defined in BorderLayout ' + ct.id; - } - - if(n && n.isVisible()){ - b = n.getSize(); - m = n.getMargins(); - b.width = w - (m.left+m.right); - b.x = m.left; - b.y = m.top; - centerY = b.height + b.y + m.bottom; - centerH -= centerY; - n.applyLayout(b); - } - if(s && s.isVisible()){ - b = s.getSize(); - m = s.getMargins(); - b.width = w - (m.left+m.right); - b.x = m.left; - totalHeight = (b.height + m.top + m.bottom); - b.y = h - totalHeight + m.top; - centerH -= totalHeight; - s.applyLayout(b); - } - if(west && west.isVisible()){ - b = west.getSize(); - m = west.getMargins(); - b.height = centerH - (m.top+m.bottom); - b.x = m.left; - b.y = centerY + m.top; - totalWidth = (b.width + m.left + m.right); - centerX += totalWidth; - centerW -= totalWidth; - west.applyLayout(b); - } - if(e && e.isVisible()){ - b = e.getSize(); - m = e.getMargins(); - b.height = centerH - (m.top+m.bottom); - totalWidth = (b.width + m.left + m.right); - b.x = w - totalWidth + m.left; - b.y = centerY + m.top; - centerW -= totalWidth; - e.applyLayout(b); } - if(c){ - m = c.getMargins(); - var centerBox = { - x: centerX + m.left, - y: centerY + m.top, - width: centerW - (m.left+m.right), - height: centerH - (m.top+m.bottom) - }; - c.applyLayout(centerBox); + + if (!suppressEvent && me.fireEvent('beforecollapse', parent, records, collapseIndex) === false) { + return; } - if(collapsed){ - for(i = 0, len = collapsed.length; i < len; i++){ - collapsed[i].collapse(false); + + for (i = 0; i < ln; i++) { + record = records[i]; + me.remove(record); + if (record.isExpanded()) { + me.onNodeCollapse(record, record.childNodes, true); } } - if(Ext.isIE && Ext.isStrict){ - target.repaint(); - } - if (i = target.getStyle('overflow') && i != 'hidden' && !this.adjustmentPass) { - var ts = this.getLayoutTargetSize(); - if (ts.width != size.width || ts.height != size.height){ - this.adjustmentPass = true; - this.onLayout(ct, target); - } + if (!suppressEvent) { + me.fireEvent('collapse', parent, records, collapseIndex); } - delete this.adjustmentPass; }, + + onNodeAppend: function(parent, node, index) { + var me = this, + refNode, sibling; - destroy: function() { - var r = ['north', 'south', 'east', 'west'], i, region; - for (i = 0; i < r.length; i++) { - region = this[r[i]]; - if(region){ - if(region.destroy){ - region.destroy(); - }else if (region.split){ - region.split.destroy(true); + if (me.isVisible(node)) { + if (index === 0) { + refNode = parent; + } else { + sibling = node.previousSibling; + while (sibling.isExpanded() && sibling.lastChild) { + sibling = sibling.lastChild; + } + refNode = sibling; + } + me.insert(me.indexOf(refNode) + 1, node); + if (!node.isLeaf() && node.isExpanded()) { + if (node.isLoaded()) { + + me.onNodeExpand(node, node.childNodes, true); + } + else { + node.set('expanded', false); + node.expand(); + } + } + } + }, + + onNodeInsert: function(parent, node, refNode) { + var me = this, + index = this.indexOf(refNode); + + if (index != -1 && me.isVisible(node)) { + me.insert(index, node); + if (!node.isLeaf() && node.isExpanded()) { + if (node.isLoaded()) { + + me.onNodeExpand(node, node.childNodes, true); + } + else { + node.set('expanded', false); + node.expand(); } } } - Ext.layout.BorderLayout.superclass.destroy.call(this); - } - + }, -}); - - -Ext.layout.BorderLayout.Region = function(layout, config, pos){ - Ext.apply(this, config); - this.layout = layout; - this.position = pos; - this.state = {}; - if(typeof this.margins == 'string'){ - this.margins = this.layout.parseMargins(this.margins); - } - this.margins = Ext.applyIf(this.margins || {}, this.defaultMargins); - if(this.collapsible){ - if(typeof this.cmargins == 'string'){ - this.cmargins = this.layout.parseMargins(this.cmargins); + onNodeRemove: function(parent, node, index) { + var me = this; + if (me.indexOf(node) != -1) { + if (!node.isLeaf() && node.isExpanded()) { + me.onNodeCollapse(node, node.childNodes, true); + } + me.remove(node); } - if(this.collapseMode == 'mini' && !this.cmargins){ - this.cmargins = {left:0,top:0,right:0,bottom:0}; - }else{ - this.cmargins = Ext.applyIf(this.cmargins || {}, - pos == 'north' || pos == 'south' ? this.defaultNSCMargins : this.defaultEWCMargins); + }, + + isVisible: function(node) { + var parent = node.parentNode; + while (parent) { + if (parent === this.node && !this.rootVisible && parent.isExpanded()) { + return true; + } + + if (this.indexOf(parent) === -1 || !parent.isExpanded()) { + return false; + } + + parent = parent.parentNode; } + return true; } -}; +}); -Ext.layout.BorderLayout.Region.prototype = { - - +Ext.define('Ext.data.Request', { + action: undefined, + params: undefined, - collapsible : false, - - split:false, - - floatable: true, - - minWidth:50, - - minHeight:50, - - - defaultMargins : {left:0,top:0,right:0,bottom:0}, - defaultNSCMargins : {left:5,top:5,right:5,bottom:5}, + method: 'GET', - defaultEWCMargins : {left:5,top:0,right:5,bottom:0}, - floatingZIndex: 100, - - isCollapsed : false, + url: undefined, - - - + constructor: function(config) { + Ext.apply(this, config); + } +}); +Ext.define('Ext.data.Tree', { + alias: 'data.tree', - render : function(ct, p){ - this.panel = p; - p.el.enableDisplayMode(); - this.targetEl = ct; - this.el = p.el; - - var gs = p.getState, ps = this.position; - p.getState = function(){ - return Ext.apply(gs.call(p) || {}, this.state); - }.createDelegate(this); - - if(ps != 'center'){ - p.allowQueuedExpand = false; - p.on({ - beforecollapse: this.beforeCollapse, - collapse: this.onCollapse, - beforeexpand: this.beforeExpand, - expand: this.onExpand, - hide: this.onHide, - show: this.onShow, - scope: this - }); - if(this.collapsible || this.floatable){ - p.collapseEl = 'el'; - p.slideAnchor = this.getSlideAnchor(); - } - if(p.tools && p.tools.toggle){ - p.tools.toggle.addClass('x-tool-collapse-'+ps); - p.tools.toggle.addClassOnOver('x-tool-collapse-'+ps+'-over'); - } - } + mixins: { + observable: "Ext.util.Observable" }, - getCollapsedEl : function(){ - if(!this.collapsedEl){ - if(!this.toolTemplate){ - var tt = new Ext.Template( - '
 
' - ); - tt.disableFormats = true; - tt.compile(); - Ext.layout.BorderLayout.Region.prototype.toolTemplate = tt; - } - this.collapsedEl = this.targetEl.createChild({ - cls: "x-layout-collapsed x-layout-collapsed-"+this.position, - id: this.panel.id + '-xcollapsed' - }); - this.collapsedEl.enableDisplayMode('block'); + root: null, + + constructor: function(root) { + var me = this; + + me.nodeHash = {}; - if(this.collapseMode == 'mini'){ - this.collapsedEl.addClass('x-layout-cmini-'+this.position); - this.miniCollapsedEl = this.collapsedEl.createChild({ - cls: "x-layout-mini x-layout-mini-"+this.position, html: " " - }); - this.miniCollapsedEl.addClassOnOver('x-layout-mini-over'); - this.collapsedEl.addClassOnOver("x-layout-collapsed-over"); - this.collapsedEl.on('click', this.onExpandClick, this, {stopEvent:true}); - }else { - if(this.collapsible !== false && !this.hideCollapseTool) { - var t = this.expandToolEl = this.toolTemplate.append( - this.collapsedEl.dom, - {id:'expand-'+this.position}, true); - t.addClassOnOver('x-tool-expand-'+this.position+'-over'); - t.on('click', this.onExpandClick, this, {stopEvent:true}); - } - if(this.floatable !== false || this.titleCollapse){ - this.collapsedEl.addClassOnOver("x-layout-collapsed-over"); - this.collapsedEl.on("click", this[this.floatable ? 'collapseClick' : 'onExpandClick'], this); - } - } + me.mixins.observable.constructor.call(me); + + if (root) { + me.setRootNode(root); } - return this.collapsedEl; }, - onExpandClick : function(e){ - if(this.isSlid){ - this.panel.expand(false); - }else{ - this.panel.expand(); - } + getRootNode : function() { + return this.root; }, - onCollapseClick : function(e){ - this.panel.collapse(); - }, + 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", - - beforeCollapse : function(p, animate){ - this.lastAnim = animate; - if(this.splitEl){ - this.splitEl.hide(); - } - this.getCollapsedEl().show(); - var el = this.panel.getEl(); - this.originalZIndex = el.getStyle('z-index'); - el.setStyle('z-index', 100); - this.isCollapsed = true; - this.layout.layout(); - }, + + "remove", - - onCollapse : function(animate){ - this.panel.el.setStyle('z-index', 1); - if(this.lastAnim === false || this.panel.animCollapse === false){ - this.getCollapsedEl().dom.style.visibility = 'visible'; - }else{ - this.getCollapsedEl().slideIn(this.panel.slideAnchor, {duration:.2}); - } - this.state.collapsed = true; - this.panel.saveState(); - }, + + "move", - - beforeExpand : function(animate){ - if(this.isSlid){ - this.afterSlideIn(); - } - var c = this.getCollapsedEl(); - this.el.show(); - if(this.position == 'east' || this.position == 'west'){ - this.panel.setSize(undefined, c.getHeight()); - }else{ - this.panel.setSize(c.getWidth(), undefined); - } - c.hide(); - c.dom.style.visibility = 'hidden'; - this.panel.el.setStyle('z-index', this.floatingZIndex); - }, + + "insert", - - onExpand : function(){ - this.isCollapsed = false; - if(this.splitEl){ - this.splitEl.show(); - } - this.layout.layout(); - this.panel.el.setStyle('z-index', this.originalZIndex); - this.state.collapsed = false; - this.panel.saveState(); - }, + + "beforeappend", - - collapseClick : function(e){ - if(this.isSlid){ - e.stopPropagation(); - this.slideIn(); - }else{ - e.stopPropagation(); - this.slideOut(); - } - }, + + "beforeremove", - - onHide : function(){ - if(this.isCollapsed){ - this.getCollapsedEl().hide(); - }else if(this.splitEl){ - this.splitEl.hide(); + + "beforemove", + + + "beforeinsert", + + + "expand", + + + "collapse", + + + "beforeexpand", + + + "beforecollapse" , + + + "rootchange" + ]); + + node.on({ + scope: me, + insert: me.onNodeInsert, + append: me.onNodeAppend, + remove: me.onNodeRemove + }); + + me.registerNode(node); + me.fireEvent('append', null, node); + me.fireEvent('rootchange', node); } + + return node; }, - - onShow : function(){ - if(this.isCollapsed){ - this.getCollapsedEl().show(); - }else if(this.splitEl){ - this.splitEl.show(); + + flatten: function(){ + var nodes = [], + hash = this.nodeHash, + key; + + for (key in hash) { + if (hash.hasOwnProperty(key)) { + nodes.push(hash[key]); + } } + return nodes; }, - - isVisible : function(){ - return !this.panel.hidden; - }, - - getMargins : function(){ - return this.isCollapsed && this.cmargins ? this.cmargins : this.margins; + onNodeInsert: function(parent, node) { + this.registerNode(node); }, - - getSize : function(){ - return this.isCollapsed ? this.getCollapsedEl().getSize() : this.panel.getSize(); - }, - - setPanel : function(panel){ - this.panel = panel; + onNodeAppend: function(parent, node) { + this.registerNode(node); }, - - getMinWidth: function(){ - return this.minWidth; - }, - - getMinHeight: function(){ - return this.minHeight; + onNodeRemove: function(parent, node) { + this.unregisterNode(node); }, - applyLayoutCollapsed : function(box){ - var ce = this.getCollapsedEl(); - ce.setLeftTop(box.x, box.y); - ce.setSize(box.width, box.height); + getNodeById : function(id) { + return this.nodeHash[id]; }, - applyLayout : function(box){ - if(this.isCollapsed){ - this.applyLayoutCollapsed(box); - }else{ - this.panel.setPosition(box.x, box.y); - this.panel.setSize(box.width, box.height); - } + registerNode : function(node) { + this.nodeHash[node.getId() || node.internalId] = node; }, - beforeSlide: function(){ - this.panel.beforeEffect(); + unregisterNode : function(node) { + delete this.nodeHash[node.getId() || node.internalId]; }, - - afterSlide : function(){ - this.panel.afterEffect(); + + sort: function(sorterFn, recursive) { + this.getRootNode().sort(sorterFn, recursive); }, + + + filter: function(filters, recursive) { + this.getRootNode().filter(filters, recursive); + } +}); + +Ext.define('Ext.data.TreeStore', { + extend: 'Ext.data.AbstractStore', + alias: 'store.tree', + requires: ['Ext.data.Tree', 'Ext.data.NodeInterface', 'Ext.data.NodeStore'], - initAutoHide : function(){ - if(this.autoHide !== false){ - if(!this.autoHideHd){ - this.autoHideSlideTask = new Ext.util.DelayedTask(this.slideIn, this); - this.autoHideHd = { - "mouseout": function(e){ - if(!e.within(this.el, true)){ - this.autoHideSlideTask.delay(500); - } - }, - "mouseover" : function(e){ - this.autoHideSlideTask.cancel(); - }, - scope : this - }; - } - this.el.on(this.autoHideHd); - this.collapsedEl.on(this.autoHideHd); - } - }, + clearOnLoad : true, - clearAutoHide : function(){ - if(this.autoHide !== false){ - this.el.un("mouseout", this.autoHideHd.mouseout); - this.el.un("mouseover", this.autoHideHd.mouseover); - this.collapsedEl.un("mouseout", this.autoHideHd.mouseout); - this.collapsedEl.un("mouseover", this.autoHideHd.mouseover); - } - }, + nodeParam: 'node', - clearMonitor : function(){ - Ext.getDoc().un("click", this.slideInIf, this); - }, + defaultRootId: 'root', + + + defaultRootProperty: 'children', - slideOut : function(){ - if(this.isSlid || this.el.hasActiveFx()){ - return; - } - this.isSlid = true; - var ts = this.panel.tools, dh, pc; - if(ts && ts.toggle){ - ts.toggle.hide(); + folderSort: false, + + constructor: function(config) { + var me = this, + root, + fields; + + + config = Ext.apply({}, config); + + + fields = config.fields || me.fields; + if (!fields) { + config.fields = [{name: 'text', type: 'string'}]; } - this.el.show(); + me.callParent([config]); - pc = this.panel.collapsed; - this.panel.collapsed = false; - - if(this.position == 'east' || this.position == 'west'){ - - dh = this.panel.deferHeight; - this.panel.deferHeight = false; + + 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 + }); - this.panel.setSize(undefined, this.collapsedEl.getHeight()); + me.onBeforeSort(); + + root = me.root; + if (root) { + delete me.root; + me.setRootNode(root); + } + me.relayEvents(me.tree, [ - this.panel.deferHeight = dh; - }else{ - this.panel.setSize(this.collapsedEl.getWidth(), undefined); - } + "append", + + + "remove", + + + "move", + + + "insert", + + + "beforeappend", + + + "beforeremove", + + + "beforemove", + + + "beforeinsert", + + + "expand", + + + "collapse", + + + "beforeexpand", + + + "beforecollapse", + + "sort", + + + "rootchange" + ]); - this.panel.collapsed = pc; - - this.restoreLT = [this.el.dom.style.left, this.el.dom.style.top]; - this.el.alignTo(this.collapsedEl, this.getCollapseAnchor()); - this.el.setStyle("z-index", this.floatingZIndex+2); - this.panel.el.replaceClass('x-panel-collapsed', 'x-panel-floating'); - if(this.animFloat !== false){ - this.beforeSlide(); - this.el.slideIn(this.getSlideAnchor(), { - callback: function(){ - this.afterSlide(); - this.initAutoHide(); - Ext.getDoc().on("click", this.slideInIf, this); - }, - scope: this, - block: true - }); - }else{ - this.initAutoHide(); - Ext.getDoc().on("click", this.slideInIf, this); + me.addEvents( + + 'rootchange' + ); + + 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.'); + } + me.nodeParam = me.nodeParameter; + delete me.nodeParameter; } }, - - afterSlideIn : function(){ - this.clearAutoHide(); - this.isSlid = false; - this.clearMonitor(); - this.el.setStyle("z-index", ""); - this.panel.el.replaceClass('x-panel-floating', 'x-panel-collapsed'); - this.el.dom.style.left = this.restoreLT[0]; - this.el.dom.style.top = this.restoreLT[1]; - - var ts = this.panel.tools; - if(ts && ts.toggle){ - ts.toggle.show(); - } - }, - - slideIn : function(cb){ - if(!this.isSlid || this.el.hasActiveFx()){ - Ext.callback(cb); - return; + setProxy: function(proxy) { + var reader, + needsRoot; + + if (proxy instanceof Ext.data.proxy.Proxy) { + + needsRoot = Ext.isEmpty(proxy.getReader().root); + } else if (Ext.isString(proxy)) { + + needsRoot = true; + } else { + + reader = proxy.reader; + needsRoot = !(reader && !Ext.isEmpty(reader.root)); } - this.isSlid = false; - if(this.animFloat !== false){ - this.beforeSlide(); - this.el.slideOut(this.getSlideAnchor(), { - callback: function(){ - this.el.hide(); - this.afterSlide(); - this.afterSlideIn(); - Ext.callback(cb); - }, - scope: this, - block: true - }); - }else{ - this.el.hide(); - this.afterSlideIn(); + proxy = this.callParent(arguments); + if (needsRoot) { + reader = proxy.getReader(); + reader.root = this.defaultRootProperty; + + reader.buildExtractors(true); } }, - - slideInIf : function(e){ - if(!e.within(this.el)){ - this.slideIn(); + + onBeforeSort: function() { + if (this.folderSort) { + this.sort({ + property: 'leaf', + direction: 'ASC' + }, 'prepend', false); } }, - - anchors : { - "west" : "left", - "east" : "right", - "north" : "top", - "south" : "bottom" - }, - - sanchors : { - "west" : "l", - "east" : "r", - "north" : "t", - "south" : "b" + onBeforeNodeExpand: function(node, callback, scope) { + if (node.isLoaded()) { + Ext.callback(callback, scope || node, [node.childNodes]); + } + else if (node.isLoading()) { + this.on('load', function() { + Ext.callback(callback, scope || node, [node.childNodes]); + }, this, {single: true}); + } + else { + this.read({ + node: node, + callback: function() { + Ext.callback(callback, scope || node, [node.childNodes]); + } + }); + } }, - - canchors : { - "west" : "tl-tr", - "east" : "tr-tl", - "north" : "tl-bl", - "south" : "bl-tl" - }, - - getAnchor : function(){ - return this.anchors[this.position]; + getNewRecords: function() { + return Ext.Array.filter(this.tree.flatten(), this.filterNew); }, - getCollapseAnchor : function(){ - return this.canchors[this.position]; + getUpdatedRecords: function() { + return Ext.Array.filter(this.tree.flatten(), this.filterUpdated); }, - - getSlideAnchor : function(){ - return this.sanchors[this.position]; + + onBeforeNodeCollapse: function(node, callback, scope) { + callback.call(scope || node, node.childNodes); }, - - getAlignAdj : function(){ - var cm = this.cmargins; - switch(this.position){ - case "west": - return [0, 0]; - break; - case "east": - return [0, 0]; - break; - case "north": - return [0, 0]; - break; - case "south": - return [0, 0]; - break; + onNodeRemove: function(parent, node) { + var removed = this.removed; + + if (!node.isReplace && Ext.Array.indexOf(removed, node) == -1) { + removed.push(node); } }, - - getExpandAdj : function(){ - var c = this.collapsedEl, cm = this.cmargins; - switch(this.position){ - case "west": - return [-(cm.right+c.getWidth()+cm.left), 0]; - break; - case "east": - return [cm.right+c.getWidth()+cm.left, 0]; - break; - case "north": - return [0, -(cm.top+cm.bottom+c.getHeight())]; - break; - case "south": - return [0, cm.top+cm.bottom+c.getHeight()]; - break; + onNodeAdded: function(parent, node) { + var proxy = this.getProxy(), + reader = proxy.getReader(), + data = node.raw || node.data, + dataRoot, children; + + Ext.Array.remove(this.removed, node); + + if (!node.isLeaf() && !node.isLoaded()) { + dataRoot = reader.getRoot(data); + if (dataRoot) { + this.fillNode(node, reader.extractData(dataRoot)); + delete data[reader.root]; + } } }, + + + setRootNode: function(root) { + var me = this; - destroy : function(){ - if (this.autoHideSlideTask && this.autoHideSlideTask.cancel){ - this.autoHideSlideTask.cancel(); + root = root || {}; + if (!root.isNode) { + + Ext.applyIf(root, { + id: me.defaultRootId, + text: 'Root', + allowDrag: false + }); + root = Ext.ModelManager.create(root, me.model); } - Ext.destroyMembers(this, 'miniCollapsedEl', 'collapsedEl', 'expandToolEl'); - } -}; - - -Ext.layout.BorderLayout.SplitRegion = function(layout, config, pos){ - Ext.layout.BorderLayout.SplitRegion.superclass.constructor.call(this, layout, config, pos); - - this.applyLayout = this.applyFns[pos]; -}; + Ext.data.NodeInterface.decorate(root); -Ext.extend(Ext.layout.BorderLayout.SplitRegion, Ext.layout.BorderLayout.Region, { - - - splitTip : "Drag to resize.", - - collapsibleSplitTip : "Drag to resize. Double click to hide.", + + + me.getProxy().getReader().buildExtractors(true); + + + me.tree.setRootNode(root); + + + if (!root.isLoaded() && root.isExpanded()) { + me.load({ + node: root + }); + } + + return root; + }, + - useSplitTips : false, + getRootNode: function() { + return this.tree.getRootNode(); + }, - splitSettings : { - north : { - orientation: Ext.SplitBar.VERTICAL, - placement: Ext.SplitBar.TOP, - maxFn : 'getVMaxSize', - minProp: 'minHeight', - maxProp: 'maxHeight' - }, - south : { - orientation: Ext.SplitBar.VERTICAL, - placement: Ext.SplitBar.BOTTOM, - maxFn : 'getVMaxSize', - minProp: 'minHeight', - maxProp: 'maxHeight' - }, - east : { - orientation: Ext.SplitBar.HORIZONTAL, - placement: Ext.SplitBar.RIGHT, - maxFn : 'getHMaxSize', - minProp: 'minWidth', - maxProp: 'maxWidth' - }, - west : { - orientation: Ext.SplitBar.HORIZONTAL, - placement: Ext.SplitBar.LEFT, - maxFn : 'getHMaxSize', - minProp: 'minWidth', - maxProp: 'maxWidth' - } + getNodeById: function(id) { + return this.tree.getNodeById(id); }, - applyFns : { - west : function(box){ - if(this.isCollapsed){ - return this.applyLayoutCollapsed(box); - } - var sd = this.splitEl.dom, s = sd.style; - this.panel.setPosition(box.x, box.y); - var sw = sd.offsetWidth; - s.left = (box.x+box.width-sw)+'px'; - s.top = (box.y)+'px'; - s.height = Math.max(0, box.height)+'px'; - this.panel.setSize(box.width-sw, box.height); - }, - east : function(box){ - if(this.isCollapsed){ - return this.applyLayoutCollapsed(box); - } - var sd = this.splitEl.dom, s = sd.style; - var sw = sd.offsetWidth; - this.panel.setPosition(box.x+sw, box.y); - s.left = (box.x)+'px'; - s.top = (box.y)+'px'; - s.height = Math.max(0, box.height)+'px'; - this.panel.setSize(box.width-sw, box.height); - }, - north : function(box){ - if(this.isCollapsed){ - return this.applyLayoutCollapsed(box); - } - var sd = this.splitEl.dom, s = sd.style; - var sh = sd.offsetHeight; - this.panel.setPosition(box.x, box.y); - s.left = (box.x)+'px'; - s.top = (box.y+box.height-sh)+'px'; - s.width = Math.max(0, box.width)+'px'; - this.panel.setSize(box.width, box.height-sh); - }, - south : function(box){ - if(this.isCollapsed){ - return this.applyLayoutCollapsed(box); - } - var sd = this.splitEl.dom, s = sd.style; - var sh = sd.offsetHeight; - this.panel.setPosition(box.x, box.y+sh); - s.left = (box.x)+'px'; - s.top = (box.y)+'px'; - s.width = Math.max(0, box.width)+'px'; - this.panel.setSize(box.width, box.height-sh); + load: function(options) { + options = options || {}; + options.params = options.params || {}; + + var me = this, + node = options.node || me.tree.getRootNode(), + root; + + + + if (!node) { + node = me.setRootNode({ + expanded: true + }); + } + + if (me.clearOnLoad) { + node.removeAll(); + } + + Ext.applyIf(options, { + node: node + }); + options.params[me.nodeParam] = node ? node.getId() : 'root'; + + if (node) { + node.set('loading', true); } + + return me.callParent([options]); }, + - render : function(ct, p){ - Ext.layout.BorderLayout.SplitRegion.superclass.render.call(this, ct, p); - - var ps = this.position; - - this.splitEl = ct.createChild({ - cls: "x-layout-split x-layout-split-"+ps, html: " ", - id: this.panel.id + '-xsplit' - }); + fillNode: function(node, records) { + var me = this, + ln = records ? records.length : 0, + i = 0, sortCollection; - if(this.collapseMode == 'mini'){ - this.miniSplitEl = this.splitEl.createChild({ - cls: "x-layout-mini x-layout-mini-"+ps, html: " " - }); - this.miniSplitEl.addClassOnOver('x-layout-mini-over'); - this.miniSplitEl.on('click', this.onCollapseClick, this, {stopEvent:true}); + if (ln && me.sortOnLoad && !me.remoteSort && me.sorters && me.sorters.items) { + sortCollection = Ext.create('Ext.util.MixedCollection'); + sortCollection.addAll(records); + sortCollection.sort(me.sorters.items); + records = sortCollection.items; } + + node.set('loaded', true); + for (; i < ln; i++) { + node.appendChild(records[i], undefined, true); + } + + return records; + }, - var s = this.splitSettings[ps]; - - this.split = new Ext.SplitBar(this.splitEl.dom, p.el, s.orientation); - this.split.tickSize = this.tickSize; - this.split.placement = s.placement; - this.split.getMaximumSize = this[s.maxFn].createDelegate(this); - this.split.minSize = this.minSize || this[s.minProp]; - this.split.on("beforeapply", this.onSplitMove, this); - this.split.useShim = this.useShim === true; - this.maxSize = this.maxSize || this[s.maxProp]; + + onProxyLoad: function(operation) { + var me = this, + successful = operation.wasSuccessful(), + records = operation.getRecords(), + node = operation.node; - if(p.hidden){ - this.splitEl.hide(); + 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) { + var i = 0, + length = records.length, + originalRecords = operation.records, + parentNode, + record, + original, + index; - if(this.useSplitTips){ - this.splitEl.dom.title = this.collapsible ? this.collapsibleSplitTip : this.splitTip; - } - if(this.collapsible){ - this.splitEl.on("dblclick", this.onCollapseClick, this); + + for (; i < length; ++i) { + record = records[i]; + original = originalRecords[i]; + if (original) { + parentNode = original.parentNode; + if (parentNode) { + + original.isReplace = true; + parentNode.replaceChild(record, original); + delete original.isReplace; + } + record.phantom = false; + } + } } }, - getSize : function(){ - if(this.isCollapsed){ - return this.collapsedEl.getSize(); - } - var s = this.panel.getSize(); - if(this.position == 'north' || this.position == 'south'){ - s.height += this.splitEl.dom.offsetHeight; - }else{ - s.width += this.splitEl.dom.offsetWidth; + onUpdateRecords: function(records, operation, success){ + if (success) { + var me = this, + i = 0, + length = records.length, + data = me.data, + original, + parentNode, + record; + + for (; i < length; ++i) { + record = records[i]; + original = me.tree.getNodeById(record.getId()); + parentNode = original.parentNode; + if (parentNode) { + + original.isReplace = true; + parentNode.replaceChild(record, original); + original.isReplace = false; + } + } } - return s; }, - getHMaxSize : function(){ - var cmax = this.maxSize || 10000; - var center = this.layout.center; - return Math.min(cmax, (this.el.getWidth()+center.el.getWidth())-center.getMinWidth()); + onDestroyRecords: function(records, operation, success){ + if (success) { + this.removed = []; + } }, - getVMaxSize : function(){ - var cmax = this.maxSize || 10000; - var center = this.layout.center; - return Math.min(cmax, (this.el.getHeight()+center.el.getHeight())-center.getMinHeight()); + removeAll: function() { + this.getRootNode().destroy(); + this.fireEvent('clear', this); }, - onSplitMove : function(split, newSize){ - var s = this.panel.getSize(); - this.lastSplitSize = newSize; - if(this.position == 'north' || this.position == 'south'){ - this.panel.setSize(s.width, newSize); - this.state.height = newSize; - }else{ - this.panel.setSize(newSize, s.height); - this.state.width = newSize; - } - this.layout.layout(); - this.panel.saveState(); - return false; - }, + doSort: function(sorterFn) { + var me = this; + if (me.remoteSort) { + + me.load(); + } else { + me.tree.sort(sorterFn, true); + me.fireEvent('datachanged', me); + } + me.fireEvent('sort', me); + } +}); + +Ext.define('Ext.data.XmlStore', { + extend: 'Ext.data.Store', + alternateClassName: 'Ext.data.XmlStore', + alias: 'store.xml', - getSplitBar : function(){ - return this.split; - }, + constructor: function(config){ + config = config || {}; + config = config || {}; + + Ext.applyIf(config, { + proxy: { + type: 'ajax', + reader: 'xml', + writer: 'xml' + } + }); + + this.callParent([config]); + } +}); + +Ext.define('Ext.data.proxy.Client', { + extend: 'Ext.data.proxy.Proxy', + alternateClassName: 'Ext.data.ClientProxy', - destroy : function() { - Ext.destroy(this.miniSplitEl, this.split, this.splitEl); - Ext.layout.BorderLayout.SplitRegion.superclass.destroy.call(this); + + 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."); } }); -Ext.Container.LAYOUTS['border'] = Ext.layout.BorderLayout; +Ext.define('Ext.data.proxy.JsonP', { + extend: 'Ext.data.proxy.Server', + alternateClassName: 'Ext.data.ScriptTagProxy', + alias: ['proxy.jsonp', 'proxy.scripttag'], + requires: ['Ext.data.JsonP'], -Ext.layout.FormLayout = Ext.extend(Ext.layout.AnchorLayout, { + defaultWriterType: 'base', - labelSeparator : ':', + callbackKey : 'callback', + recordParam: 'records', - trackLabels: true, + autoAppendParams: true, + + constructor: function(){ + this.addEvents( + + 'exception' + ); + this.callParent(arguments); + }, - type: 'form', + + doRequest: function(operation, callback, scope) { + + var me = this, + writer = me.getWriter(), + request = me.buildRequest(operation), + params = request.params; - onRemove: function(c){ - Ext.layout.FormLayout.superclass.onRemove.call(this, c); - if(this.trackLabels){ - c.un('show', this.onFieldShow, this); - c.un('hide', this.onFieldHide, this); + if (operation.allowWrite()) { + request = writer.write(request); } + - var el = c.getPositionEl(), - ct = c.getItemCt && c.getItemCt(); - if (c.rendered && ct) { - if (el && el.dom) { - el.insertAfter(ct); - } - Ext.destroy(ct); - Ext.destroyMembers(c, 'label', 'itemCt'); - if (c.customItemCt) { - Ext.destroyMembers(c, 'getItemCt', 'customItemCt'); - } + Ext.apply(request, { + callbackKey: me.callbackKey, + timeout: me.timeout, + scope: me, + disableCaching: false, + callback: me.createRequestCallback(request, operation, callback, scope) + }); + + + if (me.autoAppendParams) { + request.params = {}; } + + request.jsonp = Ext.data.JsonP.request(request); + + request.params = params; + operation.setStarted(); + me.lastRequest = request; + + return request; }, - setContainer : function(ct){ - Ext.layout.FormLayout.superclass.setContainer.call(this, ct); - if(ct.labelAlign){ - ct.addClass('x-form-label-'+ct.labelAlign); - } + createRequestCallback: function(request, operation, callback, scope) { + var me = this; - if(ct.hideLabels){ - Ext.apply(this, { - labelStyle: 'display:none', - elementStyle: 'padding-left:0;', - labelAdjust: 0 - }); - }else{ - this.labelSeparator = Ext.isDefined(ct.labelSeparator) ? ct.labelSeparator : this.labelSeparator; - ct.labelWidth = ct.labelWidth || 100; - if(Ext.isNumber(ct.labelWidth)){ - var pad = Ext.isNumber(ct.labelPad) ? ct.labelPad : 5; - Ext.apply(this, { - labelAdjust: ct.labelWidth + pad, - labelStyle: 'width:' + ct.labelWidth + 'px;', - elementStyle: 'padding-left:' + (ct.labelWidth + pad) + 'px' - }); - } - if(ct.labelAlign == 'top'){ - Ext.apply(this, { - labelStyle: 'width:auto;', - labelAdjust: 0, - elementStyle: 'padding-left:0;' - }); - } - } + return function(success, response, errorType) { + delete me.lastRequest; + me.processResponse(success, operation, request, response, callback, scope); + }; }, - - isHide: function(c){ - return c.hideLabel || this.container.hideLabels; + + setException: function(operation, response) { + operation.setException(operation.request.jsonp.errorType); }, - onFieldShow: function(c){ - c.getItemCt().removeClass('x-hide-' + c.hideMode); - - if (c.isComposite) { - c.doLayout(); + + buildUrl: function(request) { + var me = this, + url = me.callParent(arguments), + params = Ext.apply({}, request.params), + filters = params.filters, + records, + filter, i; + + delete params.filters; + + if (me.autoAppendParams) { + url = Ext.urlAppend(url, Ext.Object.toQueryString(params)); } - }, - onFieldHide: function(c){ - c.getItemCt().addClass('x-hide-' + c.hideMode); - }, + if (filters && filters.length) { + for (i = 0; i < filters.length; i++) { + filter = filters[i]; - - getLabelStyle: function(s){ - var ls = '', items = [this.labelStyle, s]; - for (var i = 0, len = items.length; i < len; ++i){ - if (items[i]){ - ls += items[i]; - if (ls.substr(-1, 1) != ';'){ - ls += ';'; + if (filter.value) { + url = Ext.urlAppend(url, filter.property + "=" + filter.value); } } } - return ls; - }, - + + records = request.records; - - renderItem : function(c, position, target){ - if(c && (c.isFormField || c.fieldLabel) && c.inputType != 'hidden'){ - var args = this.getTemplateArgs(c); - if(Ext.isNumber(position)){ - position = target.dom.childNodes[position] || null; - } - if(position){ - c.itemCt = this.fieldTpl.insertBefore(position, args, true); - }else{ - c.itemCt = this.fieldTpl.append(target, args, true); - } - if(!c.getItemCt){ - - - Ext.apply(c, { - getItemCt: function(){ - return c.itemCt; - }, - customItemCt: true - }); - } - c.label = c.getItemCt().child('label.x-form-item-label'); - if(!c.rendered){ - c.render('x-form-el-' + c.id); - }else if(!this.isValidParent(c, target)){ - Ext.fly('x-form-el-' + c.id).appendChild(c.getPositionEl()); - } - if(this.trackLabels){ - if(c.hidden){ - this.onFieldHide(c); - } - c.on({ - scope: this, - show: this.onFieldShow, - hide: this.onFieldHide - }); - } - this.configureItem(c); - }else { - Ext.layout.FormLayout.superclass.renderItem.apply(this, arguments); + if (Ext.isArray(records) && records.length > 0) { + url = Ext.urlAppend(url, Ext.String.format("{0}={1}", me.recordParam, me.encodeRecords(records))); } + + return url; }, - getTemplateArgs: function(field) { - var noLabelSep = !field.fieldLabel || field.hideLabel; - - return { - id : field.id, - label : field.fieldLabel, - itemCls : (field.itemCls || this.container.itemCls || '') + (field.hideLabel ? ' x-hide-label' : ''), - clearCls : field.clearCls || 'x-form-clear-left', - labelStyle : this.getLabelStyle(field.labelStyle), - elementStyle : this.elementStyle || '', - labelSeparator: noLabelSep ? '' : (Ext.isDefined(field.labelSeparator) ? field.labelSeparator : this.labelSeparator) - }; + destroy: function() { + this.abort(); + this.callParent(); }, - adjustWidthAnchor: function(value, c){ - if(c.label && !this.isHide(c) && (this.container.labelAlign != 'top')){ - var adjust = Ext.isIE6 || (Ext.isIE && !Ext.isStrict); - return value - this.labelAdjust + (adjust ? -3 : 0); + abort: function() { + var lastRequest = this.lastRequest; + if (lastRequest) { + Ext.data.JsonP.abort(lastRequest.jsonp); } - return value; }, - adjustHeightAnchor : function(value, c){ - if(c.label && !this.isHide(c) && (this.container.labelAlign == 'top')){ - return value - c.label.getHeight(); + + encodeRecords: function(records) { + var encoded = "", + i = 0, + len = records.length; + + for (; i < len; i++) { + encoded += Ext.Object.toQueryString(records[i].data); } - return value; - }, - - isValidParent : function(c, target){ - return target && this.container.getEl().contains(c.getPositionEl()); + return encoded; } - - }); -Ext.Container.LAYOUTS['form'] = Ext.layout.FormLayout; -Ext.layout.AccordionLayout = Ext.extend(Ext.layout.FitLayout, { - - fill : true, - - autoWidth : true, - - titleCollapse : true, - - hideCollapseTool : false, - - collapseFirst : false, - - animate : false, +Ext.define('Ext.data.proxy.WebStorage', { + extend: 'Ext.data.proxy.Client', + alternateClassName: 'Ext.data.WebStorageProxy', - sequence : false, - activeOnTop : false, - - type: 'accordion', - - renderItem : function(c){ - if(this.animate === false){ - c.animCollapse = false; - } - c.collapsible = true; - if(this.autoWidth){ - c.autoWidth = true; - } - if(this.titleCollapse){ - c.titleCollapse = true; - } - if(this.hideCollapseTool){ - c.hideCollapseTool = true; - } - if(this.collapseFirst !== undefined){ - c.collapseFirst = this.collapseFirst; - } - if(!this.activeItem && !c.collapsed){ - this.setActiveItem(c, true); - }else if(this.activeItem && this.activeItem != c){ - c.collapsed = true; - } - Ext.layout.AccordionLayout.superclass.renderItem.apply(this, arguments); - c.header.addClass('x-accordion-hd'); - c.on('beforeexpand', this.beforeExpand, this); - }, - - onRemove: function(c){ - Ext.layout.AccordionLayout.superclass.onRemove.call(this, c); - if(c.rendered){ - c.header.removeClass('x-accordion-hd'); - } - c.un('beforeexpand', this.beforeExpand, this); - }, + id: undefined, - beforeExpand : function(p, anim){ - var ai = this.activeItem; - if(ai){ - if(this.sequence){ - delete this.activeItem; - if (!ai.collapsed){ - ai.collapse({callback:function(){ - p.expand(anim || true); - }, scope: this}); - return false; - } - }else{ - ai.collapse(this.animate); - } - } - this.setActive(p); - if(this.activeOnTop){ - p.el.dom.parentNode.insertBefore(p.el.dom, p.el.dom.parentNode.firstChild); - } + constructor: function(config) { + this.callParent(arguments); - this.layout(); - }, + + this.cache = {}; - - setItemSize : function(item, size){ - if(this.fill && item){ - var hh = 0, i, ct = this.getRenderedItems(this.container), len = ct.length, p; - - for (i = 0; i < len; i++) { - if((p = ct[i]) != item && !p.hidden){ - hh += p.header.getHeight(); - } - }; - - size.height -= hh; - - - item.setSize(size); + if (this.getStorageObject() === undefined) { + Ext.Error.raise("Local Storage is not supported in this browser, please use another type of data proxy"); } - }, - - setActiveItem : function(item){ - this.setActive(item, true); - }, + + this.id = this.id || (this.store ? this.store.storeId : undefined); - - setActive : function(item, expand){ - var ai = this.activeItem; - item = this.container.getComponent(item); - if(ai != item){ - if(item.rendered && item.collapsed && expand){ - item.expand(); - }else{ - if(ai){ - ai.fireEvent('deactivate', ai); - } - this.activeItem = item; - item.fireEvent('activate', item); - } + 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"); } - } -}); -Ext.Container.LAYOUTS.accordion = Ext.layout.AccordionLayout; - -Ext.layout.Accordion = Ext.layout.AccordionLayout; -Ext.layout.TableLayout = Ext.extend(Ext.layout.ContainerLayout, { - + this.initialize(); + }, - monitorResize:false, - - type: 'table', + create: function(operation, callback, scope) { + var records = operation.records, + length = records.length, + ids = this.getIds(), + id, record, i; + + operation.setStarted(); - targetCls: 'x-table-layout-ct', + for (i = 0; i < length; i++) { + record = records[i]; - - tableAttrs:null, + if (record.phantom) { + record.phantom = false; + id = this.getNextId(); + } else { + id = record.getId(); + } - - setContainer : function(ct){ - Ext.layout.TableLayout.superclass.setContainer.call(this, ct); + this.setRecord(record, id); + ids.push(id); + } - this.currentRow = 0; - this.currentColumn = 0; - this.cells = []; - }, - - - onLayout : function(ct, target){ - var cs = ct.items.items, len = cs.length, c, i; + this.setIds(ids); - if(!this.table){ - target.addClass('x-table-layout-ct'); + operation.setCompleted(); + operation.setSuccessful(); - this.table = target.createChild( - Ext.apply({tag:'table', cls:'x-table-layout', cellspacing: 0, cn: {tag: 'tbody'}}, this.tableAttrs), null, true); + if (typeof callback == 'function') { + callback.call(scope || this, operation); } - this.renderAll(ct, target); }, - getRow : function(index){ - var row = this.table.tBodies[0].childNodes[index]; - if(!row){ - row = document.createElement('tr'); - this.table.tBodies[0].appendChild(row); - } - return row; - }, + read: function(operation, callback, scope) { + - - getNextCell : function(c){ - var cell = this.getNextNonSpan(this.currentColumn, this.currentRow); - var curCol = this.currentColumn = cell[0], curRow = this.currentRow = cell[1]; - for(var rowIndex = curRow; rowIndex < curRow + (c.rowspan || 1); rowIndex++){ - if(!this.cells[rowIndex]){ - this.cells[rowIndex] = []; + var records = [], + ids = this.getIds(), + length = ids.length, + i, recordData, record; + + + if (operation.id) { + record = this.getRecord(operation.id); + + if (record) { + records.push(record); + operation.setSuccessful(); } - for(var colIndex = curCol; colIndex < curCol + (c.colspan || 1); colIndex++){ - this.cells[rowIndex][colIndex] = true; + } else { + for (i = 0; i < length; i++) { + records.push(this.getRecord(ids[i])); } + operation.setSuccessful(); } - var td = document.createElement('td'); - if(c.cellId){ - td.id = c.cellId; - } - var cls = 'x-table-layout-cell'; - if(c.cellCls){ - cls += ' ' + c.cellCls; - } - td.className = cls; - if(c.colspan){ - td.colSpan = c.colspan; - } - if(c.rowspan){ - td.rowSpan = c.rowspan; + + operation.setCompleted(); + + operation.resultSet = Ext.create('Ext.data.ResultSet', { + records: records, + total : records.length, + loaded : true + }); + + if (typeof callback == 'function') { + callback.call(scope || this, operation); } - this.getRow(curRow).appendChild(td); - return td; }, - getNextNonSpan: function(colIndex, rowIndex){ - var cols = this.columns; - while((cols && colIndex >= cols) || (this.cells[rowIndex] && this.cells[rowIndex][colIndex])) { - if(cols && colIndex >= cols){ - rowIndex++; - colIndex = 0; - }else{ - colIndex++; + update: function(operation, callback, scope) { + var records = operation.records, + length = records.length, + ids = this.getIds(), + record, id, i; + + operation.setStarted(); + + for (i = 0; i < length; i++) { + record = records[i]; + this.setRecord(record); + + + + id = record.getId(); + if (id !== undefined && Ext.Array.indexOf(ids, id) == -1) { + ids.push(id); } } - return [colIndex, rowIndex]; - }, + this.setIds(ids); - - renderItem : function(c, position, target){ - - if(!this.table){ - this.table = target.createChild( - Ext.apply({tag:'table', cls:'x-table-layout', cellspacing: 0, cn: {tag: 'tbody'}}, this.tableAttrs), null, true); - } - if(c && !c.rendered){ - c.render(this.getNextCell(c)); - this.configureItem(c); - }else if(c && !this.isValidParent(c, target)){ - var container = this.getNextCell(c); - container.insertBefore(c.getPositionEl().dom, null); - c.container = Ext.get(container); - this.configureItem(c); - } - }, + operation.setCompleted(); + operation.setSuccessful(); - - isValidParent : function(c, target){ - return c.getPositionEl().up('table', 5).dom.parentNode === (target.dom || target); + if (typeof callback == 'function') { + callback.call(scope || this, operation); + } }, - - destroy: function(){ - delete this.table; - Ext.layout.TableLayout.superclass.destroy.call(this); - } -}); - -Ext.Container.LAYOUTS['table'] = Ext.layout.TableLayout; -Ext.layout.AbsoluteLayout = Ext.extend(Ext.layout.AnchorLayout, { + destroy: function(operation, callback, scope) { + var records = operation.records, + length = records.length, + ids = this.getIds(), - extraCls: 'x-abs-layout-item', + + newIds = [].concat(ids), + i; - type: 'absolute', + for (i = 0; i < length; i++) { + Ext.Array.remove(newIds, records[i].getId()); + this.removeRecord(records[i], false); + } - onLayout : function(ct, target){ - target.position(); - this.paddingLeft = target.getPadding('l'); - this.paddingTop = target.getPadding('t'); - Ext.layout.AbsoluteLayout.superclass.onLayout.call(this, ct, target); - }, + this.setIds(newIds); + + operation.setCompleted(); + operation.setSuccessful(); - - adjustWidthAnchor : function(value, comp){ - return value ? value - comp.getPosition(true)[0] + this.paddingLeft : value; + if (typeof callback == 'function') { + callback.call(scope || this, operation); + } }, - adjustHeightAnchor : function(value, comp){ - return value ? value - comp.getPosition(true)[1] + this.paddingTop : value; - } - -}); -Ext.Container.LAYOUTS['absolute'] = Ext.layout.AbsoluteLayout; + getRecord: function(id) { + if (this.cache[id] === undefined) { + var rawData = Ext.decode(this.getStorageObject().getItem(this.getRecordKey(id))), + data = {}, + Model = this.model, + fields = Model.prototype.fields.items, + length = fields.length, + i, field, name, record; -Ext.layout.BoxLayout = Ext.extend(Ext.layout.ContainerLayout, { - - defaultMargins : {left:0,top:0,right:0,bottom:0}, - - padding : '0', - - pack : 'start', + for (i = 0; i < length; i++) { + field = fields[i]; + name = field.name; - - monitorResize : true, - type: 'box', - scrollOffset : 0, - extraCls : 'x-box-item', - targetCls : 'x-box-layout-ct', - innerCls : 'x-box-inner', + if (typeof field.decode == 'function') { + data[name] = field.decode(rawData[name]); + } else { + data[name] = rawData[name]; + } + } - constructor : function(config){ - Ext.layout.BoxLayout.superclass.constructor.call(this, config); + record = new Model(data, id); + record.phantom = false; - if (Ext.isString(this.defaultMargins)) { - this.defaultMargins = this.parseMargins(this.defaultMargins); - } - - var handler = this.overflowHandler; - - if (typeof handler == 'string') { - handler = { - type: handler - }; - } - - var handlerType = 'none'; - if (handler && handler.type != undefined) { - handlerType = handler.type; - } - - var constructor = Ext.layout.boxOverflow[handlerType]; - if (constructor[this.type]) { - constructor = constructor[this.type]; + this.cache[id] = record; } - this.overflowHandler = new constructor(this, handler); + return this.cache[id]; }, - onLayout: function(container, target) { - Ext.layout.BoxLayout.superclass.onLayout.call(this, container, target); + setRecord: function(record, id) { + if (id) { + record.setId(id); + } else { + id = record.getId(); + } - var tSize = this.getLayoutTargetSize(), - items = this.getVisibleItems(container), - calcs = this.calculateChildBoxes(items, tSize), - boxes = calcs.boxes, - meta = calcs.meta; - - - if (tSize.width > 0) { - var handler = this.overflowHandler, - method = meta.tooNarrow ? 'handleOverflow' : 'clearOverflow'; - - var results = handler[method](calcs, tSize); - - if (results) { - if (results.targetSize) { - tSize = results.targetSize; - } - - if (results.recalculate) { - items = this.getVisibleItems(container); - calcs = this.calculateChildBoxes(items, tSize); - boxes = calcs.boxes; - } + var me = this, + rawData = record.data, + data = {}, + model = me.model, + fields = model.prototype.fields.items, + length = fields.length, + i = 0, + field, name, obj, key; + + for (; i < length; i++) { + field = fields[i]; + name = field.name; + + if (typeof field.encode == 'function') { + data[name] = field.encode(rawData[name], record); + } else { + data[name] = rawData[name]; } } + + obj = me.getStorageObject(); + key = me.getRecordKey(id); - this.layoutTargetLastSize = tSize; - - - this.childBoxCache = calcs; + me.cache[id] = record; - this.updateInnerCtSize(tSize, calcs); - this.updateChildBoxes(boxes); - - this.handleTargetOverflow(tSize, container, target); + obj.removeItem(key); + obj.setItem(key, Ext.encode(data)); }, - updateChildBoxes: function(boxes) { - for (var i = 0, length = boxes.length; i < length; i++) { - var box = boxes[i], - comp = box.component; - - if (box.dirtySize) { - comp.setSize(box.width, box.height); - } - - if (isNaN(box.left) || isNaN(box.top)) { - continue; - } + removeRecord: function(id, updateIds) { + var me = this, + ids; - comp.setPosition(box.left, box.top); + if (id.isModel) { + id = id.getId(); } - }, - - updateInnerCtSize: function(tSize, calcs) { - var align = this.align, - padding = this.padding, - width = tSize.width, - height = tSize.height; - - if (this.type == 'hbox') { - var innerCtWidth = width, - innerCtHeight = calcs.meta.maxHeight + padding.top + padding.bottom; - - if (align == 'stretch') { - innerCtHeight = height; - } else if (align == 'middle') { - innerCtHeight = Math.max(height, innerCtHeight); - } - } else { - var innerCtHeight = height, - innerCtWidth = calcs.meta.maxWidth + padding.left + padding.right; - - if (align == 'stretch') { - innerCtWidth = width; - } else if (align == 'center') { - innerCtWidth = Math.max(width, innerCtWidth); - } + if (updateIds !== false) { + ids = me.getIds(); + Ext.Array.remove(ids, id); + me.setIds(ids); } - this.innerCt.setSize(innerCtWidth || undefined, innerCtHeight || undefined); + me.getStorageObject().removeItem(me.getRecordKey(id)); }, - handleTargetOverflow: function(previousTargetSize, container, target) { - var overflow = target.getStyle('overflow'); - - if (overflow && overflow != 'hidden' &&!this.adjustmentPass) { - var newTargetSize = this.getLayoutTargetSize(); - if (newTargetSize.width != previousTargetSize.width || newTargetSize.height != previousTargetSize.height){ - this.adjustmentPass = true; - this.onLayout(container, target); - } + getRecordKey: function(id) { + if (id.isModel) { + id = id.getId(); } - delete this.adjustmentPass; + return Ext.String.format("{0}-{1}", this.id, id); }, - isValidParent : function(c, target) { - return this.innerCt && c.getPositionEl().dom.parentNode == this.innerCt.dom; + getRecordCounterKey: function() { + return Ext.String.format("{0}-counter", this.id); }, - getVisibleItems: function(ct) { - var ct = ct || this.container, - t = ct.getLayoutTarget(), - cti = ct.items.items, - len = cti.length, - - i, c, items = []; + getIds: function() { + var ids = (this.getStorageObject().getItem(this.id) || "").split(","), + length = ids.length, + i; - for (i = 0; i < len; i++) { - if((c = cti[i]).rendered && this.isValidParent(c, t) && c.hidden !== true && c.collapsed !== true && c.shouldLayout !== false){ - items.push(c); + if (length == 1 && ids[0] === "") { + ids = []; + } else { + for (i = 0; i < length; i++) { + ids[i] = parseInt(ids[i], 10); } } - return items; + return ids; }, - renderAll : function(ct, target) { - if (!this.innerCt) { - - this.innerCt = target.createChild({cls:this.innerCls}); - this.padding = this.parseMargins(this.padding); + setIds: function(ids) { + var obj = this.getStorageObject(), + str = ids.join(","); + + obj.removeItem(this.id); + + if (!Ext.isEmpty(str)) { + obj.setItem(this.id, str); } - Ext.layout.BoxLayout.superclass.renderAll.call(this, ct, this.innerCt); }, - getLayoutTargetSize : function() { - var target = this.container.getLayoutTarget(), ret; + + getNextId: function() { + var obj = this.getStorageObject(), + key = this.getRecordCounterKey(), + last = obj.getItem(key), + ids, id; - if (target) { - ret = target.getViewSize(); - - - - - if (Ext.isIE && Ext.isStrict && ret.width == 0){ - ret = target.getStyleSize(); - } - - ret.width -= target.getPadding('lr'); - ret.height -= target.getPadding('tb'); + if (last === null) { + ids = this.getIds(); + last = ids[ids.length - 1] || 0; } - return ret; + id = parseInt(last, 10) + 1; + obj.setItem(key, id); + + return id; }, - renderItem : function(c) { - if(Ext.isString(c.margins)){ - c.margins = this.parseMargins(c.margins); - }else if(!c.margins){ - c.margins = this.defaultMargins; - } - Ext.layout.BoxLayout.superclass.renderItem.apply(this, arguments); + initialize: function() { + var storageObject = this.getStorageObject(); + storageObject.setItem(this.id, storageObject.getItem(this.id) || ""); }, + - - destroy: function() { - Ext.destroy(this.overflowHandler); + clear: function() { + var obj = this.getStorageObject(), + ids = this.getIds(), + len = ids.length, + i; + + + for (i = 0; i < len; i++) { + this.removeRecord(ids[i]); + } + - Ext.layout.BoxLayout.superclass.destroy.apply(this, arguments); + obj.removeItem(this.getRecordCounterKey()); + obj.removeItem(this.id); + }, + + + getStorageObject: function() { + Ext.Error.raise("The getStorageObject function has not been defined in your Ext.data.proxy.WebStorage subclass"); } }); +Ext.define('Ext.data.proxy.LocalStorage', { + extend: 'Ext.data.proxy.WebStorage', + alias: 'proxy.localstorage', + alternateClassName: 'Ext.data.LocalStorageProxy', + + + getStorageObject: function() { + return window.localStorage; + } +}); +Ext.define('Ext.data.proxy.Memory', { + extend: 'Ext.data.proxy.Client', + alias: 'proxy.memory', + alternateClassName: 'Ext.data.MemoryProxy', -Ext.ns('Ext.layout.boxOverflow'); - + + constructor: function(config) { + this.callParent([config]); -Ext.layout.boxOverflow.None = Ext.extend(Object, { - constructor: function(layout, config) { - this.layout = layout; - Ext.apply(this, config || {}); + this.setReader(this.reader); }, + - handleOverflow: Ext.emptyFn, - - clearOverflow: Ext.emptyFn -}); + read: function(operation, callback, scope) { + var me = this, + reader = me.getReader(), + result = reader.read(me.data); + + Ext.apply(operation, { + resultSet: result + }); + + operation.setCompleted(); + operation.setSuccessful(); + Ext.callback(callback, scope || me, [operation]); + }, + clear: Ext.emptyFn +}); -Ext.layout.boxOverflow.none = Ext.layout.boxOverflow.None; -Ext.layout.boxOverflow.Menu = Ext.extend(Ext.layout.boxOverflow.None, { +Ext.define('Ext.data.proxy.Rest', { + extend: 'Ext.data.proxy.Ajax', + alternateClassName: 'Ext.data.RestProxy', + alias : 'proxy.rest', - afterCls: 'x-strip-right', + appendId: true, - noItemsMenuText : '
(None)
', - constructor: function(layout) { - Ext.layout.boxOverflow.Menu.superclass.constructor.apply(this, arguments); - - - this.menuItems = []; - }, - createInnerElements: function() { - if (!this.afterCt) { - this.afterCt = this.layout.innerCt.insertSibling({cls: this.afterCls}, 'before'); - } - }, + batchActions: false, - clearOverflow: function(calculations, targetSize) { - var newWidth = targetSize.width + (this.afterCt ? this.afterCt.getWidth() : 0), - items = this.menuItems; + buildUrl: function(request) { + var me = this, + operation = request.operation, + records = operation.records || [], + record = records[0], + format = me.format, + url = me.getUrl(request), + id = record ? record.getId() : operation.id; - this.hideTrigger(); - - for (var index = 0, length = items.length; index < length; index++) { - items.pop().component.show(); + if (me.appendId && id) { + if (!url.match(/\/$/)) { + url += '/'; + } + + url += id; } - return { - targetSize: { - height: targetSize.height, - width : newWidth + if (format) { + if (!url.match(/\.$/)) { + url += '.'; } - }; - }, - + + url += format; + } + + request.url = url; + + return me.callParent(arguments); + } +}, function() { + Ext.apply(this.prototype, { + + actionMethods: { + create : 'POST', + read : 'GET', + update : 'PUT', + destroy: 'DELETE' + } + }); +}); + + +Ext.define('Ext.data.proxy.SessionStorage', { + extend: 'Ext.data.proxy.WebStorage', + alias: 'proxy.sessionstorage', + alternateClassName: 'Ext.data.SessionStorageProxy', - showTrigger: function() { - this.createMenu(); - this.menuTrigger.show(); - }, + getStorageObject: function() { + return window.sessionStorage; + } +}); + + +Ext.define('Ext.data.reader.Array', { + extend: 'Ext.data.reader.Json', + alternateClassName: 'Ext.data.ArrayReader', + alias : 'reader.array', + - hideTrigger: function() { - if (this.menuTrigger != undefined) { - this.menuTrigger.hide(); + buildExtractors: function() { + this.callParent(arguments); + + var fields = this.model.prototype.fields.items, + length = fields.length, + extractorFunctions = [], + i; + + for (i = 0; i < length; i++) { + extractorFunctions.push(function(index) { + return function(data) { + return data[index]; + }; + }(fields[i].mapping || i)); } - }, + + this.extractorFunctions = extractorFunctions; + } +}); + + +Ext.define('Ext.data.reader.Xml', { + extend: 'Ext.data.reader.Reader', + alternateClassName: 'Ext.data.XmlReader', + alias : 'reader.xml', - beforeMenuShow: function(menu) { - var items = this.menuItems, - len = items.length, - item, - prev; - var needsSep = function(group, item){ - return group.isXType('buttongroup') && !(item instanceof Ext.Toolbar.Separator); + + + createAccessor: function() { + var selectValue = function(expr, root){ + var node = Ext.DomQuery.selectNode(expr, root), + val; + + + }; - - this.clearMenu(); - menu.removeAll(); - - for (var i = 0; i < len; i++) { - item = items[i].component; + + return function(expr) { + var me = this; - if (prev && (needsSep(item, prev) || needsSep(prev, item))) { - menu.add('-'); + if (Ext.isEmpty(expr)) { + return Ext.emptyFn; } - this.addComponentToMenu(menu, item); - prev = item; - } - - - if (menu.items.length < 1) { - menu.add(this.noItemsMenuText); + 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; + }; + }; + }(), + + getNodeValue: function(node) { + var val; + if (node && node.firstChild) { + val = node.firstChild.nodeValue; } + return val || null; }, - - - createMenuConfig : function(component, hideOnClick){ - var config = Ext.apply({}, component.initialConfig), - group = component.toggleGroup; - Ext.copyTo(config, component, [ - 'iconCls', 'icon', 'itemId', 'disabled', 'handler', 'scope', 'menu' - ]); - - Ext.apply(config, { - text : component.overflowText || component.text, - hideOnClick: hideOnClick - }); + + getResponseData: function(response) { + var xml = response.responseXML; - if (group || component.enableToggle) { - Ext.apply(config, { - group : group, - checked: component.pressed, - listeners: { - checkchange: function(item, checked){ - component.toggle(checked); - } - } + if (!xml) { + Ext.Error.raise({ + response: response, + msg: 'XML data not found in the response' }); } - delete config.ownerCt; - delete config.xtype; - delete config.id; - - return config; + return xml; }, - addComponentToMenu : function(menu, component) { - if (component instanceof Ext.Toolbar.Separator) { - menu.add('-'); - - } else if (Ext.isFunction(component.isXType)) { - if (component.isXType('splitbutton')) { - menu.add(this.createMenuConfig(component, true)); + getData: function(data) { + return data.documentElement || data; + }, - } else if (component.isXType('button')) { - menu.add(this.createMenuConfig(component, !component.menu)); + + getRoot: function(data) { + var nodeName = data.nodeName, + root = this.root; + + if (!root || (nodeName && nodeName == root)) { + return data; + } else if (Ext.DomQuery.isXml(data)) { + + + + return Ext.DomQuery.selectNode(root, data); + } + }, - } else if (component.isXType('buttongroup')) { - component.items.each(function(item){ - this.addComponentToMenu(menu, item); - }, this); - } + + 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 { + root = [root]; } + return this.callParent([root]); + }, + + + getAssociatedDataRoot: function(data, associationName) { + return Ext.DomQuery.select(associationName, data)[0]; }, + + + readRecords: function(doc) { + + if (Ext.isArray(doc)) { + doc = doc[0]; + } + + + this.xmlData = doc; + return this.callParent([doc]); + } +}); + + +Ext.define('Ext.data.writer.Xml', { + + + + extend: 'Ext.data.writer.Writer', + alternateClassName: 'Ext.data.XmlWriter', + + alias: 'writer.xml', - clearMenu : function(){ - var menu = this.moreMenu; - if (menu && menu.items) { - menu.items.each(function(item){ - delete item.menu; - }); - } - }, - createMenu: function() { - if (!this.menuTrigger) { - this.createInnerElements(); - - - this.menu = new Ext.menu.Menu({ - ownerCt : this.layout.container, - listeners: { - scope: this, - beforeshow: this.beforeMenuShow - } - }); - - - this.menuTrigger = new Ext.Button({ - iconCls : 'x-toolbar-more-icon', - cls : 'x-toolbar-more', - menu : this.menu, - renderTo: this.afterCt - }); - } - }, + documentRoot: 'xmlData', - destroy: function() { - Ext.destroy(this.menu, this.menuTrigger); - } -}); - -Ext.layout.boxOverflow.menu = Ext.layout.boxOverflow.Menu; + defaultDocumentRoot: 'xmlData', + + header: '', + + record: 'record', -Ext.layout.boxOverflow.HorizontalMenu = Ext.extend(Ext.layout.boxOverflow.Menu, { - constructor: function() { - Ext.layout.boxOverflow.HorizontalMenu.superclass.constructor.apply(this, arguments); - + writeRecords: function(request, data) { var me = this, - layout = me.layout, - origFunction = layout.calculateChildBoxes; - - layout.calculateChildBoxes = function(visibleItems, targetSize) { - var calcs = origFunction.apply(layout, arguments), - meta = calcs.meta, - items = me.menuItems; - - - - var hiddenWidth = 0; - for (var index = 0, length = items.length; index < length; index++) { - hiddenWidth += items[index].width; - } - - meta.minimumWidth += hiddenWidth; - meta.tooNarrow = meta.minimumWidth > targetSize.width; + xml = [], + i = 0, + len = data.length, + root = me.documentRoot, + record = me.record, + needsRoot = data.length !== 1, + item, + key; - return calcs; - }; - }, - - handleOverflow: function(calculations, targetSize) { - this.showTrigger(); - var newWidth = targetSize.width - this.afterCt.getWidth(), - boxes = calculations.boxes, - usedWidth = 0, - recalculate = false; + xml.push(me.header || ''); - - for (var index = 0, length = boxes.length; index < length; index++) { - usedWidth += boxes[index].width; + if (!root && needsRoot) { + root = me.defaultDocumentRoot; } - var spareWidth = newWidth - usedWidth, - showCount = 0; - - - for (var index = 0, length = this.menuItems.length; index < length; index++) { - var hidden = this.menuItems[index], - comp = hidden.component, - width = hidden.width; - - if (width < spareWidth) { - comp.show(); - - spareWidth -= width; - showCount ++; - recalculate = true; - } else { - break; - } + if (root) { + xml.push('<', root, '>'); } - - if (recalculate) { - this.menuItems = this.menuItems.slice(showCount); - } else { - for (var i = boxes.length - 1; i >= 0; i--) { - var item = boxes[i].component, - right = boxes[i].left + boxes[i].width; - - if (right >= newWidth) { - this.menuItems.unshift({ - component: item, - width : boxes[i].width - }); - - item.hide(); - } else { - break; + + for (; i < len; ++i) { + item = data[i]; + xml.push('<', record, '>'); + for (key in item) { + if (item.hasOwnProperty(key)) { + xml.push('<', key, '>', item[key], ''); } } + xml.push(''); } - if (this.menuItems.length == 0) { - this.hideTrigger(); + if (root) { + xml.push(''); } - - return { - targetSize: { - height: targetSize.height, - width : newWidth - }, - recalculate: recalculate - }; + + request.xmlData = xml.join(''); + return request; } }); -Ext.layout.boxOverflow.menu.hbox = Ext.layout.boxOverflow.HorizontalMenu; -Ext.layout.boxOverflow.Scroller = Ext.extend(Ext.layout.boxOverflow.None, { - - animateScroll: true, + +Ext.define('Ext.direct.Event', { - scrollIncrement: 100, + + alias: 'direct.event', + requires: ['Ext.direct.Manager'], - wheelIncrement: 3, + + status: true, - scrollRepeatInterval: 400, + constructor: function(config) { + Ext.apply(this, config); + }, - scrollDuration: 0.4, + getData: function(){ + return this.data; + } +}); + + +Ext.define('Ext.direct.RemotingEvent', { - beforeCls: 'x-strip-left', + + extend: 'Ext.direct.Event', + alias: 'direct.rpc', - afterCls: 'x-strip-right', - scrollerCls: 'x-strip-scroller', + getTransaction: function(){ + return this.transaction || Ext.direct.Manager.getTransaction(this.tid); + } +}); + + +Ext.define('Ext.direct.ExceptionEvent', { - beforeScrollerCls: 'x-strip-scroller-left', + + extend: 'Ext.direct.RemotingEvent', - afterScrollerCls: 'x-strip-scroller-right', + alias: 'direct.exception', - createWheelListener: function() { - this.layout.innerCt.on({ - scope : this, - mousewheel: function(e) { - e.stopEvent(); + + status: false +}); - this.scrollBy(e.getWheelDelta() * this.wheelIncrement * -1, false); - } - }); - }, + +Ext.define('Ext.direct.Provider', { - handleOverflow: function(calculations, targetSize) { - this.createInnerElements(); - this.showScrollers(); + + alias: 'direct.provider', + + mixins: { + observable: 'Ext.util.Observable' }, + + + - clearOverflow: function() { - this.hideScrollers(); + constructor : function(config){ + var me = this; + + Ext.apply(me, config); + me.addEvents( + + 'connect', + + 'disconnect', + + 'data', + + 'exception' + ); + me.mixins.observable.constructor.call(me, config); }, - showScrollers: function() { - this.createScrollers(); - - this.beforeScroller.show(); - this.afterScroller.show(); - - this.updateScrollButtons(); + isConnected: function(){ + return false; }, + + + connect: Ext.emptyFn, - hideScrollers: function() { - if (this.beforeScroller != undefined) { - this.beforeScroller.hide(); - this.afterScroller.hide(); + disconnect: Ext.emptyFn +}); + + + +Ext.define('Ext.direct.JsonProvider', { + + + + extend: 'Ext.direct.Provider', + + alias: 'direct.jsonprovider', + + uses: ['Ext.direct.ExceptionEvent'], + + + + + parseResponse: function(response){ + if (!Ext.isEmpty(response.responseText)) { + if (Ext.isObject(response.responseText)) { + return response.responseText; + } + return Ext.decode(response.responseText); } + return null; }, + - - createScrollers: function() { - if (!this.beforeScroller && !this.afterScroller) { - var before = this.beforeCt.createChild({ - cls: String.format("{0} {1} ", this.scrollerCls, this.beforeScrollerCls) - }); - - var after = this.afterCt.createChild({ - cls: String.format("{0} {1}", this.scrollerCls, this.afterScrollerCls) - }); - - before.addClassOnOver(this.beforeScrollerCls + '-hover'); - after.addClassOnOver(this.afterScrollerCls + '-hover'); - - before.setVisibilityMode(Ext.Element.DISPLAY); - after.setVisibilityMode(Ext.Element.DISPLAY); - - this.beforeRepeater = new Ext.util.ClickRepeater(before, { - interval: this.scrollRepeatInterval, - handler : this.scrollLeft, - scope : this - }); + createEvents: function(response){ + var data = null, + events = [], + event, + i = 0, + len; - this.afterRepeater = new Ext.util.ClickRepeater(after, { - interval: this.scrollRepeatInterval, - handler : this.scrollRight, - scope : this + try{ + data = this.parseResponse(response); + } catch(e) { + event = Ext.create('Ext.direct.ExceptionEvent', { + data: e, + xhr: response, + code: Ext.direct.Manager.self.exceptions.PARSE, + message: 'Error parsing json response: \n\n ' + data }); - - - this.beforeScroller = before; - - - this.afterScroller = after; + return [event]; + } + + if (Ext.isArray(data)) { + for (len = data.length; i < len; ++i) { + events.push(this.createEvent(data[i])); + } + } else { + events.push(this.createEvent(data)); } + return events; }, - destroy: function() { - Ext.destroy(this.beforeScroller, this.afterScroller, this.beforeRepeater, this.afterRepeater, this.beforeCt, this.afterCt); - }, + createEvent: function(response){ + return Ext.create('direct.' + response.type, response); + } +}); + +Ext.define('Ext.direct.PollingProvider', { - scrollBy: function(delta, animate) { - this.scrollTo(this.getScrollPosition() + delta, animate); - }, + extend: 'Ext.direct.JsonProvider', - getItem: function(item) { - if (Ext.isString(item)) { - item = Ext.getCmp(item); - } else if (Ext.isNumber(item)) { - item = this.items[item]; - } - - return item; - }, + alias: 'direct.pollingprovider', + uses: ['Ext.direct.ExceptionEvent'], - getScrollAnim: function() { - return { - duration: this.scrollDuration, - callback: this.updateScrollButtons, - scope : this - }; - }, + requires: ['Ext.Ajax', 'Ext.util.DelayedTask'], - updateScrollButtons: function() { - if (this.beforeScroller == undefined || this.afterScroller == undefined) { - return; - } - - var beforeMeth = this.atExtremeBefore() ? 'addClass' : 'removeClass', - afterMeth = this.atExtremeAfter() ? 'addClass' : 'removeClass', - beforeCls = this.beforeScrollerCls + '-disabled', - afterCls = this.afterScrollerCls + '-disabled'; - - this.beforeScroller[beforeMeth](beforeCls); - this.afterScroller[afterMeth](afterCls); - this.scrolling = false; - }, - atExtremeBefore: function() { - return this.getScrollPosition() === 0; - }, + interval: 3000, + - scrollLeft: function(animate) { - this.scrollBy(-this.scrollIncrement, animate); - }, + - scrollRight: function(animate) { - this.scrollBy(this.scrollIncrement, animate); + constructor : function(config){ + this.callParent(arguments); + this.addEvents( + + 'beforepoll', + + 'poll' + ); }, + + isConnected: function(){ + return !!this.pollTask; + }, + - scrollToItem: function(item, animate) { - item = this.getItem(item); + connect: function(){ + var me = this, url = me.url; - if (item != undefined) { - var visibility = this.getItemVisibility(item); - - if (!visibility.fullyVisible) { - var box = item.getBox(true, true), - newX = box.x; - - if (visibility.hiddenRight) { - newX -= (this.layout.innerCt.getWidth() - box.width); - } - - this.scrollTo(newX, animate); - } + if (url && !me.pollTask) { + me.pollTask = Ext.TaskManager.start({ + run: function(){ + if (me.fireEvent('beforepoll', me) !== false) { + if (Ext.isFunction(url)) { + url(me.baseParams); + } else { + Ext.Ajax.request({ + url: url, + callback: me.onData, + scope: me, + params: me.baseParams + }); + } + } + }, + interval: me.interval, + scope: me + }); + me.fireEvent('connect', me); + } else if (!url) { + Ext.Error.raise('Error initializing PollingProvider, no url configured.'); } }, - - - getItemVisibility: function(item) { - var box = this.getItem(item).getBox(true, true), - itemLeft = box.x, - itemRight = box.x + box.width, - scrollLeft = this.getScrollPosition(), - scrollRight = this.layout.innerCt.getWidth() + scrollLeft; - - return { - hiddenLeft : itemLeft < scrollLeft, - hiddenRight : itemRight > scrollRight, - fullyVisible: itemLeft > scrollLeft && itemRight < scrollRight - }; - } -}); -Ext.layout.boxOverflow.scroller = Ext.layout.boxOverflow.Scroller; - - - -Ext.layout.boxOverflow.VerticalScroller = Ext.extend(Ext.layout.boxOverflow.Scroller, { - scrollIncrement: 75, - wheelIncrement : 2, - handleOverflow: function(calculations, targetSize) { - Ext.layout.boxOverflow.VerticalScroller.superclass.handleOverflow.apply(this, arguments); + disconnect: function(){ + var me = this; - return { - targetSize: { - height: targetSize.height - (this.beforeCt.getHeight() + this.afterCt.getHeight()), - width : targetSize.width - } - }; + if (me.pollTask) { + Ext.TaskManager.stop(me.pollTask); + delete me.pollTask; + me.fireEvent('disconnect', me); + } }, + - - createInnerElements: function() { - var target = this.layout.innerCt; - - + onData: function(opt, success, response){ + var me = this, + i = 0, + len, + events; - if (!this.beforeCt) { - this.beforeCt = target.insertSibling({cls: this.beforeCls}, 'before'); - this.afterCt = target.insertSibling({cls: this.afterCls}, 'after'); + if (success) { + events = me.createEvents(response); + for (len = events.length; i < len; ++i) { + me.fireEvent('data', me, events[i]); + } + } else { + me.fireEvent('data', me, Ext.create('Ext.direct.ExceptionEvent', { + data: null, + code: Ext.direct.Manager.self.exceptions.TRANSPORT, + message: 'Unable to connect to the server.', + xhr: response + })); + } + } +}); - this.createWheelListener(); +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)) { + + me.len = params; + me.ordered = true; + } else { + + me.params = []; + Ext.each(params, function(param){ + name = Ext.isObject(param) ? param.name : param; + me.params.push(name); + }); } }, - scrollTo: function(position, animate) { - var oldPosition = this.getScrollPosition(), - newPosition = position.constrain(0, this.getMaxScrollBottom()); - - if (newPosition != oldPosition && !this.scrolling) { - if (animate == undefined) { - animate = this.animateScroll; + getCallData: function(args){ + var me = this, + data = null, + len = me.len, + params = me.params, + callback, + scope, + name; + + if (me.ordered) { + callback = args[len]; + scope = args[len + 1]; + if (len !== 0) { + data = args.slice(0, len); } + } else { + data = Ext.apply({}, args[0]); + callback = args[1]; + scope = args[2]; - this.layout.innerCt.scrollTo('top', newPosition, animate ? this.getScrollAnim() : false); - if (animate) { - this.scrolling = true; - } else { - this.scrolling = false; - this.updateScrollButtons(); + for (name in data) { + if (data.hasOwnProperty(name)) { + if (!Ext.Array.contains(params, name)) { + delete data[name]; + } + } } } - }, + + return { + data: data, + callback: callback, + scope: scope + }; + } +}); + + +Ext.define('Ext.direct.Transaction', { - getScrollPosition: function(){ - return parseInt(this.layout.innerCt.dom.scrollTop, 10) || 0; + + alias: 'direct.transaction', + alternateClassName: 'Ext.Direct.Transaction', + + statics: { + TRANSACTION_ID: 0 }, + - - getMaxScrollBottom: function() { - return this.layout.innerCt.dom.scrollHeight - this.layout.innerCt.getHeight(); + + constructor: function(config){ + var me = this; + + Ext.apply(me, config); + me.id = ++me.self.TRANSACTION_ID; + me.retryCount = 0; + }, + + send: function(){ + this.provider.queueTransaction(this); }, - - - atExtremeAfter: function() { - return this.getScrollPosition() >= this.getMaxScrollBottom(); - } -}); -Ext.layout.boxOverflow.scroller.vbox = Ext.layout.boxOverflow.VerticalScroller; + retry: function(){ + this.retryCount++; + this.send(); + }, + getProvider: function(){ + return this.provider; + } +}); -Ext.layout.boxOverflow.HorizontalScroller = Ext.extend(Ext.layout.boxOverflow.Scroller, { - handleOverflow: function(calculations, targetSize) { - Ext.layout.boxOverflow.HorizontalScroller.superclass.handleOverflow.apply(this, arguments); - - return { - targetSize: { - height: targetSize.height, - width : targetSize.width - (this.beforeCt.getWidth() + this.afterCt.getWidth()) - } - }; - }, +Ext.define('Ext.direct.RemotingProvider', { - createInnerElements: function() { - var target = this.layout.innerCt; - - - - if (!this.beforeCt) { - this.afterCt = target.insertSibling({cls: this.afterCls}, 'before'); - this.beforeCt = target.insertSibling({cls: this.beforeCls}, 'before'); - - this.createWheelListener(); - } + + alias: 'direct.remotingprovider', + + extend: 'Ext.direct.JsonProvider', + + requires: [ + 'Ext.util.MixedCollection', + 'Ext.util.DelayedTask', + 'Ext.direct.Transaction', + 'Ext.direct.RemotingMethod' + ], + + + + + + + + + + + + + enableBuffer: 10, + + + maxRetries: 1, + + + timeout: undefined, + + constructor : function(config){ + var me = this; + me.callParent(arguments); + me.addEvents( + + 'beforecall', + + 'call' + ); + me.namespace = (Ext.isString(me.namespace)) ? Ext.ns(me.namespace) : me.namespace || window; + me.transactions = Ext.create('Ext.util.MixedCollection'); + me.callBuffer = []; }, - scrollTo: function(position, animate) { - var oldPosition = this.getScrollPosition(), - newPosition = position.constrain(0, this.getMaxScrollRight()); - - if (newPosition != oldPosition && !this.scrolling) { - if (animate == undefined) { - animate = this.animateScroll; - } + initAPI : function(){ + var actions = this.actions, + namespace = this.namespace, + action, + cls, + methods, + i, + len, + method; - this.layout.innerCt.scrollTo('left', newPosition, animate ? this.getScrollAnim() : false); + for (action in actions) { + cls = namespace[action]; + if (!cls) { + cls = namespace[action] = {}; + } + methods = actions[action]; - if (animate) { - this.scrolling = true; - } else { - this.scrolling = false; - this.updateScrollButtons(); + for (i = 0, len = methods.length; i < len; ++i) { + method = Ext.create('Ext.direct.RemotingMethod', methods[i]); + cls[method.name] = this.createHandler(action, method); } } }, - getScrollPosition: function(){ - return parseInt(this.layout.innerCt.dom.scrollLeft, 10) || 0; + createHandler : function(action, method){ + var me = this, + handler; + + if (!method.formHandler) { + handler = function(){ + me.configureRequest(action, method, Array.prototype.slice.call(arguments, 0)); + }; + } else { + handler = function(form, callback, scope){ + me.configureFormRequest(action, method, form, callback, scope); + }; + } + handler.directCfg = { + action: action, + method: method + }; + return handler; }, - getMaxScrollRight: function() { - return this.layout.innerCt.dom.scrollWidth - this.layout.innerCt.getWidth(); + isConnected: function(){ + return !!this.connected; }, - - - atExtremeAfter: function() { - return this.getScrollPosition() >= this.getMaxScrollRight(); - } -}); -Ext.layout.boxOverflow.scroller.hbox = Ext.layout.boxOverflow.HorizontalScroller; -Ext.layout.HBoxLayout = Ext.extend(Ext.layout.BoxLayout, { - align: 'top', - - type : 'hbox', + connect: function(){ + var me = this; + + if (me.url) { + me.initAPI(); + me.connected = true; + me.fireEvent('connect', me); + } else if(!me.url) { + Ext.Error.raise('Error initializing RemotingProvider, no url configured.'); + } + }, + disconnect: function(){ + var me = this; + + if (me.connected) { + me.connected = false; + me.fireEvent('disconnect', me); + } + }, - - calculateChildBoxes: function(visibleItems, targetSize) { - var visibleCount = visibleItems.length, - - padding = this.padding, - topOffset = padding.top, - leftOffset = padding.left, - paddingVert = topOffset + padding.bottom, - paddingHoriz = leftOffset + padding.right, - - width = targetSize.width - this.scrollOffset, - height = targetSize.height, - availHeight = Math.max(0, height - paddingVert), - - isStart = this.pack == 'start', - isCenter = this.pack == 'center', - isEnd = this.pack == 'end', - - nonFlexWidth = 0, - maxHeight = 0, - totalFlex = 0, - desiredWidth = 0, - minimumWidth = 0, - - - boxes = [], - - - child, childWidth, childHeight, childSize, childMargins, canLayout, i, calcs, flexedWidth, - horizMargins, vertMargins, stretchHeight; - + runCallback: function(transaction, event){ + var funcName = event.status ? 'success' : 'failure', + callback, + result; - for (i = 0; i < visibleCount; i++) { - child = visibleItems[i]; - childHeight = child.height; - childWidth = child.width; - canLayout = !child.hasLayout && typeof child.doLayout == 'function'; - - - if (typeof childWidth != 'number') { - - - if (child.flex && !childWidth) { - totalFlex += child.flex; - - - } else { - - - if (!childWidth && canLayout) { - child.doLayout(); - } - - childSize = child.getSize(); - childWidth = childSize.width; - childHeight = childSize.height; - } - } - - childMargins = child.margins; - horizMargins = childMargins.left + childMargins.right; - - nonFlexWidth += horizMargins + (childWidth || 0); - desiredWidth += horizMargins + (child.flex ? child.minWidth || 0 : childWidth); - minimumWidth += horizMargins + (child.minWidth || childWidth || 0); - - - if (typeof childHeight != 'number') { - if (canLayout) { - child.doLayout(); - } - childHeight = child.getHeight(); + if (transaction && transaction.callback) { + callback = transaction.callback; + result = Ext.isDefined(event.result) ? event.result : event.data; + + if (Ext.isFunction(callback)) { + callback(result, event); + } else { + Ext.callback(callback[funcName], callback.scope, [result, event]); + Ext.callback(callback.callback, callback.scope, [result, event]); } - - maxHeight = Math.max(maxHeight, childHeight + childMargins.top + childMargins.bottom); - - - boxes.push({ - component: child, - height : childHeight || undefined, - width : childWidth || undefined - }); } - - var shortfall = desiredWidth - width, - tooNarrow = minimumWidth > width; - - - var availableWidth = Math.max(0, width - nonFlexWidth - paddingHoriz); - - if (tooNarrow) { - for (i = 0; i < visibleCount; i++) { - boxes[i].width = visibleItems[i].minWidth || visibleItems[i].width || boxes[i].width; + }, + + + onData: function(options, success, response){ + var me = this, + i = 0, + len, + events, + event, + transaction, + transactions; + + if (success) { + events = me.createEvents(response); + for (len = events.length; i < len; ++i) { + event = events[i]; + transaction = me.getTransaction(event); + me.fireEvent('data', me, event); + if (transaction) { + me.runCallback(transaction, event, true); + Ext.direct.Manager.removeTransaction(transaction); + } } } else { - - - if (shortfall > 0) { - var minWidths = []; - - - for (var index = 0, length = visibleCount; index < length; index++) { - var item = visibleItems[index], - minWidth = item.minWidth || 0; - - - - if (item.flex) { - boxes[index].width = minWidth; - } else { - minWidths.push({ - minWidth : minWidth, - available: boxes[index].width - minWidth, - index : index - }); - } - } - - - minWidths.sort(function(a, b) { - return a.available > b.available ? 1 : -1; - }); - - - for (var i = 0, length = minWidths.length; i < length; i++) { - var itemIndex = minWidths[i].index; - - if (itemIndex == undefined) { - continue; + transactions = [].concat(options.transaction); + for (len = transactions.length; i < len; ++i) { + transaction = me.getTransaction(transactions[i]); + if (transaction && transaction.retryCount < me.maxRetries) { + transaction.retry(); + } else { + event = Ext.create('Ext.direct.ExceptionEvent', { + data: null, + transaction: transaction, + code: Ext.direct.Manager.self.exceptions.TRANSPORT, + message: 'Unable to connect to the server.', + xhr: response + }); + me.fireEvent('data', me, event); + if (transaction) { + me.runCallback(transaction, event, false); + Ext.direct.Manager.removeTransaction(transaction); } - - var item = visibleItems[itemIndex], - box = boxes[itemIndex], - oldWidth = box.width, - minWidth = item.minWidth, - newWidth = Math.max(minWidth, oldWidth - Math.ceil(shortfall / (length - i))), - reduction = oldWidth - newWidth; - - boxes[itemIndex].width = newWidth; - shortfall -= reduction; } - } else { - - var remainingWidth = availableWidth, - remainingFlex = totalFlex; - - - for (i = 0; i < visibleCount; i++) { - child = visibleItems[i]; - calcs = boxes[i]; - - childMargins = child.margins; - vertMargins = childMargins.top + childMargins.bottom; + } + } + }, + + + getTransaction: function(options){ + return options && options.tid ? Ext.direct.Manager.getTransaction(options.tid) : null; + }, + + + configureRequest: function(action, method, args){ + var me = this, + callData = method.getCallData(args), + data = callData.data, + callback = callData.callback, + scope = callData.scope, + transaction; + + transaction = Ext.create('Ext.direct.Transaction', { + provider: me, + args: args, + action: action, + method: method.name, + data: data, + callback: scope && Ext.isFunction(callback) ? Ext.Function.bind(callback, scope) : callback + }); - if (isStart && child.flex && !child.width) { - flexedWidth = Math.ceil((child.flex / remainingFlex) * remainingWidth); - remainingWidth -= flexedWidth; - remainingFlex -= child.flex; + if (me.fireEvent('beforecall', me, transaction, method) !== false) { + Ext.direct.Manager.addTransaction(transaction); + me.queueTransaction(transaction); + me.fireEvent('call', me, transaction, method); + } + }, + + + getCallData: function(transaction){ + return { + action: transaction.action, + method: transaction.method, + data: transaction.data, + type: 'rpc', + tid: transaction.id + }; + }, + + + sendRequest : function(data){ + var me = this, + request = { + url: me.url, + callback: me.onData, + scope: me, + transaction: data, + timeout: me.timeout + }, callData, + enableUrlEncode = me.enableUrlEncode, + i = 0, + len, + params; + - calcs.width = flexedWidth; - calcs.dirtySize = true; - } - } + if (Ext.isArray(data)) { + callData = []; + for (len = data.length; i < len; ++i) { + callData.push(me.getCallData(data[i])); } + } else { + callData = me.getCallData(data); } - - if (isCenter) { - leftOffset += availableWidth / 2; - } else if (isEnd) { - leftOffset += availableWidth; + + if (enableUrlEncode) { + params = {}; + params[Ext.isString(enableUrlEncode) ? enableUrlEncode : 'data'] = Ext.encode(callData); + request.params = params; + } else { + request.jsonData = callData; } + Ext.Ajax.request(request); + }, + + + queueTransaction: function(transaction){ + var me = this, + enableBuffer = me.enableBuffer; + if (transaction.form) { + me.sendFormRequest(transaction); + return; + } - for (i = 0; i < visibleCount; i++) { - child = visibleItems[i]; - calcs = boxes[i]; - - childMargins = child.margins; - leftOffset += childMargins.left; - vertMargins = childMargins.top + childMargins.bottom; - - calcs.left = leftOffset; - calcs.top = topOffset + childMargins.top; - - switch (this.align) { - case 'stretch': - stretchHeight = availHeight - vertMargins; - calcs.height = stretchHeight.constrain(child.minHeight || 0, child.maxHeight || 1000000); - calcs.dirtySize = true; - break; - case 'stretchmax': - stretchHeight = maxHeight - vertMargins; - calcs.height = stretchHeight.constrain(child.minHeight || 0, child.maxHeight || 1000000); - calcs.dirtySize = true; - break; - case 'middle': - var diff = availHeight - calcs.height - vertMargins; - if (diff > 0) { - calcs.top = topOffset + vertMargins + (diff / 2); - } + me.callBuffer.push(transaction); + if (enableBuffer) { + if (!me.callTask) { + me.callTask = Ext.create('Ext.util.DelayedTask', me.combineAndSend, me); } + me.callTask.delay(Ext.isNumber(enableBuffer) ? enableBuffer : 10); + } else { + me.combineAndSend(); + } + }, + + + combineAndSend : function(){ + var buffer = this.callBuffer, + len = buffer.length; - leftOffset += calcs.width + childMargins.right; + if (len > 0) { + this.sendRequest(len == 1 ? buffer[0] : buffer); + this.callBuffer = []; } - - return { - boxes: boxes, - meta : { - maxHeight : maxHeight, - nonFlexWidth: nonFlexWidth, - desiredWidth: desiredWidth, - minimumWidth: minimumWidth, - shortfall : desiredWidth - width, - tooNarrow : tooNarrow - } - }; - } -}); - -Ext.Container.LAYOUTS.hbox = Ext.layout.HBoxLayout; -Ext.layout.VBoxLayout = Ext.extend(Ext.layout.BoxLayout, { + }, - align : 'left', - type: 'vbox', - - + configureFormRequest : function(action, method, form, callback, scope){ + var me = this, + transaction = Ext.create('Ext.direct.Transaction', { + provider: me, + action: action, + method: method.name, + args: [form, callback, scope], + callback: scope && Ext.isFunction(callback) ? Ext.Function.bind(callback, scope) : callback, + isForm: true + }), + isUpload, + params; + + if (me.fireEvent('beforecall', me, transaction, method) !== false) { + Ext.direct.Manager.addTransaction(transaction); + isUpload = String(form.getAttribute("enctype")).toLowerCase() == 'multipart/form-data'; + + params = { + extTID: transaction.id, + extAction: action, + extMethod: method.name, + extType: 'rpc', + extUpload: String(isUpload) + }; + + + + Ext.apply(transaction, { + form: Ext.getDom(form), + isUpload: isUpload, + params: callback && Ext.isObject(callback.params) ? Ext.apply(params, callback.params) : params + }); + me.fireEvent('call', me, transaction, method); + me.sendFormRequest(transaction); + } + }, - - calculateChildBoxes: function(visibleItems, targetSize) { - var visibleCount = visibleItems.length, - - padding = this.padding, - topOffset = padding.top, - leftOffset = padding.left, - paddingVert = topOffset + padding.bottom, - paddingHoriz = leftOffset + padding.right, - - width = targetSize.width - this.scrollOffset, - height = targetSize.height, - availWidth = Math.max(0, width - paddingHoriz), + sendFormRequest: function(transaction){ + Ext.Ajax.request({ + url: this.url, + params: transaction.params, + callback: this.onData, + scope: this, + form: transaction.form, + isUpload: transaction.isUpload, + transaction: transaction + }); + } + +}); - isStart = this.pack == 'start', - isCenter = this.pack == 'center', - isEnd = this.pack == 'end', - nonFlexHeight= 0, - maxWidth = 0, - totalFlex = 0, - desiredHeight= 0, - minimumHeight= 0, +Ext.define('Ext.draw.Matrix', { - - boxes = [], - - - child, childWidth, childHeight, childSize, childMargins, canLayout, i, calcs, flexedWidth, - horizMargins, vertMargins, stretchWidth; + - - for (i = 0; i < visibleCount; i++) { - child = visibleItems[i]; - childHeight = child.height; - childWidth = child.width; - canLayout = !child.hasLayout && typeof child.doLayout == 'function'; + requires: ['Ext.draw.Draw'], - - if (typeof childHeight != 'number') { + - - if (child.flex && !childHeight) { - totalFlex += child.flex; + constructor: function(a, b, c, d, e, f) { + if (a != null) { + this.matrix = [[a, c, e], [b, d, f], [0, 0, 1]]; + } + else { + this.matrix = [[1, 0, 0], [0, 1, 0], [0, 0, 1]]; + } + }, - - } else { - - - if (!childHeight && canLayout) { - child.doLayout(); - } + add: function(a, b, c, d, e, f) { + var me = this, + out = [[], [], []], + matrix = [[a, c, e], [b, d, f], [0, 0, 1]], + x, + y, + z, + res; - childSize = child.getSize(); - childWidth = childSize.width; - childHeight = childSize.height; + for (x = 0; x < 3; x++) { + for (y = 0; y < 3; y++) { + res = 0; + for (z = 0; z < 3; z++) { + res += me.matrix[x][z] * matrix[z][y]; } + out[x][y] = res; } - - childMargins = child.margins; - vertMargins = childMargins.top + childMargins.bottom; + } + me.matrix = out; + }, - nonFlexHeight += vertMargins + (childHeight || 0); - desiredHeight += vertMargins + (child.flex ? child.minHeight || 0 : childHeight); - minimumHeight += vertMargins + (child.minHeight || childHeight || 0); + prepend: function(a, b, c, d, e, f) { + var me = this, + out = [[], [], []], + matrix = [[a, c, e], [b, d, f], [0, 0, 1]], + x, + y, + z, + res; - - if (typeof childWidth != 'number') { - if (canLayout) { - child.doLayout(); + for (x = 0; x < 3; x++) { + for (y = 0; y < 3; y++) { + res = 0; + for (z = 0; z < 3; z++) { + res += matrix[x][z] * me.matrix[z][y]; } - childWidth = child.getWidth(); + out[x][y] = res; } + } + me.matrix = out; + }, - maxWidth = Math.max(maxWidth, childWidth + childMargins.left + childMargins.right); + invert: function() { + var matrix = this.matrix, + a = matrix[0][0], + b = matrix[1][0], + c = matrix[0][1], + d = matrix[1][1], + e = matrix[0][2], + f = matrix[1][2], + x = a * d - b * c; + return new Ext.draw.Matrix(d / x, -b / x, -c / x, a / x, (c * f - d * e) / x, (b * e - a * f) / x); + }, - - boxes.push({ - component: child, - height : childHeight || undefined, - width : childWidth || undefined - }); - } - - var shortfall = desiredHeight - height, - tooNarrow = minimumHeight > height; + clone: function() { + var matrix = this.matrix, + a = matrix[0][0], + b = matrix[1][0], + c = matrix[0][1], + d = matrix[1][1], + e = matrix[0][2], + f = matrix[1][2]; + return new Ext.draw.Matrix(a, b, c, d, e, f); + }, - - var availableHeight = Math.max(0, (height - nonFlexHeight - paddingVert)); - - if (tooNarrow) { - for (i = 0, length = visibleCount; i < length; i++) { - boxes[i].height = visibleItems[i].minHeight || visibleItems[i].height || boxes[i].height; - } - } else { - - - if (shortfall > 0) { - var minHeights = []; + translate: function(x, y) { + this.prepend(1, 0, 0, 1, x, y); + }, - - for (var index = 0, length = visibleCount; index < length; index++) { - var item = visibleItems[index], - minHeight = item.minHeight || 0; + scale: function(x, y, cx, cy) { + var me = this; + if (y == null) { + y = x; + } + me.add(1, 0, 0, 1, cx, cy); + me.add(x, 0, 0, y, 0, 0); + me.add(1, 0, 0, 1, -cx, -cy); + }, - - - if (item.flex) { - boxes[index].height = minHeight; - } else { - minHeights.push({ - minHeight: minHeight, - available: boxes[index].height - minHeight, - index : index - }); - } - } + rotate: function(a, x, y) { + a = Ext.draw.Draw.rad(a); + var me = this, + cos = +Math.cos(a).toFixed(9), + sin = +Math.sin(a).toFixed(9); + me.add(cos, sin, -sin, cos, x, y); + me.add(1, 0, 0, 1, -x, -y); + }, - - minHeights.sort(function(a, b) { - return a.available > b.available ? 1 : -1; - }); + x: function(x, y) { + var matrix = this.matrix; + return x * matrix[0][0] + y * matrix[0][1] + matrix[0][2]; + }, - - for (var i = 0, length = minHeights.length; i < length; i++) { - var itemIndex = minHeights[i].index; + y: function(x, y) { + var matrix = this.matrix; + return x * matrix[1][0] + y * matrix[1][1] + matrix[1][2]; + }, - if (itemIndex == undefined) { - continue; - } + get: function(i, j) { + return + this.matrix[i][j].toFixed(4); + }, - var item = visibleItems[itemIndex], - box = boxes[itemIndex], - oldHeight = box.height, - minHeight = item.minHeight, - newHeight = Math.max(minHeight, oldHeight - Math.ceil(shortfall / (length - i))), - reduction = oldHeight - newHeight; + toString: function() { + var me = this; + return [me.get(0, 0), me.get(0, 1), me.get(1, 0), me.get(1, 1), 0, 0].join(); + }, - boxes[itemIndex].height = newHeight; - shortfall -= reduction; - } - } else { - - var remainingHeight = availableHeight, - remainingFlex = totalFlex; - - - for (i = 0; i < visibleCount; i++) { - child = visibleItems[i]; - calcs = boxes[i]; + toSvg: function() { + var me = this; + return "matrix(" + [me.get(0, 0), me.get(1, 0), me.get(0, 1), me.get(1, 1), me.get(0, 2), me.get(1, 2)].join() + ")"; + }, - childMargins = child.margins; - horizMargins = childMargins.left + childMargins.right; + toFilter: function() { + var me = this; + return "progid:DXImageTransform.Microsoft.Matrix(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) + ")"; + }, - if (isStart && child.flex && !child.height) { - flexedHeight = Math.ceil((child.flex / remainingFlex) * remainingHeight); - remainingHeight -= flexedHeight; - remainingFlex -= child.flex; + offset: function() { + var matrix = this.matrix; + return [matrix[0][2].toFixed(4), matrix[1][2].toFixed(4)]; + }, - calcs.height = flexedHeight; - calcs.dirtySize = true; - } - } - } + + split: function () { + function norm(a) { + return a[0] * a[0] + a[1] * a[1]; } - - if (isCenter) { - topOffset += availableHeight / 2; - } else if (isEnd) { - topOffset += availableHeight; + function normalize(a) { + var mag = Math.sqrt(norm(a)); + a[0] /= mag; + a[1] /= mag; } + var matrix = this.matrix, + out = { + translateX: matrix[0][2], + translateY: matrix[1][2] + }, + row; - for (i = 0; i < visibleCount; i++) { - child = visibleItems[i]; - calcs = boxes[i]; + row = [[matrix[0][0], matrix[0][1]], [matrix[1][1], matrix[1][1]]]; + out.scaleX = Math.sqrt(norm(row[0])); + normalize(row[0]); - childMargins = child.margins; - topOffset += childMargins.top; - horizMargins = childMargins.left + childMargins.right; - + out.shear = row[0][0] * row[1][0] + row[0][1] * row[1][1]; + row[1] = [row[1][0] - row[0][0] * out.shear, row[1][1] - row[0][1] * out.shear]; - calcs.left = leftOffset + childMargins.left; - calcs.top = topOffset; - - switch (this.align) { - case 'stretch': - stretchWidth = availWidth - horizMargins; - calcs.width = stretchWidth.constrain(child.minWidth || 0, child.maxWidth || 1000000); - calcs.dirtySize = true; - break; - case 'stretchmax': - stretchWidth = maxWidth - horizMargins; - calcs.width = stretchWidth.constrain(child.minWidth || 0, child.maxWidth || 1000000); - calcs.dirtySize = true; - break; - case 'center': - var diff = availWidth - calcs.width - horizMargins; - if (diff > 0) { - calcs.left = leftOffset + horizMargins + (diff / 2); - } - } + out.scaleY = Math.sqrt(norm(row[1])); + normalize(row[1]); + out.shear /= out.scaleY; - topOffset += calcs.height + childMargins.bottom; - } - return { - boxes: boxes, - meta : { - maxWidth : maxWidth, - nonFlexHeight: nonFlexHeight, - desiredHeight: desiredHeight, - minimumHeight: minimumHeight, - shortfall : desiredHeight - height, - tooNarrow : tooNarrow - } - }; - } -}); - -Ext.Container.LAYOUTS.vbox = Ext.layout.VBoxLayout; + out.rotate = Math.asin(-row[0][1]); -Ext.layout.ToolbarLayout = Ext.extend(Ext.layout.ContainerLayout, { - monitorResize : true, + out.isSimple = !+out.shear.toFixed(9) && (out.scaleX.toFixed(9) == out.scaleY.toFixed(9) || !out.rotate); - type: 'toolbar', - - - triggerWidth: 18, + return out; + } +}); - - noItemsMenuText : '
(None)
', +Ext.define('Ext.draw.SpriteDD', { + extend: 'Ext.dd.DragSource', - - lastOverflow: false, + constructor : function(sprite, cfg){ + var me = this, + el = sprite.el; + me.sprite = sprite; + me.el = el; + me.dragData = {el: el, sprite: sprite}; + me.callParent([el, cfg]); + me.sprite.setStyle('cursor', 'move'); + }, - - tableHTML: [ - '', - '', - '', - '', - '', - '', - '', - '
', - '', - '', - '', - '', - '
', - '
', - '', - '', - '', - '', - '', - '', - '', - '
', - '', - '', - '', - '', - '
', - '
', - '', - '', - '', - '', - '
', - '
', - '
' - ].join(""), + showFrame: Ext.emptyFn, + createFrame : Ext.emptyFn, + getDragEl : function(e){ + return this.el; + }, - onLayout : function(ct, target) { + getRegion: function() { + var me = this, + el = me.el, + pos, x1, x2, y1, y2, t, r, b, l, bbox, sprite; - if (!this.leftTr) { - var align = ct.buttonAlign == 'center' ? 'center' : 'left'; - - target.addClass('x-toolbar-layout-ct'); - target.insertHtml('beforeEnd', String.format(this.tableHTML, align)); - - this.leftTr = target.child('tr.x-toolbar-left-row', true); - this.rightTr = target.child('tr.x-toolbar-right-row', true); - this.extrasTr = target.child('tr.x-toolbar-extras-row', true); - - if (this.hiddenItem == undefined) { - - this.hiddenItems = []; - } - } - - var side = ct.buttonAlign == 'right' ? this.rightTr : this.leftTr, - items = ct.items.items, - position = 0; - + sprite = me.sprite; + bbox = sprite.getBBox(); - for (var i = 0, len = items.length, c; i < len; i++, position++) { - c = items[i]; + try { + pos = Ext.core.Element.getXY(el); + } catch (e) { } - if (c.isFill) { - side = this.rightTr; - position = -1; - } else if (!c.rendered) { - c.render(this.insertCell(c, side, position)); - this.configureItem(c); - } else { - if (!c.xtbHidden && !this.isValidParent(c, side.childNodes[position])) { - var td = this.insertCell(c, side, position); - td.appendChild(c.getPositionEl().dom); - c.container = Ext.get(td); - } - } + if (!pos) { + return null; } + x1 = pos[0]; + x2 = x1 + bbox.width; + y1 = pos[1]; + y2 = y1 + bbox.height; - this.cleanup(this.leftTr); - this.cleanup(this.rightTr); - this.cleanup(this.extrasTr); - this.fitToSize(target); + return Ext.create('Ext.util.Region', y1, x2, y2, x1); }, - cleanup : function(el) { - var cn = el.childNodes, i, c; + + 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; + } + }, - for (i = cn.length-1; i >= 0 && (c = cn[i]); i--) { - if (!c.firstChild) { - el.removeChild(c); + 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; + sprite.setAttributes({ + translate: { + x: me.translateX, + y: me.translateY } + }, true); + if (sprite.vml) { + me.prevX = xy[0] + attr.x || 0; + me.prevY = xy[1] + attr.y || 0; } - }, + } +}); +Ext.define('Ext.draw.Sprite', { - insertCell : function(c, target, position) { - var td = document.createElement('td'); - td.className = 'x-toolbar-cell'; - target.insertBefore(td, target.childNodes[position] || null); - - return td; + mixins: { + observable: 'Ext.util.Observable', + animate: 'Ext.util.Animate' }, + requires: ['Ext.draw.SpriteDD'], + - hideItem : function(item) { - this.hiddenItems.push(item); - item.xtbHidden = true; - item.xtbWidth = item.getPositionEl().dom.parentNode.offsetWidth; - item.hide(); + dirty: false, + dirtyHidden: false, + dirtyTransform: false, + dirtyPath: true, + dirtyFont: true, + zIndexDirty: true, + isSprite: true, + zIndex: 0, + fontProperties: [ + 'font', + 'font-size', + 'font-weight', + 'font-style', + 'font-family', + 'text-anchor', + 'text' + ], + pathProperties: [ + 'x', + 'y', + 'd', + 'path', + 'height', + 'width', + 'radius', + 'r', + 'rx', + 'ry', + 'cx', + 'cy' + ], + constructor: function(config) { + var me = this; + config = config || {}; + me.id = Ext.id(null, 'ext-sprite-'); + me.transformations = []; + Ext.copyTo(this, config, 'surface,group,type,draggable'); + + me.bbox = {}; + me.attr = { + zIndex: 0, + translation: { + x: null, + y: null + }, + rotation: { + degrees: null, + x: null, + y: null + }, + scaling: { + x: null, + y: null, + cx: null, + cy: null + } + }; + + delete config.surface; + delete config.group; + delete config.type; + delete config.draggable; + me.setAttributes(config); + me.addEvents( + 'beforedestroy', + 'destroy', + 'render', + 'mousedown', + 'mouseup', + 'mouseover', + 'mouseout', + 'mousemove', + 'click' + ); + me.mixins.observable.constructor.apply(this, arguments); }, - unhideItem : function(item) { - item.show(); - item.xtbHidden = false; - this.hiddenItems.remove(item); + initDraggable: function() { + var me = this; + me.draggable = true; + + if (!me.el) { + me.surface.createSprite(me); + } + me.dd = Ext.create('Ext.draw.SpriteDD', me, Ext.isBoolean(me.draggable) ? null : me.draggable); + me.on('beforedestroy', me.dd.destroy, me.dd); }, - getItemWidth : function(c) { - return c.hidden ? (c.xtbWidth || 0) : c.getPositionEl().dom.parentNode.offsetWidth; - }, + setAttributes: function(attrs, redraw) { + var me = this, + fontProps = me.fontProperties, + fontPropsLength = fontProps.length, + pathProps = me.pathProperties, + pathPropsLength = pathProps.length, + hasSurface = !!me.surface, + custom = hasSurface && me.surface.customAttributes || {}, + spriteAttrs = me.attr, + attr, i, translate, translation, rotate, rotation, scale, scaling; - - fitToSize : function(target) { - if (this.container.enableOverflow === false) { - return; + for (attr in custom) { + if (attrs.hasOwnProperty(attr) && typeof custom[attr] == "function") { + Ext.apply(attrs, custom[attr].apply(me, [].concat(attrs[attr]))); + } } - var width = target.dom.clientWidth, - tableWidth = target.dom.firstChild.offsetWidth, - clipWidth = width - this.triggerWidth, - lastWidth = this.lastWidth || 0, - - hiddenItems = this.hiddenItems, - hasHiddens = hiddenItems.length != 0, - isLarger = width >= lastWidth; - - this.lastWidth = width; - - if (tableWidth > width || (hasHiddens && isLarger)) { - var items = this.container.items.items, - len = items.length, - loopWidth = 0, - item; - - for (var i = 0; i < len; i++) { - item = items[i]; + + if (!!attrs.hidden !== !!spriteAttrs.hidden) { + me.dirtyHidden = true; + } - if (!item.isFill) { - loopWidth += this.getItemWidth(item); - if (loopWidth > clipWidth) { - if (!(item.hidden || item.xtbHidden)) { - this.hideItem(item); - } - } else if (item.xtbHidden) { - this.unhideItem(item); - } - } + + for (i = 0; i < pathPropsLength; i++) { + attr = pathProps[i]; + if (attr in attrs && attrs[attr] !== spriteAttrs[attr]) { + me.dirtyPath = true; + break; } } - hasHiddens = hiddenItems.length != 0; - - if (hasHiddens) { - this.initMore(); + if ('zIndex' in attrs) { + me.zIndexDirty = true; + } - if (!this.lastOverflow) { - this.container.fireEvent('overflowchange', this.container, true); - this.lastOverflow = true; + + for (i = 0; i < fontPropsLength; i++) { + attr = fontProps[i]; + if (attr in attrs && attrs[attr] !== spriteAttrs[attr]) { + me.dirtyFont = true; + break; } - } else if (this.more) { - this.clearMenu(); - this.more.destroy(); - delete this.more; + } - if (this.lastOverflow) { - this.container.fireEvent('overflowchange', this.container, false); - this.lastOverflow = false; + translate = attrs.translate; + translation = spriteAttrs.translation; + if (translate) { + if ((translate.x && translate.x !== translation.x) || + (translate.y && translate.y !== translation.y)) { + Ext.apply(translation, translate); + me.dirtyTransform = true; } + delete attrs.translate; } - }, - - - createMenuConfig : function(component, hideOnClick){ - var config = Ext.apply({}, component.initialConfig), - group = component.toggleGroup; - - Ext.copyTo(config, component, [ - 'iconCls', 'icon', 'itemId', 'disabled', 'handler', 'scope', 'menu' - ]); - Ext.apply(config, { - text : component.overflowText || component.text, - hideOnClick: hideOnClick - }); + rotate = attrs.rotate; + rotation = spriteAttrs.rotation; + if (rotate) { + if ((rotate.x && rotate.x !== rotation.x) || + (rotate.y && rotate.y !== rotation.y) || + (rotate.degrees && rotate.degrees !== rotation.degrees)) { + Ext.apply(rotation, rotate); + me.dirtyTransform = true; + } + delete attrs.rotate; + } - if (group || component.enableToggle) { - Ext.apply(config, { - group : group, - checked: component.pressed, - listeners: { - checkchange: function(item, checked){ - component.toggle(checked); - } - } - }); + scale = attrs.scale; + scaling = spriteAttrs.scaling; + if (scale) { + 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)) { + Ext.apply(scaling, scale); + me.dirtyTransform = true; + } + delete attrs.scale; } - delete config.ownerCt; - delete config.xtype; - delete config.id; + Ext.apply(spriteAttrs, attrs); + me.dirty = true; - return config; + if (redraw === true && hasSurface) { + me.redraw(); + } + return this; }, - addComponentToMenu : function(menu, component) { - if (component instanceof Ext.Toolbar.Separator) { - menu.add('-'); - - } else if (Ext.isFunction(component.isXType)) { - if (component.isXType('splitbutton')) { - menu.add(this.createMenuConfig(component, true)); - - } else if (component.isXType('button')) { - menu.add(this.createMenuConfig(component, !component.menu)); - - } else if (component.isXType('buttongroup')) { - component.items.each(function(item){ - this.addComponentToMenu(menu, item); - }, this); - } - } + getBBox: function() { + return this.surface.getBBox(this); }, - - clearMenu : function(){ - var menu = this.moreMenu; - if (menu && menu.items) { - menu.items.each(function(item){ - delete item.menu; - }); - } + setText: function(text) { + return this.surface.setText(this, text); }, - beforeMoreShow : function(menu) { - var items = this.container.items.items, - len = items.length, - item, - prev; + hide: function(redraw) { + this.setAttributes({ + hidden: true + }, redraw); + return this; + }, - var needsSep = function(group, item){ - return group.isXType('buttongroup') && !(item instanceof Ext.Toolbar.Separator); - }; + + show: function(redraw) { + this.setAttributes({ + hidden: false + }, redraw); + return this; + }, - this.clearMenu(); - menu.removeAll(); - for (var i = 0; i < len; i++) { - item = items[i]; - if (item.xtbHidden) { - if (prev && (needsSep(item, prev) || needsSep(prev, item))) { - menu.add('-'); - } - this.addComponentToMenu(menu, item); - prev = item; - } + + remove: function() { + if (this.surface) { + this.surface.remove(this); + return true; } + return false; + }, - - if (menu.items.length < 1) { - menu.add(this.noItemsMenuText); + onRemove: function() { + this.surface.onRemove(this); + }, + + + destroy: function() { + var me = this; + if (me.fireEvent('beforedestroy', me) !== false) { + me.remove(); + me.surface.onDestroy(me); + me.clearListeners(); + me.fireEvent('destroy'); } }, - initMore : function(){ - if (!this.more) { - - this.moreMenu = new Ext.menu.Menu({ - ownerCt : this.container, - listeners: { - beforeshow: this.beforeMoreShow, - scope: this - } - }); + redraw: function() { + this.surface.renderItem(this); + return this; + }, - - this.more = new Ext.Button({ - iconCls: 'x-toolbar-more-icon', - cls : 'x-toolbar-more', - menu : this.moreMenu, - ownerCt: this.container - }); + + setStyle: function() { + this.el.setStyle.apply(this.el, arguments); + return this; + }, - var td = this.insertCell(this.more, this.extrasTr, 100); - this.more.render(td); - } + + addCls: function(obj) { + this.surface.addCls(this, obj); + return this; }, - destroy : function(){ - Ext.destroy(this.more, this.moreMenu); - delete this.leftTr; - delete this.rightTr; - delete this.extrasTr; - Ext.layout.ToolbarLayout.superclass.destroy.call(this); + + removeCls: function(obj) { + this.surface.removeCls(this, obj); + return this; } }); -Ext.Container.LAYOUTS.toolbar = Ext.layout.ToolbarLayout; - Ext.layout.MenuLayout = Ext.extend(Ext.layout.ContainerLayout, { - monitorResize : true, +Ext.define('Ext.draw.engine.Svg', { - type: 'menu', + - setContainer : function(ct){ - this.monitorResize = !ct.floating; - - - ct.on('autosize', this.doAutoSize, this); - Ext.layout.MenuLayout.superclass.setContainer.call(this, ct); - }, + extend: 'Ext.draw.Surface', - renderItem : function(c, position, target){ - if (!this.itemTpl) { - this.itemTpl = Ext.layout.MenuLayout.prototype.itemTpl = new Ext.XTemplate( - '
  • ', - '', - '{altText}', - '', - '
  • ' - ); - } + requires: ['Ext.draw.Draw', 'Ext.draw.Sprite', 'Ext.draw.Matrix', 'Ext.core.Element'], - if(c && !c.rendered){ - if(Ext.isNumber(position)){ - position = target.dom.childNodes[position]; - } - var a = this.getItemArgs(c); + + engine: 'Svg', - c.render(c.positionEl = position ? - this.itemTpl.insertBefore(position, a, true) : - this.itemTpl.append(target, a, true)); + trimRe: /^\s+|\s+$/g, + spacesRe: /\s+/, + xlink: "http:/" + "/www.w3.org/1999/xlink", + translateAttrs: { + radius: "r", + radiusX: "rx", + radiusY: "ry", + path: "d", + lineWidth: "stroke-width", + fillOpacity: "fill-opacity", + strokeOpacity: "stroke-opacity", + strokeLinejoin: "stroke-linejoin" + }, + + minDefaults: { + circle: { + cx: 0, + cy: 0, + r: 0, + fill: "none", + stroke: null, + "stroke-width": null, + opacity: null, + "fill-opacity": null, + "stroke-opacity": null + }, + ellipse: { + cx: 0, + cy: 0, + rx: 0, + ry: 0, + fill: "none", + stroke: null, + "stroke-width": null, + opacity: null, + "fill-opacity": null, + "stroke-opacity": null + }, + rect: { + x: 0, + y: 0, + width: 0, + height: 0, + rx: 0, + ry: 0, + fill: "none", + stroke: null, + "stroke-width": null, + opacity: null, + "fill-opacity": null, + "stroke-opacity": null + }, + text: { + x: 0, + y: 0, + "text-anchor": "start", + "font-family": null, + "font-size": null, + "font-weight": null, + "font-style": null, + fill: "#000", + stroke: null, + "stroke-width": null, + opacity: null, + "fill-opacity": null, + "stroke-opacity": null + }, + path: { + d: "M0,0", + fill: "none", + stroke: null, + "stroke-width": null, + opacity: null, + "fill-opacity": null, + "stroke-opacity": null + }, + image: { + x: 0, + y: 0, + width: 0, + height: 0, + preserveAspectRatio: "none", + opacity: null + } + }, - c.positionEl.menuItemId = c.getItemId(); + createSvgElement: function(type, attrs) { + var el = this.domRef.createElementNS("http:/" + "/www.w3.org/2000/svg", type), + key; + if (attrs) { + for (key in attrs) { + el.setAttribute(key, String(attrs[key])); + } + } + return el; + }, + createSpriteElement: function(sprite) { + + var el = this.createSvgElement(sprite.type); + el.id = sprite.id; + if (el.style) { + el.style.webkitTapHighlightColor = "rgba(0,0,0,0)"; + } + sprite.el = Ext.get(el); + this.applyZIndex(sprite); + sprite.matrix = Ext.create('Ext.draw.Matrix'); + sprite.bbox = { + plain: 0, + transform: 0 + }; + sprite.fireEvent("render", sprite); + return el; + }, + getBBox: function (sprite, isWithoutTransform) { + var realPath = this["getPath" + sprite.type](sprite); + if (isWithoutTransform) { + sprite.bbox.plain = sprite.bbox.plain || Ext.draw.Draw.pathDimensions(realPath); + return sprite.bbox.plain; + } + sprite.bbox.transform = sprite.bbox.transform || Ext.draw.Draw.pathDimensions(Ext.draw.Draw.mapPath(realPath, sprite.matrix)); + return sprite.bbox.transform; + }, + + getBBoxText: function (sprite) { + var bbox = {}, + bb, height, width, i, ln, el; - if (!a.isMenuItem && a.needsIcon) { - c.positionEl.addClass('x-menu-list-item-indent'); + if (sprite && sprite.el) { + el = sprite.el.dom; + try { + bbox = el.getBBox(); + return bbox; + } catch(e) { + } - this.configureItem(c); - }else if(c && !this.isValidParent(c, target)){ - if(Ext.isNumber(position)){ - position = target.dom.childNodes[position]; + bbox = {x: bbox.x, y: Infinity, width: 0, height: 0}; + ln = el.getNumberOfChars(); + for (i = 0; i < ln; i++) { + bb = el.getExtentOfChar(i); + bbox.y = Math.min(bb.y, bbox.y); + height = bb.y + bb.height - bbox.y; + bbox.height = Math.max(bbox.height, height); + width = bb.x + bb.width - bbox.x; + bbox.width = Math.max(bbox.width, width); } - target.dom.insertBefore(c.getActionEl().dom, position || null); + return bbox; } }, - getItemArgs : function(c) { - var isMenuItem = c instanceof Ext.menu.Item, - canHaveIcon = !(isMenuItem || c instanceof Ext.menu.Separator); + hide: function() { + Ext.get(this.el).hide(); + }, - return { - isMenuItem: isMenuItem, - needsIcon: canHaveIcon && (c.icon || c.iconCls), - icon: c.icon || Ext.BLANK_IMAGE_URL, - iconCls: 'x-menu-item-icon ' + (c.iconCls || ''), - itemId: 'x-menu-el-' + c.id, - itemCls: 'x-menu-list-item ', - altText: c.altText || '' - }; + show: function() { + Ext.get(this.el).show(); }, - - isValidParent : function(c, target) { - return c.el.up('li.x-menu-list-item', 5).dom.parentNode === (target.dom || target); + hidePrim: function(sprite) { + this.addCls(sprite, Ext.baseCSSPrefix + 'hide-visibility'); + }, + + showPrim: function(sprite) { + this.removeCls(sprite, Ext.baseCSSPrefix + 'hide-visibility'); }, - onLayout : function(ct, target){ - Ext.layout.MenuLayout.superclass.onLayout.call(this, ct, target); - this.doAutoSize(); + getDefs: function() { + return this._defs || (this._defs = this.createSvgElement("defs")); }, - doAutoSize : function(){ - var ct = this.container, w = ct.width; - if(ct.floating){ - if(w){ - ct.setWidth(w); - }else if(Ext.isIE){ - ct.setWidth(Ext.isStrict && (Ext.isIE7 || Ext.isIE8) ? 'auto' : ct.minWidth); - var el = ct.getEl(), t = el.dom.offsetWidth; - ct.setWidth(ct.getLayoutTarget().getWidth() + el.getFrameWidth('lr')); + transform: function(sprite) { + var me = this, + matrix = Ext.create('Ext.draw.Matrix'), + transforms = sprite.transformations, + transformsLength = transforms.length, + i = 0, + transform, type; + + 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); + } + else if (type == "scale") { + matrix.scale(transform.x, transform.y, transform.centerX, transform.centerY); } } - } -}); -Ext.Container.LAYOUTS['menu'] = Ext.layout.MenuLayout; + sprite.matrix = matrix; + sprite.el.set({transform: matrix.toSvg()}); + }, -Ext.Viewport = Ext.extend(Ext.Container, { - - - - - - - - - - - - + setSize: function(w, h) { + var me = this, + el = me.el; + + w = +w || me.width; + h = +h || me.height; + me.width = w; + me.height = h; - initComponent : function() { - Ext.Viewport.superclass.initComponent.call(this); - document.getElementsByTagName('html')[0].className += ' x-viewport'; - this.el = Ext.getBody(); - this.el.setHeight = Ext.emptyFn; - this.el.setWidth = Ext.emptyFn; - this.el.setSize = Ext.emptyFn; - this.el.dom.scroll = 'no'; - this.allowDomMove = false; - this.autoWidth = true; - this.autoHeight = true; - Ext.EventManager.onWindowResize(this.fireResize, this); - this.renderTo = this.el; + el.setSize(w, h); + el.set({ + width: w, + height: h + }); + me.callParent([w, h]); }, - fireResize : function(w, h){ - this.fireEvent('resize', this, w, h, w, h); - } -}); -Ext.reg('viewport', Ext.Viewport); - -Ext.Panel = Ext.extend(Ext.Container, { - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + getRegion: function() { + + + var svgXY = this.el.getXY(), + rectXY = this.bgRect.getXY(), + max = Math.max, + x = max(svgXY[0], rectXY[0]), + y = max(svgXY[1], rectXY[1]); + return { + left: x, + top: y, + right: x + this.width, + bottom: y + this.height + }; + }, + onRemove: function(sprite) { + if (sprite.el) { + sprite.el.remove(); + delete sprite.el; + } + this.callParent(arguments); + }, - - - - - - - - + setViewBox: function(x, y, width, height) { + if (isFinite(x) && isFinite(y) && isFinite(width) && isFinite(height)) { + this.callParent(arguments); + this.el.dom.setAttribute("viewBox", [x, y, width, height].join(" ")); + } + }, - - baseCls : 'x-panel', - - collapsedCls : 'x-panel-collapsed', - - maskDisabled : true, - - animCollapse : Ext.enableFx, - - headerAsText : true, - - buttonAlign : 'right', - - collapsed : false, - - collapseFirst : true, - - minButtonWidth : 75, - - - elements : 'body', - - preventBodyReset : false, + render: function (container) { + var me = this; + if (!me.el) { + var width = me.width || 10, + height = me.height || 10, + el = me.createSvgElement('svg', { + xmlns: "http:/" + "/www.w3.org/2000/svg", + version: 1.1, + width: width, + height: height + }), + defs = me.getDefs(), - - padding: undefined, + + + + + bgRect = me.createSvgElement("rect", { + width: "100%", + height: "100%", + fill: "#000", + stroke: "none", + opacity: 0 + }), + webkitRect; + + if (Ext.isSafari3) { + + webkitRect = me.createSvgElement("rect", { + x: -10, + y: -10, + width: "110%", + height: "110%", + fill: "none", + stroke: "#000" + }); + } + el.appendChild(defs); + if (Ext.isSafari3) { + el.appendChild(webkitRect); + } + el.appendChild(bgRect); + container.appendChild(el); + me.el = Ext.get(el); + me.bgRect = Ext.get(bgRect); + if (Ext.isSafari3) { + me.webkitRect = Ext.get(webkitRect); + me.webkitRect.hide(); + } + me.el.on({ + scope: me, + mouseup: me.onMouseUp, + mousedown: me.onMouseDown, + mouseover: me.onMouseOver, + mouseout: me.onMouseOut, + mousemove: me.onMouseMove, + mouseenter: me.onMouseEnter, + mouseleave: me.onMouseLeave, + click: me.onClick + }); + } + me.renderAll(); + }, - resizeEvent: 'bodyresize', + onMouseEnter: function(e) { + if (this.el.parent().getRegion().contains(e.getPoint())) { + this.fireEvent('mouseenter', e); + } + }, + onMouseLeave: function(e) { + if (!this.el.parent().getRegion().contains(e.getPoint())) { + this.fireEvent('mouseleave', e); + } + }, - - toolTarget : 'header', - collapseEl : 'bwrap', - slideAnchor : 't', - disabledClass : '', + processEvent: function(name, e) { + var target = e.getTarget(), + surface = this.surface, + sprite; - - deferHeight : true, - - expandDefaults: { - duration : 0.25 + this.fireEvent(name, e); + + if (target.nodeName == "tspan" && target.parentNode) { + target = target.parentNode; + } + sprite = this.items.get(target.id); + if (sprite) { + sprite.fireEvent(name, sprite, e); + } }, + - collapseDefaults : { - duration : 0.25 + tuneText: function (sprite, attrs) { + var el = sprite.el.dom, + tspans = [], + height, tspan, text, i, ln, texts, factor; + + if (attrs.hasOwnProperty("text")) { + tspans = this.setText(sprite, attrs.text); + } + + if (tspans.length) { + height = this.getBBoxText(sprite).height; + for (i = 0, ln = tspans.length; i < ln; i++) { + + + factor = (Ext.isFF3_0 || Ext.isFF3_5) ? 2 : 4; + tspans[i].setAttribute("dy", i ? height * 1.2 : height / factor); + } + sprite.dirty = true; + } }, - - initComponent : function(){ - Ext.Panel.superclass.initComponent.call(this); + setText: function(sprite, textString) { + var me = this, + el = sprite.el.dom, + x = el.getAttribute("x"), + tspans = [], + height, tspan, text, i, ln, texts; + + while (el.firstChild) { + el.removeChild(el.firstChild); + } + + texts = String(textString).split("\n"); + for (i = 0, ln = texts.length; i < ln; i++) { + text = texts[i]; + if (text) { + tspan = me.createSvgElement("tspan"); + tspan.appendChild(document.createTextNode(Ext.htmlDecode(text))); + tspan.setAttribute("x", x); + el.appendChild(tspan); + tspans[i] = tspan; + } + } + return tspans; + }, - this.addEvents( - - 'bodyresize', - - 'titlechange', - - 'iconchange', - - 'collapse', - - 'expand', - - 'beforecollapse', - - 'beforeexpand', - - 'beforeclose', - - 'close', - - 'activate', - - 'deactivate' - ); + renderAll: function() { + this.items.each(this.renderItem, this); + }, - if(this.unstyled){ - this.baseCls = 'x-plain'; + renderItem: function (sprite) { + if (!this.el) { + return; + } + if (!sprite.el) { + this.createSpriteElement(sprite); + } + if (sprite.zIndexDirty) { + this.applyZIndex(sprite); + } + if (sprite.dirty) { + this.applyAttrs(sprite); + this.applyTransformations(sprite); } + }, + + redraw: function(sprite) { + sprite.dirty = sprite.zIndexDirty = true; + this.renderItem(sprite); + }, + + applyAttrs: function (sprite) { + var me = this, + el = sprite.el, + group = sprite.group, + sattr = sprite.attr, + groups, i, ln, attrs, font, key, style, name, rect; + if (group) { + groups = [].concat(group); + ln = groups.length; + for (i = 0; i < ln; i++) { + group = groups[i]; + me.getGroup(group).add(sprite); + } + delete sprite.group; + } + attrs = me.scrubAttrs(sprite) || {}; - this.toolbars = []; - if(this.tbar){ - this.elements += ',tbar'; - this.topToolbar = this.createToolbar(this.tbar); - this.tbar = null; + 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; + } + else if (sprite.type == "rect") { + attrs.rx = attrs.ry = attrs.r; + } + else if (sprite.type == "path" && attrs.d) { + attrs.d = Ext.draw.Draw.pathToAbsolute(attrs.d); + } + sprite.dirtyPath = false; + + if (attrs['clip-rect']) { + me.setClip(sprite, attrs); + delete attrs['clip-rect']; } - if(this.bbar){ - this.elements += ',bbar'; - this.bottomToolbar = this.createToolbar(this.bbar); - this.bbar = null; + if (sprite.type == 'text' && attrs.font && sprite.dirtyFont) { + el.set({ style: "font: " + attrs.font}); + sprite.dirtyFont = false; } - - if(this.header === true){ - this.elements += ',header'; - this.header = null; - }else if(this.headerCfg || (this.title && this.header !== false)){ - this.elements += ',header'; + if (sprite.type == "image") { + el.dom.setAttributeNS(me.xlink, "href", attrs.src); } + Ext.applyIf(attrs, me.minDefaults[sprite.type]); - if(this.footerCfg || this.footer === true){ - this.elements += ',footer'; - this.footer = null; + if (sprite.dirtyHidden) { + (sattr.hidden) ? me.hidePrim(sprite) : me.showPrim(sprite); + sprite.dirtyHidden = false; } - - if(this.buttons){ - this.fbar = this.buttons; - this.buttons = null; + for (key in attrs) { + if (attrs.hasOwnProperty(key) && attrs[key] != null) { + el.dom.setAttribute(key, String(attrs[key])); + } } - if(this.fbar){ - this.createFbar(this.fbar); + if (sprite.type == 'text') { + me.tuneText(sprite, attrs); + } + + + style = sattr.style; + if (style) { + el.setStyle(style); } - if(this.autoLoad){ - this.on('render', this.doAutoLoad, this, {delay:10}); + + sprite.dirty = false; + + if (Ext.isSafari3) { + + me.webkitRect.show(); + setTimeout(function () { + me.webkitRect.hide(); + }); } }, - - createFbar : function(fbar){ - var min = this.minButtonWidth; - this.elements += ',footer'; - this.fbar = this.createToolbar(fbar, { - buttonAlign: this.buttonAlign, - toolbarCls: 'x-panel-fbar', - enableOverflow: false, - defaults: function(c){ - return { - minWidth: c.minWidth || min - }; + setClip: function(sprite, params) { + var me = this, + rect = params["clip-rect"], + clipEl, clipPath; + if (rect) { + if (sprite.clip) { + sprite.clip.parentNode.parentNode.removeChild(sprite.clip.parentNode); } - }); + clipEl = me.createSvgElement('clipPath'); + clipPath = me.createSvgElement('rect'); + clipEl.id = Ext.id(null, 'ext-clip-'); + clipPath.setAttribute("x", rect.x); + clipPath.setAttribute("y", rect.y); + clipPath.setAttribute("width", rect.width); + clipPath.setAttribute("height", rect.height); + clipEl.appendChild(clipPath); + me.getDefs().appendChild(clipEl); + sprite.el.dom.setAttribute("clip-path", "url(#" + clipEl.id + ")"); + sprite.clip = clipPath; + } + + + - this.fbar.items.each(function(c){ - c.minWidth = c.minWidth || this.minButtonWidth; - }, this); - this.buttons = this.fbar.items.items; }, - createToolbar: function(tb, options){ - var result; - - if(Ext.isArray(tb)){ - tb = { - items: tb - }; + applyZIndex: function(sprite) { + var idx = this.normalizeSpriteCollection(sprite), + el = sprite.el, + prevEl; + if (this.el.dom.childNodes[idx + 2] !== el.dom) { + if (idx > 0) { + + do { + prevEl = this.items.getAt(--idx).el; + } while (!prevEl && idx > 0); + } + el.insertAfter(prevEl || this.bgRect); } - result = tb.events ? Ext.apply(tb, options) : this.createComponent(Ext.apply({}, tb, options), 'toolbar'); - this.toolbars.push(result); - return result; + sprite.zIndexDirty = false; }, - - createElement : function(name, pnode){ - if(this[name]){ - pnode.appendChild(this[name].dom); - return; + createItem: function (config) { + var sprite = Ext.create('Ext.draw.Sprite', config); + sprite.surface = this; + return sprite; + }, + + addGradient: function(gradient) { + gradient = Ext.draw.Draw.parseGradient(gradient); + var 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); + } + } + 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); } + }, - if(name === 'bwrap' || this.elements.indexOf(name) != -1){ - if(this[name+'Cfg']){ - this[name] = Ext.fly(pnode).createChild(this[name+'Cfg']); - }else{ - var el = document.createElement('div'); - el.className = this[name+'Cls']; - this[name] = Ext.get(pnode.appendChild(el)); + + hasCls: function(sprite, className) { + return className && (' ' + (sprite.el.dom.getAttribute('class') || '') + ' ').indexOf(' ' + className + ' ') != -1; + }, + + addCls: function(sprite, className) { + var el = sprite.el, + i, + len, + v, + cls = [], + curCls = el.getAttribute('class') || ''; + + if (!Ext.isArray(className)) { + if (typeof className == 'string' && !this.hasCls(sprite, className)) { + el.set({ 'class': curCls + ' ' + className }); + } + } + else { + for (i = 0, len = className.length; i < len; i++) { + v = className[i]; + if (typeof v == 'string' && (' ' + curCls + ' ').indexOf(' ' + v + ' ') == -1) { + cls.push(v); + } } - if(this[name+'CssClass']){ - this[name].addClass(this[name+'CssClass']); + if (cls.length) { + el.set({ 'class': ' ' + cls.join(' ') }); } - if(this[name+'Style']){ - this[name].applyStyles(this[name+'Style']); + } + }, + + removeCls: function(sprite, className) { + var me = this, + el = sprite.el, + curCls = el.getAttribute('class') || '', + i, idx, len, cls, elClasses; + if (!Ext.isArray(className)){ + className = [className]; + } + if (curCls) { + elClasses = curCls.replace(me.trimRe, ' ').split(me.spacesRe); + for (i = 0, len = className.length; i < len; i++) { + cls = className[i]; + if (typeof cls == 'string') { + cls = cls.replace(me.trimRe, ''); + idx = Ext.Array.indexOf(elClasses, cls); + if (idx != -1) { + elClasses.splice(idx, 1); + } + } } + el.set({ 'class': elClasses.join(' ') }); } }, + destroy: function() { + var me = this; + + me.callParent(); + if (me.el) { + me.el.remove(); + } + delete me.el; + } +}); + + +Ext.define('Ext.draw.engine.Vml', { + - onRender : function(ct, position){ - Ext.Panel.superclass.onRender.call(this, ct, position); - this.createClasses(); - var el = this.el, - d = el.dom, - bw, - ts; + extend: 'Ext.draw.Surface', + requires: ['Ext.draw.Draw', 'Ext.draw.Color', 'Ext.draw.Sprite', 'Ext.draw.Matrix', 'Ext.core.Element'], - if(this.collapsible && !this.hideCollapseTool){ - this.tools = this.tools ? this.tools.slice(0) : []; - this.tools[this.collapseFirst?'unshift':'push']({ - id: 'toggle', - handler : this.toggleCollapse, - scope: this + + + engine: 'Vml', + + map: {M: "m", L: "l", C: "c", Z: "x", m: "t", l: "r", c: "v", z: "x"}, + bitesRe: /([clmz]),?([^clmz]*)/gi, + valRe: /-?[^,\s-]+/g, + fillUrlRe: /^url\(\s*['"]?([^\)]+?)['"]?\s*\)$/i, + pathlike: /^(path|rect)$/, + NonVmlPathRe: /[ahqstv]/ig, // Non-VML Pathing ops + partialPathRe: /[clmz]/g, + fontFamilyRe: /^['"]+|['"]+$/g, + baseVmlCls: Ext.baseCSSPrefix + 'vml-base', + vmlGroupCls: Ext.baseCSSPrefix + 'vml-group', + spriteCls: Ext.baseCSSPrefix + 'vml-sprite', + measureSpanCls: Ext.baseCSSPrefix + 'vml-measure-span', + zoom: 21600, + coordsize: 1000, + coordorigin: '0 0', + + // @private + // Convert an SVG standard path into a VML path + path2vml: function (path) { + var me = this, + nonVML = me.NonVmlPathRe, + map = me.map, + val = me.valRe, + zoom = me.zoom, + bites = me.bitesRe, + command = Ext.Function.bind(Ext.draw.Draw.pathToAbsolute, Ext.draw.Draw), + res, pa, p, r, i, ii, j, jj; + if (String(path).match(nonVML)) { + command = Ext.Function.bind(Ext.draw.Draw.path2curve, Ext.draw.Draw); + } else if (!String(path).match(me.partialPathRe)) { + res = String(path).replace(bites, function (all, command, args) { + var vals = [], + isMove = command.toLowerCase() == "m", + res = map[command]; + args.replace(val, function (value) { + if (isMove && vals[length] == 2) { + res += vals + map[command == "m" ? "l" : "L"]; + vals = []; + } + vals.push(Math.round(value * zoom)); + }); + return res + vals; }); + return res; + } + pa = command(path); + res = []; + for (i = 0, ii = pa.length; i < ii; i++) { + p = pa[i]; + r = pa[i][0].toLowerCase(); + if (r == "z") { + r = "x"; + } + for (j = 1, jj = p.length; j < jj; j++) { + r += Math.round(p[j] * me.zoom) + (j != jj - 1 ? "," : ""); + } + res.push(r); + } + 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", + radiusY: "ry", + lineWidth: "stroke-width", + fillOpacity: "fill-opacity", + strokeOpacity: "stroke-opacity", + strokeLinejoin: "stroke-linejoin" + }, + + // @private - Minimun set of defaults for different types of sprites. + minDefaults: { + circle: { + fill: "none", + stroke: null, + "stroke-width": null, + opacity: null, + "fill-opacity": null, + "stroke-opacity": null + }, + ellipse: { + cx: 0, + cy: 0, + rx: 0, + ry: 0, + fill: "none", + stroke: null, + "stroke-width": null, + opacity: null, + "fill-opacity": null, + "stroke-opacity": null + }, + rect: { + x: 0, + y: 0, + width: 0, + height: 0, + rx: 0, + ry: 0, + fill: "none", + stroke: null, + "stroke-width": null, + opacity: null, + "fill-opacity": null, + "stroke-opacity": null + }, + text: { + x: 0, + y: 0, + "text-anchor": "start", + font: '10px "Arial"', + fill: "#000", + stroke: null, + "stroke-width": null, + opacity: null, + "fill-opacity": null, + "stroke-opacity": null + }, + path: { + d: "M0,0", + fill: "none", + stroke: null, + "stroke-width": null, + opacity: null, + "fill-opacity": null, + "stroke-opacity": null + }, + image: { + x: 0, + y: 0, + width: 0, + height: 0, + preserveAspectRatio: "none", + opacity: null } + }, - if(this.tools){ - ts = this.tools; - this.elements += (this.header !== false) ? ',header' : ''; - } - this.tools = {}; + // private + onMouseEnter: function(e) { + this.fireEvent("mouseenter", e); + }, - el.addClass(this.baseCls); - if(d.firstChild){ - this.header = el.down('.'+this.headerCls); - this.bwrap = el.down('.'+this.bwrapCls); - var cp = this.bwrap ? this.bwrap : el; - this.tbar = cp.down('.'+this.tbarCls); - this.body = cp.down('.'+this.bodyCls); - this.bbar = cp.down('.'+this.bbarCls); - this.footer = cp.down('.'+this.footerCls); - this.fromMarkup = true; - } - if (this.preventBodyReset === true) { - el.addClass('x-panel-reset'); - } - if(this.cls){ - el.addClass(this.cls); - } + // private + onMouseLeave: function(e) { + this.fireEvent("mouseleave", e); + }, - if(this.buttons){ - this.elements += ',footer'; + // @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, + sprite; + this.fireEvent(name, e); + sprite = this.items.get(target.id); + if (sprite) { + sprite.fireEvent(name, sprite, e); } + }, - - - - if(this.frame){ - el.insertHtml('afterBegin', String.format(Ext.Element.boxMarkup, this.baseCls)); + // Create the VML element/elements and append them to the DOM + createSpriteElement: function(sprite) { + var me = this, + attr = sprite.attr, + type = sprite.type, + zoom = me.zoom, + vml = sprite.vml || (sprite.vml = {}), + round = Math.round, + el = (type === 'image') ? me.createNode('image') : me.createNode('shape'), + path, skew, textPath; + + el.coordsize = zoom + ' ' + zoom; + el.coordorigin = attr.coordorigin || "0 0"; + Ext.get(el).addCls(me.spriteCls); + if (type == "text") { + vml.path = path = me.createNode("path"); + path.textpathok = true; + vml.textpath = textPath = me.createNode("textpath"); + textPath.on = true; + el.appendChild(textPath); + el.appendChild(path); + } + el.id = sprite.id; + sprite.el = Ext.get(el); + me.el.appendChild(el); + if (type !== 'image') { + skew = me.createNode("skew"); + skew.on = true; + el.appendChild(skew); + sprite.skew = skew; + } + sprite.matrix = Ext.create('Ext.draw.Matrix'); + sprite.bbox = { + plain: null, + transform: null + }; + sprite.fireEvent("render", sprite); + return sprite.el; + }, - this.createElement('header', d.firstChild.firstChild.firstChild); - this.createElement('bwrap', d); + // @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) { + sprite.bbox.plain = sprite.bbox.plain || Ext.draw.Draw.pathDimensions(realPath); + return sprite.bbox.plain; + } + sprite.bbox.transform = sprite.bbox.transform || Ext.draw.Draw.pathDimensions(Ext.draw.Draw.mapPath(realPath, sprite.matrix)); + return sprite.bbox.transform; + }, - - bw = this.bwrap.dom; - var ml = d.childNodes[1], bl = d.childNodes[2]; - bw.appendChild(ml); - bw.appendChild(bl); + getBBoxText: function (sprite) { + var vml = sprite.vml; + return { + x: vml.X + (vml.bbx || 0) - vml.W / 2, + y: vml.Y - vml.H / 2, + width: vml.W, + height: vml.H + }; + }, - var mc = bw.firstChild.firstChild.firstChild; - this.createElement('tbar', mc); - this.createElement('body', mc); - this.createElement('bbar', mc); - this.createElement('footer', bw.lastChild.firstChild.firstChild); + applyAttrs: function (sprite) { + var me = this, + vml = sprite.vml, + group = sprite.group, + spriteAttr = sprite.attr, + el = sprite.el, + dom = el.dom, + style, name, groups, i, ln, scrubbedAttrs, font, key, bbox; - if(!this.footer){ - this.bwrap.dom.lastChild.className += ' x-panel-nofooter'; + if (group) { + groups = [].concat(group); + ln = groups.length; + for (i = 0; i < ln; i++) { + group = groups[i]; + me.getGroup(group).add(sprite); } - - this.ft = Ext.get(this.bwrap.dom.lastChild); - this.mc = Ext.get(mc); - }else{ - this.createElement('header', d); - this.createElement('bwrap', d); + delete sprite.group; + } + scrubbedAttrs = me.scrubAttrs(sprite) || {}; - - bw = this.bwrap.dom; - this.createElement('tbar', bw); - this.createElement('body', bw); - this.createElement('bbar', bw); - this.createElement('footer', bw); + if (sprite.zIndexDirty) { + me.setZIndex(sprite); + } - if(!this.header){ - this.body.addClass(this.bodyCls + '-noheader'); - if(this.tbar){ - this.tbar.addClass(this.tbarCls + '-noheader'); - } - } + // 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(Ext.isDefined(this.padding)){ - this.body.setStyle('padding', this.body.addUnits(this.padding)); + if (dom.href) { + dom.href = scrubbedAttrs.href; + } + if (dom.title) { + dom.title = scrubbedAttrs.title; + } + if (dom.target) { + dom.target = scrubbedAttrs.target; + } + if (dom.cursor) { + dom.cursor = scrubbedAttrs.cursor; } - if(this.border === false){ - this.el.addClass(this.baseCls + '-noborder'); - this.body.addClass(this.bodyCls + '-noborder'); - if(this.header){ - this.header.addClass(this.headerCls + '-noborder'); - } - if(this.footer){ - this.footer.addClass(this.footerCls + '-noborder'); - } - if(this.tbar){ - this.tbar.addClass(this.tbarCls + '-noborder'); + // 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, + cy = scrubbedAttrs.y, + rx = scrubbedAttrs.rx || scrubbedAttrs.r || 0, + ry = scrubbedAttrs.ry || scrubbedAttrs.r || 0; + dom.path = Ext.String.format("ar{0},{1},{2},{3},{4},{1},{4},{1}", + Math.round((cx - rx) * me.zoom), + Math.round((cy - ry) * me.zoom), + Math.round((cx + rx) * me.zoom), + Math.round((cy + ry) * me.zoom), + Math.round(cx * me.zoom)); + sprite.dirtyPath = false; } - if(this.bbar){ - this.bbar.addClass(this.bbarCls + '-noborder'); + else if (sprite.type !== "text" && sprite.type !== 'image') { + sprite.attr.path = scrubbedAttrs.path = me.setPaths(sprite, scrubbedAttrs) || scrubbedAttrs.path; + dom.path = me.path2vml(scrubbedAttrs.path); + sprite.dirtyPath = false; } } - if(this.bodyBorder === false){ - this.body.addClass(this.bodyCls + '-noborder'); + // Apply clipping + if ("clip-rect" in scrubbedAttrs) { + me.setClip(sprite, scrubbedAttrs); } - this.bwrap.enableDisplayMode('block'); + // Handle text (special handling required) + if (sprite.type == "text") { + me.setTextAttributes(sprite, scrubbedAttrs); + } - if(this.header){ - this.header.unselectable(); + // Handle fill and opacity + if (scrubbedAttrs.opacity || scrubbedAttrs['stroke-opacity'] || scrubbedAttrs.fill) { + me.setFill(sprite, scrubbedAttrs); + } - - if(this.headerAsText){ - this.header.dom.innerHTML = - ''+this.header.dom.innerHTML+''; + // 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); + } - if(this.iconCls){ - this.setIconClass(this.iconCls); - } + sprite.dirty = false; + }, + + setZIndex: function(sprite) { + if (sprite.el) { + if (sprite.attr.zIndex != undefined) { + sprite.el.setStyle('zIndex', sprite.attr.zIndex); } + sprite.zIndexDirty = false; } + }, - if(this.floating){ - this.makeFloating(this.floating); + // 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') { + spriteAttr.rx = spriteAttr.ry = params.r; + return Ext.draw.Draw.ellipsePath(sprite); } - - if(this.collapsible && this.titleCollapse && this.header){ - this.mon(this.header, 'click', this.toggleCollapse, this); - this.header.setStyle('cursor', 'pointer'); + else if (sprite.type == 'ellipse') { + spriteAttr.rx = params.rx; + spriteAttr.ry = params.ry; + return Ext.draw.Draw.ellipsePath(sprite); } - if(ts){ - this.addTool.apply(this, ts); + else if (sprite.type == 'rect') { + spriteAttr.rx = spriteAttr.ry = params.r; + return Ext.draw.Draw.rectPath(sprite); } + else if (sprite.type == 'path' && spriteAttr.path) { + return Ext.draw.Draw.pathToAbsolute(spriteAttr.path); + } + return false; + }, - - if(this.fbar){ - this.footer.addClass('x-panel-btns'); - this.fbar.ownerCt = this; - this.fbar.render(this.footer); - this.footer.createChild({cls:'x-clear'}); + setFill: function(sprite, params) { + var me = this, + el = sprite.el.dom, + fillEl = el.fill, + newfill = false, + 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 (Ext.isArray(params.fill)) { + params.fill = params.fill[0]; + } + if (params.fill == "none") { + fillEl.on = false; } - if(this.tbar && this.topToolbar){ - this.topToolbar.ownerCt = this; - this.topToolbar.render(this.tbar); + else { + if (typeof params.opacity == "number") { + fillEl.opacity = params.opacity; + } + if (typeof params["fill-opacity"] == "number") { + fillEl.opacity = params["fill-opacity"]; + } + fillEl.on = true; + if (typeof params.fill == "string") { + 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; + } + // Otherwise treat it as an image + else { + fillEl.src = fillUrl; + fillEl.type = "tile"; + } + } + else { + fillEl.color = Ext.draw.Color.toHex(params.fill); + fillEl.src = ""; + fillEl.type = "solid"; + } + } } - if(this.bbar && this.bottomToolbar){ - this.bottomToolbar.ownerCt = this; - this.bottomToolbar.render(this.bbar); + if (newfill) { + el.appendChild(fillEl); } }, - - setIconClass : function(cls){ - var old = this.iconCls; - this.iconCls = cls; - if(this.rendered && this.header){ - if(this.frame){ - this.header.addClass('x-panel-icon'); - this.header.replaceClass(old, this.iconCls); - }else{ - var hd = this.header, - img = hd.child('img.x-panel-inline-icon'); - if(img){ - Ext.fly(img).replaceClass(old, this.iconCls); - }else{ - var hdspan = hd.child('span.' + this.headerTextCls); - if (hdspan) { - Ext.DomHelper.insertBefore(hdspan.dom, { - tag:'img', alt: '', src: Ext.BLANK_IMAGE_URL, cls:'x-panel-inline-icon '+this.iconCls - }); - } - } + setStroke: function(sprite, params) { + var me = this, + el = sprite.el.dom, + strokeEl = sprite.strokeEl, + newStroke = false, + width, opacity; + + if (!strokeEl) { + strokeEl = sprite.strokeEl = me.createNode("stroke"); + newStroke = true; + } + if (Ext.isArray(params.stroke)) { + params.stroke = params.stroke[0]; + } + if (!params.stroke || params.stroke == "none" || params.stroke == 0 || params["stroke-width"] == 0) { + strokeEl.on = false; + } + 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"]; + strokeEl.endcap = params["stroke-linecap"] || "round"; + 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; + } + else { + strokeEl.weight = width; + strokeEl.opacity = opacity; } } - this.fireEvent('iconchange', this, cls, old); + if (newStroke) { + el.appendChild(strokeEl); + } }, - - makeFloating : function(cfg){ - this.floating = true; - this.el = new Ext.Layer(Ext.apply({}, cfg, { - shadow: Ext.isDefined(this.shadow) ? this.shadow : 'sides', - shadowOffset: this.shadowOffset, - constrain:false, - shim: this.shim === false ? false : undefined - }), this.el); + setClip: function(sprite, params) { + var me = this, + el = sprite.el, + clipEl = sprite.clipEl, + rect = String(params["clip-rect"]).split(me.separatorRe); + if (!clipEl) { + clipEl = sprite.clipEl = me.el.insertFirst(Ext.getDoc().dom.createElement("div")); + clipEl.addCls(Ext.baseCSSPrefix + 'vml-sprite'); + } + if (rect.length == 4) { + rect[2] = +rect[2] + (+rect[0]); + rect[3] = +rect[3] + (+rect[1]); + clipEl.setStyle("clip", Ext.String.format("rect({1}px {2}px {3}px {0}px)", rect[0], rect[1], rect[2], rect[3])); + clipEl.setSize(me.el.width, me.el.height); + } + else { + clipEl.setStyle("clip", ""); + } }, + setTextAttributes: function(sprite, params) { + var me = this, + vml = sprite.vml, + textStyle = vml.textpath.style, + spanCacheStyle = me.span.style, + zoom = me.zoom, + round = Math.round, + fontObj = { + fontSize: "font-size", + fontWeight: "font-weight", + fontStyle: "font-style" + }, + fontProp, + paramProp; + if (sprite.dirtyFont) { + if (params.font) { + textStyle.font = spanCacheStyle.font = params.font; + } + if (params["font-family"]) { + textStyle.fontFamily = '"' + params["font-family"].split(",")[0].replace(me.fontFamilyRe, "") + '"'; + spanCacheStyle.fontFamily = params["font-family"]; + } + + for (fontProp in fontObj) { + paramProp = params[fontObj[fontProp]]; + if (paramProp) { + textStyle[fontProp] = spanCacheStyle[fontProp] = paramProp; + } + } + + me.setText(sprite, params.text); + + if (vml.textpath.string) { + me.span.innerHTML = String(vml.textpath.string).replace(/"); + } + vml.W = me.span.offsetWidth; + vml.H = me.span.offsetHeight + 2; + + + if (params["text-anchor"] == "middle") { + textStyle["v-text-align"] = "center"; + } + else if (params["text-anchor"] == "end") { + textStyle["v-text-align"] = "right"; + vml.bbx = -Math.round(vml.W / 2); + } + else { + textStyle["v-text-align"] = "left"; + vml.bbx = Math.round(vml.W / 2); + } + } + vml.X = params.x; + vml.Y = params.y; + vml.path.v = Ext.String.format("m{0},{1}l{2},{1}", Math.round(vml.X * zoom), Math.round(vml.Y * zoom), Math.round(vml.X * zoom) + 1); + + sprite.bbox.plain = null; + sprite.bbox.transform = null; + sprite.dirtyFont = false; + }, - getTopToolbar : function(){ - return this.topToolbar; + setText: function(sprite, text) { + sprite.vml.textpath.string = Ext.htmlDecode(text); }, - - getBottomToolbar : function(){ - return this.bottomToolbar; + hide: function() { + this.el.hide(); }, - - getFooterToolbar : function() { - return this.fbar; + show: function() { + this.el.show(); }, - - addButton : function(config, handler, scope){ - if(!this.fbar){ - this.createFbar([]); - } - if(handler){ - if(Ext.isString(config)){ - config = {text: config}; - } - config = Ext.apply({ - handler: handler, - scope: scope - }, config); - } - return this.fbar.add(config); + hidePrim: function(sprite) { + sprite.el.addCls(Ext.baseCSSPrefix + 'hide-visibility'); }, - - addTool : function(){ - if(!this.rendered){ - if(!this.tools){ - this.tools = []; - } - Ext.each(arguments, function(arg){ - this.tools.push(arg); - }, this); + showPrim: function(sprite) { + sprite.el.removeCls(Ext.baseCSSPrefix + 'hide-visibility'); + }, + + setSize: function(width, height) { + var me = this, + viewBox = me.viewBox, + scaleX, scaleY, items, i, len; + width = width || me.width; + height = height || me.height; + me.width = width; + me.height = height; + + if (!me.el) { return; } - - if(!this[this.toolTarget]){ - return; + + + if (width != undefined) { + me.el.setWidth(width); + } + if (height != undefined) { + me.el.setHeight(height); } - if(!this.toolTemplate){ + + + if (viewBox && (width || height)) { + var viewBoxX = viewBox.x, + viewBoxY = viewBox.y, + viewBoxWidth = viewBox.width, + viewBoxHeight = viewBox.height, + relativeHeight = height / viewBoxHeight, + relativeWidth = width / viewBoxWidth, + size; + 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); - var tt = new Ext.Template( - '
     
    ' - ); - tt.disableFormats = true; - tt.compile(); - Ext.Panel.prototype.toolTemplate = tt; - } - for(var i = 0, a = arguments, len = a.length; i < len; i++) { - var tc = a[i]; - if(!this.tools[tc.id]){ - var overCls = 'x-tool-'+tc.id+'-over'; - var t = this.toolTemplate.insertFirst(this[this.toolTarget], tc, true); - this.tools[tc.id] = t; - t.enableDisplayMode('block'); - this.mon(t, 'click', this.createToolHandler(t, tc, overCls, this)); - if(tc.on){ - this.mon(t, tc.on); - } - if(tc.hidden){ - t.hide(); - } - if(tc.qtip){ - if(Ext.isObject(tc.qtip)){ - Ext.QuickTips.register(Ext.apply({ - target: t.id - }, tc.qtip)); - } else { - t.dom.qtip = tc.qtip; - } - } - t.addClassOnOver(overCls); + 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]); } } + this.callParent(arguments); }, - onLayout : function(shallow, force){ - Ext.Panel.superclass.onLayout.apply(this, arguments); - if(this.hasLayout && this.toolbars.length > 0){ - Ext.each(this.toolbars, function(tb){ - tb.doLayout(undefined, force); - }); - this.syncHeight(); - } + setViewBox: function(x, y, width, height) { + this.callParent(arguments); + this.viewBox = { + x: x, + y: y, + width: width, + height: height + }; }, - syncHeight : function(){ - var h = this.toolbarHeight, - bd = this.body, - lsh = this.lastSize.height, - sz; - - if(this.autoHeight || !Ext.isDefined(lsh) || lsh == 'auto'){ - return; + onAdd: function(item) { + this.callParent(arguments); + if (this.el) { + this.renderItem(item); } + }, - - if(h != this.getToolbarHeight()){ - h = Math.max(0, lsh - this.getFrameHeight()); - bd.setHeight(h); - sz = bd.getSize(); - this.toolbarHeight = this.getToolbarHeight(); - this.onBodyResize(sz.width, sz.height); + onRemove: function(sprite) { + if (sprite.el) { + sprite.el.remove(); + delete sprite.el; } + this.callParent(arguments); }, - - onShow : function(){ - if(this.floating){ - return this.el.show(); + 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">'); + }; + } } - Ext.Panel.superclass.onShow.call(this); - }, - - onHide : function(){ - if(this.floating){ - return this.el.hide(); + if (!me.el) { + var el = doc.createElement("div"); + me.el = Ext.get(el); + me.el.addCls(me.baseVmlCls); + + + me.span = doc.createElement("span"); + Ext.get(me.span).addCls(me.measureSpanCls); + el.appendChild(me.span); + me.el.setSize(me.width || 10, me.height || 10); + container.appendChild(el); + me.el.on({ + scope: me, + mouseup: me.onMouseUp, + mousedown: me.onMouseDown, + mouseover: me.onMouseOver, + mouseout: me.onMouseOut, + mousemove: me.onMouseMove, + mouseenter: me.onMouseEnter, + mouseleave: me.onMouseLeave, + click: me.onClick + }); } - Ext.Panel.superclass.onHide.call(this); + me.renderAll(); }, - - createToolHandler : function(t, tc, overCls, panel){ - return function(e){ - t.removeClass(overCls); - if(tc.stopEvent !== false){ - e.stopEvent(); - } - if(tc.handler){ - tc.handler.call(tc.scope || t, e, t, panel, tc); - } - }; + renderAll: function() { + this.items.each(this.renderItem, this); }, - - afterRender : function(){ - if(this.floating && !this.hidden){ - this.el.show(); + redraw: function(sprite) { + sprite.dirty = true; + this.renderItem(sprite); + }, + + renderItem: function (sprite) { + + if (!this.el) { + return; } - if(this.title){ - this.setTitle(this.title); + + + if (!sprite.el) { + this.createSpriteElement(sprite); } - Ext.Panel.superclass.afterRender.call(this); - if (this.collapsed) { - this.collapsed = false; - this.collapse(false); + + if (sprite.dirty) { + this.applyAttrs(sprite); + if (sprite.dirtyTransform) { + this.applyTransformations(sprite); + } } - this.initEvents(); }, - - getKeyMap : function(){ - if(!this.keyMap){ - this.keyMap = new Ext.KeyMap(this.el, this.keys); - } - return this.keyMap; + rotationCompensation: function (deg, dx, dy) { + var matrix = Ext.create('Ext.draw.Matrix'); + matrix.rotate(-deg, 0.5, 0.5); + return { + x: matrix.x(dx, dy), + y: matrix.y(dx, dy) + }; }, - - initEvents : function(){ - if(this.keys){ - this.getKeyMap(); - } - if(this.draggable){ - this.initDraggable(); - } - if(this.toolbars.length > 0){ - Ext.each(this.toolbars, function(tb){ - tb.doLayout(); - tb.on({ - scope: this, - afterlayout: this.syncHeight, - remove: this.syncHeight - }); - }, this); - this.syncHeight(); + transform: 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; + + 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; + } } - }, + 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); + } + + sprite.matrix = matrix; + - - initDraggable : function(){ - this.dd = new Ext.Panel.DD(this, Ext.isBoolean(this.draggable) ? null : this.draggable); - }, - - beforeEffect : function(anim){ - if(this.floating){ - this.el.beforeAction(); + if (sprite.type != "image" && skew) { + + skew.matrix = matrix.toString(); + skew.offset = matrix.offset(); } - if(anim !== false){ - this.el.addClass('x-panel-animated'); + 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; + } + if (flip != "" && !dom.style.flip) { + domStyle.flip = flip; + } + + + newOrigin = (deltaX * -zoomScaleX) + " " + (deltaY * -zoomScaleY); + if (newOrigin != dom.coordorigin) { + dom.coordorigin = (deltaX * -zoomScaleX) + " " + (deltaY * -zoomScaleY); + } } }, - - afterEffect : function(anim){ - this.syncShadow(); - this.el.removeClass('x-panel-animated'); + createItem: function (config) { + return Ext.create('Ext.draw.Sprite', config); }, - - createEffect : function(a, cb, scope){ - var o = { - scope:scope, - block:true - }; - if(a === true){ - o.callback = cb; - return o; - }else if(!a.callback){ - o.callback = cb; - }else { - o.callback = function(){ - cb.call(scope); - Ext.callback(a.callback, a.scope); - }; - } - return Ext.applyIf(o, a); + getRegion: function() { + return this.el.getRegion(); }, - - collapse : function(animate){ - if(this.collapsed || this.el.hasFxBlock() || this.fireEvent('beforecollapse', this, animate) === false){ - return; + addCls: function(sprite, className) { + if (sprite && sprite.el) { + sprite.el.addCls(className); } - var doAnim = animate === true || (animate !== false && this.animCollapse); - this.beforeEffect(doAnim); - this.onCollapse(doAnim, animate); - return this; }, - - onCollapse : function(doAnim, animArg){ - if(doAnim){ - this[this.collapseEl].slideOut(this.slideAnchor, - Ext.apply(this.createEffect(animArg||true, this.afterCollapse, this), - this.collapseDefaults)); - }else{ - this[this.collapseEl].hide(this.hideMode); - this.afterCollapse(false); + removeCls: function(sprite, className) { + if (sprite && sprite.el) { + sprite.el.removeCls(className); } }, - afterCollapse : function(anim){ - this.collapsed = true; - this.el.addClass(this.collapsedCls); - if(anim !== false){ - this[this.collapseEl].hide(this.hideMode); - } - this.afterEffect(anim); + addGradient: function(gradient) { + var gradients = this.gradientsColl || (this.gradientsColl = Ext.create('Ext.util.MixedCollection')), + colors = [], + stops = Ext.create('Ext.util.MixedCollection'); - this.cascade(function(c) { - if (c.lastSize) { - c.lastSize = { width: undefined, height: undefined }; - } + stops.addAll(gradient.stops); + stops.sortByKey("ASC", function(a, b) { + a = parseInt(a, 10); + b = parseInt(b, 10); + return a > b ? 1 : (a < b ? -1 : 0); + }); + stops.eachKey(function(k, v) { + colors.push(k + "% " + v.color); }); - this.fireEvent('collapse', this); - }, - - expand : function(animate){ - if(!this.collapsed || this.el.hasFxBlock() || this.fireEvent('beforeexpand', this, animate) === false){ - return; - } - var doAnim = animate === true || (animate !== false && this.animCollapse); - this.el.removeClass(this.collapsedCls); - this.beforeEffect(doAnim); - this.onExpand(doAnim, animate); - return this; + gradients.add(gradient.id, { + colors: colors.join(","), + angle: gradient.angle + }); }, - - onExpand : function(doAnim, animArg){ - if(doAnim){ - this[this.collapseEl].slideIn(this.slideAnchor, - Ext.apply(this.createEffect(animArg||true, this.afterExpand, this), - this.expandDefaults)); - }else{ - this[this.collapseEl].show(this.hideMode); - this.afterExpand(false); + destroy: function() { + var me = this; + + me.callParent(arguments); + if (me.el) { + me.el.remove(); } - }, + delete me.el; + } +}); - - afterExpand : function(anim){ - this.collapsed = false; - if(anim !== false){ - this[this.collapseEl].show(this.hideMode); - } - this.afterEffect(anim); - if (this.deferLayout) { - delete this.deferLayout; - this.doLayout(true); - } - this.fireEvent('expand', this); - }, - - toggleCollapse : function(animate){ - this[this.collapsed ? 'expand' : 'collapse'](animate); - return this; - }, +Ext.define('Ext.fx.target.ElementCSS', { - onDisable : function(){ - if(this.rendered && this.maskDisabled){ - this.el.mask(); - } - Ext.Panel.superclass.onDisable.call(this); - }, - - onEnable : function(){ - if(this.rendered && this.maskDisabled){ - this.el.unmask(); - } - Ext.Panel.superclass.onEnable.call(this); - }, + extend: 'Ext.fx.target.Element', - onResize : function(adjWidth, adjHeight, rawWidth, rawHeight){ - var w = adjWidth, - h = adjHeight; - - if(Ext.isDefined(w) || Ext.isDefined(h)){ - if(!this.collapsed){ - - - - if(Ext.isNumber(w)){ - this.body.setWidth(w = this.adjustBodyWidth(w - this.getFrameWidth())); - } else if (w == 'auto') { - w = this.body.setWidth('auto').dom.offsetWidth; - } else { - w = this.body.dom.offsetWidth; + setAttr: function(targetData, isFirstFrame) { + var cssArr = { + attrs: [], + duration: [], + easing: [] + }, + ln = targetData.length, + attributes, + attrs, + attr, + easing, + duration, + o, + i, + j, + ln2; + for (i = 0; i < ln; i++) { + attrs = targetData[i]; + duration = attrs.duration; + easing = attrs.easing; + attrs = attrs.attrs; + for (attr in attrs) { + if (Ext.Array.indexOf(cssArr.attrs, attr) == -1) { + cssArr.attrs.push(attr.replace(/[A-Z]/g, function(v) { + return '-' + v.toLowerCase(); + })); + cssArr.duration.push(duration + 'ms'); + cssArr.easing.push(easing); } + } + } + attributes = cssArr.attrs.join(','); + duration = cssArr.duration.join(','); + easing = cssArr.easing.join(', '); + for (i = 0; i < ln; i++) { + attrs = targetData[i].attrs; + for (attr in attrs) { + ln2 = attrs[attr].length; + for (j = 0; j < ln2; j++) { + o = attrs[attr][j]; + o[0].setStyle(Ext.supports.CSS3Prefix + 'TransitionProperty', isFirstFrame ? '' : attributes); + o[0].setStyle(Ext.supports.CSS3Prefix + 'TransitionDuration', isFirstFrame ? '' : duration); + o[0].setStyle(Ext.supports.CSS3Prefix + 'TransitionTimingFunction', isFirstFrame ? '' : easing); + o[0].setStyle(attr, o[1]); - if(this.tbar){ - this.tbar.setWidth(w); - if(this.topToolbar){ - this.topToolbar.setSize(w); + + if (isFirstFrame) { + o = o[0].dom.offsetWidth; } - } - if(this.bbar){ - this.bbar.setWidth(w); - if(this.bottomToolbar){ - this.bottomToolbar.setSize(w); + else { - if (Ext.isIE) { - this.bbar.setStyle('position', 'static'); - this.bbar.setStyle('position', ''); - } + o[0].on(Ext.supports.CSS3TransitionEnd, function() { + this.setStyle(Ext.supports.CSS3Prefix + 'TransitionProperty', null); + this.setStyle(Ext.supports.CSS3Prefix + 'TransitionDuration', null); + this.setStyle(Ext.supports.CSS3Prefix + 'TransitionTimingFunction', null); + }, o[0], { single: true }); } } - if(this.footer){ - this.footer.setWidth(w); - if(this.fbar){ - this.fbar.setSize(Ext.isIE ? (w - this.footer.getFrameWidth('lr')) : 'auto'); - } - } - - - if(Ext.isNumber(h)){ - h = Math.max(0, h - this.getFrameHeight()); - - this.body.setHeight(h); - }else if(h == 'auto'){ - this.body.setHeight(h); - } - - if(this.disabled && this.el._mask){ - this.el._mask.setSize(this.el.dom.clientWidth, this.el.getHeight()); - } - }else{ - - this.queuedBodySize = {width: w, height: h}; - if(!this.queuedExpand && this.allowQueuedExpand !== false){ - this.queuedExpand = true; - this.on('expand', function(){ - delete this.queuedExpand; - this.onResize(this.queuedBodySize.width, this.queuedBodySize.height); - }, this, {single:true}); - } } - this.onBodyResize(w, h); } - this.syncShadow(); - Ext.Panel.superclass.onResize.call(this, adjWidth, adjHeight, rawWidth, rawHeight); + } +}); - }, +Ext.define('Ext.fx.target.CompositeElementCSS', { - onBodyResize: function(w, h){ - this.fireEvent('bodyresize', this, w, h); - }, + + extend: 'Ext.fx.target.CompositeElement', + + requires: ['Ext.fx.target.ElementCSS'], - getToolbarHeight: function(){ - var h = 0; - if(this.rendered){ - Ext.each(this.toolbars, function(tb){ - h += tb.getHeight(); - }, this); - } - return h; - }, + setAttr: function() { + return Ext.fx.target.ElementCSS.prototype.setAttr.apply(this, arguments); + } +}); + +Ext.define('Ext.layout.container.AbstractFit', { - adjustBodyHeight : function(h){ - return h; - }, + + extend: 'Ext.layout.container.Container', - adjustBodyWidth : function(w){ - return w; - }, + + itemCls: Ext.baseCSSPrefix + 'fit-item', + targetCls: Ext.baseCSSPrefix + 'layout-fit', + type: 'fit' +}); + +Ext.define('Ext.layout.container.Fit', { - onPosition : function(){ - this.syncShadow(); - }, + extend: 'Ext.layout.container.AbstractFit', + alias: 'layout.fit', + alternateClassName: 'Ext.layout.FitLayout', + + + - getFrameWidth : function(){ - var w = this.el.getFrameWidth('lr') + this.bwrap.getFrameWidth('lr'); + onLayout : function() { + var me = this; + me.callParent(); - if(this.frame){ - var l = this.bwrap.dom.firstChild; - w += (Ext.fly(l).getFrameWidth('l') + Ext.fly(l.firstChild).getFrameWidth('r')); - w += this.mc.getFrameWidth('lr'); + if (me.owner.items.length) { + me.setItemBox(me.owner.items.get(0), me.getLayoutTargetSize()); } - return w; }, - - getFrameHeight : function() { - var h = this.el.getFrameWidth('tb') + this.bwrap.getFrameWidth('tb'); - h += (this.tbar ? this.tbar.getHeight() : 0) + - (this.bbar ? this.bbar.getHeight() : 0); + getTargetBox : function() { + return this.getLayoutTargetSize(); + }, - if(this.frame){ - h += this.el.dom.firstChild.offsetHeight + this.ft.dom.offsetHeight + this.mc.getFrameWidth('tb'); - }else{ - h += (this.header ? this.header.getHeight() : 0) + - (this.footer ? this.footer.getHeight() : 0); + setItemBox : function(item, box) { + var me = this; + if (item && box.height > 0) { + if (me.isManaged('width') === true) { + box.width = undefined; + } + if (me.isManaged('height') === true) { + box.height = undefined; + } + me.setItemSize(item, box.width, box.height); } - return h; - }, + } +}); + + +Ext.define('Ext.layout.container.AbstractCard', { - getInnerWidth : function(){ - return this.getSize().width - this.getFrameWidth(); - }, + + extend: 'Ext.layout.container.Fit', - getInnerHeight : function(){ - return this.body.getHeight(); - - }, + + type: 'card', + + sizeAllCards: false, + + hideInactive: true, - syncShadow : function(){ - if(this.floating){ - this.el.sync(true); + deferredRender : false, + + beforeLayout: function() { + var me = this; + me.activeItem = me.getActiveItem(); + if (me.activeItem && me.deferredRender) { + me.renderItems([me.activeItem], me.getRenderTarget()); + return true; + } + else { + return this.callParent(arguments); } }, - - getLayoutTarget : function(){ - return this.body; + onLayout: function() { + var me = this, + activeItem = me.activeItem, + items = me.getVisibleItems(), + ln = items.length, + targetBox = me.getTargetBox(), + i, item; + + for (i = 0; i < ln; i++) { + item = items[i]; + me.setItemBox(item, targetBox); + } + + if (!me.firstActivated && activeItem) { + if (activeItem.fireEvent('beforeactivate', activeItem) !== false) { + activeItem.fireEvent('activate', activeItem); + } + me.firstActivated = true; + } }, - - getContentTarget : function(){ - return this.body; + isValidParent : function(item, target, position) { + + + var itemEl = item.el ? item.el.dom : Ext.getDom(item); + return (itemEl && itemEl.parentNode === (target.dom || target)) || false; }, - setTitle : function(title, iconCls){ - this.title = title; - if(this.header && this.headerAsText){ - this.header.child('span').update(title); + getActiveItem: function() { + var me = this; + if (!me.activeItem && me.owner) { + me.activeItem = me.parseActiveItem(me.owner.activeItem); } - if(iconCls){ - this.setIconClass(iconCls); + + if (me.activeItem && me.owner.items.indexOf(me.activeItem) != -1) { + return me.activeItem; } - this.fireEvent('titlechange', this, title); - return this; - }, - - getUpdater : function(){ - return this.body.getUpdater(); + return null; }, - - load : function(){ - var um = this.body.getUpdater(); - um.update.apply(um, arguments); - return this; + + parseActiveItem: function(item) { + if (item && item.isComponent) { + return item; + } + else if (typeof item == 'number' || item === undefined) { + return this.getLayoutItems()[item || 0]; + } + else { + return this.owner.getComponent(item); + } }, - beforeDestroy : function(){ - Ext.Panel.superclass.beforeDestroy.call(this); - if(this.header){ - this.header.removeAllListeners(); - } - if(this.tools){ - for(var k in this.tools){ - Ext.destroy(this.tools[k]); - } + configureItem: function(item, position) { + this.callParent([item, position]); + if (this.hideInactive && this.activeItem !== item) { + item.hide(); } - if(this.toolbars.length > 0){ - Ext.each(this.toolbars, function(tb){ - tb.un('afterlayout', this.syncHeight, this); - tb.un('remove', this.syncHeight, this); - }, this); + else { + item.show(); } - if(Ext.isArray(this.buttons)){ - while(this.buttons.length) { - Ext.destroy(this.buttons[0]); + }, + + onRemove: function(component) { + if (component === this.activeItem) { + this.activeItem = null; + if (this.owner.items.getCount() === 0) { + this.firstActivated = false; } } - if(this.rendered){ - Ext.destroy( - this.ft, - this.header, - this.footer, - this.tbar, - this.bbar, - this.body, - this.mc, - this.bwrap, - this.dd - ); - if (this.fbar) { - Ext.destroy( - this.fbar, - this.fbar.el - ); - } + }, + + + getAnimation: function(newCard, owner) { + var newAnim = (newCard || {}).cardSwitchAnimation; + if (newAnim === false) { + return false; } - Ext.destroy(this.toolbars); + return newAnim || owner.cardSwitchAnimation; }, - createClasses : function(){ - this.headerCls = this.baseCls + '-header'; - this.headerTextCls = this.baseCls + '-header-text'; - this.bwrapCls = this.baseCls + '-bwrap'; - this.tbarCls = this.baseCls + '-tbar'; - this.bodyCls = this.baseCls + '-body'; - this.bbarCls = this.baseCls + '-bbar'; - this.footerCls = this.baseCls + '-footer'; + getNext: function(wrap) { + + + + var items = this.getLayoutItems(), + index = Ext.Array.indexOf(items, this.activeItem); + return items[index + 1] || (wrap ? items[0] : false); }, - createGhost : function(cls, useShim, appendTo){ - var el = document.createElement('div'); - el.className = 'x-panel-ghost ' + (cls ? cls : ''); - if(this.header){ - el.appendChild(this.el.dom.firstChild.cloneNode(true)); - } - Ext.fly(el.appendChild(document.createElement('ul'))).setHeight(this.bwrap.getHeight()); - el.style.width = this.el.dom.offsetWidth + 'px';; - if(!appendTo){ - this.container.dom.appendChild(el); - }else{ - Ext.getDom(appendTo).appendChild(el); - } - if(useShim !== false && this.el.useShim !== false){ - var layer = new Ext.Layer({shadow:false, useDisplay:true, constrain:false}, el); - layer.show(); - return layer; - }else{ - return new Ext.Element(el); - } + next: function(anim, wrap) { + + + + return this.setActiveItem(this.getNext(wrap), anim); }, - doAutoLoad : function(){ - var u = this.body.getUpdater(); - if(this.renderer){ - u.setRenderer(this.renderer); - } - u.update(Ext.isObject(this.autoLoad) ? this.autoLoad : {url: this.autoLoad}); + getPrev: function(wrap) { + + + + var items = this.getLayoutItems(), + index = Ext.Array.indexOf(items, this.activeItem); + return items[index - 1] || (wrap ? items[items.length - 1] : false); }, - getTool : function(id) { - return this.tools[id]; + prev: function(anim, wrap) { + + + + return this.setActiveItem(this.getPrev(wrap), anim); } - - }); -Ext.reg('panel', Ext.Panel); -Ext.Editor = function(field, config){ - if(field.field){ - this.field = Ext.create(field.field, 'textfield'); - config = Ext.apply({}, field); - delete config.field; - }else{ - this.field = field; - } - Ext.Editor.superclass.constructor.call(this, config); -}; -Ext.extend(Ext.Editor, Ext.Component, { - - - allowBlur: true, - - +Ext.define('Ext.selection.Model', { + extend: 'Ext.util.Observable', + alternateClassName: 'Ext.AbstractStoreSelectionModel', + requires: ['Ext.data.StoreManager'], + - value : "", - - alignment: "c-c?", - - offsets: [0, 0], - - shadow : "frame", - constrain : false, + allowDeselect: false, + - swallowKeys : true, + selected: null, - completeOnEnter : true, - cancelOnEsc : true, - updateEl : false, + pruneRemoved: true, - initComponent : function(){ - Ext.Editor.superclass.initComponent.call(this); - this.addEvents( - - "beforestartedit", - - "startedit", - - "beforecomplete", - - "complete", - - "canceledit", + constructor: function(cfg) { + var me = this; + + cfg = cfg || {}; + Ext.apply(me, cfg); + + me.addEvents( - "specialkey" + 'selectionchange' ); - }, - - onRender : function(ct, position){ - this.el = new Ext.Layer({ - shadow: this.shadow, - cls: "x-editor", - parentEl : ct, - shim : this.shim, - shadowOffset: this.shadowOffset || 4, - id: this.id, - constrain: this.constrain - }); - if(this.zIndex){ - this.el.setZIndex(this.zIndex); - } - this.el.setStyle("overflow", Ext.isGecko ? "auto" : "hidden"); - if(this.field.msgTarget != 'title'){ - this.field.msgTarget = 'qtip'; - } - this.field.inEditor = true; - this.mon(this.field, { - scope: this, - blur: this.onBlur, - specialkey: this.onSpecialKey - }); - if(this.field.grow){ - this.mon(this.field, "autosize", this.el.sync, this.el, {delay:1}); - } - this.field.render(this.el).show(); - this.field.getEl().dom.name = ''; - if(this.swallowKeys){ - this.field.el.swallowEvent([ - 'keypress', - 'keydown' - ]); - } + me.modes = { + SINGLE: true, + SIMPLE: true, + MULTI: true + }; + + + me.setSelectionMode(cfg.mode || me.mode); + + + me.selected = Ext.create('Ext.util.MixedCollection'); + + me.callParent(arguments); }, - onSpecialKey : function(field, e){ - var key = e.getKey(), - complete = this.completeOnEnter && key == e.ENTER, - cancel = this.cancelOnEsc && key == e.ESC; - if(complete || cancel){ - e.stopEvent(); - if(complete){ - this.completeEdit(); + bind : function(store, initial){ + var me = this; + + if(!initial && me.store){ + if(store !== me.store && me.store.autoDestroy){ + me.store.destroy(); }else{ - this.cancelEdit(); - } - if(field.triggerBlur){ - field.triggerBlur(); + me.store.un("add", me.onStoreAdd, me); + me.store.un("clear", me.onStoreClear, me); + me.store.un("remove", me.onStoreRemove, me); + me.store.un("update", me.onStoreUpdate, me); } } - this.fireEvent('specialkey', field, e); - }, - - - startEdit : function(el, value){ - if(this.editing){ - this.completeEdit(); - } - this.boundEl = Ext.get(el); - var v = value !== undefined ? value : this.boundEl.dom.innerHTML; - if(!this.rendered){ - this.render(this.parentEl || document.body); + if(store){ + store = Ext.data.StoreManager.lookup(store); + store.on({ + add: me.onStoreAdd, + clear: me.onStoreClear, + remove: me.onStoreRemove, + update: me.onStoreUpdate, + scope: me + }); } - if(this.fireEvent("beforestartedit", this, this.boundEl, v) !== false){ - this.startValue = v; - this.field.reset(); - this.field.setValue(v); - this.realign(true); - this.editing = true; - this.show(); + me.store = store; + if(store && !initial) { + me.refresh(); } }, - - doAutoSize : function(){ - if(this.autoSize){ - var sz = this.boundEl.getSize(), - fs = this.field.getSize(); - - switch(this.autoSize){ - case "width": - this.setSize(sz.width, fs.height); - break; - case "height": - this.setSize(fs.width, sz.height); - break; - case "none": - this.setSize(fs.width, fs.height); - break; - default: - this.setSize(sz.width, sz.height); - } + selectAll: function(silent) { + var selections = this.store.getRange(), + i = 0, + len = selections.length; + + for (; i < len; i++) { + this.doSelect(selections[i], true, silent); } }, - - setSize : function(w, h){ - delete this.field.lastSize; - this.field.setSize(w, h); - if(this.el){ + deselectAll: function() { + var selections = this.getSelection(), + i = 0, + len = selections.length; - if(Ext.isGecko2 || Ext.isOpera || (Ext.isIE7 && Ext.isStrict)){ - - this.el.setSize(w, h); - } - this.el.sync(); + for (; i < len; i++) { + this.doDeselect(selections[i]); } }, - realign : function(autoSize){ - if(autoSize === true){ - this.doAutoSize(); + + + selectWithEvent: function(record, e) { + var me = this; + + switch (me.selectionMode) { + case 'MULTI': + if (e.ctrlKey && me.isSelected(record)) { + me.doDeselect(record, false); + } else if (e.shiftKey && me.lastFocused) { + me.selectRange(me.lastFocused, record, e.ctrlKey); + } 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); + } else { + me.doSelect(record, false); + } + break; + case 'SIMPLE': + if (me.isSelected(record)) { + me.doDeselect(record); + } else { + me.doSelect(record, true); + } + break; + case 'SINGLE': + + if (me.allowDeselect && me.isSelected(record)) { + me.doDeselect(record); + + } else { + me.doSelect(record, false); + } + break; } - this.el.alignTo(this.boundEl, this.alignment, this.offsets); }, - completeEdit : function(remainVisible){ - if(!this.editing){ + selectRange : function(startRow, endRow, keepExisting, dir){ + var me = this, + store = me.store, + selectedCount = 0, + i, + tmp, + dontDeselect, + records = []; + + if (me.isLocked()){ return; } - if (this.field.assertValue) { - this.field.assertValue(); + if (!keepExisting) { + me.clearSelections(); + } + + if (!Ext.isNumber(startRow)) { + startRow = store.indexOf(startRow); + } + if (!Ext.isNumber(endRow)) { + endRow = store.indexOf(endRow); + } + + + if (startRow > endRow){ + tmp = endRow; + endRow = startRow; + startRow = tmp; } - var v = this.getValue(); - if(!this.field.isValid()){ - if(this.revertInvalid !== false){ - this.cancelEdit(remainVisible); + + for (i = startRow; i <= endRow; i++) { + if (me.isSelected(store.getAt(i))) { + selectedCount++; } - return; } - if(String(v) === String(this.startValue) && this.ignoreNoChange){ - this.hideEdit(remainVisible); - return; + + if (!dir) { + dontDeselect = -1; + } else { + dontDeselect = (dir == 'up') ? startRow : endRow; } - if(this.fireEvent("beforecomplete", this, v, this.startValue) !== false){ - v = this.getValue(); - if(this.updateEl && this.boundEl){ - this.boundEl.update(v); + + for (i = startRow; i <= endRow; i++){ + if (selectedCount == (endRow - startRow + 1)) { + if (i != dontDeselect) { + me.doDeselect(i, true); + } + } else { + records.push(store.getAt(i)); } - this.hideEdit(remainVisible); - this.fireEvent("complete", this, v, this.startValue); } + me.doMultiSelect(records, true); }, - - onShow : function(){ - this.el.show(); - if(this.hideEl !== false){ - this.boundEl.hide(); - } - this.field.show().focus(false, true); - this.fireEvent("startedit", this.boundEl, this.startValue); + + select: function(records, keepExisting, suppressEvent) { + this.doSelect(records, keepExisting, suppressEvent); }, - cancelEdit : function(remainVisible){ - if(this.editing){ - var v = this.getValue(); - this.setValue(this.startValue); - this.hideEdit(remainVisible); - this.fireEvent("canceledit", this, v, this.startValue); - } + deselect: function(records, suppressEvent) { + this.doDeselect(records, suppressEvent); }, - - hideEdit: function(remainVisible){ - if(remainVisible !== true){ - this.editing = false; - this.hide(); + doSelect: function(records, keepExisting, suppressEvent) { + var me = this, + record; + + if (me.locked) { + return; + } + if (typeof records === "number") { + records = [me.store.getAt(records)]; + } + if (me.selectionMode == "SINGLE" && records) { + record = records.length ? records[0] : records; + me.doSingleSelect(record, suppressEvent); + } else { + me.doMultiSelect(records, keepExisting, suppressEvent); } }, - - onBlur : function(){ + doMultiSelect: function(records, keepExisting, suppressEvent) { + var me = this, + selected = me.selected, + change = false, + i = 0, + len, record; + + if (me.locked) { + return; + } - if(this.allowBlur === true && this.editing && this.selectSameEditor !== true){ - this.completeEdit(); + + records = !Ext.isArray(records) ? [records] : records; + len = records.length; + if (!keepExisting && selected.getCount() > 0) { + change = true; + me.doDeselect(me.getSelection(), true); + } + + for (; i < len; i++) { + record = records[i]; + if (keepExisting && me.isSelected(record)) { + continue; + } + change = true; + me.lastSelected = record; + selected.add(record); + + me.onSelectChange(record, true, suppressEvent); } + me.setLastFocused(record, suppressEvent); + + me.maybeFireSelectionChange(change && !suppressEvent); }, - onHide : function(){ - if(this.editing){ - this.completeEdit(); + doDeselect: function(records, suppressEvent) { + var me = this, + selected = me.selected, + change = false, + i = 0, + len, record; + + if (me.locked) { return; } - this.field.blur(); - if(this.field.collapse){ - this.field.collapse(); + + if (typeof records === "number") { + records = [me.store.getAt(records)]; } - this.el.hide(); - if(this.hideEl !== false){ - this.boundEl.show(); + + records = !Ext.isArray(records) ? [records] : records; + len = records.length; + for (; i < len; i++) { + record = records[i]; + if (selected.remove(record)) { + if (me.lastSelected == record) { + me.lastSelected = selected.last(); + } + me.onSelectChange(record, false, suppressEvent); + change = true; + } } + + me.maybeFireSelectionChange(change && !suppressEvent); }, - - setValue : function(v){ - this.field.setValue(v); + doSingleSelect: function(record, suppressEvent) { + var me = this, + selected = me.selected; + + if (me.locked) { + return; + } + + + if (me.isSelected(record)) { + return; + } + if (selected.getCount() > 0) { + me.doDeselect(me.lastSelected, suppressEvent); + } + selected.add(record); + me.lastSelected = record; + me.onSelectChange(record, true, suppressEvent); + if (!suppressEvent) { + me.setLastFocused(record); + } + me.maybeFireSelectionChange(!suppressEvent); }, - getValue : function(){ - return this.field.getValue(); + setLastFocused: function(record, supressFocus) { + var me = this, + recordBeforeLast = me.lastFocused; + me.lastFocused = record; + me.onLastFocusChanged(recordBeforeLast, record, supressFocus); + }, + + + isFocused: function(record) { + return record === this.getLastFocused(); }, - beforeDestroy : function(){ - Ext.destroyMembers(this, 'field'); - - delete this.parentEl; - delete this.boundEl; - } -}); -Ext.reg('editor', Ext.Editor); -Ext.ColorPalette = Ext.extend(Ext.Component, { - - itemCls : 'x-color-palette', - value : null, + maybeFireSelectionChange: function(fireEvent) { + if (fireEvent) { + var me = this; + me.fireEvent('selectionchange', me, me.getSelection()); + } + }, + - clickEvent :'click', + getLastSelected: function() { + return this.lastSelected; + }, - ctype : 'Ext.ColorPalette', + getLastFocused: function() { + return this.lastFocused; + }, - allowReselect : false, + getSelection: function() { + return this.selected.getRange(); + }, - colors : [ - '000000', '993300', '333300', '003300', '003366', '000080', '333399', '333333', - '800000', 'FF6600', '808000', '008000', '008080', '0000FF', '666699', '808080', - 'FF0000', 'FF9900', '99CC00', '339966', '33CCCC', '3366FF', '800080', '969696', - 'FF00FF', 'FFCC00', 'FFFF00', '00FF00', '00FFFF', '00CCFF', '993366', 'C0C0C0', - 'FF99CC', 'FFCC99', 'FFFF99', 'CCFFCC', 'CCFFFF', '99CCFF', 'CC99FF', 'FFFFFF' - ], + getSelectionMode: function() { + return this.selectionMode; + }, - - - - initComponent : function(){ - Ext.ColorPalette.superclass.initComponent.call(this); - this.addEvents( - - 'select' - ); - - if(this.handler){ - this.on('select', this.handler, this.scope, true); - } + setSelectionMode: function(selMode) { + selMode = selMode ? selMode.toUpperCase() : 'SINGLE'; + + + this.selectionMode = this.modes[selMode] ? selMode : 'SINGLE'; }, - onRender : function(container, position){ - this.autoEl = { - tag: 'div', - cls: this.itemCls - }; - Ext.ColorPalette.superclass.onRender.call(this, container, position); - var t = this.tpl || new Ext.XTemplate( - ' ' - ); - t.overwrite(this.el, this.colors); - this.mon(this.el, this.clickEvent, this.handleClick, this, {delegate: 'a'}); - if(this.clickEvent != 'click'){ - this.mon(this.el, 'click', Ext.emptyFn, this, {delegate: 'a', preventDefault: true}); - } + isLocked: function() { + return this.locked; }, - afterRender : function(){ - Ext.ColorPalette.superclass.afterRender.call(this); - if(this.value){ - var s = this.value; - this.value = null; - this.select(s, true); - } + setLocked: function(locked) { + this.locked = !!locked; }, - handleClick : function(e, t){ - e.preventDefault(); - if(!this.disabled){ - var c = t.className.match(/(?:^|\s)color-(.{6})(?:\s|$)/)[1]; - this.select(c.toUpperCase()); - } + isSelected: function(record) { + record = Ext.isNumber(record) ? this.store.getAt(record) : record; + return this.selected.indexOf(record) !== -1; }, - - select : function(color, suppressEvent){ - color = color.replace('#', ''); - if(color != this.value || this.allowReselect){ - var el = this.el; - if(this.value){ - el.child('a.color-'+this.value).removeClass('x-color-palette-sel'); - } - el.child('a.color-'+color).addClass('x-color-palette-sel'); - this.value = color; - if(suppressEvent !== true){ - this.fireEvent('select', this, color); + + hasSelection: function() { + return this.selected.getCount() > 0; + }, + + refresh: function() { + var me = this, + toBeSelected = [], + oldSelections = me.getSelection(), + len = oldSelections.length, + selection, + change, + i = 0, + lastFocused = this.getLastFocused(); + + + + + for (; i < len; i++) { + selection = oldSelections[i]; + if (!this.pruneRemoved || me.store.indexOf(selection) !== -1) { + toBeSelected.push(selection); } } - } + + + + if (me.selected.getCount() != toBeSelected.length) { + change = true; + } + + me.clearSelections(); + + if (me.store.indexOf(lastFocused) !== -1) { + + this.setLastFocused(lastFocused, true); + } + + if (toBeSelected.length) { + + me.doSelect(toBeSelected, false, true); + } + + me.maybeFireSelectionChange(change); + }, + + clearSelections: function() { + + var me = this; + me.selected.clear(); + me.lastSelected = null; + me.setLastFocused(null); + }, -}); -Ext.reg('colorpalette', Ext.ColorPalette); -Ext.DatePicker = Ext.extend(Ext.BoxComponent, { - - todayText : 'Today', - - okText : ' OK ', - - cancelText : 'Cancel', - - - - todayTip : '{0} (Spacebar)', - - minText : 'This date is before the minimum date', - - maxText : 'This date is after the maximum date', - - format : 'm/d/y', - - disabledDaysText : 'Disabled', - - disabledDatesText : 'Disabled', - - monthNames : Date.monthNames, - - dayNames : Date.dayNames, - - nextText : 'Next Month (Control+Right)', - - prevText : 'Previous Month (Control+Left)', - - monthYearText : 'Choose a month (Control+Up/Down to move years)', - - startDay : 0, - - showToday : true, - - - - - + onStoreAdd: function() { + + }, - focusOnSelect: true, + onStoreClear: function() { + var me = this, + selected = this.selected; + + if (selected.getCount > 0) { + selected.clear(); + me.lastSelected = null; + me.setLastFocused(null); + me.maybeFireSelectionChange(true); + } + }, - initHour: 12, - - initComponent : function(){ - Ext.DatePicker.superclass.initComponent.call(this); - - this.value = this.value ? - this.value.clearTime(true) : new Date().clearTime(); - - this.addEvents( + onStoreRemove: function(store, record) { + var me = this, + selected = me.selected; - 'select' - ); + if (me.locked || !me.pruneRemoved) { + return; + } - if(this.handler){ - this.on('select', this.handler, this.scope || this); + if (selected.remove(record)) { + if (me.lastSelected == record) { + me.lastSelected = null; + } + if (me.getLastFocused() == record) { + me.setLastFocused(null); + } + me.maybeFireSelectionChange(true); } + }, - this.initDisabledDays(); + getCount: function() { + return this.selected.getCount(); }, - initDisabledDays : function(){ - if(!this.disabledDatesRE && this.disabledDates){ - var dd = this.disabledDates, - len = dd.length - 1, - re = '(?:'; + destroy: function() { - Ext.each(dd, function(d, i){ - re += Ext.isDate(d) ? '^' + Ext.escapeRe(d.dateFormat(this.format)) + '$' : dd[i]; - if(i != len){ - re += '|'; - } - }, this); - this.disabledDatesRE = new RegExp(re + ')'); - } }, - setDisabledDates : function(dd){ - if(Ext.isArray(dd)){ - this.disabledDates = dd; - this.disabledDatesRE = null; - }else{ - this.disabledDatesRE = dd; - } - this.initDisabledDays(); - this.update(this.value, true); + onStoreUpdate: function() { + }, - setDisabledDays : function(dd){ - this.disabledDays = dd; - this.update(this.value, true); + onSelectChange: function(record, isSelected, suppressEvent) { + }, - setMinDate : function(dt){ - this.minDate = dt; - this.update(this.value, true); + onLastFocusChanged: function(oldFocused, newFocused) { + }, - setMaxDate : function(dt){ - this.maxDate = dt; - this.update(this.value, true); + onEditorKey: function(field, e) { + }, - setValue : function(value){ - this.value = value.clearTime(true); - this.update(this.value); - }, + bindComponent: function(cmp) { + + } +}); +Ext.define('Ext.selection.DataViewModel', { + extend: 'Ext.selection.Model', - getValue : function(){ - return this.value; - }, + requires: ['Ext.util.KeyNav'], + deselectOnContainerClick: true, - focus : function(){ - this.update(this.activeDate); + + enableKeyNav: true, + + constructor: function(cfg){ + this.addEvents( + + 'deselect', + + + 'select' + ); + this.callParent(arguments); }, - - onEnable: function(initial){ - Ext.DatePicker.superclass.onEnable.call(this); - this.doDisabled(false); - this.update(initial ? this.value : this.activeDate); - if(Ext.isIE){ - this.el.repaint(); + bindComponent: function(view) { + var me = this, + eventListeners = { + refresh: me.refresh, + scope: me + }; + + me.view = view; + me.bind(view.getStore()); + + view.on(view.triggerEvent, me.onItemClick, me); + view.on(view.triggerCtEvent, me.onContainerClick, me); + + view.on(eventListeners); + + if (me.enableKeyNav) { + me.initKeyNav(view); } + }, + onItemClick: function(view, record, item, index, e) { + this.selectWithEvent(record, e); }, + onContainerClick: function() { + if (this.deselectOnContainerClick) { + this.deselectAll(); + } + }, - onDisable : function(){ - Ext.DatePicker.superclass.onDisable.call(this); - this.doDisabled(true); - if(Ext.isIE && !Ext.isIE8){ - - Ext.each([].concat(this.textNodes, this.el.query('th span')), function(el){ - Ext.fly(el).repaint(); - }); + 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 + }); + me.keyNav = Ext.create('Ext.util.KeyNav', view.el, { + down: Ext.pass(me.onNavKey, [1], me), + right: Ext.pass(me.onNavKey, [1], me), + left: Ext.pass(me.onNavKey, [-1], me), + up: Ext.pass(me.onNavKey, [-1], me), + scope: me + }); }, - - doDisabled : function(disabled){ - this.keyNav.setDisabled(disabled); - this.prevRepeater.setDisabled(disabled); - this.nextRepeater.setDisabled(disabled); - if(this.showToday){ - this.todayKeyListener.setDisabled(disabled); - this.todayBtn.setDisabled(disabled); + onNavKey: function(step) { + step = step || 1; + var me = this, + view = me.view, + 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); }, - onRender : function(container, position){ - var m = [ - '', - '', - '', - this.showToday ? '' : '', - '
      
    '], - dn = this.dayNames, - i; - for(i = 0; i < 7; i++){ - var d = this.startDay+i; - if(d > 6){ - d = d-7; + onSelectChange: function(record, isSelected, suppressEvent) { + var me = this, + view = me.view, + allowSelect = true; + + if (isSelected) { + if (!suppressEvent) { + allowSelect = me.fireEvent('beforeselect', me, record) !== false; } - m.push(''); - } - m[m.length] = ''; - for(i = 0; i < 42; i++) { - if(i % 7 === 0 && i !== 0){ - m[m.length] = ''; + if (allowSelect) { + view.onItemSelect(record); + if (!suppressEvent) { + me.fireEvent('select', me, record); + } + } + } else { + view.onItemDeselect(record); + if (!suppressEvent) { + me.fireEvent('deselect', me, record); } - m[m.length] = ''; } - m.push('
    ', dn[d].substr(0,1), '
    '); - - var el = document.createElement('div'); - el.className = 'x-date-picker'; - el.innerHTML = m.join(''); - - container.dom.insertBefore(el, position); - - this.el = Ext.get(el); - this.eventEl = Ext.get(el.firstChild); + } +}); - this.prevRepeater = new Ext.util.ClickRepeater(this.el.child('td.x-date-left a'), { - handler: this.showPrevMonth, - scope: this, - preventDefault:true, - stopDefault:true - }); - this.nextRepeater = new Ext.util.ClickRepeater(this.el.child('td.x-date-right a'), { - handler: this.showNextMonth, - scope: this, - preventDefault:true, - stopDefault:true - }); +Ext.define('Ext.state.CookieProvider', { + extend: 'Ext.state.Provider', - this.monthPicker = this.el.down('div.x-date-mp'); - this.monthPicker.enableDisplayMode('block'); + constructor : function(config){ + var me = this; + me.path = "/"; + me.expires = new Date(new Date().getTime()+(1000*60*60*24*7)); + me.domain = null; + me.secure = false; + me.callParent(arguments); + me.state = me.readCookies(); + }, + + + set : function(name, value){ + var me = this; + + if(typeof value == "undefined" || value === null){ + me.clear(name); + return; + } + me.setCookie(name, value); + me.callParent(arguments); + }, - this.keyNav = new Ext.KeyNav(this.eventEl, { - 'left' : function(e){ - if(e.ctrlKey){ - this.showPrevMonth(); - }else{ - this.update(this.activeDate.add('d', -1)); - } - }, + + clear : function(name){ + this.clearCookie(name); + this.callParent(arguments); + }, - 'right' : function(e){ - if(e.ctrlKey){ - this.showNextMonth(); - }else{ - this.update(this.activeDate.add('d', 1)); - } - }, + + readCookies : function(){ + var cookies = {}, + c = document.cookie + ";", + re = /\s?(.*?)=(.*?);/g, + prefix = this.prefix, + len = prefix.length, + matches, + name, + value; + + while((matches = re.exec(c)) != null){ + name = matches[1]; + value = matches[2]; + if (name && name.substring(0, len) == prefix){ + cookies[name.substr(len)] = this.decodeValue(value); + } + } + return cookies; + }, - 'up' : function(e){ - if(e.ctrlKey){ - this.showNextYear(); - }else{ - this.update(this.activeDate.add('d', -7)); - } - }, + + 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)) + + ((me.domain == null) ? "" : ("; domain=" + me.domain)) + + ((me.secure == true) ? "; secure" : ""); + }, - 'down' : function(e){ - if(e.ctrlKey){ - this.showPrevYear(); - }else{ - this.update(this.activeDate.add('d', 7)); - } - }, + + 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)) + + ((me.secure == true) ? "; secure" : ""); + } +}); - 'pageUp' : function(e){ - this.showNextMonth(); - }, +Ext.define('Ext.state.LocalStorageProvider', { + + + extend: 'Ext.state.Provider', + + alias: 'state.localstorage', + + + + constructor: function(){ + var me = this; + me.callParent(arguments); + me.store = me.getStorageObject(); + me.state = me.readLocalStorage(); + }, + + readLocalStorage: function(){ + var store = this.store, + i = 0, + len = store.length, + prefix = this.prefix, + prefixLen = prefix.length, + data = {}, + key; + + for (; i < len; ++i) { + key = store.key(i); + if (key.substring(0, prefixLen) == prefix) { + data[key.substr(prefixLen)] = this.decodeValue(store.getItem(key)); + } + } + return data; + }, + + set : function(name, value){ + var me = this; + + me.clear(name); + if (typeof value == "undefined" || value === null) { + return; + } + me.store.setItem(me.prefix + name, me.encodeValue(value)); + me.callParent(arguments); + }, - 'pageDown' : function(e){ - this.showPrevMonth(); - }, + + clear : function(name){ + this.store.removeItem(this.prefix + name); + this.callParent(arguments); + }, + + getStorageObject: function(){ + try { + var supports = 'localStorage' in window && window['localStorage'] !== null; + if (supports) { + return window.localStorage; + } + } catch (e) { + return false; + } + Ext.Error.raise('LocalStorage is not supported by the current browser'); + } +}); - 'enter' : function(e){ - e.stopPropagation(); - return true; - }, - scope : this - }); - this.el.unselectable(); +Ext.define('Ext.util.Point', { - this.cells = this.el.select('table.x-date-inner tbody td'); - this.textNodes = this.el.query('table.x-date-inner tbody span'); + + extend: 'Ext.util.Region', - this.mbtn = new Ext.Button({ - text: ' ', - tooltip: this.monthYearText, - renderTo: this.el.child('td.x-date-middle', true) - }); - this.mbtn.el.child('em').addClass('x-btn-arrow'); + statics: { - if(this.showToday){ - this.todayKeyListener = this.eventEl.addKeyListener(Ext.EventObject.SPACE, this.selectToday, this); - var today = (new Date()).dateFormat(this.format); - this.todayBtn = new Ext.Button({ - renderTo: this.el.child('td.x-date-bottom', true), - text: String.format(this.todayText, today), - tooltip: String.format(this.todayTip, today), - handler: this.selectToday, - scope: this - }); + + fromEvent: function(e) { + e = (e.changedTouches && e.changedTouches.length > 0) ? e.changedTouches[0] : e; + return new this(e.pageX, e.pageY); } - this.mon(this.eventEl, 'mousewheel', this.handleMouseWheel, this); - this.mon(this.eventEl, 'click', this.handleDateClick, this, {delegate: 'a.x-date-date'}); - this.mon(this.mbtn, 'click', this.showMonthPicker, this); - this.onEnable(true); }, - createMonthPicker : function(){ - if(!this.monthPicker.dom.firstChild){ - var buf = ['']; - for(var i = 0; i < 6; i++){ - buf.push( - '', - '', - i === 0 ? - '' : - '' - ); - } - buf.push( - '', - '
    ', Date.getShortMonthName(i), '', Date.getShortMonthName(i + 6), '
    ' - ); - this.monthPicker.update(buf.join('')); - this.mon(this.monthPicker, 'click', this.onMonthClick, this); - this.mon(this.monthPicker, 'dblclick', this.onMonthDblClick, this); + constructor: function(x, y) { + this.callParent([y, x, y, x]); + }, + + + toString: function() { + return "Point[" + this.x + "," + this.y + "]"; + }, - this.mpMonths = this.monthPicker.select('td.x-date-mp-month'); - this.mpYears = this.monthPicker.select('td.x-date-mp-year'); + + equals: function(p) { + return (this.x == p.x && this.y == p.y); + }, - this.mpMonths.each(function(m, a, i){ - i += 1; - if((i%2) === 0){ - m.dom.xmonth = 5 + Math.round(i * 0.5); - }else{ - m.dom.xmonth = Math.round((i-1) * 0.5); - } - }); + + isWithin: function(p, threshold) { + if (!Ext.isObject(threshold)) { + threshold = { + x: threshold, + y: threshold + }; } + + return (this.x <= p.x + threshold.x && this.x >= p.x - threshold.x && + this.y <= p.y + threshold.y && this.y >= p.y - threshold.y); }, - showMonthPicker : function(){ - if(!this.disabled){ - this.createMonthPicker(); - var size = this.el.getSize(); - this.monthPicker.setSize(size); - this.monthPicker.child('table').setSize(size); + roundedEquals: function(p) { + return (Math.round(this.x) == Math.round(p.x) && Math.round(this.y) == Math.round(p.y)); + } +}, function() { + + this.prototype.translate = Ext.util.Region.prototype.translateBy; +}); - this.mpSelMonth = (this.activeDate || this.value).getMonth(); - this.updateMPMonth(this.mpSelMonth); - this.mpSelYear = (this.activeDate || this.value).getFullYear(); - this.updateMPYear(this.mpSelYear); - this.monthPicker.slideIn('t', {duration:0.2}); +Ext.define('Ext.view.AbstractView', { + extend: 'Ext.Component', + alternateClassName: 'Ext.view.AbstractView', + requires: [ + 'Ext.LoadMask', + 'Ext.data.StoreManager', + 'Ext.CompositeElementLite', + 'Ext.DomQuery', + 'Ext.selection.DataViewModel' + ], + + inheritableStatics: { + getRecord: function(node) { + return this.getBoundView(node).getRecord(node); + }, + + getBoundView: function(node) { + return Ext.getCmp(node.boundView); } }, + + + - updateMPYear : function(y){ - this.mpyear = y; - var ys = this.mpYears.elements; - for(var i = 1; i <= 10; i++){ - var td = ys[i-1], y2; - if((i%2) === 0){ - y2 = y + Math.round(i * 0.5); - td.firstChild.innerHTML = y2; - td.xyear = y2; - }else{ - y2 = y - (5-Math.round(i * 0.5)); - td.firstChild.innerHTML = y2; - td.xyear = y2; - } - this.mpYears.item(i-1)[y2 == this.mpSelYear ? 'addClass' : 'removeClass']('x-date-mp-sel'); - } - }, + + + itemCls: Ext.baseCSSPrefix + 'dataview-item', + + - updateMPMonth : function(sm){ - this.mpMonths.each(function(m, a, i){ - m[m.dom.xmonth == sm ? 'addClass' : 'removeClass']('x-date-mp-sel'); - }); - }, - selectMPMonth : function(m){ + loadingText: 'Loading...', + + + + + loadingUseMsg: true, + - }, + - onMonthClick : function(e, t){ - e.stopEvent(); - var el = new Ext.Element(t), pn; - if(el.is('button.x-date-mp-cancel')){ - this.hideMonthPicker(); - } - else if(el.is('button.x-date-mp-ok')){ - var d = new Date(this.mpSelYear, this.mpSelMonth, (this.activeDate || this.value).getDate()); - if(d.getMonth() != this.mpSelMonth){ - - d = new Date(this.mpSelYear, this.mpSelMonth, 1).getLastDateOfMonth(); - } - this.update(d); - this.hideMonthPicker(); - } - else if((pn = el.up('td.x-date-mp-month', 2))){ - this.mpMonths.removeClass('x-date-mp-sel'); - pn.addClass('x-date-mp-sel'); - this.mpSelMonth = pn.dom.xmonth; - } - else if((pn = el.up('td.x-date-mp-year', 2))){ - this.mpYears.removeClass('x-date-mp-sel'); - pn.addClass('x-date-mp-sel'); - this.mpSelYear = pn.dom.xyear; - } - else if(el.is('a.x-date-mp-prev')){ - this.updateMPYear(this.mpyear-10); - } - else if(el.is('a.x-date-mp-next')){ - this.updateMPYear(this.mpyear+10); - } - }, + selectedItemCls: Ext.baseCSSPrefix + 'item-selected', - onMonthDblClick : function(e, t){ - e.stopEvent(); - var el = new Ext.Element(t), pn; - if((pn = el.up('td.x-date-mp-month', 2))){ - this.update(new Date(this.mpSelYear, pn.dom.xmonth, (this.activeDate || this.value).getDate())); - this.hideMonthPicker(); - } - else if((pn = el.up('td.x-date-mp-year', 2))){ - this.update(new Date(pn.dom.xyear, this.mpSelMonth, (this.activeDate || this.value).getDate())); - this.hideMonthPicker(); - } - }, + emptyText: "", - hideMonthPicker : function(disableAnim){ - if(this.monthPicker){ - if(disableAnim === true){ - this.monthPicker.hide(); - }else{ - this.monthPicker.slideOut('t', {duration:0.2}); - } - } - }, + deferEmptyText: true, - showPrevMonth : function(e){ - this.update(this.activeDate.add('mo', -1)); - }, + trackOver: false, - showNextMonth : function(e){ - this.update(this.activeDate.add('mo', 1)); - }, + blockRefresh: false, - showPrevYear : function(){ - this.update(this.activeDate.add('y', -1)); - }, + - showNextYear : function(){ - this.update(this.activeDate.add('y', 1)); + last: false, + + triggerEvent: 'itemclick', + triggerCtEvent: 'containerclick', + + addCmpEvents: function() { + }, - handleMouseWheel : function(e){ - e.stopEvent(); - if(!this.disabled){ - var delta = e.getWheelDelta(); - if(delta > 0){ - this.showPrevMonth(); - } else if(delta < 0){ - this.showNextMonth(); + initComponent : function(){ + var me = this, + isDef = Ext.isDefined, + itemTpl = me.itemTpl, + memberFn = {}; + + if (itemTpl) { + if (Ext.isArray(itemTpl)) { + + itemTpl = itemTpl.join(''); + } else if (Ext.isObject(itemTpl)) { + + 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); } - }, - - handleDateClick : function(e, t){ - e.stopEvent(); - if(!this.disabled && t.dateValue && !Ext.fly(t.parentNode).hasClass('x-date-disabled')){ - this.cancelFocus = this.focusOnSelect === false; - this.setValue(new Date(t.dateValue)); - delete this.cancelFocus; - this.fireEvent('select', this, this.value); + 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." + }); } - }, - - selectToday : function(){ - if(this.todayBtn && !this.todayBtn.disabled){ - this.setValue(new Date().clearTime()); - this.fireEvent('select', this, this.value); + me.callParent(); + if(Ext.isString(me.tpl) || Ext.isArray(me.tpl)){ + me.tpl = Ext.create('Ext.XTemplate', me.tpl); } - }, - - update : function(date, forceRefresh){ - if(this.rendered){ - var vd = this.activeDate, vis = this.isVisible(); - this.activeDate = date; - if(!forceRefresh && vd && this.el){ - var t = date.getTime(); - if(vd.getMonth() == date.getMonth() && vd.getFullYear() == date.getFullYear()){ - this.cells.removeClass('x-date-selected'); - this.cells.each(function(c){ - if(c.dom.firstChild.dateValue == t){ - c.addClass('x-date-selected'); - if(vis && !this.cancelFocus){ - Ext.fly(c.dom.firstChild).focus(50); - } - return false; - } - }, this); - return; - } + + + 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.'); } - var days = date.getDaysInMonth(), - firstOfMonth = date.getFirstDateOfMonth(), - startingPos = firstOfMonth.getDay()-this.startDay; + me.overItemCls = me.overCls || me.overClass; + delete me.overCls; + delete me.overClass; + } - if(startingPos < 0){ - startingPos += 7; + 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.'); } - days += startingPos; + me.selectedItemCls = me.selectedCls || me.selectedClass; + delete me.selectedCls; + delete me.selectedClass; + } + + me.addEvents( + + 'beforerefresh', + + 'refresh', + + 'itemupdate', + + 'itemadd', + + 'itemremove' + ); - var pm = date.add('mo', -1), - prevStart = pm.getDaysInMonth()-startingPos, - cells = this.cells.elements, - textEls = this.textNodes, - - d = (new Date(pm.getFullYear(), pm.getMonth(), prevStart, this.initHour)), - today = new Date().clearTime().getTime(), - sel = date.clearTime(true).getTime(), - min = this.minDate ? this.minDate.clearTime(true) : Number.NEGATIVE_INFINITY, - max = this.maxDate ? this.maxDate.clearTime(true) : Number.POSITIVE_INFINITY, - ddMatch = this.disabledDatesRE, - ddText = this.disabledDatesText, - ddays = this.disabledDays ? this.disabledDays.join('') : false, - ddaysText = this.disabledDaysText, - format = this.format; + me.addCmpEvents(); - if(this.showToday){ - var td = new Date().clearTime(), - disable = (td < min || td > max || - (ddMatch && format && ddMatch.test(td.dateFormat(format))) || - (ddays && ddays.indexOf(td.getDay()) != -1)); + if (me.store) { + me.store = Ext.data.StoreManager.lookup(me.store); + } + me.all = new Ext.CompositeElementLite(); + me.getSelectionModel().bindComponent(me); + }, - if(!this.disabled){ - this.todayBtn.setDisabled(disable); - this.todayKeyListener[disable ? 'disable' : 'enable'](); - } - } + onRender: function() { + var me = this, + loadingText = me.loadingText, + loadingHeight = me.loadingHeight, + undef; - var setCellClass = function(cal, cell){ - cell.title = ''; - var t = d.clearTime(true).getTime(); - cell.firstChild.dateValue = t; - if(t == today){ - cell.className += ' x-date-today'; - cell.title = cal.todayText; - } - if(t == sel){ - cell.className += ' x-date-selected'; - if(vis){ - Ext.fly(cell.firstChild).focus(50); - } - } - - if(t < min) { - cell.className = ' x-date-disabled'; - cell.title = cal.minText; - return; - } - if(t > max) { - cell.className = ' x-date-disabled'; - cell.title = cal.maxText; - return; - } - if(ddays){ - if(ddays.indexOf(d.getDay()) != -1){ - cell.title = ddaysText; - cell.className = ' x-date-disabled'; - } - } - if(ddMatch && format){ - var fvalue = d.dateFormat(format); - if(ddMatch.test(fvalue)){ - cell.title = ddText.replace('%0', fvalue); - cell.className = ' x-date-disabled'; + me.callParent(arguments); + if (loadingText) { + + + + + + 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); + } } } - }; - - var i = 0; - for(; i < startingPos; i++) { - textEls[i].innerHTML = (++prevStart); - d.setDate(d.getDate()+1); - cells[i].className = 'x-date-prevday'; - setCellClass(this, cells[i]); - } - for(; i < days; i++){ - var intDay = i - startingPos + 1; - textEls[i].innerHTML = (intDay); - d.setDate(d.getDate()+1); - cells[i].className = 'x-date-active'; - setCellClass(this, cells[i]); - } - var extraDays = 0; - for(; i < 42; i++) { - textEls[i].innerHTML = (++extraDays); - d.setDate(d.getDate()+1); - cells[i].className = 'x-date-nextday'; - setCellClass(this, cells[i]); - } - - this.mbtn.setText(this.monthNames[date.getMonth()] + ' ' + date.getFullYear()); - - if(!this.internalRender){ - var main = this.el.dom.firstChild, - w = main.offsetWidth; - this.el.setWidth(w + this.el.getBorderWidth('lr')); - Ext.fly(main).setWidth(w); - this.internalRender = true; - - - - if(Ext.isOpera && !this.secondPass){ - main.rows[0].cells[1].style.width = (w - (main.rows[0].cells[0].offsetWidth+main.rows[0].cells[2].offsetWidth)) + 'px'; - this.secondPass = true; - this.update.defer(10, this, [date]); - } - } + }); } }, - - beforeDestroy : function() { - if(this.rendered){ - Ext.destroy( - this.keyNav, - this.monthPicker, - this.eventEl, - this.mbtn, - this.nextRepeater, - this.prevRepeater, - this.cells.el, - this.todayBtn - ); - delete this.textNodes; - delete this.cells.elements; - } - } + getSelectionModel: function(){ + var me = this, + mode = 'SINGLE'; - -}); + if (!me.selModel) { + me.selModel = {}; + } -Ext.reg('datepicker', Ext.DatePicker); + if (me.simpleSelect) { + mode = 'SIMPLE'; + } else if (me.multiSelect) { + mode = 'MULTI'; + } -Ext.LoadMask = function(el, config){ - this.el = Ext.get(el); - Ext.apply(this, config); - if(this.store){ - this.store.on({ - scope: this, - beforeload: this.onBeforeLoad, - load: this.onLoad, - exception: this.onLoad + Ext.applyIf(me.selModel, { + allowDeselect: me.allowDeselect, + mode: mode }); - this.removeMask = Ext.value(this.removeMask, false); - }else{ - var um = this.el.getUpdater(); - um.showLoadIndicator = false; - um.on({ - scope: this, - beforeupdate: this.onBeforeLoad, - update: this.onLoad, - failure: this.onLoad - }); - this.removeMask = Ext.value(this.removeMask, true); - } -}; -Ext.LoadMask.prototype = { - - - - msg : 'Loading...', - - msgCls : 'x-mask-loading', + if (!me.selModel.events) { + me.selModel = Ext.create('Ext.selection.DataViewModel', me.selModel); + } - - disabled: false, + if (!me.selModel.hasRelaySetup) { + me.relayEvents(me.selModel, ['selectionchange', 'beforeselect', 'select', 'deselect']); + me.selModel.hasRelaySetup = true; + } - - disable : function(){ - this.disabled = true; - }, + + + if (me.disableSelection) { + me.selModel.locked = true; + } - - enable : function(){ - this.disabled = false; + return me.selModel; }, - onLoad : function(){ - this.el.unmask(this.removeMask); - }, + refresh: function() { + var me = this, + el, + records; + + if (!me.rendered) { + return; + } + + me.fireEvent('beforerefresh', me); + el = me.getTargetEl(); + records = me.store.getRange(); - - onBeforeLoad : function(){ - if(!this.disabled){ - this.el.mask(this.msg, this.msgCls); + el.update(''); + if (records.length < 1) { + if (!me.deferEmptyText || me.hasSkippedEmptyText) { + el.update(me.emptyText); + } + me.all.clear(); + } else { + me.tpl.overwrite(el, me.collectData(records, 0)); + me.all.fill(Ext.query(me.getItemSelector(), el.dom)); + me.updateIndexes(0); } + + me.selModel.refresh(); + me.hasSkippedEmptyText = true; + me.fireEvent('refresh', me); }, - show: function(){ - this.onBeforeLoad(); + prepareData: function(data, index, record) { + if (record) { + Ext.apply(data, record.getAssociatedData()); + } + return data; }, - - hide: function(){ - this.onLoad(); - }, - - destroy : function(){ - if(this.store){ - this.store.un('beforeload', this.onBeforeLoad, this); - this.store.un('load', this.onLoad, this); - this.store.un('exception', this.onLoad, this); - }else{ - var um = this.el.getUpdater(); - um.un('beforeupdate', this.onBeforeLoad, this); - um.un('update', this.onLoad, this); - um.un('failure', this.onLoad, this); + collectData : function(records, startIndex){ + var r = [], + i = 0, + len = records.length; + + for(; i < len; i++){ + r[r.length] = this.prepareData(records[i].data, startIndex + i, records[i]); } - } -};Ext.ns('Ext.slider'); + return r; + }, -Ext.slider.Thumb = Ext.extend(Object, { - - dragging: false, + bufferRender : function(records, index){ + var div = document.createElement('div'); + this.tpl.overwrite(div, this.collectData(records, index)); + return Ext.query(this.getItemSelector(), div); + }, - constructor: function(config) { - - Ext.apply(this, config || {}, { - cls: 'x-slider-thumb', + onUpdate : function(ds, record){ + var me = this, + index = me.store.indexOf(record), + original, + node; - - constrain: false - }); + if (index > -1){ + original = me.all.elements[index]; + node = me.bufferRender([record], index)[0]; - Ext.slider.Thumb.superclass.constructor.call(this, config); + me.all.replaceElement(index, node, true); + me.updateIndexes(index, index); - if (this.slider.vertical) { - Ext.apply(this, Ext.slider.Thumb.Vertical); + + + me.selModel.refresh(); + me.fireEvent('itemupdate', record, index, node); } + }, - render: function() { - this.el = this.slider.innerEl.insertFirst({cls: this.cls}); + 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); - this.initEvents(); + me.selModel.refresh(); + me.updateIndexes(index); + me.fireEvent('itemadd', records, index, nodes); }, + 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); + } + }, - enable: function() { - this.disabled = false; - this.el.removeClass(this.slider.disabledClass); + + onRemove : function(ds, record, index) { + var me = this; + + me.doRemove(record, index); + me.updateIndexes(index); + if (me.store.getCount() === 0){ + me.refresh(); + } + me.fireEvent('itemremove', record, index); }, - - disable: function() { - this.disabled = true; - this.el.addClass(this.slider.disabledClass); + doRemove: function(record, index) { + this.all.removeElement(index, true); }, - initEvents: function() { - var el = this.el; - - el.addClassOnOver('x-slider-thumb-over'); - - this.tracker = new Ext.dd.DragTracker({ - onBeforeStart: this.onBeforeDragStart.createDelegate(this), - onStart : this.onDragStart.createDelegate(this), - onDrag : this.onDrag.createDelegate(this), - onEnd : this.onDragEnd.createDelegate(this), - tolerance : 3, - autoStart : 300 - }); - - this.tracker.initEl(el); + refreshNode : function(index){ + this.onUpdate(this.store, this.store.getAt(index)); }, - onBeforeDragStart : function(e) { - if (this.disabled) { - return false; - } else { - this.slider.promoteThumb(this); - return true; + updateIndexes : function(startIndex, endIndex) { + var ns = this.all.elements, + records = this.store.getRange(); + startIndex = startIndex || 0; + endIndex = endIndex || ((endIndex === 0) ? 0 : (ns.length - 1)); + for(var i = startIndex; i <= endIndex; i++){ + ns[i].viewIndex = i; + ns[i].viewRecordId = records[i].internalId; + if (!ns[i].boundView) { + ns[i].boundView = this.id; + } } }, - onDragStart: function(e){ - this.el.addClass('x-slider-thumb-drag'); - this.dragging = true; - this.dragStartValue = this.value; - - this.slider.fireEvent('dragstart', this.slider, e, this); + getStore : function(){ + return this.store; }, - onDrag: function(e) { - var slider = this.slider, - index = this.index, - newValue = this.getNewValue(); - - if (this.constrain) { - var above = slider.thumbs[index + 1], - below = slider.thumbs[index - 1]; - - if (below != undefined && newValue <= below.value) newValue = below.value; - if (above != undefined && newValue >= above.value) newValue = above.value; + bindStore : function(store, initial) { + var me = this; + + if (!initial && me.store) { + if (store !== me.store && me.store.autoDestroy) { + me.store.destroy(); + } + else { + me.mun(me.store, { + scope: me, + datachanged: me.onDataChanged, + add: me.onAdd, + remove: me.onRemove, + update: me.onUpdate, + clear: me.refresh + }); + } + if (!store) { + if (me.loadMask) { + me.loadMask.bindStore(null); + } + me.store = null; + } + } + if (store) { + store = Ext.data.StoreManager.lookup(store); + me.mon(store, { + scope: me, + datachanged: me.onDataChanged, + add: me.onAdd, + remove: me.onRemove, + update: me.onUpdate, + clear: me.refresh + }); + if (me.loadMask) { + me.loadMask.bindStore(store); + } + } + + me.store = store; + + me.getSelectionModel().bind(store); + + if (store) { + me.refresh(true); } - - slider.setValue(index, newValue, false); - slider.fireEvent('drag', slider, e, this); }, - getNewValue: function() { - var slider = this.slider, - pos = slider.innerEl.translatePoints(this.tracker.getXY()); - - return Ext.util.Format.round(slider.reverseValue(pos.left), slider.decimalPrecision); + + onDataChanged: function() { + if (this.blockRefresh !== true) { + this.refresh.apply(this, arguments); + } }, - onDragEnd: function(e) { - var slider = this.slider, - value = this.value; + findItemByChild: function(node){ + return Ext.fly(node).findParent(this.getItemSelector(), this.getTargetEl()); + }, + + + findTargetByEvent: function(e) { + return e.getTarget(this.getItemSelector(), this.getTargetEl()); + }, - this.el.removeClass('x-slider-thumb-drag'); - this.dragging = false; - slider.fireEvent('dragend', slider, e); + + getSelectedNodes: function(){ + var nodes = [], + records = this.selModel.getSelection(), + ln = records.length, + i = 0; - if (this.dragStartValue != value) { - slider.fireEvent('changecomplete', slider, value, this); + for (; i < ln; i++) { + nodes.push(this.getNode(records[i])); } + + return nodes; }, + - - destroy: function(){ - Ext.destroyMembers(this, 'tracker', 'el'); - } -}); + getRecords: function(nodes) { + var records = [], + i = 0, + len = nodes.length, + data = this.store.data; + for (; i < len; i++) { + records[records.length] = data.getByKey(nodes[i].viewRecordId); + } + + return records; + }, -Ext.slider.MultiSlider = Ext.extend(Ext.BoxComponent, { - - - vertical: false, - minValue: 0, + getRecord: function(node){ + return this.store.data.getByKey(Ext.getDom(node).viewRecordId); + }, - maxValue: 100, + - decimalPrecision: 0, + isSelected : function(node) { + + var r = this.getRecord(node); + return this.selModel.isSelected(r); + }, - keyIncrement: 1, - increment: 0, + select: function(records, keepExisting, suppressEvent) { + this.selModel.select(records, keepExisting, suppressEvent); + }, - clickRange: [5,15], + deselect: function(records, suppressEvent) { + this.selModel.deselect(records, suppressEvent); + }, - clickToChange : true, + getNode : function(nodeInfo) { + if (Ext.isString(nodeInfo)) { + return document.getElementById(nodeInfo); + } else if (Ext.isNumber(nodeInfo)) { + return this.all.elements[nodeInfo]; + } else if (nodeInfo instanceof Ext.data.Model) { + return this.getNodeByRecord(nodeInfo); + } + return nodeInfo; + }, - animate: true, - constrainThumbs: true, - + 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; + }, + - topThumbZIndex: 10000, + getNodes: function(start, end) { + var ns = this.all.elements, + nodes = [], + i; + + start = start || 0; + end = !Ext.isDefined(end) ? Math.max(ns.length - 1, 0) : end; + if (start <= end) { + for (i = start; i <= end && ns[i]; i++) { + nodes.push(ns[i]); + } + } else { + for (i = start; i >= end && ns[i]; i--) { + nodes.push(ns[i]); + } + } + return nodes; + }, - initComponent : function(){ - if(!Ext.isDefined(this.value)){ - this.value = this.minValue; + indexOf: function(node) { + node = this.getNode(node); + if (Ext.isNumber(node.viewIndex)) { + return node.viewIndex; } + return this.all.indexOf(node); + }, + onDestroy : function() { + var me = this; - this.thumbs = []; - - Ext.slider.MultiSlider.superclass.initComponent.call(this); + me.all.clear(); + me.callParent(); + me.bindStore(null); + me.selModel.destroy(); + }, - this.keyIncrement = Math.max(this.increment, this.keyIncrement); - this.addEvents( - - 'beforechange', + + onItemSelect: function(record) { + var node = this.getNode(record); + Ext.fly(node).addCls(this.selectedItemCls); + }, + + onItemDeselect: function(record) { + var node = this.getNode(record); + Ext.fly(node).removeCls(this.selectedItemCls); + }, + + getItemSelector: function() { + return this.itemSelector; + } +}, function() { + + + + + Ext.deprecate('extjs', '4.0', function() { + Ext.view.AbstractView.override({ - 'change', - - 'changecomplete', - - 'dragstart', - - 'drag', - - 'dragend' - ); - + getSelectionCount : function(){ + console.warn("DataView: getSelectionCount will be removed, please interact with the Ext.selection.DataViewModel"); + return this.selModel.getSelection().length; + }, - if (this.values == undefined || Ext.isEmpty(this.values)) this.values = [0]; - - var values = this.values; + + getSelectedRecords : function(){ + 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()"); + 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()"); + var sm = this.getSelectionModel(); + return sm.deselectAll(); + } + }); + }); +}); - for (var i=0; i < values.length; i++) { - this.addThumb(values[i]); - } - if(this.vertical){ - Ext.apply(this, Ext.slider.Vertical); - } - }, +Ext.define('Ext.Action', { - addThumb: function(value) { - var thumb = new Ext.slider.Thumb({ - value : value, - slider : this, - index : this.thumbs.length, - constrain: this.constrainThumbs - }); - this.thumbs.push(thumb); - - - if (this.rendered) thumb.render(); - }, - promoteThumb: function(topThumb) { - var thumbs = this.thumbs, - zIndex, thumb; - - for (var i = 0, j = thumbs.length; i < j; i++) { - thumb = thumbs[i]; - - if (thumb == topThumb) { - zIndex = this.topThumbZIndex; - } else { - zIndex = ''; - } - - thumb.el.setStyle('zIndex', zIndex); - } - }, - onRender : function() { - this.autoEl = { - cls: 'x-slider ' + (this.vertical ? 'x-slider-vert' : 'x-slider-horz'), - cn : { - cls: 'x-slider-end', - cn : { - cls:'x-slider-inner', - cn : [{tag:'a', cls:'x-slider-focus', href:"#", tabIndex: '-1', hidefocus:'on'}] - } - } - }; - - Ext.slider.MultiSlider.superclass.onRender.apply(this, arguments); - - this.endEl = this.el.first(); - this.innerEl = this.endEl.first(); - this.focusEl = this.innerEl.child('.x-slider-focus'); - - - for (var i=0; i < this.thumbs.length; i++) { - this.thumbs[i].render(); - } - - - var thumb = this.innerEl.child('.x-slider-thumb'); - this.halfThumb = (this.vertical ? thumb.getHeight() : thumb.getWidth()) / 2; + + + + + + - this.initEvents(); + constructor : function(config){ + this.initialConfig = config; + this.itemId = config.itemId = (config.itemId || config.id || Ext.id()); + this.items = []; }, - initEvents : function(){ - this.mon(this.el, { - scope : this, - mousedown: this.onMouseDown, - keydown : this.onKeyDown - }); + isAction : true, - this.focusEl.swallowEvent("click", true); + + setText : function(text){ + this.initialConfig.text = text; + this.callEach('setText', [text]); }, - onMouseDown : function(e){ - if(this.disabled){ - return; - } - - - var thumbClicked = false; - for (var i=0; i < this.thumbs.length; i++) { - thumbClicked = thumbClicked || e.target == this.thumbs[i].el.dom; - } - - if (this.clickToChange && !thumbClicked) { - var local = this.innerEl.translatePoints(e.getXY()); - this.onClickChange(local); - } - this.focus(); + getText : function(){ + return this.initialConfig.text; }, - onClickChange : function(local) { - if (local.top > this.clickRange[0] && local.top < this.clickRange[1]) { - - var thumb = this.getNearest(local, 'left'), - index = thumb.index; - - this.setValue(index, Ext.util.Format.round(this.reverseValue(local.left), this.decimalPrecision), undefined, true); - } + setIconCls : function(cls){ + this.initialConfig.iconCls = cls; + this.callEach('setIconCls', [cls]); }, - getNearest: function(local, prop) { - var localValue = prop == 'top' ? this.innerEl.getHeight() - local[prop] : local[prop], - clickValue = this.reverseValue(localValue), - nearestDistance = (this.maxValue - this.minValue) + 5, - index = 0, - nearest = null; - - for (var i=0; i < this.thumbs.length; i++) { - var thumb = this.thumbs[i], - value = thumb.value, - dist = Math.abs(value - clickValue); - - if (Math.abs(dist <= nearestDistance)) { - nearest = thumb; - index = i; - nearestDistance = dist; - } - } - return nearest; + getIconCls : function(){ + return this.initialConfig.iconCls; }, - onKeyDown : function(e){ - - if(this.disabled || this.thumbs.length !== 1){ - e.preventDefault(); - return; - } - var k = e.getKey(), - val; - switch(k){ - case e.UP: - case e.RIGHT: - e.stopEvent(); - val = e.ctrlKey ? this.maxValue : this.getValue(0) + this.keyIncrement; - this.setValue(0, val, undefined, true); - break; - case e.DOWN: - case e.LEFT: - e.stopEvent(); - val = e.ctrlKey ? this.minValue : this.getValue(0) - this.keyIncrement; - this.setValue(0, val, undefined, true); - break; - default: - e.preventDefault(); - } + setDisabled : function(v){ + this.initialConfig.disabled = v; + this.callEach('setDisabled', [v]); }, - doSnap : function(value){ - if (!(this.increment && value)) { - return value; - } - var newValue = value, - inc = this.increment, - m = value % inc; - if (m != 0) { - newValue -= m; - if (m * 2 >= inc) { - newValue += inc; - } else if (m * 2 < -inc) { - newValue -= inc; - } - } - return newValue.constrain(this.minValue, this.maxValue); + enable : function(){ + this.setDisabled(false); }, - afterRender : function(){ - Ext.slider.MultiSlider.superclass.afterRender.apply(this, arguments); - - for (var i=0; i < this.thumbs.length; i++) { - var thumb = this.thumbs[i]; - - if (thumb.value !== undefined) { - var v = this.normalizeValue(thumb.value); - - if (v !== thumb.value) { - - this.setValue(i, v, false); - } else { - this.moveThumb(i, this.translateValue(v), false); - } - } - }; + disable : function(){ + this.setDisabled(true); }, - getRatio : function(){ - var w = this.innerEl.getWidth(), - v = this.maxValue - this.minValue; - return v == 0 ? w : (w/v); + isDisabled : function(){ + return this.initialConfig.disabled; }, - normalizeValue : function(v){ - v = this.doSnap(v); - v = Ext.util.Format.round(v, this.decimalPrecision); - v = v.constrain(this.minValue, this.maxValue); - return v; + setHidden : function(v){ + this.initialConfig.hidden = v; + this.callEach('setVisible', [!v]); }, - setMinValue : function(val){ - this.minValue = val; - var i = 0, - thumbs = this.thumbs, - len = thumbs.length, - t; - - for(; i < len; ++i){ - t = thumbs[i]; - t.value = t.value < val ? val : t.value; - } - this.syncThumb(); + show : function(){ + this.setHidden(false); }, - setMaxValue : function(val){ - this.maxValue = val; - var i = 0, - thumbs = this.thumbs, - len = thumbs.length, - t; - - for(; i < len; ++i){ - t = thumbs[i]; - t.value = t.value > val ? val : t.value; - } - this.syncThumb(); + hide : function(){ + this.setHidden(true); }, - setValue : function(index, v, animate, changeComplete) { - var thumb = this.thumbs[index], - el = thumb.el; - - v = this.normalizeValue(v); - - if (v !== thumb.value && this.fireEvent('beforechange', this, v, thumb.value, thumb) !== false) { - thumb.value = v; - if(this.rendered){ - this.moveThumb(index, this.translateValue(v), animate !== false); - this.fireEvent('change', this, v, thumb); - if(changeComplete){ - this.fireEvent('changecomplete', this, v, thumb); - } - } - } + isHidden : function(){ + return this.initialConfig.hidden; }, - translateValue : function(v) { - var ratio = this.getRatio(); - return (v * ratio) - (this.minValue * ratio) - this.halfThumb; + setHandler : function(fn, scope){ + this.initialConfig.handler = fn; + this.initialConfig.scope = scope; + this.callEach('setHandler', [fn, scope]); }, - reverseValue : function(pos){ - var ratio = this.getRatio(); - return (pos + (this.minValue * ratio)) / ratio; + each : function(fn, scope){ + Ext.each(this.items, fn, scope); }, - moveThumb: function(index, v, animate){ - var thumb = this.thumbs[index].el; - - if(!animate || this.animate === false){ - thumb.setLeft(v); - }else{ - thumb.shift({left: v, stopFx: true, duration:.35}); + 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); } }, - focus : function(){ - this.focusEl.focus(10); + addComponent : function(comp){ + this.items.push(comp); + comp.on('destroy', this.removeComponent, this); }, - onResize : function(w, h){ - var thumbs = this.thumbs, - len = thumbs.length, - i = 0; - - - for(; i < len; ++i){ - thumbs[i].el.stopFx(); - } - - if(Ext.isNumber(w)){ - this.innerEl.setWidth(w - (this.el.getPadding('l') + this.endEl.getPadding('r'))); - } - this.syncThumb(); - Ext.slider.MultiSlider.superclass.onResize.apply(this, arguments); + removeComponent : function(comp){ + this.items.remove(comp); }, - onDisable: function(){ - Ext.slider.MultiSlider.superclass.onDisable.call(this); + execute : function(){ + this.initialConfig.handler.apply(this.initialConfig.scope || Ext.global, arguments); + } +}); - for (var i=0; i < this.thumbs.length; i++) { - var thumb = this.thumbs[i], - el = thumb.el; - thumb.disable(); +Ext.define('Ext.layout.component.Editor', { - if(Ext.isIE){ - - - var xy = el.getXY(); - el.hide(); + - this.innerEl.addClass(this.disabledClass).dom.disabled = true; + alias: ['layout.editor'], - if (!this.thumbHolder) { - this.thumbHolder = this.endEl.createChild({cls: 'x-slider-thumb ' + this.disabledClass}); - } + extend: 'Ext.layout.component.Component', - this.thumbHolder.show().setXY(xy); - } + + + onLayout: function(width, height) { + var me = this, + owner = me.owner, + autoSize = owner.autoSize; + + if (autoSize === true) { + autoSize = { + width: 'field', + height: 'field' + }; + } + + if (autoSize) { + width = me.getDimension(owner, autoSize.width, 'Width', width); + height = me.getDimension(owner, autoSize.height, 'Height', height); } + me.setTargetSize(width, height); + owner.field.setSize(width, height); }, - - onEnable: function(){ - Ext.slider.MultiSlider.superclass.onEnable.call(this); + getDimension: function(owner, type, dimension, actual){ + var method = 'get' + dimension; + switch (type) { + case 'boundEl': + return owner.boundEl[method](); + case 'field': + return owner.field[method](); + default: + return actual; + } + } +}); - for (var i=0; i < this.thumbs.length; i++) { - var thumb = this.thumbs[i], - el = thumb.el; +Ext.define('Ext.Editor', { - thumb.enable(); + - if (Ext.isIE) { - this.innerEl.removeClass(this.disabledClass).dom.disabled = false; + extend: 'Ext.Component', - if (this.thumbHolder) this.thumbHolder.hide(); + alias: 'widget.editor', - el.show(); - this.syncThumb(); - } - } - }, + requires: ['Ext.layout.component.Editor'], - syncThumb : function() { - if (this.rendered) { - for (var i=0; i < this.thumbs.length; i++) { - this.moveThumb(i, this.translateValue(this.thumbs[i].value)); - } - } - }, + + componentLayout: 'editor', - getValue : function(index) { - return this.thumbs[index].value; - }, - getValues: function() { - var values = []; + allowBlur: true, - for (var i=0; i < this.thumbs.length; i++) { - values.push(this.thumbs[i].value); - } + - return values; - }, + + revertInvalid: true, - beforeDestroy : function(){ - var thumbs = this.thumbs; - for(var i = 0, len = thumbs.length; i < len; ++i){ - thumbs[i].destroy(); - thumbs[i] = null; - } - Ext.destroyMembers(this, 'endEl', 'innerEl', 'focusEl', 'thumbHolder'); - Ext.slider.MultiSlider.superclass.beforeDestroy.call(this); - } -}); -Ext.reg('multislider', Ext.slider.MultiSlider); + + + value : '', -Ext.slider.SingleSlider = Ext.extend(Ext.slider.MultiSlider, { - constructor: function(config) { - config = config || {}; + + alignment: 'c-c?', - Ext.applyIf(config, { - values: [config.value || 0] - }); + + offsets: [0, 0], - Ext.slider.SingleSlider.superclass.constructor.call(this, config); - }, + + shadow : 'frame', - getValue: function() { - - return Ext.slider.SingleSlider.superclass.getValue.call(this, 0); - }, + constrain : false, - setValue: function(value, animate) { - var args = Ext.toArray(arguments), - len = args.length; + swallowKeys : true, - - - - if (len == 1 || (len <= 3 && typeof arguments[1] != 'number')) { - args.unshift(0); - } + + completeOnEnter : true, - return Ext.slider.SingleSlider.superclass.setValue.apply(this, args); - }, + + cancelOnEsc : true, - syncThumb : function() { - return Ext.slider.SingleSlider.superclass.syncThumb.apply(this, [0].concat(arguments)); - }, + updateEl : false, + + - getNearest : function(){ - - return this.thumbs[0]; - } -}); + hidden: true, + baseCls: Ext.baseCSSPrefix + 'editor', + initComponent : function() { + var me = this, + field = me.field = Ext.ComponentManager.create(me.field, 'textfield'); -Ext.Slider = Ext.slider.SingleSlider; + Ext.apply(field, { + inEditor: true, + msgTarget: field.msgTarget == 'title' ? 'title' : 'qtip' + }); + me.mon(field, { + scope: me, + blur: { + fn: me.onBlur, + + delay: 1 + }, + specialkey: me.onSpecialKey + }); -Ext.reg('slider', Ext.slider.SingleSlider); + if (field.grow) { + me.mon(field, 'autosize', me.onAutoSize, me, {delay: 1}); + } + me.floating = { + constrain: me.constrain + }; + me.callParent(arguments); -Ext.slider.Vertical = { - onResize : function(w, h){ - this.innerEl.setHeight(h - (this.el.getPadding('t') + this.endEl.getPadding('b'))); - this.syncThumb(); + me.addEvents( + + 'beforestartedit', + + 'startedit', + + 'beforecomplete', + + 'complete', + + 'canceledit', + + 'specialkey' + ); }, - getRatio : function(){ - var h = this.innerEl.getHeight(), - v = this.maxValue - this.minValue; - return h/v; + + onAutoSize: function(){ + this.doComponentLayout(); }, - moveThumb: function(index, v, animate) { - var thumb = this.thumbs[index], - el = thumb.el; + + onRender : function(ct, position) { + var me = this, + field = me.field; + + me.callParent(arguments); - if (!animate || this.animate === false) { - el.setBottom(v); - } else { - el.shift({bottom: v, stopFx: true, duration:.35}); + field.render(me.el); + + + field.inputEl.dom.name = ''; + if (me.swallowKeys) { + field.inputEl.swallowEvent([ + 'keypress', + 'keydown' + ]); } }, - onClickChange : function(local) { - if (local.left > this.clickRange[0] && local.left < this.clickRange[1]) { - var thumb = this.getNearest(local, 'top'), - index = thumb.index, - value = this.minValue + this.reverseValue(this.innerEl.getHeight() - local.top); + + onSpecialKey : function(field, event) { + var me = this, + key = event.getKey(), + complete = me.completeOnEnter && key == event.ENTER, + cancel = me.cancelOnEsc && key == event.ESC; - this.setValue(index, Ext.util.Format.round(value, this.decimalPrecision), undefined, true); + if (complete || cancel) { + event.stopEvent(); + + + Ext.defer(function() { + if (complete) { + me.completeEdit(); + } else { + me.cancelEdit(); + } + if (field.triggerBlur) { + field.triggerBlur(); + } + }, 10); } - } -}; + this.fireEvent('specialkey', this, field, event); + }, -Ext.slider.Thumb.Vertical = { - getNewValue: function() { - var slider = this.slider, - innerEl = slider.innerEl, - pos = innerEl.translatePoints(this.tracker.getXY()), - bottom = innerEl.getHeight() - pos.top; + + startEdit : function(el, value) { + var me = this, + field = me.field; - return slider.minValue + Ext.util.Format.round(bottom / slider.getRatio(), slider.decimalPrecision); - } -}; + me.completeEdit(); + me.boundEl = Ext.get(el); + value = Ext.isDefined(value) ? value : me.boundEl.dom.innerHTML; -Ext.ProgressBar = Ext.extend(Ext.BoxComponent, { - - baseCls : 'x-progress', - - - animate : false, + if (!me.rendered) { + me.render(me.parentEl || document.body); + } - - waitTimer : null, + if (me.fireEvent('beforestartedit', me, me.boundEl, value) !== false) { + me.startValue = value; + me.show(); + field.reset(); + field.setValue(value); + me.realign(true); + field.focus(false, 10); + if (field.autoSize) { + field.autoSize(); + } + me.editing = true; + } + }, - initComponent : function(){ - Ext.ProgressBar.superclass.initComponent.call(this); - this.addEvents( - - "update" - ); + realign : function(autoSize) { + var me = this; + if (autoSize === true) { + me.doComponentLayout(); + } + me.alignTo(me.boundEl, me.alignment, me.offsets); }, - onRender : function(ct, position){ - var tpl = new Ext.Template( - '
    ', - '
    ', - '
    ', - '
    ', - '
     
    ', - '
    ', - '
    ', - '
    ', - '
     
    ', - '
    ', - '
    ', - '
    ' - ); + completeEdit : function(remainVisible) { + var me = this, + field = me.field, + value; - this.el = position ? tpl.insertBefore(position, {cls: this.baseCls}, true) - : tpl.append(ct, {cls: this.baseCls}, true); - - if(this.id){ - this.el.dom.id = this.id; + if (!me.editing) { + return; } - var inner = this.el.dom.firstChild; - this.progressBar = Ext.get(inner.firstChild); - if(this.textEl){ - - this.textEl = Ext.get(this.textEl); - delete this.textTopEl; - }else{ - - this.textTopEl = Ext.get(this.progressBar.dom.firstChild); - var textBackEl = Ext.get(inner.childNodes[1]); - this.textTopEl.setStyle("z-index", 99).addClass('x-hidden'); - this.textEl = new Ext.CompositeElement([this.textTopEl.dom.firstChild, textBackEl.dom.firstChild]); - this.textEl.setWidth(inner.offsetWidth); + + if (field.assertValue) { + field.assertValue(); } - this.progressBar.setHeight(inner.offsetHeight); - }, - - - afterRender : function(){ - Ext.ProgressBar.superclass.afterRender.call(this); - if(this.value){ - this.updateProgress(this.value, this.text); - }else{ - this.updateText(this.text); + + value = me.getValue(); + if (!field.isValid()) { + if (me.revertInvalid !== false) { + me.cancelEdit(remainVisible); + } + return; } - }, - - updateProgress : function(value, text, animate){ - this.value = value || 0; - if(text){ - this.updateText(text); + if (String(value) === String(me.startValue) && me.ignoreNoChange) { + me.hideEdit(remainVisible); + return; } - if(this.rendered && !this.isDestroyed){ - var w = Math.floor(value*this.el.dom.firstChild.offsetWidth); - this.progressBar.setWidth(w, animate === true || (animate !== false && this.animate)); - if(this.textTopEl){ - - this.textTopEl.removeClass('x-hidden').setWidth(w); + + if (me.fireEvent('beforecomplete', me, value, me.startValue) !== false) { + + value = me.getValue(); + if (me.updateEl && me.boundEl) { + me.boundEl.update(value); } + me.hideEdit(remainVisible); + me.fireEvent('complete', me, value, me.startValue); } - this.fireEvent('update', this, value, text); - return this; }, - wait : function(o){ - if(!this.waitTimer){ - var scope = this; - o = o || {}; - this.updateText(o.text); - this.waitTimer = Ext.TaskMgr.start({ - run: function(i){ - var inc = o.increment || 10; - i -= 1; - this.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); - } - this.reset(); - }, - scope: scope - }); + onShow : function() { + var me = this; + + me.callParent(arguments); + if (me.hideEl !== false) { + me.boundEl.hide(); } - return this; + me.fireEvent("startedit", me.boundEl, me.startValue); }, - isWaiting : function(){ - return this.waitTimer !== null; - }, + cancelEdit : function(remainVisible) { + var me = this, + startValue = me.startValue, + value; - - updateText : function(text){ - this.text = text || ' '; - if(this.rendered){ - this.textEl.update(this.text); + if (me.editing) { + value = me.getValue(); + me.setValue(startValue); + me.hideEdit(remainVisible); + me.fireEvent('canceledit', me, value, startValue); } - return this; }, + - - syncProgressBar : function(){ - if(this.value){ - this.updateProgress(this.value, this.text); + hideEdit: function(remainVisible) { + if (remainVisible !== true) { + this.editing = false; + this.hide(); } - return this; }, - setSize : function(w, h){ - Ext.ProgressBar.superclass.setSize.call(this, w, h); - if(this.textTopEl){ - var inner = this.el.dom.firstChild; - this.textEl.setSize(inner.offsetWidth, inner.offsetHeight); + onBlur : function() { + var me = this; + + + if(me.allowBlur === true && me.editing && me.selectSameEditor !== true) { + me.completeEdit(); } - this.syncProgressBar(); - return this; }, - reset : function(hide){ - this.updateProgress(0); - if(this.textTopEl){ - this.textTopEl.addClass('x-hidden'); + onHide : function() { + var me = this, + field = me.field; + + if (me.editing) { + me.completeEdit(); + return; } - this.clearTimer(); - if(hide === true){ - this.hide(); + field.blur(); + if (field.collapse) { + field.collapse(); } - return this; - }, - - - clearTimer : function(){ - if(this.waitTimer){ - this.waitTimer.onStop = null; - Ext.TaskMgr.stop(this.waitTimer); - this.waitTimer = null; + + + if (me.hideEl !== false) { + me.boundEl.show(); } + me.callParent(arguments); }, + - onDestroy: function(){ - this.clearTimer(); - if(this.rendered){ - if(this.textEl.isComposite){ - this.textEl.clear(); - } - Ext.destroyMembers(this, 'textEl', 'progressBar', 'textTopEl'); - } - Ext.ProgressBar.superclass.onDestroy.call(this); - } -}); -Ext.reg('progress', Ext.ProgressBar); + setValue : function(value) { + this.field.setValue(value); + }, -(function() { + + getValue : function() { + return this.field.getValue(); + }, -var Event=Ext.EventManager; -var Dom=Ext.lib.Dom; + beforeDestroy : function() { + var me = this; + Ext.destroy(me.field); + delete me.field; + delete me.parentEl; + delete me.boundEl; -Ext.dd.DragDrop = function(id, sGroup, config) { - if(id) { - this.init(id, sGroup, config); + me.callParent(arguments); } -}; - -Ext.dd.DragDrop.prototype = { - - +}); +Ext.define('Ext.Img', { + extend: 'Ext.Component', + alias: ['widget.image', 'widget.imagecomponent'], - id: null, + src: '', + getElConfig: function() { + return { + tag: 'img', + src: this.src + }; + }, - config: null, - - dragElId: null, + setSrc: function(src) { + var me = this, + img = me.el; + me.src = src; + if (img) { + img.dom.src = src; + } + } +}); - - handleElId: null, - - invalidHandleTypes: null, +Ext.define('Ext.Layer', { + uses: ['Ext.Shadow'], - invalidHandleIds: null, + statics: { + shims: [] + }, - - invalidHandleClasses: null, + extend: 'Ext.core.Element', - - startPageX: 0, + constructor: function(config, existingEl) { + config = config || {}; + var me = this, + dh = Ext.core.DomHelper, + cp = config.parentEl, + pel = cp ? Ext.getDom(cp) : document.body, + hm = config.hideMode; + + if (existingEl) { + me.dom = Ext.getDom(existingEl); + } + if (!me.dom) { + me.dom = dh.append(pel, config.dh || { + tag: 'div', + cls: Ext.baseCSSPrefix + 'layer' + }); + } else { + me.addCls(Ext.baseCSSPrefix + 'layer'); + if (!me.dom.parentNode) { + pel.appendChild(me.dom); + } + } - - startPageY: 0, + if (config.cls) { + me.addCls(config.cls); + } + me.constrain = config.constrain !== false; - - groups: null, + + + + if (hm) { + me.setVisibilityMode(Ext.core.Element[hm.toUpperCase()]); + if (me.visibilityMode == Ext.core.Element.ASCLASS) { + me.visibilityCls = config.visibilityCls; + } + } else if (config.useDisplay) { + me.setVisibilityMode(Ext.core.Element.DISPLAY); + } else { + me.setVisibilityMode(Ext.core.Element.VISIBILITY); + } - - locked: false, + if (config.id) { + me.id = me.dom.id = config.id; + } else { + me.id = Ext.id(me.dom); + } + me.position('absolute'); + if (config.shadow) { + me.shadowOffset = config.shadowOffset || 4; + me.shadow = Ext.create('Ext.Shadow', { + offset: me.shadowOffset, + mode: config.shadow + }); + me.disableShadow(); + } else { + me.shadowOffset = 0; + } + me.useShim = config.shim !== false && Ext.useShims; + if (config.hidden === true) { + me.hide(); + } else { + this.show(); + } + }, - - lock: function() { - this.locked = true; + getZIndex: function() { + return parseInt((this.getShim() || this).getStyle('z-index'), 10); }, - - moveOnly: false, + getShim: function() { + var me = this, + shim, pn; - - unlock: function() { - this.locked = false; + if (!me.useShim) { + return null; + } + if (!me.shim) { + shim = me.self.shims.shift(); + if (!shim) { + shim = me.createShim(); + shim.enableDisplayMode('block'); + shim.hide(); + } + pn = me.dom.parentNode; + if (shim.dom.parentNode != pn) { + pn.insertBefore(shim.dom, me.dom); + } + me.shim = shim; + } + return me.shim; }, - - isTarget: true, + hideShim: function() { + if (this.shim) { + this.shim.setDisplayed(false); + this.self.shims.push(this.shim); + delete this.shim; + } + }, - - padding: null, + disableShadow: function() { + if (this.shadow) { + this.shadowDisabled = true; + this.shadow.hide(); + this.lastShadowOffset = this.shadowOffset; + this.shadowOffset = 0; + } + }, - - _domRef: null, + enableShadow: function(show) { + if (this.shadow) { + this.shadowDisabled = false; + this.shadowOffset = this.lastShadowOffset; + delete this.lastShadowOffset; + if (show) { + this.sync(true); + } + } + }, - __ygDragDrop: true, + sync: function(doShow) { + var me = this, + shadow = me.shadow, + shadowPos, shimStyle, shadowSize; - - constrainX: false, + 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(), + shimIndex; - - constrainY: false, + if (shadow && !this.shadowDisabled) { + if (doShow && !shadow.isVisible()) { + shadow.show(this); + } else { + shadow.realign(l, t, w, h); + } + if (shim) { + + shimIndex = shim.getStyle('z-index'); + if (shimIndex > me.zindex) { + me.shim.setStyle('z-index', me.zindex - 2); + } + shim.show(); + + if (shadow.isVisible()) { + shadowPos = shadow.el.getXY(); + shimStyle = shim.dom.style; + shadowSize = shadow.el.getSize(); + shimStyle.left = (shadowPos[0]) + 'px'; + shimStyle.top = (shadowPos[1]) + 'px'; + shimStyle.width = (shadowSize.width) + 'px'; + shimStyle.height = (shadowSize.height) + 'px'; + } else { + shim.setSize(w, h); + shim.setLeftTop(l, t); + } + } + } else if (shim) { + + shimIndex = shim.getStyle('z-index'); + if (shimIndex > me.zindex) { + me.shim.setStyle('z-index', me.zindex - 2); + } + shim.show(); + shim.setSize(w, h); + shim.setLeftTop(l, t); + } + } + return this; + }, - - minX: 0, + remove: function() { + this.hideUnders(); + this.callParent(); + }, - maxX: 0, + beginUpdate: function() { + this.updating = true; + }, - minY: 0, + endUpdate: function() { + this.updating = false; + this.sync(true); + }, - maxY: 0, + hideUnders: function() { + if (this.shadow) { + this.shadow.hide(); + } + this.hideShim(); + }, - maintainOffset: false, + constrainXY: function() { + if (this.constrain) { + var vw = Ext.core.Element.getViewWidth(), + vh = Ext.core.Element.getViewHeight(), + s = Ext.getDoc().getScroll(), + xy = this.getXY(), + x = xy[0], + y = xy[1], + so = this.shadowOffset, + w = this.dom.offsetWidth + so, + h = this.dom.offsetHeight + so, + moved = false; + + if ((x + w) > vw + s.left) { + x = vw - w - so; + moved = true; + } + if ((y + h) > vh + s.top) { + y = vh - h - so; + moved = true; + } + + if (x < s.left) { + x = s.left; + moved = true; + } + if (y < s.top) { + y = s.top; + moved = true; + } + if (moved) { + Ext.Layer.superclass.setXY.call(this, [x, y]); + this.sync(); + } + } + return this; + }, - - xTicks: null, + getConstrainOffset: function() { + return this.shadowOffset; + }, - yTicks: null, + setVisible: function(visible, animate, duration, callback, easing) { + var me = this, + cb; - - primaryButtonOnly: true, + + cb = function() { + if (visible) { + me.sync(true); + } + if (callback) { + callback(); + } + }; - - available: false, + + if (!visible) { + this.hideUnders(true); + } + this.callParent([visible, animate, duration, callback, easing]); + if (!animate) { + cb(); + } + return this; + }, - hasOuterHandles: false, + beforeFx: function() { + this.beforeAction(); + return this.callParent(arguments); + }, - b4StartDrag: function(x, y) { }, + afterFx: function() { + this.callParent(arguments); + this.sync(this.isVisible()); + }, - startDrag: function(x, y) { }, + beforeAction: function() { + if (!this.updating && this.shadow) { + this.shadow.hide(); + } + }, - b4Drag: function(e) { }, + setLeft: function(left) { + this.callParent(arguments); + return this.sync(); + }, - - onDrag: function(e) { }, + setTop: function(top) { + this.callParent(arguments); + return this.sync(); + }, - - onDragEnter: function(e, id) { }, + setLeftTop: function(left, top) { + this.callParent(arguments); + return this.sync(); + }, - - b4DragOver: function(e) { }, + setXY: function(xy, animate, duration, callback, easing) { - - onDragOver: function(e, id) { }, + + callback = this.createCB(callback); - - b4DragOut: function(e) { }, + this.fixDisplay(); + this.beforeAction(); + this.callParent([xy, animate, duration, callback, easing]); + if (!animate) { + callback(); + } + return this; + }, - onDragOut: function(e, id) { }, + createCB: function(callback) { + var me = this, + showShadow = me.shadow && me.shadow.isVisible(); - - b4DragDrop: function(e) { }, + return function() { + me.constrainXY(); + me.sync(showShadow); + if (callback) { + callback(); + } + }; + }, - onDragDrop: function(e, id) { }, + setX: function(x, animate, duration, callback, easing) { + this.setXY([x, this.getY()], animate, duration, callback, easing); + return this; + }, - onInvalidDrop: function(e) { }, + setY: function(y, animate, duration, callback, easing) { + this.setXY([this.getX(), y], animate, duration, callback, easing); + return this; + }, - b4EndDrag: function(e) { }, + setSize: function(w, h, animate, duration, callback, easing) { + + callback = this.createCB(callback); - - endDrag: function(e) { }, + this.beforeAction(); + this.callParent([w, h, animate, duration, callback, easing]); + if (!animate) { + callback(); + } + return this; + }, - b4MouseDown: function(e) { }, + setWidth: function(w, animate, duration, callback, easing) { + + callback = this.createCB(callback); - - onMouseDown: function(e) { }, + this.beforeAction(); + this.callParent([w, animate, duration, callback, easing]); + if (!animate) { + callback(); + } + return this; + }, - onMouseUp: function(e) { }, + setHeight: function(h, animate, duration, callback, easing) { + + callback = this.createCB(callback); - - onAvailable: function () { + this.beforeAction(); + this.callParent([h, animate, duration, callback, easing]); + if (!animate) { + callback(); + } + return this; }, - defaultPadding : {left:0, right:0, top:0, bottom:0}, + setBounds: function(x, y, width, height, animate, duration, callback, easing) { + + callback = this.createCB(callback); + + this.beforeAction(); + if (!animate) { + Ext.Layer.superclass.setXY.call(this, [x, y]); + Ext.Layer.superclass.setSize.call(this, width, height); + callback(); + } else { + this.callParent([x, y, width, height, animate, duration, callback, easing]); + } + return this; + }, - constrainTo : function(constrainTo, pad, inContent){ - if(Ext.isNumber(pad)){ - pad = {left: pad, right:pad, top:pad, bottom:pad}; + setZIndex: function(zindex) { + this.zindex = zindex; + if (this.getShim()) { + this.shim.setStyle('z-index', zindex++); } - pad = pad || this.defaultPadding; - var b = Ext.get(this.getEl()).getBox(), - ce = Ext.get(constrainTo), - s = ce.getScroll(), - c, - cd = ce.dom; - if(cd == document.body){ - c = { x: s.left, y: s.top, width: Ext.lib.Dom.getViewWidth(), height: Ext.lib.Dom.getViewHeight()}; - }else{ - var xy = ce.getXY(); - c = {x : xy[0], y: xy[1], width: cd.clientWidth, height: cd.clientHeight}; + if (this.shadow) { + this.shadow.setZIndex(zindex++); } + this.setStyle('z-index', zindex); + return this; + } +}); - var topSpace = b.y - c.y, - leftSpace = b.x - c.x; - this.resetConstraints(); - this.setXConstraint(leftSpace - (pad.left||0), - c.width - leftSpace - b.width - (pad.right||0), - this.xTickSize - ); - this.setYConstraint(topSpace - (pad.top||0), - c.height - topSpace - b.height - (pad.bottom||0), - this.yTickSize - ); - }, +Ext.define('Ext.layout.component.ProgressBar', { - getEl: function() { - if (!this._domRef) { - this._domRef = Ext.getDom(this.id); - } - - return this._domRef; - }, - - getDragEl: function() { - return Ext.getDom(this.dragElId); - }, + alias: ['layout.progressbar'], - - init: function(id, sGroup, config) { - this.initTarget(id, sGroup, config); - Event.on(this.id, "mousedown", this.handleMouseDown, this); - - }, + extend: 'Ext.layout.component.Component', - initTarget: function(id, sGroup, config) { - - this.config = config || {}; + type: 'progressbar', + onLayout: function(width, height) { + var me = this, + owner = me.owner, + textEl = owner.textEl; - this.DDM = Ext.dd.DDM; - - this.groups = {}; - + me.setElementSize(owner.el, width, height); + textEl.setWidth(owner.el.getWidth(true)); + me.callParent([width, height]); - if (typeof id !== "string") { - id = Ext.id(id); - } + owner.updateProgress(owner.value); + } +}); - - this.id = id; +Ext.define('Ext.ProgressBar', { + extend: 'Ext.Component', + alias: 'widget.progressbar', - - this.addToGroup((sGroup) ? sGroup : "default"); + requires: [ + 'Ext.Template', + 'Ext.CompositeElement', + 'Ext.TaskManager', + 'Ext.layout.component.ProgressBar' + ], - - - this.handleElId = id; + uses: ['Ext.fx.Anim'], + + baseCls: Ext.baseCSSPrefix + 'progress', + config: { - this.setDragElId(id); + animate: false, - this.invalidHandleTypes = { A: "A" }; - this.invalidHandleIds = {}; - this.invalidHandleClasses = []; - - this.applyConfig(); - - this.handleOnAvailable(); + text: '' }, - applyConfig: function() { + waitTimer: null, - - - this.padding = this.config.padding || [0, 0, 0, 0]; - this.isTarget = (this.config.isTarget !== false); - this.maintainOffset = (this.config.maintainOffset); - this.primaryButtonOnly = (this.config.primaryButtonOnly !== false); - - }, - - - handleOnAvailable: function() { - this.available = true; - this.resetConstraints(); - this.onAvailable(); - }, + renderTpl: [ + '
    ', + '
     
    ', + '
    ', + '
    ', + '
    ', + '
     
    ', + '
    ', + '
    ' + ], - - setPadding: function(iTop, iRight, iBot, iLeft) { - - if (!iRight && 0 !== iRight) { - this.padding = [iTop, iTop, iTop, iTop]; - } else if (!iBot && 0 !== iBot) { - this.padding = [iTop, iRight, iTop, iRight]; - } else { - this.padding = [iTop, iRight, iBot, iLeft]; - } - }, + componentLayout: 'progressbar', - setInitPosition: function(diffX, diffY) { - var el = this.getEl(); - - if (!this.DDM.verifyEl(el)) { - return; - } - - var dx = diffX || 0; - var dy = diffY || 0; + initComponent: function() { + this.callParent(); - var p = Dom.getXY( el ); + this.renderSelectors = Ext.apply(this.renderSelectors || {}, { + textTopEl: '.' + this.baseCls + '-text', + textBackEl: '.' + this.baseCls + '-text-back', + bar: '.' + this.baseCls + '-bar' + }); - this.initPageX = p[0] - dx; - this.initPageY = p[1] - dy; + this.addEvents( + + "update" + ); + }, - this.lastPageX = p[0]; - this.lastPageY = p[1]; + afterRender : function() { + var me = this; - this.setStartPosition(p); - }, + me.textEl = me.textEl ? Ext.get(me.textEl) : me.el.select('.' + me.baseCls + '-text'); - - setStartPosition: function(pos) { - var p = pos || Dom.getXY( this.getEl() ); - this.deltaSetXY = null; + this.callParent(arguments); - this.startPageX = p[0]; - this.startPageY = p[1]; + if (me.value) { + me.updateProgress(me.value, me.text); + } + else { + me.updateText(me.text); + } }, - addToGroup: function(sGroup) { - this.groups[sGroup] = true; - this.DDM.regDragDrop(this, sGroup); + updateProgress: function(value, text, animate) { + var newWidth; + this.value = value || 0; + if (text) { + this.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)); + } else { + this.bar.setWidth(newWidth); + } + } + this.fireEvent('update', this, this.value, text); + return this; }, - removeFromGroup: function(sGroup) { - if (this.groups[sGroup]) { - delete this.groups[sGroup]; + updateText: function(text) { + this.text = text; + if (this.rendered) { + this.textEl.update(this.text); } - - this.DDM.removeDDFromGroup(this, sGroup); + return this; }, - - setDragElId: function(id) { - this.dragElId = id; + applyText : function(text) { + this.updateText(text); }, - setHandleElId: function(id) { - if (typeof id !== "string") { - id = Ext.id(id); + wait: function(o) { + if (!this.waitTimer) { + var scope = this; + o = o || {}; + this.updateText(o.text); + this.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); + }, + interval: o.interval || 1000, + duration: o.duration, + onStop: function(){ + if (o.fn) { + o.fn.apply(o.scope || this); + } + this.reset(); + }, + scope: scope + }); } - this.handleElId = id; - this.DDM.regHandle(this.id, id); + return this; }, - setOuterHandleElId: function(id) { - if (typeof id !== "string") { - id = Ext.id(id); - } - Event.on(id, "mousedown", - this.handleMouseDown, this); - this.setHandleElId(id); - - this.hasOuterHandles = true; + isWaiting: function(){ + return this.waitTimer !== null; }, - unreg: function() { - Event.un(this.id, "mousedown", - this.handleMouseDown); - this._domRef = null; - this.DDM._remove(this); - }, - - destroy : function(){ - this.unreg(); + reset: function(hide){ + this.updateProgress(0); + this.clearTimer(); + if (hide === true) { + this.hide(); + } + return this; }, - isLocked: function() { - return (this.DDM.isLocked() || this.locked); + clearTimer: function(){ + if (this.waitTimer) { + this.waitTimer.onStop = null; + Ext.TaskManager.stop(this.waitTimer); + this.waitTimer = null; + } }, - - handleMouseDown: function(e, oDD){ - if (this.primaryButtonOnly && e.button != 0) { - return; + onDestroy: function(){ + this.clearTimer(); + if (this.rendered) { + if (this.textEl.isComposite) { + this.textEl.clear(); + } + Ext.destroyMembers(this, 'textEl', 'progressBar', 'textTopEl'); } + this.callParent(); + } +}); - if (this.isLocked()) { - return; - } - this.DDM.refreshCache(this.groups); +Ext.define('Ext.ShadowPool', { + singleton: true, + requires: ['Ext.core.DomHelper'], - var pt = new Ext.lib.Point(Ext.lib.Event.getPageX(e), Ext.lib.Event.getPageY(e)); - if (!this.hasOuterHandles && !this.DDM.isOverTarget(pt, this) ) { + markup: function() { + if (Ext.supports.CSS3BoxShadow) { + return ''; + } else if (Ext.isIE) { + return ''; } else { - if (this.clickValidator(e)) { - - - this.setStartPosition(); + return ''; + } + }(), - this.b4MouseDown(e); - this.onMouseDown(e); + shadows: [], - this.DDM.handleMouseDown(e, this); + pull: function() { + var sh = this.shadows.shift(); + if (!sh) { + sh = Ext.get(Ext.core.DomHelper.insertHtml("beforeBegin", document.body.firstChild, this.markup)); + sh.autoBoxAdjust = false; + } + return sh; + }, - this.DDM.stopEvent(e); - } else { + push: function(sh) { + this.shadows.push(sh); + }, + + reset: function() { + Ext.Array.each(this.shadows, function(shadow) { + shadow.remove(); + }); + this.shadows = []; + } +}); +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, + adjusts = { + h: 0 + }, + rad = Math.floor(this.offset / 2); - clickValidator: function(e) { - var target = e.getTarget(); - return ( this.isValidHandleChild(target) && - (this.id == this.handleElId || - this.DDM.handleWasClicked(target, this.id)) ); + switch (this.mode.toLowerCase()) { + + case "drop": + if (Ext.supports.CSS3BoxShadow) { + adjusts.w = adjusts.h = -offset; + adjusts.l = adjusts.t = offset; + } else { + adjusts.w = 0; + adjusts.l = adjusts.t = offset; + adjusts.t -= 1; + if (Ext.isIE) { + adjusts.l -= offset + rad; + adjusts.t -= offset + rad; + adjusts.w -= rad; + adjusts.h -= rad; + adjusts.t += 1; + } + } + break; + case "sides": + if (Ext.supports.CSS3BoxShadow) { + adjusts.h -= offset; + adjusts.t = offset; + adjusts.l = adjusts.w = 0; + } else { + adjusts.w = (offset * 2); + adjusts.l = -offset; + adjusts.t = offset - 1; + if (Ext.isIE) { + adjusts.l -= (offset - rad); + adjusts.t -= offset + rad; + adjusts.l += 1; + adjusts.w -= (offset - rad) * 2; + adjusts.w -= rad + 1; + adjusts.h -= 1; + } + } + break; + case "frame": + if (Ext.supports.CSS3BoxShadow) { + adjusts.l = adjusts.w = adjusts.t = 0; + } else { + adjusts.w = adjusts.h = (offset * 2); + adjusts.l = adjusts.t = -offset; + adjusts.t += 1; + adjusts.h -= 2; + if (Ext.isIE) { + adjusts.l -= (offset - rad); + adjusts.t -= (offset - rad); + adjusts.l += 1; + adjusts.w -= (offset + rad + 1); + adjusts.h -= (offset + rad); + adjusts.h += 1; + } + break; + } + } + this.adjusts = adjusts; }, - addInvalidHandleType: function(tagName) { - var type = tagName.toUpperCase(); - this.invalidHandleTypes[type] = type; - }, + + offset: 4, - addInvalidHandleId: function(id) { - if (typeof id !== "string") { - id = Ext.id(id); - } - this.invalidHandleIds[id] = id; - }, + defaultMode: "drop", - addInvalidHandleClass: function(cssClass) { - this.invalidHandleClasses.push(cssClass); + show: function(target) { + target = Ext.get(target); + if (!this.el) { + this.el = Ext.ShadowPool.pull(); + if (this.el.dom.nextSibling != target.dom) { + this.el.insertBefore(target); + } + } + this.el.setStyle("z-index", this.zIndex || parseInt(target.getStyle("z-index"), 10) - 1); + if (Ext.isIE && !Ext.supports.CSS3BoxShadow) { + this.el.dom.style.filter = "progid:DXImageTransform.Microsoft.alpha(opacity=50) progid:DXImageTransform.Microsoft.Blur(pixelradius=" + (this.offset) + ")"; + } + this.realign( + target.getLeft(true), + target.getTop(true), + target.getWidth(), + target.getHeight() + ); + this.el.dom.style.display = "block"; }, - removeInvalidHandleType: function(tagName) { - var type = tagName.toUpperCase(); - - delete this.invalidHandleTypes[type]; + isVisible: function() { + return this.el ? true: false; }, - removeInvalidHandleId: function(id) { - if (typeof id !== "string") { - id = Ext.id(id); + realign: function(l, t, targetWidth, targetHeight) { + if (!this.el) { + return; } - delete this.invalidHandleIds[id]; - }, + var adjusts = this.adjusts, + d = this.el.dom, + targetStyle = d.style, + shadowWidth, + shadowHeight, + cn, + sww, + sws, + shs; + + targetStyle.left = (l + adjusts.l) + "px"; + targetStyle.top = (t + adjusts.t) + "px"; + shadowWidth = Math.max(targetWidth + adjusts.w, 0); + shadowHeight = Math.max(targetHeight + adjusts.h, 0); + sws = shadowWidth + "px"; + shs = shadowHeight + "px"; + if (targetStyle.width != sws || targetStyle.height != shs) { + targetStyle.width = sws; + targetStyle.height = shs; + if (Ext.supports.CSS3BoxShadow) { + targetStyle.boxShadow = '0 0 ' + this.offset + 'px 0 #888'; + } else { - - removeInvalidHandleClass: function(cssClass) { - for (var i=0, len=this.invalidHandleClasses.length; i= this.minX; i = i - iTickSize) { - if (!tickMap[i]) { - this.xTicks[this.xTicks.length] = i; - tickMap[i] = true; - } - } + alias: 'widget.splitbutton', - for (i = this.initPageX; i <= this.maxX; i = i + iTickSize) { - if (!tickMap[i]) { - this.xTicks[this.xTicks.length] = i; - tickMap[i] = true; - } - } + extend: 'Ext.button.Button', + alternateClassName: 'Ext.SplitButton', - this.xTicks.sort(this.DDM.numericSort) ; - }, + + arrowCls : 'split', + split : true, - setYTicks: function(iStartY, iTickSize) { - this.yTicks = []; - this.yTickSize = iTickSize; + initComponent : function(){ + this.callParent(); + + this.addEvents("arrowclick"); + }, - var tickMap = {}; + + setArrowHandler : function(handler, scope){ + this.arrowHandler = handler; + this.scope = scope; + }, - for (var i = this.initPageY; i >= this.minY; i = i - iTickSize) { - if (!tickMap[i]) { - this.yTicks[this.yTicks.length] = i; - tickMap[i] = true; + + onClick : function(e, t) { + var me = this; + + e.preventDefault(); + if (!me.disabled) { + if (me.overMenuTrigger) { + if (me.menu && !me.menu.isVisible() && !me.ignoreNextClick) { + me.showMenu(); + } + 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(); } } + } +}); - for (i = this.initPageY; i <= this.maxY; i = i + iTickSize) { - if (!tickMap[i]) { - this.yTicks[this.yTicks.length] = i; - tickMap[i] = true; - } - } - this.yTicks.sort(this.DDM.numericSort) ; - }, +Ext.define('Ext.button.Cycle', { - setXConstraint: function(iLeft, iRight, iTickSize) { - this.leftConstraint = iLeft; - this.rightConstraint = iRight; - this.minX = this.initPageX - iLeft; - this.maxX = this.initPageX + iRight; - if (iTickSize) { this.setXTicks(this.initPageX, iTickSize); } + alias: 'widget.cycle', - this.constrainX = true; - }, + extend: 'Ext.button.Split', + alternateClassName: 'Ext.CycleButton', - clearConstraints: function() { - this.constrainX = false; - this.constrainY = false; - this.clearTicks(); - }, - clearTicks: function() { - this.xTicks = null; - this.yTicks = null; - this.xTickSize = 0; - this.yTickSize = 0; - }, + + + + + - setYConstraint: function(iUp, iDown, iTickSize) { - this.topConstraint = iUp; - this.bottomConstraint = iDown; + getButtonText: function(item) { + var me = this, + text = ''; - this.minY = this.initPageY - iUp; - this.maxY = this.initPageY + iDown; - if (iTickSize) { this.setYTicks(this.initPageY, iTickSize); } + if (item && me.showText === true) { + if (me.prependText) { + text += me.prependText; + } + text += item.text; + return text; + } + return me.text; + }, - this.constrainY = true; + + setActiveItem: function(item, suppressEvent) { + var me = this; + + if (!Ext.isObject(item)) { + item = me.menu.getComponent(item); + } + if (item) { + if (!me.rendered) { + me.text = me.getButtonText(item); + me.iconCls = item.iconCls; + } else { + me.setText(me.getButtonText(item)); + me.setIconCls(item.iconCls); + } + me.activeItem = item; + if (!item.checked) { + item.setChecked(true, false); + } + if (me.forceIcon) { + me.setIconCls(me.forceIcon); + } + if (!suppressEvent) { + me.fireEvent('change', me, item); + } + } + }, + + getActiveItem: function() { + return this.activeItem; }, - resetConstraints: function() { - - if (this.initPageX || this.initPageX === 0) { + initComponent: function() { + var me = this, + checked = 0, + items; + + me.addEvents( - var dx = (this.maintainOffset) ? this.lastPageX - this.initPageX : 0; - var dy = (this.maintainOffset) ? this.lastPageY - this.initPageY : 0; + "change" + ); - this.setInitPosition(dx, dy); + if (me.changeHandler) { + me.on('change', me.changeHandler, me.scope || me); + delete me.changeHandler; + } - } else { - this.setInitPosition(); - } + + items = (me.menu.items||[]).concat(me.items||[]); + me.menu = Ext.applyIf({ + cls: Ext.baseCSSPrefix + 'cycle-menu', + items: [] + }, me.menu); - if (this.constrainX) { - this.setXConstraint( this.leftConstraint, - this.rightConstraint, - this.xTickSize ); - } + + Ext.each(items, function(item, i) { + item = Ext.applyIf({ + group: me.id, + itemIndex: i, + checkHandler: me.checkHandler, + scope: me, + checked: item.checked || false + }, item); + me.menu.items.push(item); + if (item.checked) { + checked = i; + } + }); + me.itemCount = me.menu.items.length; + me.callParent(arguments); + me.on('click', me.toggleSelected, me); + me.setActiveItem(checked, me); - if (this.constrainY) { - this.setYConstraint( this.topConstraint, - this.bottomConstraint, - this.yTickSize ); + + if (me.width && me.showText) { + me.addCls(Ext.baseCSSPrefix + 'cycle-fixed-width'); } }, - getTick: function(val, tickArray) { - if (!tickArray) { - - - return val; - } else if (tickArray[0] >= val) { - - - return tickArray[0]; - } else { - for (var i=0, len=tickArray.length; i= val) { - var diff1 = val - tickArray[i]; - var diff2 = tickArray[next] - val; - return (diff2 > diff1) ? tickArray[i] : tickArray[next]; - } - } - - - - return tickArray[tickArray.length - 1]; + checkHandler: function(item, pressed) { + if (pressed) { + this.setActiveItem(item); } }, - toString: function() { - return ("DragDrop " + this.id); - } + toggleSelected: function() { + var me = this, + m = me.menu, + checkItem; -}; + checkItem = me.activeItem.next(':not([disabled])') || m.items.getAt(0); + checkItem.setChecked(true); + } +}); -})(); +Ext.define('Ext.container.ButtonGroup', { + extend: 'Ext.panel.Panel', + alias: 'widget.buttongroup', + alternateClassName: 'Ext.ButtonGroup', + + + baseCls: Ext.baseCSSPrefix + 'btn-group', + + layout: { + type: 'table' + }, -if (!Ext.dd.DragDropMgr) { + defaultType: 'button', + + frame: true, + + frameHeader: false, + + internalDefaults: {removeMode: 'container', hideParent: true}, -Ext.dd.DragDropMgr = function() { + initComponent : function(){ + + var me = this, + cols = me.columns; - var Event = Ext.EventManager; + me.noTitleCls = me.baseCls + '-notitle'; + if (cols) { + me.layout = Ext.apply({}, {columns: cols}, me.layout); + } - return { + if (!me.title) { + me.addCls(me.noTitleCls); + } + me.callParent(arguments); + }, + afterLayout: function() { + var me = this; - ids: {}, + me.callParent(arguments); - handleIds: {}, - - dragCurrent: null, + if (me.layout.table && (Ext.isIEQuirks || Ext.isIE6) && !me.width) { + var t = me.getTargetEl(); + t.setWidth(me.layout.table.offsetWidth + t.getPadding('lr')); + } + }, + afterRender: function() { + var me = this; - dragOvers: {}, - - deltaX: 0, - + if (me.header) { + me.header.insert(0, { + xtype: 'component', + ui : me.ui, + html : ' ', + flex : 1 + }); + } - deltaY: 0, + me.callParent(arguments); + }, + + + onBeforeAdd: function(component) { + if (component.is('button')) { + component.ui = component.ui + '-toolbar'; + } + this.callParent(arguments); + }, - - preventDefault: true, + + applyDefaults: function(c) { + if (!Ext.isString(c)) { + c = this.callParent(arguments); + var d = this.internalDefaults; + if (c.events) { + Ext.applyIf(c.initialConfig, d); + Ext.apply(c, d); + } else { + Ext.applyIf(c, d); + } + } + return c; + } - - stopPropagation: true, + + + + + +}); - - initialized: false, - - locked: false, +Ext.define('Ext.container.Viewport', { + extend: 'Ext.container.Container', + alias: 'widget.viewport', + requires: ['Ext.EventManager'], + alternateClassName: 'Ext.Viewport', - - init: function() { - this.initialized = true; - }, + + + + + + + + + + + + - - POINT: 0, + isViewport: true, + ariaRole: 'application', + initComponent : function() { + var me = this, + html = Ext.fly(document.body.parentNode), + el; + me.callParent(arguments); + html.addCls(Ext.baseCSSPrefix + 'viewport'); + if (me.autoScroll) { + html.setStyle('overflow', 'auto'); + } + me.el = el = Ext.getBody(); + el.setHeight = Ext.emptyFn; + el.setWidth = Ext.emptyFn; + el.setSize = Ext.emptyFn; + el.dom.scroll = 'no'; + me.allowDomMove = false; - INTERSECT: 1, - - mode: 0, + Ext.EventManager.onWindowResize(me.fireResize, me); + me.renderTo = me.el; + }, + fireResize : function(w, h){ - _execOnAll: function(sMethod, args) { - for (var i in this.ids) { - for (var j in this.ids[i]) { - var oDD = this.ids[i][j]; - if (! this.isTypeOfDD(oDD)) { - continue; - } - oDD[sMethod].apply(oDD, args); - } - } - }, - + this.setSize(w, h); - _onLoad: function() { + } +}); - this.init(); - Event.on(document, "mouseup", this.handleMouseUp, this, true); - Event.on(document, "mousemove", this.handleMouseMove, this, true); - Event.on(window, "unload", this._onUnload, this, true); - Event.on(window, "resize", this._onResize, this, true); - - }, - - _onResize: function(e) { - this._execOnAll("resetConstraints", []); - }, +Ext.define('Ext.dd.DDTarget', { + extend: 'Ext.dd.DragDrop', + constructor: function(id, sGroup, config) { + if (id) { + this.initTarget(id, sGroup, config); + } + }, - - lock: function() { this.locked = true; }, + + getDragEl: Ext.emptyFn, + + isValidHandleChild: Ext.emptyFn, + + startDrag: Ext.emptyFn, + + endDrag: Ext.emptyFn, + + onDrag: Ext.emptyFn, + + onDragDrop: Ext.emptyFn, + + onDragEnter: Ext.emptyFn, + + onDragOut: Ext.emptyFn, + + onDragOver: Ext.emptyFn, + + onInvalidDrop: Ext.emptyFn, + + onMouseDown: Ext.emptyFn, + + onMouseUp: Ext.emptyFn, + + setXConstraint: Ext.emptyFn, + + setYConstraint: Ext.emptyFn, + + resetConstraints: Ext.emptyFn, + + clearConstraints: Ext.emptyFn, + + clearTicks: Ext.emptyFn, + + setInitPosition: Ext.emptyFn, + + setDragElId: Ext.emptyFn, + + setHandleElId: Ext.emptyFn, + + setOuterHandleElId: Ext.emptyFn, + + addInvalidHandleClass: Ext.emptyFn, + + addInvalidHandleId: Ext.emptyFn, + + addInvalidHandleType: Ext.emptyFn, + + removeInvalidHandleClass: Ext.emptyFn, + + removeInvalidHandleId: Ext.emptyFn, + + removeInvalidHandleType: Ext.emptyFn, - - unlock: function() { this.locked = false; }, + toString: function() { + return ("DDTarget " + this.id); + } +}); - - isLocked: function() { return this.locked; }, +Ext.define('Ext.dd.DragTracker', { - - locationCache: {}, + uses: ['Ext.util.Region'], - - useCache: true, + mixins: { + observable: 'Ext.util.Observable' + }, - - clickPixelThresh: 3, + + active: false, - - clickTimeThresh: 350, + - - dragThreshMet: false, + + trackOver: false, - - clickTimeout: null, + - - startX: 0, + - - startY: 0, + + tolerance: 5, - - regDragDrop: function(oDD, sGroup) { - if (!this.initialized) { this.init(); } + + autoStart: false, - if (!this.ids[sGroup]) { - this.ids[sGroup] = {}; - } - this.ids[sGroup][oDD.id] = oDD; - }, + - - removeDDFromGroup: function(oDD, sGroup) { - if (!this.ids[sGroup]) { - this.ids[sGroup] = {}; - } + - var obj = this.ids[sGroup]; - if (obj && obj[oDD.id]) { - delete obj[oDD.id]; - } - }, + - - _remove: function(oDD) { - for (var g in oDD.groups) { - if (g && this.ids[g] && this.ids[g][oDD.id]) { - delete this.ids[g][oDD.id]; - } - } - delete this.handleIds[oDD.id]; - }, + constructor : function(config){ + Ext.apply(this, config); + this.addEvents( + + 'mouseover', - - regHandle: function(sDDId, sHandleId) { - if (!this.handleIds[sDDId]) { - this.handleIds[sDDId] = {}; - } - this.handleIds[sDDId][sHandleId] = sHandleId; - }, + + 'mouseout', - - isDragDrop: function(id) { - return ( this.getDDById(id) ) ? true : false; - }, + + 'mousedown', - - getRelated: function(p_oDD, bTargetsOnly) { - var oDDs = []; - for (var i in p_oDD.groups) { - for (var j in this.ids[i]) { - var dd = this.ids[i][j]; - if (! this.isTypeOfDD(dd)) { - continue; - } - if (!bTargetsOnly || dd.isTarget) { - oDDs[oDDs.length] = dd; - } - } - } + + 'mouseup', - return oDDs; - }, + + 'mousemove', - - isLegalTarget: function (oDD, oTargetDD) { - var targets = this.getRelated(oDD, true); - for (var i=0, len=targets.length;i this.clickPixelThresh || - diffY > this.clickPixelThresh) { - this.startDrag(this.startX, this.startY); - } + if (this.preventDefault !== false) { + e.preventDefault(); } - - if (this.dragThreshMet) { - this.dragCurrent.b4Drag(e); - this.dragCurrent.onDrag(e); - if(!this.dragCurrent.moveOnly){ - this.fireEvents(e, false); - } + 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]); } + } + }, - this.stopEvent(e); - - return true; - }, - + onMouseMove: function(e, target){ - fireEvents: function(e, isDrop) { - var dc = this.dragCurrent; + + if (this.active && Ext.isIE && !e.browserEvent.button) { + e.preventDefault(); + this.onMouseUp(e); + return; + } - - - if (!dc || dc.isLocked()) { + e.preventDefault(); + var xy = e.getXY(), + s = this.startXY; + + this.lastXY = xy; + if (!this.active) { + if (Math.max(Math.abs(s[0]-xy[0]), Math.abs(s[1]-xy[1])) > this.tolerance) { + this.triggerStart(e); + } else { return; } + } - var pt = e.getPoint(); + + if (this.fireEvent('mousemove', this, e) === false) { + this.onMouseUp(e); + } else { + this.onDrag(e); + this.fireEvent('drag', this, e); + } + }, - - var oldOvers = []; + onMouseUp: function(e) { + + + this.mouseIsDown = false; - var outEvts = []; - var overEvts = []; - var dropEvts = []; - var enterEvts = []; + + delete e.dragTracked; - - - for (var i in this.dragOvers) { + + if (this.mouseIsOut) { + this.mouseIsOut = false; + this.onMouseOut(e); + } + e.preventDefault(); + this.fireEvent('mouseup', this, e); + this.endDrag(e); + }, - var ddo = this.dragOvers[i]; + + endDrag: function(e) { + var doc = Ext.getDoc(), + wasActive = this.active; - if (! this.isTypeOfDD(ddo)) { - continue; - } + doc.un('mousemove', this.onMouseMove, this); + doc.un('mouseup', this.onMouseUp, this); + doc.un('selectstart', this.stopSelect, this); + this.clearStart(); + this.active = false; + if (wasActive) { + this.onEnd(e); + this.fireEvent('dragend', this, e); + } + + delete this._constrainRegion; + }, - if (! this.isOverTarget(pt, ddo, this.mode)) { - outEvts.push( ddo ); - } + triggerStart: function(e) { + this.clearStart(); + this.active = true; + this.onStart(e); + this.fireEvent('dragstart', this, e); + }, - oldOvers[i] = true; - delete this.dragOvers[i]; - } + clearStart : function() { + if (this.timer) { + clearTimeout(this.timer); + delete this.timer; + } + }, + + stopSelect : function(e) { + e.stopEvent(); + return false; + }, - for (var sGroup in dc.groups) { + + onBeforeStart : function(e) { - if ("string" != typeof sGroup) { - continue; - } + }, - for (i in this.ids[sGroup]) { - var oDD = this.ids[sGroup][i]; - if (! this.isTypeOfDD(oDD)) { - continue; - } + + onStart : function(xy) { - if (oDD.isTarget && !oDD.isLocked() && ((oDD != dc) || (dc.ignoreSelf === false))) { - if (this.isOverTarget(pt, oDD, this.mode)) { - - if (isDrop) { - dropEvts.push( oDD ); - - } else { + }, - - if (!oldOvers[oDD.id]) { - enterEvts.push( oDD ); - - } else { - overEvts.push( oDD ); - } + + onDrag : function(e) { - this.dragOvers[oDD.id] = oDD; - } - } - } - } - } + }, - if (this.mode) { - if (outEvts.length) { - dc.b4DragOut(e, outEvts); - dc.onDragOut(e, outEvts); - } + + onEnd : function(e) { - if (enterEvts.length) { - dc.onDragEnter(e, enterEvts); - } + }, - if (overEvts.length) { - dc.b4DragOver(e, overEvts); - dc.onDragOver(e, overEvts); - } + + getDragTarget : function(){ + return this.dragTarget; + }, - if (dropEvts.length) { - dc.b4DragDrop(e, dropEvts); - dc.onDragDrop(e, dropEvts); - } + + getDragCt : function(){ + return this.el; + }, - } else { - - var len = 0; - for (i=0, len=outEvts.length; i constrainTo.right) { + xy[0] += adjust = (constrainTo.right - dr.right); + dr.left += adjust; + } + if (dr.left < constrainTo.left) { + xy[0] += (constrainTo.left - dr.left); + } - if (len == 1) { - winner = dds[0]; - } else { - - for (var i=0; i constrainTo.bottom) { + xy[1] += adjust = (constrainTo.bottom - dr.bottom); + dr.top += adjust; } + if (dr.top < constrainTo.top) { + xy[1] += (constrainTo.top - dr.top); + } + return xy; + } + } +}); - return winner; - }, +Ext.define('Ext.dd.DragZone', { - - refreshCache: function(groups) { - for (var sGroup in groups) { - if ("string" != typeof sGroup) { - continue; - } - for (var i in this.ids[sGroup]) { - var oDD = this.ids[sGroup][i]; + extend: 'Ext.dd.DragSource', - if (this.isTypeOfDD(oDD)) { - - var loc = this.getLocation(oDD); - if (loc) { - this.locationCache[oDD.id] = loc; - } else { - delete this.locationCache[oDD.id]; - - - - } - } - } - } - }, + constructor : function(el, config){ + this.callParent([el, config]); + if (this.containerScroll) { + Ext.dd.ScrollManager.register(this.el); + } + }, - - verifyEl: function(el) { - if (el) { - var parent; - if(Ext.isIE){ - try{ - parent = el.offsetParent; - }catch(e){} - }else{ - parent = el.offsetParent; - } - if (parent) { - return true; - } - } + - return false; - }, + - - getLocation: function(oDD) { - if (! this.isTypeOfDD(oDD)) { - return null; - } + + getDragData : function(e){ + return Ext.dd.Registry.getHandleFromEvent(e); + }, - var el = oDD.getEl(), pos, x1, x2, y1, y2, t, r, b, l; + + onInitDrag : function(x, y){ + this.proxy.update(this.dragData.ddel.cloneNode(true)); + this.onStartDrag(x, y); + return true; + }, - try { - pos= Ext.lib.Dom.getXY(el); - } catch (e) { } + + afterRepair : function(){ + var me = this; + if (Ext.enableFx) { + Ext.fly(me.dragData.ddel).highlight(me.repairHighlightColor); + } + me.dragging = false; + }, - if (!pos) { - return null; - } + + getRepairXY : function(e){ + return Ext.core.Element.fly(this.dragData.ddel).getXY(); + }, - x1 = pos[0]; - x2 = x1 + el.offsetWidth; - y1 = pos[1]; - y2 = y1 + el.offsetHeight; + destroy : function(){ + this.callParent(); + if (this.containerScroll) { + Ext.dd.ScrollManager.unregister(this.el); + } + } +}); - t = y1 - oDD.padding[0]; - r = x2 + oDD.padding[1]; - b = y2 + oDD.padding[2]; - l = x1 - oDD.padding[3]; - return new Ext.lib.Region( t, r, b, l ); - }, +Ext.define('Ext.dd.ScrollManager', { + singleton: true, + requires: [ + 'Ext.dd.DragDropManager' + ], - - isOverTarget: function(pt, oTarget, intersect) { - - var loc = this.locationCache[oTarget.id]; - if (!loc || !this.useCache) { - loc = this.getLocation(oTarget); - this.locationCache[oTarget.id] = loc; + constructor: function() { + var ddm = Ext.dd.DragDropManager; + ddm.fireEvents = Ext.Function.createSequence(ddm.fireEvents, this.onFire, this); + ddm.stopDrag = Ext.Function.createSequence(ddm.stopDrag, this.onStop, this); + this.doScroll = Ext.Function.bind(this.doScroll, this); + this.ddmInstance = ddm; + this.els = {}; + this.dragEl = null; + this.proc = {}; + }, - } + onStop: function(e){ + var sm = Ext.dd.ScrollManager; + sm.dragEl = null; + sm.clearProc(); + }, - if (!loc) { - return false; - } + triggerRefresh: function() { + if (this.ddmInstance.dragCurrent) { + this.ddmInstance.refreshCache(this.ddmInstance.dragCurrent.groups); + } + }, - oTarget.cursorIsOver = loc.contains( pt ); + doScroll: function() { + if (this.ddmInstance.dragCurrent) { + var proc = this.proc, + procEl = proc.el, + ddScrollConfig = proc.el.ddScrollConfig, + inc = ddScrollConfig ? ddScrollConfig.increment : this.increment; - - - - - - var dc = this.dragCurrent; - if (!dc || !dc.getTargetCoord || - (!intersect && !dc.constrainX && !dc.constrainY)) { - return oTarget.cursorIsOver; + if (!this.animate) { + if (procEl.scroll(proc.dir, inc)) { + this.triggerRefresh(); + } + } else { + procEl.scroll(proc.dir, inc, true, this.animDuration, this.triggerRefresh); } + } + }, - oTarget.overlap = null; + clearProc: function() { + var proc = this.proc; + if (proc.id) { + clearInterval(proc.id); + } + proc.id = 0; + proc.el = null; + proc.dir = ""; + }, + startProc: function(el, dir) { + this.clearProc(); + this.proc.el = el; + this.proc.dir = dir; + var group = el.ddScrollConfig ? el.ddScrollConfig.ddGroup : undefined, + freq = (el.ddScrollConfig && el.ddScrollConfig.frequency) + ? el.ddScrollConfig.frequency + : this.frequency; + + if (group === undefined || this.ddmInstance.dragCurrent.ddGroup == group) { + this.proc.id = setInterval(this.doScroll, freq); + } + }, + + onFire: function(e, isDrop) { + if (isDrop || !this.ddmInstance.dragCurrent) { + return; + } + if (!this.dragEl || this.dragEl != this.ddmInstance.dragCurrent) { + this.dragEl = this.ddmInstance.dragCurrent; - - - - var pos = dc.getTargetCoord(pt.x, pt.y); + this.refreshCache(); + } - var el = dc.getDragEl(); - var curRegion = new Ext.lib.Region( pos.y, - pos.x + el.offsetWidth, - pos.y + el.offsetHeight, - pos.x ); + var xy = e.getXY(), + pt = e.getPoint(), + proc = this.proc, + els = this.els; - var overlap = curRegion.intersect(loc); + for (var id in els) { + var el = els[id], r = el._region; + var c = el.ddScrollConfig ? el.ddScrollConfig : this; + if (r && r.contains(pt) && el.isScrollable()) { + if (r.bottom - pt.y <= c.vthresh) { + if(proc.el != el){ + this.startProc(el, "down"); + } + return; + }else if (r.right - pt.x <= c.hthresh) { + if (proc.el != el) { + this.startProc(el, "left"); + } + return; + } else if(pt.y - r.top <= c.vthresh) { + if (proc.el != el) { + this.startProc(el, "up"); + } + return; + } else if(pt.x - r.left <= c.hthresh) { + if (proc.el != el) { + this.startProc(el, "right"); + } + return; + } + } + } + this.clearProc(); + }, - if (overlap) { - oTarget.overlap = overlap; - return (intersect) ? true : oTarget.cursorIsOver; - } else { - return false; + + register : function(el){ + if (Ext.isArray(el)) { + for(var i = 0, len = el.length; i < len; i++) { + this.register(el[i]); } - }, + } else { + el = Ext.get(el); + this.els[el.id] = el; + } + }, - - _onUnload: function(e, me) { - Ext.dd.DragDropMgr.unregAll(); - }, + + unregister : function(el){ + if(Ext.isArray(el)){ + for (var i = 0, len = el.length; i < len; i++) { + this.unregister(el[i]); + } + }else{ + el = Ext.get(el); + delete this.els[el.id]; + } + }, - - unregAll: function() { + + vthresh : 25, + + hthresh : 25, - if (this.dragCurrent) { - this.stopDrag(); - this.dragCurrent = null; - } + + increment : 100, - this._execOnAll("unreg", []); + + frequency : 500, - for (var i in this.elementCache) { - delete this.elementCache[i]; - } + + animate: true, - this.elementCache = {}; - this.ids = {}; - }, + + animDuration: 0.4, - - elementCache: {}, + + ddGroup: undefined, - - getElWrapper: function(id) { - var oWrapper = this.elementCache[id]; - if (!oWrapper || !oWrapper.el) { - oWrapper = this.elementCache[id] = - new this.ElementWrapper(Ext.getDom(id)); + + refreshCache : function(){ + var els = this.els, + id; + for (id in els) { + if(typeof els[id] == 'object'){ + els[id]._region = els[id].getRegion(); } - return oWrapper; - }, + } + } +}); - - getElement: function(id) { - return Ext.getDom(id); - }, - - getCss: function(id) { - var el = Ext.getDom(id); - return (el) ? el.style : null; - }, +Ext.define('Ext.dd.DropTarget', { + extend: 'Ext.dd.DDTarget', + requires: ['Ext.dd.ScrollManager'], - - ElementWrapper: function(el) { - - this.el = el || null; - - this.id = this.el && el.id; - - this.css = this.el && el.style; - }, + constructor : function(el, config){ + this.el = Ext.get(el); - - getPosX: function(el) { - return Ext.lib.Dom.getX(el); - }, + Ext.apply(this, config); - - getPosY: function(el) { - return Ext.lib.Dom.getY(el); - }, + if(this.containerScroll){ + Ext.dd.ScrollManager.register(this.el); + } - - swapNode: function(n1, n2) { - if (n1.swapNode) { - n1.swapNode(n2); - } else { - var p = n2.parentNode; - var s = n2.nextSibling; + this.callParent([this.el.dom, this.ddGroup || this.group, + {isTarget: true}]); + }, - if (s == n1) { - p.insertBefore(n1, n2); - } else if (n2 == n1.nextSibling) { - p.insertBefore(n2, n1); - } else { - n1.parentNode.replaceChild(n2, n1); - p.insertBefore(n1, s); - } - } - }, + + + + dropAllowed : Ext.baseCSSPrefix + 'dd-drop-ok', + + dropNotAllowed : Ext.baseCSSPrefix + 'dd-drop-nodrop', - - getScroll: function () { - var t, l, dde=document.documentElement, db=document.body; - if (dde && (dde.scrollTop || dde.scrollLeft)) { - t = dde.scrollTop; - l = dde.scrollLeft; - } else if (db) { - t = db.scrollTop; - l = db.scrollLeft; - } else { + + isTarget : true, - } - return { top: t, left: l }; - }, + + isNotifyTarget : true, - - getStyle: function(el, styleProp) { - return Ext.fly(el).getStyle(styleProp); - }, + + notifyEnter : function(dd, e, data){ + if(this.overClass){ + this.el.addCls(this.overClass); + } + return this.dropAllowed; + }, - - getScrollTop: function () { - return this.getScroll().top; - }, + + notifyOver : function(dd, e, data){ + return this.dropAllowed; + }, - - getScrollLeft: function () { - return this.getScroll().left; - }, + + notifyOut : function(dd, e, data){ + if(this.overClass){ + this.el.removeCls(this.overClass); + } + }, - - moveToEl: function (moveEl, targetEl) { - var aCoord = Ext.lib.Dom.getXY(targetEl); - Ext.lib.Dom.setXY(moveEl, aCoord); - }, + + notifyDrop : function(dd, e, data){ + return false; + }, - - numericSort: function(a, b) { - return (a - b); - }, + destroy : function(){ + this.callParent(); + if(this.containerScroll){ + Ext.dd.ScrollManager.unregister(this.el); + } + } +}); - - _timeoutCount: 0, - - _addListeners: function() { - var DDM = Ext.dd.DDM; - if ( Ext.lib.Event && document ) { - DDM._onLoad(); - } else { - if (DDM._timeoutCount > 2000) { - } else { - setTimeout(DDM._addListeners, 10); - if (document && document.body) { - DDM._timeoutCount += 1; - } - } +Ext.define('Ext.dd.Registry', { + singleton: true, + constructor: function() { + this.elements = {}; + this.handles = {}; + this.autoIdSeed = 0; + }, + + getId: function(el, autogen){ + if(typeof el == "string"){ + return el; + } + var id = el.id; + if(!id && autogen !== false){ + id = "extdd-" + (++this.autoIdSeed); + el.id = id; + } + return id; + }, + + + register : function(el, data){ + data = data || {}; + if (typeof el == "string") { + el = document.getElementById(el); + } + data.ddel = el; + this.elements[this.getId(el)] = data; + if (data.isHandle !== false) { + this.handles[data.ddel.id] = data; + } + if (data.handles) { + var hs = data.handles; + for (var i = 0, len = hs.length; i < len; i++) { + this.handles[this.getId(hs[i])] = data; } - }, - - - handleWasClicked: function(node, id) { - if (this.isHandle(id, node.id)) { - return true; - } else { - - var p = node.parentNode; + } + }, - while (p) { - if (this.isHandle(id, p.id)) { - return true; - } else { - p = p.parentNode; - } + + unregister : function(el){ + var id = this.getId(el, false); + var data = this.elements[id]; + if(data){ + delete this.elements[id]; + if(data.handles){ + var hs = data.handles; + for (var i = 0, len = hs.length; i < len; i++) { + delete this.handles[this.getId(hs[i], false)]; } } - - return false; } + }, - }; + + getHandle : function(id){ + if(typeof id != "string"){ + id = id.id; + } + return this.handles[id]; + }, -}(); + + getHandleFromEvent : function(e){ + var t = e.getTarget(); + return t ? this.handles[t.id] : null; + }, + + getTarget : function(id){ + if(typeof id != "string"){ + id = id.id; + } + return this.elements[id]; + }, -Ext.dd.DDM = Ext.dd.DragDropMgr; -Ext.dd.DDM._addListeners(); + + getTargetFromEvent : function(e){ + var t = e.getTarget(); + return t ? this.elements[t.id] || this.handles[t.id] : null; + } +}); -} +Ext.define('Ext.dd.DropZone', { + extend: 'Ext.dd.DropTarget', + requires: ['Ext.dd.Registry'], + + getTargetFromEvent : function(e){ + return Ext.dd.Registry.getTargetFromEvent(e); + }, -Ext.dd.DD = function(id, sGroup, config) { - if (id) { - this.init(id, sGroup, config); - } -}; + + onNodeEnter : function(n, dd, e, data){ + + }, -Ext.extend(Ext.dd.DD, Ext.dd.DragDrop, { + + onNodeOver : function(n, dd, e, data){ + return this.dropAllowed; + }, - scroll: true, + onNodeOut : function(n, dd, e, data){ + + }, - autoOffset: function(iPageX, iPageY) { - var x = iPageX - this.startPageX; - var y = iPageY - this.startPageY; - this.setDelta(x, y); + onNodeDrop : function(n, dd, e, data){ + return false; }, - setDelta: function(iDeltaX, iDeltaY) { - this.deltaX = iDeltaX; - this.deltaY = iDeltaY; + onContainerOver : function(dd, e, data){ + return this.dropNotAllowed; }, - setDragElPos: function(iPageX, iPageY) { - - + onContainerDrop : function(dd, e, data){ + return false; + }, - var el = this.getDragEl(); - this.alignElWithMouse(el, iPageX, iPageY); + + notifyEnter : function(dd, e, data){ + return this.dropNotAllowed; }, - alignElWithMouse: function(el, iPageX, iPageY) { - var oCoord = this.getTargetCoord(iPageX, iPageY); - var fly = el.dom ? el : Ext.fly(el, '_dd'); - if (!this.deltaSetXY) { - var aCoord = [oCoord.x, oCoord.y]; - fly.setXY(aCoord); - var newLeft = fly.getLeft(true); - var newTop = fly.getTop(true); - this.deltaSetXY = [ newLeft - oCoord.x, newTop - oCoord.y ]; - } else { - fly.setLeftTop(oCoord.x + this.deltaSetXY[0], oCoord.y + this.deltaSetXY[1]); + notifyOver : function(dd, e, data){ + var n = this.getTargetFromEvent(e); + if(!n) { + if(this.lastOverNode){ + this.onNodeOut(this.lastOverNode, dd, e, data); + this.lastOverNode = null; + } + return this.onContainerOver(dd, e, data); + } + if(this.lastOverNode != n){ + if(this.lastOverNode){ + this.onNodeOut(this.lastOverNode, dd, e, data); + } + this.onNodeEnter(n, dd, e, data); + this.lastOverNode = n; } + return this.onNodeOver(n, dd, e, data); + }, - this.cachePosition(oCoord.x, oCoord.y); - this.autoScroll(oCoord.x, oCoord.y, el.offsetHeight, el.offsetWidth); - return oCoord; + + notifyOut : function(dd, e, data){ + if(this.lastOverNode){ + this.onNodeOut(this.lastOverNode, dd, e, data); + this.lastOverNode = null; + } }, - cachePosition: function(iPageX, iPageY) { - if (iPageX) { - this.lastPageX = iPageX; - this.lastPageY = iPageY; - } else { - var aCoord = Ext.lib.Dom.getXY(this.getEl()); - this.lastPageX = aCoord[0]; - this.lastPageY = aCoord[1]; + notifyDrop : function(dd, e, data){ + if(this.lastOverNode){ + this.onNodeOut(this.lastOverNode, dd, e, data); + this.lastOverNode = null; } + var n = this.getTargetFromEvent(e); + return n ? + this.onNodeDrop(n, dd, e, data) : + this.onContainerDrop(dd, e, data); }, - autoScroll: function(x, y, h, w) { + triggerCacheRefresh : function() { + Ext.dd.DDM.refreshCache(this.groups); + } +}); - if (this.scroll) { - - var clientH = Ext.lib.Dom.getViewHeight(); +Ext.define('Ext.flash.Component', { + extend: 'Ext.Component', + alternateClassName: 'Ext.FlashComponent', + alias: 'widget.flash', - - var clientW = Ext.lib.Dom.getViewWidth(); + + flashVersion : '9.0.115', - - var st = this.DDM.getScrollTop(); + + backgroundColor: '#ffffff', - - var sl = this.DDM.getScrollLeft(); + + wmode: 'opaque', - - var bot = h + y; + - - var right = w + x; + - - - - var toBot = (clientH + st - y - this.deltaY); + - - var toRight = (clientW + sl - x - this.deltaX); + + + swfWidth: '100%', - - - var thresh = 40; + + swfHeight: '100%', - - - - var scrAmt = (document.all) ? 80 : 30; + + expressInstall: false, - - - if ( bot > clientH && toBot < thresh ) { - window.scrollTo(sl, st + scrAmt); - } + + + + renderTpl: ['
    '], - - - if ( y < st && st > 0 && y - st < thresh ) { - window.scrollTo(sl, st - scrAmt); - } + 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( - - if ( right > clientW && toRight < thresh ) { - window.scrollTo(sl + scrAmt, st); - } + 'success', - - if ( x < sl && sl > 0 && x - sl < thresh ) { - window.scrollTo(sl - scrAmt, st); - } - } + 'failure' + ); }, - - getTargetCoord: function(iPageX, iPageY) { - var x = iPageX - this.deltaX; - var y = iPageY - this.deltaY; - - if (this.constrainX) { - if (x < this.minX) { x = this.minX; } - if (x > this.maxX) { x = this.maxX; } - } - - if (this.constrainY) { - if (y < this.minY) { y = this.minY; } - if (y > this.maxY) { y = this.maxY; } - } + onRender: function() { + var me = this, + params, vars, undef, + swfId = me.getSwfId(); - x = this.getTick(x, this.xTicks); - y = this.getTick(y, this.yTicks); + me.renderData.swfId = swfId; + me.callParent(arguments); - return {x:x, y:y}; + params = Ext.apply({ + allowScriptAccess: 'always', + bgcolor: me.backgroundColor, + wmode: me.wmode + }, me.flashParams); + + vars = Ext.apply({ + allowedDomain: document.location.hostname + }, me.flashVars); + + new swfobject.embedSWF( + me.url, + swfId, + me.swfWidth, + me.swfHeight, + me.flashVersion, + me.expressInstall ? me.statics.EXPRESS_INSTALL_URL : undef, + vars, + params, + me.flashAttributes, + Ext.bind(me.swfCallback, me) + ); }, - applyConfig: function() { - Ext.dd.DD.superclass.applyConfig.call(this); - this.scroll = (this.config.scroll !== false); + swfCallback: function(e) { + var me = this; + if (e.success) { + me.swf = Ext.get(e.ref); + me.onSuccess(); + me.fireEvent('success', me); + } else { + me.onFailure(); + me.fireEvent('failure', me); + } }, - b4MouseDown: function(e) { + getSwfId: function() { + return this.swfId || (this.swfId = "extswf" + this.getAutoId()); + }, + + onSuccess: function() { - this.autoOffset(e.getPageX(), - e.getPageY()); + + this.swf.setStyle('visibility', 'inherit'); }, - - b4Drag: function(e) { - this.setDragElPos(e.getPageX(), - e.getPageY()); + onFailure: Ext.emptyFn, + + beforeDestroy: function() { + var me = this, + swf = me.swf; + if (swf) { + swfobject.removeSWF(me.getSwfId()); + Ext.destroy(swf); + delete me.swf; + } + me.callParent(); }, - toString: function() { - return ("DD " + this.id); + statics: { + + EXPRESS_INSTALL_URL: 'http:/' + '/swfobject.googlecode.com/svn/trunk/swfobject/expressInstall.swf' } +}); + + +Ext.define('Ext.form.action.Action', { + alternateClassName: 'Ext.form.Action', + - + -}); + -Ext.dd.DDProxy = function(id, sGroup, config) { - if (id) { - this.init(id, sGroup, config); - this.initFrame(); - } -}; + + -Ext.dd.DDProxy.dragElId = "ygddfdiv"; + -Ext.extend(Ext.dd.DDProxy, Ext.dd.DD, { + - resizeFrame: true, - centerFrame: false, - createFrame: function() { - var self = this; - var body = document.body; - if (!body || !body.firstChild) { - setTimeout( function() { self.createFrame(); }, 50 ); - return; - } + - var div = this.getDragEl(); + - if (!div) { - div = document.createElement("div"); - div.id = this.dragElId; - var s = div.style; + - s.position = "absolute"; - s.visibility = "hidden"; - s.cursor = "move"; - s.border = "2px solid #aaa"; - s.zIndex = 999; + - - - - body.insertBefore(div, body.firstChild); - } - }, + - initFrame: function() { - this.createFrame(); - }, - applyConfig: function() { - Ext.dd.DDProxy.superclass.applyConfig.call(this); - this.resizeFrame = (this.config.resizeFrame !== false); - this.centerFrame = (this.config.centerFrame); - this.setDragElId(this.config.dragElId || Ext.dd.DDProxy.dragElId); + + constructor: function(config) { + if (config) { + Ext.apply(this, config); + } + + + var params = config.params; + if (Ext.isString(params)) { + this.params = Ext.Object.fromQueryString(params); + } }, - showFrame: function(iPageX, iPageY) { - var el = this.getEl(); - var dragEl = this.getDragEl(); - var s = dragEl.style; - - this._resizeProxy(); + run: Ext.emptyFn, - if (this.centerFrame) { - this.setDelta( Math.round(parseInt(s.width, 10)/2), - Math.round(parseInt(s.height, 10)/2) ); - } + - this.setDragElPos(iPageX, iPageY); + - Ext.fly(dragEl).show(); + + onFailure : function(response){ + this.response = response; + this.failureType = Ext.form.action.Action.CONNECT_FAILURE; + this.form.afterAction(this, false); }, - _resizeProxy: function() { - if (this.resizeFrame) { - var el = this.getEl(); - Ext.fly(this.getDragEl()).setSize(el.offsetWidth, el.offsetHeight); + processResponse : function(response){ + this.response = response; + if (!response.responseText && !response.responseXML) { + return true; } + return (this.result = this.handleResponse(response)); }, - b4MouseDown: function(e) { - var x = e.getPageX(); - var y = e.getPageY(); - this.autoOffset(x, y); - this.setDragElPos(x, y); + getUrl: function() { + return this.url || this.form.url; }, - b4StartDrag: function(x, y) { - - this.showFrame(x, y); + getMethod: function() { + return (this.method || this.form.method || 'POST').toUpperCase(); }, - b4EndDrag: function(e) { - Ext.fly(this.getDragEl()).hide(); + getParams: function() { + return Ext.apply({}, this.params, this.form.baseParams); }, - - - endDrag: function(e) { - - var lel = this.getEl(); - var del = this.getDragEl(); + createCallback: function() { + var me = this, + undef, + form = me.form; + return { + success: me.onSuccess, + failure: me.onFailure, + scope: me, + timeout: (this.timeout * 1000) || (form.timeout * 1000), + upload: form.fileUpload ? me.onSuccess : undef + }; + }, + statics: { - del.style.visibility = ""; + CLIENT_INVALID: 'client', - this.beforeMove(); - - lel.style.visibility = "hidden"; - Ext.dd.DDM.moveToEl(lel, del); - del.style.visibility = "hidden"; - lel.style.visibility = ""; + SERVER_INVALID: 'server', - this.afterDrag(); - }, - - beforeMove : function(){ - - }, + + CONNECT_FAILURE: 'connect', - afterDrag : function(){ + + LOAD_FAILURE: 'load' - }, - toString: function() { - return ("DDProxy " + this.id); } - }); -Ext.dd.DDTarget = function(id, sGroup, config) { - if (id) { - this.initTarget(id, sGroup, config); - } -}; +Ext.define('Ext.form.action.Submit', { + extend:'Ext.form.action.Action', + alternateClassName: 'Ext.form.Action.Submit', + alias: 'formaction.submit', + + type: 'submit', -Ext.extend(Ext.dd.DDTarget, Ext.dd.DragDrop, { - - getDragEl: Ext.emptyFn, - - isValidHandleChild: Ext.emptyFn, - - startDrag: Ext.emptyFn, - - endDrag: Ext.emptyFn, - - onDrag: Ext.emptyFn, - - onDragDrop: Ext.emptyFn, - - onDragEnter: Ext.emptyFn, - - onDragOut: Ext.emptyFn, - - onDragOver: Ext.emptyFn, - - onInvalidDrop: Ext.emptyFn, - - onMouseDown: Ext.emptyFn, - - onMouseUp: Ext.emptyFn, - - setXConstraint: Ext.emptyFn, - - setYConstraint: Ext.emptyFn, - - resetConstraints: Ext.emptyFn, - - clearConstraints: Ext.emptyFn, - - clearTicks: Ext.emptyFn, - - setInitPosition: Ext.emptyFn, - - setDragElId: Ext.emptyFn, - - setHandleElId: Ext.emptyFn, - - setOuterHandleElId: Ext.emptyFn, - - addInvalidHandleClass: Ext.emptyFn, - - addInvalidHandleId: Ext.emptyFn, - - addInvalidHandleType: Ext.emptyFn, - - removeInvalidHandleClass: Ext.emptyFn, - removeInvalidHandleId: Ext.emptyFn, + - removeInvalidHandleType: Ext.emptyFn, + run : function(){ + var form = this.form; + if (this.clientValidation === false || form.isValid()) { + this.doSubmit(); + } else { + + this.failureType = Ext.form.action.Action.CLIENT_INVALID; + form.afterAction(this, false); + } + }, - toString: function() { - return ("DDTarget " + this.id); - } -}); -Ext.dd.DragTracker = Ext.extend(Ext.util.Observable, { - - active: false, - - tolerance: 5, - - autoStart: false, - constructor : function(config){ - Ext.apply(this, config); - this.addEvents( - - 'mousedown', - - 'mouseup', - - 'mousemove', - - 'dragstart', - - 'dragend', - - 'drag' - ); - - this.dragRegion = new Ext.lib.Region(0,0,0,0); - - if(this.el){ - this.initEl(this.el); - } - Ext.dd.DragTracker.superclass.constructor.call(this, config); - }, - - initEl: function(el){ - this.el = Ext.get(el); - el.on('mousedown', this.onMouseDown, this, - this.delegate ? {delegate: this.delegate} : undefined); + doSubmit: function() { + var formEl, + ajaxOptions = Ext.apply(this.createCallback(), { + url: this.getUrl(), + method: this.getMethod(), + headers: this.headers + }); + + + + if (this.form.hasUpload()) { + formEl = ajaxOptions.form = this.buildForm(); + ajaxOptions.isUpload = true; + } else { + ajaxOptions.params = this.getParams(); + } + + Ext.Ajax.request(ajaxOptions); + + if (formEl) { + Ext.removeNode(formEl); + } }, - destroy : function(){ - this.el.un('mousedown', this.onMouseDown, this); - delete this.el; + + getParams: function() { + var nope = false, + configParams = this.callParent(), + fieldParams = this.form.getValues(nope, nope, this.submitEmptyText !== nope); + return Ext.apply({}, fieldParams, configParams); }, - onMouseDown: function(e, target){ - if(this.fireEvent('mousedown', this, e) !== false && this.onBeforeStart(e) !== false){ - this.startXY = this.lastXY = e.getXY(); - this.dragTarget = this.delegate ? target : this.el.dom; - if(this.preventDefault !== false){ - e.preventDefault(); + + buildForm: function() { + var fieldsSpec = [], + formSpec, + formEl, + basicForm = this.form, + params = this.getParams(), + uploadFields = []; + + basicForm.getFields().each(function(field) { + if (field.isFileUpload()) { + uploadFields.push(field); } - Ext.getDoc().on({ - scope: this, - mouseup: this.onMouseUp, - mousemove: this.onMouseMove, - selectstart: this.stopSelect + }); + + function addField(name, val) { + fieldsSpec.push({ + tag: 'input', + type: 'hidden', + name: name, + value: val }); - if(this.autoStart){ - this.timer = this.triggerStart.defer(this.autoStart === true ? 1000 : this.autoStart, this, [e]); - } } - }, - onMouseMove: function(e, target){ - if(this.active && Ext.isIE && !e.browserEvent.button){ - e.preventDefault(); - this.onMouseUp(e); - return; + Ext.iterate(params, function(key, val) { + if (Ext.isArray(val)) { + Ext.each(val, function(v) { + addField(key, v); + }); + } else { + addField(key, val); + } + }); + + formSpec = { + tag: 'form', + action: this.getUrl(), + method: this.getMethod(), + target: this.target || '_self', + style: 'display:none', + cn: fieldsSpec + }; + + + if (uploadFields.length) { + formSpec.encoding = formSpec.enctype = 'multipart/form-data'; } - e.preventDefault(); - var xy = e.getXY(), s = this.startXY; - this.lastXY = xy; - if(!this.active){ - if(Math.abs(s[0]-xy[0]) > this.tolerance || Math.abs(s[1]-xy[1]) > this.tolerance){ - this.triggerStart(e); - }else{ - return; + + formEl = Ext.core.DomHelper.append(Ext.getBody(), formSpec); + + + + + Ext.Array.each(uploadFields, function(field) { + if (field.rendered) { + formEl.appendChild(field.extractFileInput()); } - } - this.fireEvent('mousemove', this, e); - this.onDrag(e); - this.fireEvent('drag', this, e); - }, + }); - onMouseUp: function(e) { - var doc = Ext.getDoc(), - wasActive = this.active; - - doc.un('mousemove', this.onMouseMove, this); - doc.un('mouseup', this.onMouseUp, this); - doc.un('selectstart', this.stopSelect, this); - e.preventDefault(); - this.clearStart(); - this.active = false; - delete this.elRegion; - this.fireEvent('mouseup', this, e); - if(wasActive){ - this.onEnd(e); - this.fireEvent('dragend', this, e); - } + return formEl; }, - triggerStart: function(e) { - this.clearStart(); - this.active = true; - this.onStart(e); - this.fireEvent('dragstart', this, e); - }, - clearStart : function() { - if(this.timer){ - clearTimeout(this.timer); - delete this.timer; + + + onSuccess: function(response) { + var form = this.form, + success = true, + result = this.processResponse(response); + if (result !== true && !result.success) { + if (result.errors) { + form.markInvalid(result.errors); + } + this.failureType = Ext.form.action.Action.SERVER_INVALID; + success = false; } + form.afterAction(this, success); }, - stopSelect : function(e) { - e.stopEvent(); - return false; - }, - - onBeforeStart : function(e) { + handleResponse: function(response) { + var form = this.form, + errorReader = form.errorReader, + rs, errors, i, len, records; + if (errorReader) { + rs = errorReader.read(response); + records = rs.records; + errors = []; + if (records) { + for(i = 0, len = records.length; i < len; i++) { + errors[i] = records[i].data; + } + } + if (errors.length < 1) { + errors = null; + } + return { + success : rs.success, + errors : errors + }; + } + return Ext.decode(response.responseText); + } +}); - }, + +Ext.define('Ext.util.ComponentDragger', { - onStart : function(xy) { - }, + - onDrag : function(e) { - }, + extend: 'Ext.dd.DragTracker', - - onEnd : function(e) { + autoStart: 500, + constructor: function(comp, config) { + this.comp = comp; + this.initialConstrainTo = config.constrainTo; + this.callParent([ config ]); }, - - getDragTarget : function(){ - return this.dragTarget; - }, + onStart: function(e) { + var me = this, + comp = me.comp; - getDragCt : function(){ - return this.el; - }, + + this.startPosition = comp.getPosition(); - getXY : function(constrain){ - return constrain ? - this.constrainModes[constrain].call(this, this.lastXY) : this.lastXY; - }, + + + if (comp.ghost && !comp.liveDrag) { + me.proxy = comp.ghost(); + me.dragTarget = me.proxy.header.el; + } - getOffset : function(constrain){ - var xy = this.getXY(constrain), - s = this.startXY; - return [s[0]-xy[0], s[1]-xy[1]]; + + if (me.constrain || me.constrainDelegate) { + me.constrainTo = me.calculateConstrainRegion(); + } }, - constrainModes: { - 'point' : function(xy){ + calculateConstrainRegion: function() { + var me = this, + comp = me.comp, + c = me.initialConstrainTo, + delegateRegion, + elRegion, + shadowSize = comp.el.shadow ? comp.el.shadow.offset : 0; - if(!this.elRegion){ - this.elRegion = this.getDragCt().getRegion(); - } + + if (!(c instanceof Ext.util.Region)) { + c = Ext.fly(c).getViewRegion(); + } - var dr = this.dragRegion; + + if (shadowSize) { + c.adjust(0, -shadowSize, -shadowSize, shadowSize); + } - dr.left = xy[0]; - dr.top = xy[1]; - dr.right = xy[0]; - dr.bottom = xy[1]; + + + + if (!me.constrainDelegate) { + delegateRegion = Ext.fly(me.dragTarget).getRegion(); + elRegion = me.proxy ? me.proxy.el.getRegion() : comp.el.getRegion(); - dr.constrainTo(this.elRegion); + c.adjust( + delegateRegion.top - elRegion.top, + delegateRegion.right - elRegion.right, + delegateRegion.bottom - elRegion.bottom, + delegateRegion.left - elRegion.left + ); + } + return c; + }, - return [dr.left, dr.top]; + + onDrag: function(e) { + var me = this, + 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]]); + }, + + onEnd: function(e) { + if (this.proxy && !this.comp.liveDrag) { + this.comp.unghost(); } } }); -Ext.dd.ScrollManager = function(){ - var ddm = Ext.dd.DragDropMgr; - var els = {}; - var dragEl = null; - var proc = {}; - - var onStop = function(e){ - dragEl = null; - clearProc(); - }; + +Ext.define("Ext.form.Labelable", { + requires: ['Ext.XTemplate'], + - var triggerRefresh = function(){ - if(ddm.dragCurrent){ - ddm.refreshCache(ddm.dragCurrent.groups); + labelableRenderTpl: [ + '', + ' for="{inputId}" class="{labelCls}" style="{labelStyle}">', + '{fieldLabel}{labelSeparator}', + '', + '', + '
    id="{baseBodyCls}-{inputId}" role="presentation">{subTplMarkup}
    ', + '', + '', + { + compiled: true, + disableFormats: true } - }; + ], + - var doScroll = function(){ - if(ddm.dragCurrent){ - var dds = Ext.dd.ScrollManager; - var inc = proc.el.ddScrollConfig ? - proc.el.ddScrollConfig.increment : dds.increment; - if(!dds.animate){ - if(proc.el.scroll(proc.dir, inc)){ - triggerRefresh(); - } - }else{ - proc.el.scroll(proc.dir, inc, true, dds.animDuration, triggerRefresh); - } - } - }; + activeErrorsTpl: [ + '', + '
      class="last">{.}
    ', + '
    ' + ], + - var clearProc = function(){ - if(proc.id){ - clearInterval(proc.id); - } - proc.id = 0; - proc.el = null; - proc.dir = ""; - }; + isFieldLabelable: true, - var startProc = function(el, dir){ - clearProc(); - proc.el = el; - proc.dir = dir; - var group = el.ddScrollConfig ? el.ddScrollConfig.ddGroup : undefined, - freq = (el.ddScrollConfig && el.ddScrollConfig.frequency) - ? el.ddScrollConfig.frequency - : Ext.dd.ScrollManager.frequency; + + formItemCls: Ext.baseCSSPrefix + 'form-item', - if (group === undefined || ddm.dragCurrent.ddGroup == group) { - proc.id = setInterval(doScroll, freq); - } - }; - var onFire = function(e, isDrop){ - if(isDrop || !ddm.dragCurrent){ return; } - var dds = Ext.dd.ScrollManager; - if(!dragEl || dragEl != ddm.dragCurrent){ - dragEl = ddm.dragCurrent; - - dds.refreshCache(); - } - - var xy = Ext.lib.Event.getXY(e); - var pt = new Ext.lib.Point(xy[0], xy[1]); - for(var id in els){ - var el = els[id], r = el._region; - var c = el.ddScrollConfig ? el.ddScrollConfig : dds; - if(r && r.contains(pt) && el.isScrollable()){ - if(r.bottom - pt.y <= c.vthresh){ - if(proc.el != el){ - startProc(el, "down"); - } - return; - }else if(r.right - pt.x <= c.hthresh){ - if(proc.el != el){ - startProc(el, "left"); - } - return; - }else if(pt.y - r.top <= c.vthresh){ - if(proc.el != el){ - startProc(el, "up"); - } - return; - }else if(pt.x - r.left <= c.hthresh){ - if(proc.el != el){ - startProc(el, "right"); - } - return; - } - } - } - clearProc(); - }; + labelCls: Ext.baseCSSPrefix + 'form-item-label', + - ddm.fireEvents = ddm.fireEvents.createSequence(onFire, ddm); - ddm.stopDrag = ddm.stopDrag.createSequence(onStop, ddm); + errorMsgCls: Ext.baseCSSPrefix + 'form-error-msg', + - return { - - register : function(el){ - if(Ext.isArray(el)){ - for(var i = 0, len = el.length; i < len; i++) { - this.register(el[i]); - } - }else{ - el = Ext.get(el); - els[el.id] = el; - } - }, - - - unregister : function(el){ - if(Ext.isArray(el)){ - for(var i = 0, len = el.length; i < len; i++) { - this.unregister(el[i]); - } - }else{ - el = Ext.get(el); - delete els[el.id]; - } - }, - - - vthresh : 25, - - hthresh : 25, + baseBodyCls: Ext.baseCSSPrefix + 'form-item-body', - - increment : 100, - - - frequency : 500, - - - animate: true, - - - animDuration: .4, - - - ddGroup: undefined, - - - refreshCache : function(){ - for(var id in els){ - if(typeof els[id] == 'object'){ - els[id]._region = els[id].getRegion(); - } - } - } - }; -}(); -Ext.dd.Registry = function(){ - var elements = {}; - var handles = {}; - var autoIdSeed = 0; + + fieldBodyCls: '', - var getId = function(el, autogen){ - if(typeof el == "string"){ - return el; - } - var id = el.id; - if(!id && autogen !== false){ - id = "extdd-" + (++autoIdSeed); - el.id = id; - } - return id; - }; - return { + clearCls: Ext.baseCSSPrefix + 'clear', + - register : function(el, data){ - data = data || {}; - if(typeof el == "string"){ - el = document.getElementById(el); - } - data.ddel = el; - elements[getId(el)] = data; - if(data.isHandle !== false){ - handles[data.ddel.id] = data; - } - if(data.handles){ - var hs = data.handles; - for(var i = 0, len = hs.length; i < len; i++){ - handles[getId(hs[i])] = data; - } - } - }, + invalidCls : Ext.baseCSSPrefix + 'form-invalid', - unregister : function(el){ - var id = getId(el, false); - var data = elements[id]; - if(data){ - delete elements[id]; - if(data.handles){ - var hs = data.handles; - for(var i = 0, len = hs.length; i < len; i++){ - delete handles[getId(hs[i], false)]; - } - } - } - }, + fieldLabel: undefined, - getHandle : function(id){ - if(typeof id != "string"){ - id = id.id; - } - return handles[id]; - }, + labelAlign : 'left', - getHandleFromEvent : function(e){ - var t = Ext.lib.Event.getTarget(e); - return t ? handles[t.id] : null; - }, + labelWidth: 100, + + + labelPad : 5, + + + labelSeparator : ':', + + + + + hideLabel: false, + + + hideEmptyLabel: true, + + + preventMark: false, + + + autoFitErrors: true, - getTarget : function(id){ - if(typeof id != "string"){ - id = id.id; - } - return elements[id]; - }, + msgTarget: 'qtip', - getTargetFromEvent : function(e){ - var t = Ext.lib.Event.getTarget(e); - return t ? elements[t.id] || handles[t.id] : null; - } - }; -}(); -Ext.dd.StatusProxy = function(config){ - Ext.apply(this, config); - this.id = this.id || Ext.id(); - this.el = new Ext.Layer({ - dh: { - id: this.id, tag: "div", cls: "x-dd-drag-proxy "+this.dropNotAllowed, children: [ - {tag: "div", cls: "x-dd-drop-icon"}, - {tag: "div", cls: "x-dd-drag-ghost"} - ] - }, - shadow: !config || config.shadow !== false - }); - this.ghost = Ext.get(this.el.dom.childNodes[1]); - this.dropStatus = this.dropNotAllowed; -}; -Ext.dd.StatusProxy.prototype = { + - dropAllowed : "x-dd-drop-ok", + initLabelable: function() { + this.addCls(this.formItemCls); + + this.addEvents( + + 'errorchange' + ); + }, + - dropNotAllowed : "x-dd-drop-nodrop", + getFieldLabel: function() { + return this.fieldLabel || ''; + }, - setStatus : function(cssClass){ - cssClass = cssClass || this.dropNotAllowed; - if(this.dropStatus != cssClass){ - this.el.replaceClass(this.dropStatus, cssClass); - this.dropStatus = cssClass; + getLabelableRenderData: function() { + var me = this, + labelAlign = me.labelAlign, + labelPad = me.labelPad, + labelStyle; + + + + if (labelAlign === 'top') { + labelStyle = 'margin-bottom:' + labelPad + 'px;'; + } else { + labelStyle = 'margin-right:' + labelPad + 'px;'; + + if (Ext.isBorderBox) { + labelStyle += 'width:' + me.labelWidth + 'px;'; + } } + + return Ext.copyTo( + { + inputId: me.getInputId(), + fieldLabel: me.getFieldLabel(), + labelStyle: labelStyle + (me.labelStyle || ''), + subTplMarkup: me.getSubTplMarkup() + }, + me, + 'hideLabel,hideEmptyLabel,labelCls,fieldBodyCls,baseBodyCls,errorMsgCls,clearCls,labelSeparator', + true + ); }, - reset : function(clearGhost){ - this.el.dom.className = "x-dd-drag-proxy " + this.dropNotAllowed; - this.dropStatus = this.dropNotAllowed; - if(clearGhost){ - this.ghost.update(""); - } + getLabelableSelectors: function() { + return { + + labelEl: 'label.' + this.labelCls, + + + bodyEl: '.' + this.baseBodyCls, + + + errorEl: '.' + this.errorMsgCls + }; }, - 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'); - } + getSubTplMarkup: function() { + return ''; }, - getEl : function(){ - return this.el; + getInputId: function() { + return ''; }, - getGhost : function(){ - return this.ghost; + getActiveError : function() { + return this.activeError || ''; }, - hide : function(clear){ - this.el.hide(); - if(clear){ - this.reset(true); - } + hasActiveError: function() { + return !!this.getActiveError(); }, - stop : function(){ - if(this.anim && this.anim.isAnimated && this.anim.isAnimated()){ - this.anim.stop(); - } + setActiveError: function(msg) { + this.activeError = msg; + this.activeErrors = [msg]; + this.renderActiveError(); }, - show : function(){ - this.el.show(); + getActiveErrors: function() { + return this.activeErrors || []; }, - sync : function(){ - this.el.sync(); + setActiveErrors: function(errors) { + this.activeErrors = errors; + this.activeError = this.getTpl('activeErrorsTpl').apply({errors: errors}); + this.renderActiveError(); }, - repair : function(xy, callback, scope){ - this.callback = callback; - this.scope = scope; - if(xy && this.animRepair !== false){ - this.el.addClass("x-dd-drag-repair"); - this.el.hideUnders(true); - this.anim = this.el.shift({ - duration: this.repairDuration || .5, - easing: 'easeOut', - xy: xy, - stopFx: true, - callback: this.afterRepair, - scope: this - }); - }else{ - this.afterRepair(); - } + unsetActiveError: function() { + delete this.activeError; + delete this.activeErrors; + this.renderActiveError(); }, - afterRepair : function(){ - this.hide(true); - if(typeof this.callback == "function"){ - this.callback.call(this.scope || this); + renderActiveError: function() { + var me = this, + activeError = me.getActiveError(), + hasError = !!activeError; + + if (activeError !== me.lastActiveError) { + me.fireEvent('errorchange', me, activeError); + me.lastActiveError = activeError; + } + + if (me.rendered && !me.isDestroyed && !me.preventMark) { + + me.el[hasError ? 'addCls' : 'removeCls'](me.invalidCls); + + + me.getActionEl().dom.setAttribute('aria-invalid', hasError); + + + me.errorEl.dom.innerHTML = activeError; } - this.callback = null; - this.scope = null; }, + - destroy: function(){ - Ext.destroy(this.ghost, this.el); - } -}; -Ext.dd.DragSource = function(el, config){ - this.el = Ext.get(el); - if(!this.dragData){ - this.dragData = {}; - } - - Ext.apply(this, config); + setFieldDefaults: function(defaults) { + var me = this; + Ext.iterate(defaults, function(key, val) { + if (!me.hasOwnProperty(key)) { + me[key] = val; + } + }); + }, + - if(!this.proxy){ - this.proxy = new Ext.dd.StatusProxy(); + getBodyNaturalWidth: function() { + return this.bodyEl.getWidth(); } - Ext.dd.DragSource.superclass.constructor.call(this, this.el.dom, this.ddGroup || this.group, - {dragElId : this.proxy.id, resizeFrame: false, isTarget: false, scroll: this.scroll === true}); + +}); + + +Ext.define('Ext.form.field.Field', { + - this.dragging = false; -}; + isFormField : true, -Ext.extend(Ext.dd.DragSource, Ext.dd.DDProxy, { - dropAllowed : "x-dd-drop-ok", - dropNotAllowed : "x-dd-drop-nodrop", - getDragData : function(e){ - return this.dragData; - }, + disabled : false, - onDragEnter : function(e, id){ - var target = Ext.dd.DragDropMgr.getDDById(id); - this.cachedTarget = target; - if(this.beforeDragEnter(target, e, id) !== false){ - if(target.isNotifyTarget){ - var status = target.notifyEnter(this, e, this.dragData); - this.proxy.setStatus(status); - }else{ - this.proxy.setStatus(this.dropAllowed); - } - - if(this.afterDragEnter){ - - this.afterDragEnter(target, e, id); - } - } - }, + submitValue: true, - beforeDragEnter : function(target, e, id){ - return true; - }, + validateOnChange: true, - alignElWithMouse: function() { - Ext.dd.DragSource.superclass.alignElWithMouse.apply(this, arguments); - this.proxy.sync(); - }, + suspendCheckChange: 0, - onDragOver : function(e, id){ - var target = this.cachedTarget || Ext.dd.DragDropMgr.getDDById(id); - if(this.beforeDragOver(target, e, id) !== false){ - if(target.isNotifyTarget){ - var status = target.notifyOver(this, e, this.dragData); - this.proxy.setStatus(status); - } + initField: function() { + this.addEvents( + + 'change', + + 'validitychange', + + 'dirtychange' + ); - if(this.afterDragOver){ - - this.afterDragOver(target, e, id); - } - } + this.initValue(); }, - beforeDragOver : function(target, e, id){ - return true; + initValue: function() { + var me = this; + + + me.originalValue = me.lastValue = me.value; + + + me.suspendCheckChange++; + me.setValue(me.value); + me.suspendCheckChange--; }, - onDragOut : function(e, id){ - var target = this.cachedTarget || Ext.dd.DragDropMgr.getDDById(id); - if(this.beforeDragOut(target, e, id) !== false){ - if(target.isNotifyTarget){ - target.notifyOut(this, e, this.dragData); - } - this.proxy.reset(); - if(this.afterDragOut){ - - this.afterDragOut(target, e, id); - } - } - this.cachedTarget = null; + getName: function() { + return this.name; }, - beforeDragOut : function(target, e, id){ - return true; + getValue: function() { + return this.value; }, - onDragDrop : function(e, id){ - var target = this.cachedTarget || Ext.dd.DragDropMgr.getDDById(id); - if(this.beforeDragDrop(target, e, id) !== false){ - if(target.isNotifyTarget){ - if(target.notifyDrop(this, e, this.dragData)){ - this.onValidDrop(target, e, id); - }else{ - this.onInvalidDrop(target, e, id); - } - }else{ - this.onValidDrop(target, e, id); - } - - if(this.afterDragDrop){ - - this.afterDragDrop(target, e, id); - } - } - delete this.cachedTarget; + setValue: function(value) { + var me = this; + me.value = value; + me.checkChange(); + return me; }, - beforeDragDrop : function(target, e, id){ - return true; + isEqual: function(value1, value2) { + return String(value1) === String(value2); }, - onValidDrop : function(target, e, id){ - this.hideProxy(); - if(this.afterValidDrop){ - - this.afterValidDrop(target, e, id); + getSubmitData: function() { + var me = this, + data = null; + if (!me.disabled && me.submitValue && !me.isFileUpload()) { + data = {}; + data[me.getName()] = '' + me.getValue(); } + return data; }, - getRepairXY : function(e, data){ - return this.el.getXY(); - }, - - - onInvalidDrop : function(target, e, id){ - this.beforeInvalidDrop(target, e, id); - if(this.cachedTarget){ - if(this.cachedTarget.isNotifyTarget){ - this.cachedTarget.notifyOut(this, e, this.dragData); - } - this.cacheTarget = null; - } - this.proxy.repair(this.getRepairXY(e, this.dragData), this.afterRepair, this); - - if(this.afterInvalidDrop){ - - this.afterInvalidDrop(e, id); + getModelData: function() { + var me = this, + data = null; + if (!me.disabled && !me.isFileUpload()) { + data = {}; + data[me.getName()] = me.getValue(); } + return data; }, - afterRepair : function(){ - if(Ext.enableFx){ - this.el.highlight(this.hlColor || "c3daf9"); - } - this.dragging = false; + reset : function(){ + var me = this; + + me.setValue(me.originalValue); + me.clearInvalid(); + + delete me.wasValid; }, - beforeInvalidDrop : function(target, e, id){ - return true; + resetOriginalValue: function() { + this.originalValue = this.getValue(); + this.checkDirty(); }, - handleMouseDown : function(e){ - if(this.dragging) { - return; + checkChange: function() { + if (!this.suspendCheckChange) { + var me = this, + newVal = me.getValue(), + oldVal = me.lastValue; + if (!me.isEqual(newVal, oldVal) && !me.isDestroyed) { + me.lastValue = newVal; + me.fireEvent('change', me, newVal, oldVal); + me.onChange(newVal, oldVal); + } } - var data = this.getDragData(e); - if(data && this.onBeforeDrag(data, e) !== false){ - this.dragData = data; - this.proxy.stop(); - Ext.dd.DragSource.superclass.handleMouseDown.apply(this, arguments); - } }, - onBeforeDrag : function(data, e){ - return true; + onChange: function(newVal, oldVal) { + if (this.validateOnChange) { + this.validate(); + } + this.checkDirty(); }, - onStartDrag : Ext.emptyFn, + isDirty : function() { + var me = this; + return !me.disabled && !me.isEqual(me.getValue(), me.originalValue); + }, - startDrag : function(x, y){ - this.proxy.reset(); - this.dragging = true; - this.proxy.update(""); - this.onInitDrag(x, y); - this.proxy.show(); + checkDirty: function() { + var me = this, + isDirty = me.isDirty(); + if (isDirty !== me.wasDirty) { + me.fireEvent('dirtychange', me, isDirty); + me.onDirtyChange(isDirty); + me.wasDirty = isDirty; + } }, - onInitDrag : function(x, y){ - var clone = this.el.dom.cloneNode(true); - clone.id = Ext.id(); - this.proxy.update(clone); - this.onStartDrag(x, y); - return true; - }, + onDirtyChange: Ext.emptyFn, - getProxy : function(){ - return this.proxy; + getErrors: function(value) { + return []; }, - hideProxy : function(){ - this.proxy.hide(); - this.proxy.reset(true); - this.dragging = false; + isValid : function() { + var me = this; + return me.disabled || Ext.isEmpty(me.getErrors()); }, - triggerCacheRefresh : function(){ - Ext.dd.DDM.refreshCache(this.groups); + validate : function() { + var me = this, + isValid = me.isValid(); + if (isValid !== me.wasValid) { + me.wasValid = isValid; + me.fireEvent('validitychange', me, isValid); + } + return isValid; }, - b4EndDrag: function(e) { + batchChanges: function(fn) { + this.suspendCheckChange++; + fn(); + this.suspendCheckChange--; + this.checkChange(); }, - endDrag : function(e){ - this.onEndDrag(this.dragData, e); + isFileUpload: function() { + return false; }, - onEndDrag : function(data, e){ + extractFileInput: function() { + return null; }, + + markInvalid: Ext.emptyFn, + - autoOffset : function(x, y) { - this.setDelta(-12, -20); - }, - - destroy: function(){ - Ext.dd.DragSource.superclass.destroy.call(this); - Ext.destroy(this.proxy); - } + clearInvalid: Ext.emptyFn + }); -Ext.dd.DropTarget = Ext.extend(Ext.dd.DDTarget, { - - constructor : function(el, config){ - this.el = Ext.get(el); - - Ext.apply(this, config); + + +Ext.define('Ext.layout.component.field.Field', { + - if(this.containerScroll){ - Ext.dd.ScrollManager.register(this.el); - } + + alias: ['layout.field'], + + extend: 'Ext.layout.component.Component', + + uses: ['Ext.tip.QuickTip', 'Ext.util.TextMetrics'], + - Ext.dd.DropTarget.superclass.constructor.call(this, this.el.dom, this.ddGroup || this.group, - {isTarget: true}); + + type: 'field', + + beforeLayout: function(width, height) { + var me = this; + return me.callParent(arguments) || (!me.owner.preventMark && me.activeError !== me.owner.getActiveError()); }, - - - - - dropAllowed : "x-dd-drop-ok", - - dropNotAllowed : "x-dd-drop-nodrop", - - isTarget : true, + onLayout: function(width, height) { + var me = this, + owner = me.owner, + labelStrategy = me.getLabelStrategy(), + errorStrategy = me.getErrorStrategy(), + isDefined = Ext.isDefined, + isNumber = Ext.isNumber, + lastSize, autoWidth, autoHeight, info, undef; - - isNotifyTarget : true, + lastSize = me.lastComponentSize || {}; + if (!isDefined(width)) { + width = lastSize.width; + if (width < 0) { + width = undef; + } + } + if (!isDefined(height)) { + height = lastSize.height; + if (height < 0) { + height = undef; + } + } + autoWidth = !isNumber(width); + autoHeight = !isNumber(height); - - notifyEnter : function(dd, e, data){ - if(this.overClass){ - this.el.addClass(this.overClass); + info = { + autoWidth: autoWidth, + autoHeight: autoHeight, + width: autoWidth ? owner.getBodyNaturalWidth() : width, + height: height, + + + insets: { + top: 0, + right: 0, + bottom: 0, + left: 0 + } + }; + + + + + + + labelStrategy.prepare(owner, info); + errorStrategy.prepare(owner, info); + + + labelStrategy.adjustHorizInsets(owner, info); + errorStrategy.adjustHorizInsets(owner, info); + + + labelStrategy.layoutHoriz(owner, info); + errorStrategy.layoutHoriz(owner, info); + + + labelStrategy.adjustVertInsets(owner, info); + errorStrategy.adjustVertInsets(owner, info); + + + labelStrategy.layoutVert(owner, info); + errorStrategy.layoutVert(owner, info); + + + if (autoWidth && autoHeight) { + + me.setElementSize(owner.el, info.width, info.height); + } else { + me.setTargetSize(info.width, info.height); } - return this.dropAllowed; + me.sizeBody(info); + + me.activeError = owner.getActiveError(); }, + - notifyOver : function(dd, e, data){ - return this.dropAllowed; + sizeBody: function(info) { + var me = this, + owner = me.owner, + insets = info.insets, + totalWidth = info.width, + totalHeight = info.height, + width = Ext.isNumber(totalWidth) ? totalWidth - insets.left - insets.right : totalWidth, + height = Ext.isNumber(totalHeight) ? totalHeight - insets.top - insets.bottom : totalHeight; + + + me.setElementSize(owner.bodyEl, width, height); + + + me.sizeBodyContents(width, height); }, - notifyOut : function(dd, e, data){ - if(this.overClass){ - this.el.removeClass(this.overClass); - } + sizeBodyContents: Ext.emptyFn, + + + + getLabelStrategy: function() { + var me = this, + strategies = me.labelStrategies, + labelAlign = me.owner.labelAlign; + return strategies[labelAlign] || strategies.base; }, - notifyDrop : function(dd, e, data){ - return false; + getErrorStrategy: function() { + var me = this, + owner = me.owner, + strategies = me.errorStrategies, + msgTarget = owner.msgTarget; + return !owner.preventMark && Ext.isString(msgTarget) ? + (strategies[msgTarget] || strategies.elementId) : + strategies.none; }, + + + - destroy : function(){ - Ext.dd.DropTarget.superclass.destroy.call(this); - if(this.containerScroll){ - Ext.dd.ScrollManager.unregister(this.el); + labelStrategies: (function() { + var applyIf = Ext.applyIf, + emptyFn = Ext.emptyFn, + base = { + prepare: function(owner, info) { + var cls = owner.labelCls + '-' + owner.labelAlign, + labelEl = owner.labelEl; + if (labelEl && !labelEl.hasCls(cls)) { + labelEl.addCls(cls); + } + }, + adjustHorizInsets: emptyFn, + adjustVertInsets: emptyFn, + layoutHoriz: emptyFn, + layoutVert: emptyFn + }, + left = applyIf({ + prepare: function(owner, info) { + base.prepare(owner, info); + + if (info.autoWidth) { + info.width += (!owner.labelEl ? 0 : owner.labelWidth + owner.labelPad); + } + }, + adjustHorizInsets: function(owner, info) { + if (owner.labelEl) { + info.insets.left += owner.labelWidth + owner.labelPad; + } + }, + layoutHoriz: function(owner, info) { + + + + + + var labelEl = owner.labelEl; + if (labelEl && !owner.isLabelSized && !Ext.isBorderBox) { + labelEl.setWidth(owner.labelWidth); + owner.isLabelSized = true; + } + } + }, base); + + + return { + base: base, + + + top: applyIf({ + adjustVertInsets: function(owner, info) { + var labelEl = owner.labelEl; + if (labelEl) { + info.insets.top += Ext.util.TextMetrics.measure(labelEl, owner.fieldLabel, info.width).height + + labelEl.getFrameWidth('tb') + owner.labelPad; + } + } + }, base), + + + left: left, + + + right: left + }; + })(), + + + + + errorStrategies: (function() { + function setDisplayed(el, displayed) { + var wasDisplayed = el.getStyle('display') !== 'none'; + if (displayed !== wasDisplayed) { + el.setDisplayed(displayed); + } + } + + function setStyle(el, name, value) { + if (el.getStyle(name) !== value) { + el.setStyle(name, value); + } + } + + var applyIf = Ext.applyIf, + emptyFn = Ext.emptyFn, + base = { + prepare: function(owner) { + setDisplayed(owner.errorEl, false); + }, + adjustHorizInsets: emptyFn, + adjustVertInsets: emptyFn, + layoutHoriz: emptyFn, + layoutVert: emptyFn + }; + + return { + none: base, + + + side: applyIf({ + prepare: function(owner) { + var errorEl = owner.errorEl; + errorEl.addCls(Ext.baseCSSPrefix + 'form-invalid-icon'); + Ext.layout.component.field.Field.initTip(); + errorEl.dom.setAttribute('data-errorqtip', owner.getActiveError() || ''); + setDisplayed(errorEl, owner.hasActiveError()); + }, + adjustHorizInsets: function(owner, info) { + if (owner.autoFitErrors && owner.hasActiveError()) { + info.insets.right += owner.errorEl.getWidth(); + } + }, + layoutHoriz: function(owner, info) { + if (owner.hasActiveError()) { + setStyle(owner.errorEl, 'left', info.width - info.insets.right + 'px'); + } + }, + layoutVert: function(owner, info) { + if (owner.hasActiveError()) { + setStyle(owner.errorEl, 'top', info.insets.top + 'px'); + } + } + }, base), + + + under: applyIf({ + prepare: function(owner) { + var errorEl = owner.errorEl, + cls = Ext.baseCSSPrefix + 'form-invalid-under'; + if (!errorEl.hasCls(cls)) { + errorEl.addCls(cls); + } + setDisplayed(errorEl, owner.hasActiveError()); + }, + adjustVertInsets: function(owner, info) { + if (owner.autoFitErrors) { + info.insets.bottom += owner.errorEl.getHeight(); + } + }, + layoutHoriz: function(owner, info) { + var errorEl = owner.errorEl, + insets = info.insets; + + setStyle(errorEl, 'width', info.width - insets.right - insets.left + 'px'); + setStyle(errorEl, 'marginLeft', insets.left + 'px'); + } + }, base), + + + qtip: applyIf({ + prepare: function(owner) { + setDisplayed(owner.errorEl, false); + Ext.layout.component.field.Field.initTip(); + owner.getActionEl().dom.setAttribute('data-errorqtip', owner.getActiveError() || ''); + } + }, base), + + + title: applyIf({ + prepare: function(owner) { + setDisplayed(owner.errorEl, false); + owner.el.dom.title = owner.getActiveError() || ''; + } + }, base), + + + elementId: applyIf({ + prepare: function(owner) { + setDisplayed(owner.errorEl, false); + var targetEl = Ext.fly(owner.msgTarget); + if (targetEl) { + targetEl.dom.innerHTML = owner.getActiveError() || ''; + targetEl.setDisplayed(owner.hasActiveError()); + } + } + }, base) + }; + })(), + + statics: { + + initTip: function() { + var tip = this.tip; + if (!tip) { + tip = this.tip = Ext.create('Ext.tip.QuickTip', { + baseCls: Ext.baseCSSPrefix + 'form-invalid-tip', + renderTo: Ext.getBody() + }); + tip.tagConfig = Ext.apply({}, {attribute: 'errorqtip'}, tip.tagConfig); + } + }, + + + destroyTip: function() { + var tip = this.tip; + if (tip) { + tip.destroy(); + delete this.tip; + } } } + }); -Ext.dd.DragZone = Ext.extend(Ext.dd.DragSource, { - - constructor : function(el, config){ - Ext.dd.DragZone.superclass.constructor.call(this, el, config); - if(this.containerScroll){ - Ext.dd.ScrollManager.register(this.el); - } - }, - - - - + +Ext.define('Ext.form.field.VTypes', (function(){ - getDragData : function(e){ - return Ext.dd.Registry.getHandleFromEvent(e); - }, - - - onInitDrag : function(x, y){ - this.proxy.update(this.dragData.ddel.cloneNode(true)); - this.onStartDrag(x, y); - return true; - }, - + var alpha = /^[a-zA-Z_]+$/, + alphanum = /^[a-zA-Z0-9_]+$/, + email = /^(\w+)([\-+.][\w]+)*@(\w[\-\w]*\.){1,5}([A-Za-z]){2,6}$/, + url = /(((^https?)|(^ftp)):\/\/([\-\w]+\.)+\w{2,3}(\/[%\-\w]+(\.\w{2,})?)*(([\w\-\.\?\\\/+@&#;`~=%!]*)(\.\w{2,})?)*\/?)/i; + - afterRepair : function(){ - if(Ext.enableFx){ - Ext.Element.fly(this.dragData.ddel).highlight(this.hlColor || "c3daf9"); - } - this.dragging = false; + return { + singleton: true, + alternateClassName: 'Ext.form.VTypes', + + + 'email' : function(v){ + return email.test(v); + }, + + 'emailText' : 'This field should be an e-mail address in the format "user@example.com"', + + 'emailMask' : /[a-z0-9_\.\-@\+]/i, + + + 'url' : function(v){ + return url.test(v); + }, + + 'urlText' : 'This field should be a URL in the format "http:/'+'/www.example.com"', + + + 'alpha' : function(v){ + return alpha.test(v); + }, + + 'alphaText' : 'This field should only contain letters and _', + + 'alphaMask' : /[a-z_]/i, + + + 'alphanum' : function(v){ + return alphanum.test(v); + }, + + 'alphanumText' : 'This field should only contain letters, numbers and _', + + 'alphanumMask' : /[a-z0-9_]/i + }; +})()); + + +Ext.define('Ext.layout.component.field.Text', { + extend: 'Ext.layout.component.field.Field', + alias: 'layout.textfield', + requires: ['Ext.util.TextMetrics'], + + type: 'textfield', + + + + beforeLayout: function(width, height) { + var me = this, + owner = me.owner, + lastValue = this.lastValue, + value = owner.getRawValue(); + this.lastValue = value; + return me.callParent(arguments) || (owner.grow && value !== lastValue); }, + - getRepairXY : function(e){ - return Ext.Element.fly(this.dragData.ddel).getXY(); + sizeBodyContents: function(width, height) { + var size = this.adjustForGrow(width, height); + this.setElementSize(this.owner.inputEl, size[0], size[1]); }, + + - destroy : function(){ - Ext.dd.DragZone.superclass.destroy.call(this); - if(this.containerScroll){ - Ext.dd.ScrollManager.unregister(this.el); + adjustForGrow: function(width, height) { + var me = this, + owner = me.owner, + inputEl, value, calcWidth, + result = [width, height]; + + if (owner.grow) { + inputEl = owner.inputEl; + + + value = (inputEl.dom.value || (owner.hasFocus ? '' : owner.emptyText) || '') + owner.growAppend; + calcWidth = inputEl.getTextWidth(value) + inputEl.getBorderWidth("lr") + inputEl.getPadding("lr"); + + + result[0] = Ext.Number.constrain(calcWidth, owner.growMin, + Math.max(owner.growMin, Math.min(owner.growMax, Ext.isNumber(width) ? width : Infinity))); } + + return result; } + }); -Ext.dd.DropZone = function(el, config){ - Ext.dd.DropZone.superclass.constructor.call(this, el, config); -}; -Ext.extend(Ext.dd.DropZone, Ext.dd.DropTarget, { - - getTargetFromEvent : function(e){ - return Ext.dd.Registry.getTargetFromEvent(e); - }, - - onNodeEnter : function(n, dd, e, data){ - - }, +Ext.define('Ext.layout.component.field.TextArea', { + extend: 'Ext.layout.component.field.Text', + alias: 'layout.textareafield', - - onNodeOver : function(n, dd, e, data){ - return this.dropAllowed; - }, + type: 'textareafield', - - onNodeOut : function(n, dd, e, data){ - - }, - onNodeDrop : function(n, dd, e, data){ - return false; - }, + adjustForGrow: function(width, height) { + var me = this, + owner = me.owner, + inputEl, value, max, + curWidth, curHeight, calcHeight, + result = [width, height]; - - onContainerOver : function(dd, e, data){ - return this.dropNotAllowed; - }, + if (owner.grow) { + inputEl = owner.inputEl; + curWidth = inputEl.getWidth(true); + curHeight = inputEl.getHeight(); - - onContainerDrop : function(dd, e, data){ - return false; - }, + + value = inputEl.dom.value || ' '; + value += owner.growAppend; - - notifyEnter : function(dd, e, data){ - return this.dropNotAllowed; - }, + + value = value.replace(/\n/g, '
    '); - - notifyOver : function(dd, e, data){ - var n = this.getTargetFromEvent(e); - if(!n){ - if(this.lastOverNode){ - this.onNodeOut(this.lastOverNode, dd, e, data); - this.lastOverNode = null; - } - return this.onContainerOver(dd, e, data); - } - if(this.lastOverNode != n){ - if(this.lastOverNode){ - this.onNodeOut(this.lastOverNode, dd, e, data); - } - this.onNodeEnter(n, dd, e, data); - this.lastOverNode = n; - } - return this.onNodeOver(n, dd, e, data); - }, + + calcHeight = Ext.util.TextMetrics.measure(inputEl, value, curWidth).height + + inputEl.getBorderWidth("tb") + inputEl.getPadding("tb"); - - notifyOut : function(dd, e, data){ - if(this.lastOverNode){ - this.onNodeOut(this.lastOverNode, dd, e, data); - this.lastOverNode = null; + + max = owner.growMax; + if (Ext.isNumber(height)) { + max = Math.min(max, height); + } + result[1] = Ext.Number.constrain(calcHeight, owner.growMin, max); } - }, - - notifyDrop : function(dd, e, data){ - if(this.lastOverNode){ - this.onNodeOut(this.lastOverNode, dd, e, data); - this.lastOverNode = null; - } - var n = this.getTargetFromEvent(e); - return n ? - this.onNodeDrop(n, dd, e, data) : - this.onContainerDrop(dd, e, data); - }, + return result; + } - - triggerCacheRefresh : function(){ - Ext.dd.DDM.refreshCache(this.groups); - } }); -Ext.Element.addMethods({ - - initDD : function(group, config, overrides){ - var dd = new Ext.dd.DD(Ext.id(this.dom), group, config); - return Ext.apply(dd, overrides); - }, - - initDDProxy : function(group, config, overrides){ - var dd = new Ext.dd.DDProxy(Ext.id(this.dom), group, config); - return Ext.apply(dd, overrides); - }, + +Ext.define('Ext.layout.container.Anchor', { - initDDTarget : function(group, config, overrides){ - var dd = new Ext.dd.DDTarget(Ext.id(this.dom), group, config); - return Ext.apply(dd, overrides); - } -}); -Ext.data.Api = (function() { + alias: 'layout.anchor', + extend: 'Ext.layout.container.Container', + alternateClassName: 'Ext.layout.AnchorLayout', + + + type: 'anchor', + + defaultAnchor: '100%', + + parseAnchorRE: /^(r|right|b|bottom)$/i, + - var validActions = {}; + onLayout: function() { + this.callParent(arguments); - return { - - actions : { - create : 'create', - read : 'read', - update : 'update', - destroy : 'destroy' - }, + var me = this, + size = me.getLayoutTargetSize(), + owner = me.owner, + target = me.getTarget(), + ownerWidth = size.width, + ownerHeight = size.height, + overflow = target.getStyle('overflow'), + components = me.getVisibleItems(owner), + len = components.length, + boxes = [], + box, newTargetSize, anchorWidth, anchorHeight, component, anchorSpec, calcWidth, calcHeight, + anchorsArray, anchor, i, el; - - restActions : { - create : 'POST', - read : 'GET', - update : 'PUT', - destroy : 'DELETE' - }, + if (ownerWidth < 20 && ownerHeight < 20) { + return; + } - isAction : function(action) { - return (Ext.data.Api.actions[action]) ? true : false; - }, + + + if (!me.clearEl) { + me.clearEl = target.createChild({ + cls: Ext.baseCSSPrefix + 'clear', + role: 'presentation' + }); + } - getVerb : function(name) { - if (validActions[name]) { - return validActions[name]; + if (owner.anchorSize) { + if (typeof owner.anchorSize == 'number') { + anchorWidth = owner.anchorSize; } - for (var verb in this.actions) { - if (this.actions[verb] === name) { - validActions[name] = verb; - break; - } + else { + anchorWidth = owner.anchorSize.width; + anchorHeight = owner.anchorSize.height; } - return (validActions[name] !== undefined) ? validActions[name] : null; - }, + } + else { + anchorWidth = owner.initialConfig.width; + anchorHeight = owner.initialConfig.height; + } - isValid : function(api){ - var invalid = []; - var crud = this.actions; - for (var action in api) { - if (!(action in crud)) { - invalid.push(action); - } - } - return (!invalid.length) ? true : invalid; - }, + if (!Ext.supports.RightMargin) { + target.addCls(Ext.baseCSSPrefix + 'inline-children'); + } - - hasUniqueUrl : function(proxy, verb) { - var url = (proxy.api[verb]) ? proxy.api[verb].url : null; - var unique = true; - for (var action in proxy.api) { - if ((unique = (action === verb) ? true : (proxy.api[action].url != url) ? true : false) === false) { - break; - } - } - return unique; - }, + for (i = 0; i < len; i++) { + component = components[i]; + el = component.el; + anchor = component.anchor; - - prepare : function(proxy) { - if (!proxy.api) { - proxy.api = {}; + if (!component.anchor && component.items && !Ext.isNumber(component.width) && !(Ext.isIE6 && Ext.isStrict)) { + component.anchor = anchor = me.defaultAnchor; } - for (var verb in this.actions) { - var action = this.actions[verb]; - proxy.api[action] = proxy.api[action] || proxy.url || proxy.directFn; - if (typeof(proxy.api[action]) == 'string') { - proxy.api[action] = { - url: proxy.api[action], - method: (proxy.restful === true) ? Ext.data.Api.restActions[action] : undefined + + 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) }; } + 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, + anchor: true, + width: calcWidth || undefined, + height: calcHeight || undefined + }); + } else { + boxes.push({ + component: component, + anchor: false + }); } - }, + } - restify : function(proxy) { - proxy.restful = true; - for (var verb in this.restActions) { - proxy.api[this.actions[verb]].method || - (proxy.api[this.actions[verb]].method = this.restActions[verb]); - } - - - proxy.onWrite = proxy.onWrite.createInterceptor(function(action, o, response, rs) { - var reader = o.reader; - var res = new Ext.data.Response({ - action: action, - raw: response - }); - - switch (response.status) { - case 200: - return true; - break; - case 201: - if (Ext.isEmpty(res.raw.responseText)) { - res.success = true; - } else { - - return true; - } - break; - case 204: - res.success = true; - res.data = null; - break; - default: - return true; - break; - } - if (res.success === true) { - this.fireEvent("write", this, action, res.data, res, rs, o.request.arg); - } else { - this.fireEvent('exception', this, 'remote', action, o, res, rs); - } - o.request.callback.call(o.request.scope, res.data, res, res.success); - - return false; - }, proxy); + if (!Ext.supports.RightMargin) { + target.removeCls(Ext.baseCSSPrefix + 'inline-children'); } - }; -})(); + for (i = 0; i < len; i++) { + box = boxes[i]; + me.setItemSize(box.component, box.width, box.height); + } -Ext.data.Response = function(params, response) { - Ext.apply(this, params, { - raw: response - }); -}; -Ext.data.Response.prototype = { - message : null, - success : false, - status : null, - root : null, - raw : null, + if (overflow && overflow != 'hidden' && !me.adjustmentPass) { + newTargetSize = me.getLayoutTargetSize(); + if (newTargetSize.width != size.width || newTargetSize.height != size.height) { + me.adjustmentPass = true; + me.onLayout(); + } + } - getMessage : function() { - return this.message; - }, - getSuccess : function() { - return this.success; + delete me.adjustmentPass; }, - getStatus : function() { - return this.status; - }, - getRoot : function() { - return this.root; - }, - getRawResponse : function() { - return this.raw; - } -}; + + parseAnchor: function(a, start, cstart) { + if (a && a != 'none') { + var ratio; + + if (this.parseAnchorRE.test(a)) { + var diff = cstart - start; + return function(v) { + return v - diff; + }; + } + + else if (a.indexOf('%') != -1) { + ratio = parseFloat(a.replace('%', '')) * 0.01; + return function(v) { + return Math.floor(v * ratio); + }; + } + + else { + a = parseInt(a, 10); + if (!isNaN(a)) { + return function(v) { + return v + a; + }; + } + } + } + return null; + }, -Ext.data.Api.Error = Ext.extend(Ext.Error, { - constructor : function(message, arg) { - this.arg = arg; - Ext.Error.call(this, message); + + adjustWidthAnchor: function(value, comp) { + return value; }, - name: 'Ext.data.Api' -}); -Ext.apply(Ext.data.Api.Error.prototype, { - lang: { - 'action-url-undefined': 'No fallback url defined for this action. When defining a DataProxy api, please be sure to define an url for each CRUD action in Ext.data.Api.actions or define a default url in addition to your api-configuration.', - 'invalid': 'received an invalid API-configuration. Please ensure your proxy API-configuration contains only the actions defined in Ext.data.Api.actions', - 'invalid-url': 'Invalid url. Please review your proxy configuration.', - 'execute': 'Attempted to execute an unknown action. Valid API actions are defined in Ext.data.Api.actions"' + + + adjustHeightAnchor: function(value, comp) { + return value; } -}); +}); +Ext.define('Ext.form.action.Load', { + extend:'Ext.form.action.Action', + requires: ['Ext.data.Connection'], + alternateClassName: 'Ext.form.Action.Load', + alias: 'formaction.load', + type: 'load', -Ext.data.SortTypes = { - none : function(s){ - return s; + run: function() { + Ext.Ajax.request(Ext.apply( + this.createCallback(), + { + method: this.getMethod(), + url: this.getUrl(), + headers: this.headers, + params: this.getParams() + } + )); }, + - - stripTagsRE : /<\/?[^>]+>/gi, - - - asText : function(s){ - return String(s).replace(this.stripTagsRE, ""); + onSuccess: function(response){ + var result = this.processResponse(response), + form = this.form; + if (result === true || !result.success || !result.data) { + this.failureType = Ext.form.action.Action.LOAD_FAILURE; + form.afterAction(this, false); + return; + } + form.clearInvalid(); + form.setValues(result.data); + form.afterAction(this, true); }, + + handleResponse: function(response) { + var reader = this.form.reader, + rs, data; + if (reader) { + rs = reader.read(response); + data = rs.records && rs.records[0] ? rs.records[0].data : null; + return { + success : rs.success, + data : data + }; + } + return Ext.decode(response.responseText); + } +}); + + + +Ext.define('Ext.window.Window', { + extend: 'Ext.panel.Panel', + + alternateClassName: 'Ext.Window', + + requires: ['Ext.util.ComponentDragger', 'Ext.util.Region', 'Ext.EventManager'], + + alias: 'widget.window', + - asUCText : function(s){ - return String(s).toUpperCase().replace(this.stripTagsRE, ""); - }, - asUCString : function(s) { - return String(s).toUpperCase(); - }, - asDate : function(s) { - if(!s){ - return 0; - } - if(Ext.isDate(s)){ - return s.getTime(); - } - return Date.parse(String(s)); - }, - asFloat : function(s) { - var val = parseFloat(String(s).replace(/,/g, "")); - return isNaN(val) ? 0 : val; - }, + - asInt : function(s) { - var val = parseInt(String(s).replace(/,/g, ""), 10); - return isNaN(val) ? 0 : val; - } -}; -Ext.data.Record = function(data, id){ + baseCls: Ext.baseCSSPrefix + 'window', + - this.id = (id || id === 0) ? id : Ext.data.Record.id(this); - this.data = data || {}; -}; + resizable: true, + + draggable: true, -Ext.data.Record.create = function(o){ - var f = Ext.extend(Ext.data.Record, {}); - var p = f.prototype; - p.fields = new Ext.util.MixedCollection(false, function(field){ - return field.name; - }); - for(var i = 0, len = o.length; i < len; i++){ - p.fields.add(new Ext.data.Field(o[i])); - } - f.getField = function(name){ - return p.fields.get(name); - }; - return f; -}; + + constrain: false, -Ext.data.Record.PREFIX = 'ext-record'; -Ext.data.Record.AUTO_ID = 1; -Ext.data.Record.EDIT = 'edit'; -Ext.data.Record.REJECT = 'reject'; -Ext.data.Record.COMMIT = 'commit'; + + constrainHeader: false, + + plain: false, + + minimizable: false, -Ext.data.Record.id = function(rec) { - rec.phantom = true; - return [Ext.data.Record.PREFIX, '-', Ext.data.Record.AUTO_ID++].join(''); -}; + + maximizable: false, -Ext.data.Record.prototype = { + minHeight: 100, + + minWidth: 200, + + expandOnShow: true, + + collapsible: false, + + closable: true, + - dirty : false, - editing : false, - error : null, + hidden: true, + - modified : null, + autoRender: true, + - phantom : false, + hideMode: 'visibility', - join : function(store){ - - this.store = store; - }, + floating: true, + ariaRole: 'alertdialog', - set : function(name, value){ - var encode = Ext.isPrimitive(value) ? String : Ext.encode; - if(encode(this.data[name]) == encode(value)) { - return; - } - this.dirty = true; - if(!this.modified){ - this.modified = {}; - } - if(this.modified[name] === undefined){ - this.modified[name] = this.data[name]; - } - this.data[name] = value; - if(!this.editing){ - this.afterEdit(); - } - }, + itemCls: 'x-window-item', + overlapHeader: true, - afterEdit : function(){ - if (this.store != undefined && typeof this.store.afterEdit == "function") { - this.store.afterEdit(this); - } - }, + ignoreHeaderBorderManagement: true, - afterReject : function(){ - if(this.store){ - this.store.afterReject(this); + initComponent: function() { + var me = this; + me.callParent(); + me.addEvents( + + + + 'resize', + + 'maximize', + + 'minimize', + + 'restore' + ); + + if (me.plain) { + me.addClsWithUI('plain'); } - }, - - afterCommit : function(){ - if(this.store){ - this.store.afterCommit(this); + if (me.modal) { + me.ariaRole = 'dialog'; } }, - get : function(name){ - return this.data[name]; - }, - - beginEdit : function(){ - this.editing = true; - this.modified = this.modified || {}; - }, - - cancelEdit : function(){ - this.editing = false; - delete this.modified; + initStateEvents: function(){ + var events = this.stateEvents; + + Ext.each(['maximize', 'restore', 'resize', 'dragend'], function(event){ + if (Ext.Array.indexOf(events, event)) { + events.push(event); + } + }); + this.callParent(); }, - - endEdit : function(){ - this.editing = false; - if(this.dirty){ - this.afterEdit(); - } + getState: function() { + var me = this, + state = me.callParent() || {}, + maximized = !!me.maximized; + + state.maximized = maximized; + Ext.apply(state, { + size: maximized ? me.restoreSize : me.getSize(), + pos: maximized ? me.restorePos : me.getPosition() + }); + return state; }, - - reject : function(silent){ - var m = this.modified; - for(var n in m){ - if(typeof m[n] != "function"){ - this.data[n] = m[n]; + applyState: function(state){ + var me = this; + + if (state) { + me.maximized = state.maximized; + if (me.maximized) { + me.hasSavedRestore = true; + me.restoreSize = state.size; + me.restorePos = state.pos; + } else { + Ext.apply(me, { + width: state.size.width, + height: state.size.height, + x: state.pos[0], + y: state.pos[1] + }); } } - this.dirty = false; - delete this.modified; - this.editing = false; - if(silent !== true){ - this.afterReject(); - } }, - commit : function(silent){ - this.dirty = false; - delete this.modified; - this.editing = false; - if(silent !== true){ - this.afterCommit(); + onMouseDown: function () { + if (this.floating) { + this.toFront(); } }, - getChanges : function(){ - var m = this.modified, cs = {}; - for(var n in m){ - if(m.hasOwnProperty(n)){ - cs[n] = this.data[n]; - } - } - return cs; - }, + onRender: function(ct, position) { + var me = this; + me.callParent(arguments); + me.focusEl = me.el; - - hasError : function(){ - return this.error !== null; + + if (me.maximizable) { + me.header.on({ + dblclick: { + fn: me.toggleMaximize, + element: 'el', + scope: me + } + }); + } }, - clearError : function(){ - this.error = null; - }, + afterRender: function() { + var me = this, + hidden = me.hidden, + keyMap; - - copy : function(newId) { - return new this.constructor(Ext.apply({}, this.data), newId || this.id); - }, + me.hidden = false; + + me.callParent(); + me.hidden = hidden; - - isModified : function(fieldName){ - return !!(this.modified && this.modified.hasOwnProperty(fieldName)); - }, + + me.proxy = me.getProxy(); - - isValid : function() { - return this.fields.find(function(f) { - return (f.allowBlank === false && Ext.isEmpty(this.data[f.name])) ? true : false; - },this) ? false : true; - }, + + me.mon(me.el, 'mousedown', me.onMouseDown, me); - - markDirty : function(){ - this.dirty = true; - if(!this.modified){ - this.modified = {}; + + if (me.maximized) { + me.maximized = false; + me.maximize(); } - this.fields.each(function(f) { - this.modified[f.name] = this.data[f.name]; - },this); - } -}; - -Ext.StoreMgr = Ext.apply(new Ext.util.MixedCollection(), { - - - register : function(){ - for(var i = 0, s; (s = arguments[i]); i++){ - this.add(s); + if (me.closable) { + keyMap = me.getKeyMap(); + keyMap.on(27, me.onEsc, me); + keyMap.disable(); } }, - unregister : function(){ - for(var i = 0, s; (s = arguments[i]); i++){ - this.remove(this.lookup(s)); + initDraggable: function() { + var me = this, + ddConfig; + + if (!me.header) { + me.updateHeader(true); } - }, - - lookup : function(id){ - if(Ext.isArray(id)){ - var fields = ['field1'], expand = !Ext.isArray(id[0]); - if(!expand){ - for(var i = 2, len = id[0].length; i <= len; ++i){ - fields.push('field' + i); - } - } - return new Ext.data.ArrayStore({ - fields: fields, - data: id, - expandData: expand, - autoDestroy: true, - autoCreated: 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; } - return Ext.isObject(id) ? (id.events ? id : Ext.create(id, 'store')) : this.get(id); + + + me.dd = Ext.create('Ext.util.ComponentDragger', this, ddConfig); + me.relayEvents(me.dd, ['dragstart', 'drag', 'dragend']); }, - getKey : function(o){ - return o.storeId; - } -}); -Ext.data.Store = Ext.extend(Ext.util.Observable, { - - - - - - - - writer : undefined, - - - - remoteSort : false, + onEsc: function(k, e) { + e.stopEvent(); + this[this.closeAction](); + }, - autoDestroy : false, + beforeDestroy: function() { + var me = this; + if (me.rendered) { + delete this.animateTarget; + me.hide(); + Ext.destroy( + me.keyMap + ); + } + me.callParent(); + }, - pruneModifiedRecords : false, + addTools: function() { + var me = this; - - lastOptions : null, + + me.callParent(); - - autoSave : true, + if (me.minimizable) { + me.addTool({ + type: 'minimize', + handler: Ext.Function.bind(me.minimize, me, []) + }); + } + if (me.maximizable) { + me.addTool({ + type: 'maximize', + handler: Ext.Function.bind(me.maximize, me, []) + }); + me.addTool({ + type: 'restore', + handler: Ext.Function.bind(me.restore, me, []), + hidden: true + }); + } + }, - batch : true, + getFocusEl: function() { + var me = this, + f = me.focusEl, + defaultComp = me.defaultButton || me.defaultFocus, + t = typeof db, + el, + ct; - - restful: false, + if (Ext.isDefined(defaultComp)) { + if (Ext.isNumber(defaultComp)) { + f = me.query('button')[defaultComp]; + } else if (Ext.isString(defaultComp)) { + f = me.down('#' + defaultComp); + } else { + f = defaultComp; + } + } + return f || me.focusEl; + }, - paramNames : undefined, + beforeShow: function() { + this.callParent(); - - defaultParamNames : { - start : 'start', - limit : 'limit', - sort : 'sort', - dir : 'dir' + if (this.expandOnShow) { + this.expand(false); + } }, - isDestroyed: false, - hasMultiSort: false, - - batchKey : '_ext_batch_', + afterShow: function(animateTarget) { + var me = this, + size; - constructor : function(config){ - - - this.data = new Ext.util.MixedCollection(false); - this.data.getKey = function(o){ - return o.id; - }; - + me.callParent(arguments); - - this.removed = []; + if (me.maximized) { + me.fitContainer(); + } - if(config && config.data){ - this.inlineData = config.data; - delete config.data; + if (me.monitorResize || me.constrain || me.constrainHeader) { + Ext.EventManager.onWindowResize(me.onWindowResize, me); + } + me.doConstrain(); + if (me.keyMap) { + me.keyMap.enable(); } + }, - Ext.apply(this, config); + + doClose: function() { + var me = this; - this.baseParams = Ext.isObject(this.baseParams) ? this.baseParams : {}; + if (me.hidden) { + me.fireEvent('close', me); + me[me.closeAction](); + } else { + + me.hide(me.animTarget, me.doClose, me); + } + }, - this.paramNames = Ext.applyIf(this.paramNames || {}, this.defaultParamNames); + + afterHide: function() { + var me = this; - if((this.url || this.api) && !this.proxy){ - this.proxy = new Ext.data.HttpProxy({url: this.url, api: this.api}); - } - if (this.restful === true && this.proxy) { - - - this.batch = false; - Ext.data.Api.restify(this.proxy); + if (me.monitorResize || me.constrain || me.constrainHeader) { + Ext.EventManager.removeResizeListener(me.onWindowResize, me); } - if(this.reader){ - if(!this.recordType){ - this.recordType = this.reader.recordType; - } - if(this.reader.onMetaChange){ - this.reader.onMetaChange = this.reader.onMetaChange.createSequence(this.onMetaChange, this); - } - if (this.writer) { - if (this.writer instanceof(Ext.data.DataWriter) === false) { - this.writer = this.buildWriter(this.writer); - } - this.writer.meta = this.reader.meta; - this.pruneModifiedRecords = true; - } + + if (me.keyMap) { + me.keyMap.disable(); } + me.callParent(arguments); + }, - if(this.recordType){ - - this.fields = this.recordType.prototype.fields; + + onWindowResize: function() { + if (this.maximized) { + this.fitContainer(); } - this.modified = []; + this.doConstrain(); + }, - this.addEvents( - - 'datachanged', - - 'metachange', - - 'add', - - 'remove', - - 'update', - - 'clear', - - 'exception', - - 'beforeload', - - 'load', - - 'loadexception', - - 'beforewrite', - - 'write', - - 'beforesave', - - 'save' + + minimize: function() { + this.fireEvent('minimize', this); + return this; + }, - ); + afterCollapse: function() { + var me = this; - if(this.proxy){ - - this.relayEvents(this.proxy, ['loadexception', 'exception']); - } - - if (this.writer) { - this.on({ - scope: this, - add: this.createRecords, - remove: this.destroyRecord, - update: this.updateRecord, - clear: this.onClear - }); + if (me.maximizable) { + me.tools.maximize.hide(); + me.tools.restore.hide(); } - - this.sortToggle = {}; - if(this.sortField){ - this.setDefaultSort(this.sortField, this.sortDir); - }else if(this.sortInfo){ - this.setDefaultSort(this.sortInfo.field, this.sortInfo.direction); + if (me.resizer) { + me.resizer.disable(); } + me.callParent(arguments); + }, - Ext.data.Store.superclass.constructor.call(this); + afterExpand: function() { + var me = this; - if(this.id){ - this.storeId = this.id; - delete this.id; - } - if(this.storeId){ - Ext.StoreMgr.register(this); + if (me.maximized) { + me.tools.restore.show(); + } else if (me.maximizable) { + me.tools.maximize.show(); } - if(this.inlineData){ - this.loadData(this.inlineData); - delete this.inlineData; - }else if(this.autoLoad){ - this.load.defer(10, this, [ - typeof this.autoLoad == 'object' ? - this.autoLoad : undefined]); + if (me.resizer) { + me.resizer.enable(); } - - this.batchCounter = 0; - this.batches = {}; + me.callParent(arguments); }, - - buildWriter : function(config) { - var klass = undefined, - type = (config.format || 'json').toLowerCase(); - switch (type) { - case 'json': - klass = Ext.data.JsonWriter; - break; - case 'xml': - klass = Ext.data.XmlWriter; - break; - default: - klass = Ext.data.JsonWriter; + + maximize: function() { + var me = this; + + if (!me.maximized) { + me.expand(false); + if (!me.hasSavedRestore) { + me.restoreSize = me.getSize(); + me.restorePos = me.getPosition(true); + } + if (me.maximizable) { + me.tools.maximize.hide(); + me.tools.restore.show(); + } + me.maximized = true; + me.el.disableShadow(); + + if (me.dd) { + me.dd.disable(); + } + if (me.collapseTool) { + me.collapseTool.hide(); + } + me.el.addCls(Ext.baseCSSPrefix + 'window-maximized'); + me.container.addCls(Ext.baseCSSPrefix + 'window-maximized-ct'); + + me.setPosition(0, 0); + me.fitContainer(); + me.fireEvent('maximize', me); } - return new klass(config); + return me; }, - destroy : function(){ - if(!this.isDestroyed){ - if(this.storeId){ - Ext.StoreMgr.unregister(this); + restore: function() { + var me = this, + tools = me.tools; + + if (me.maximized) { + delete me.hasSavedRestore; + me.removeCls(Ext.baseCSSPrefix + 'window-maximized'); + + + if (tools.restore) { + tools.restore.hide(); + } + if (tools.maximize) { + tools.maximize.show(); + } + if (me.collapseTool) { + me.collapseTool.show(); } - this.clearData(); - this.data = null; - Ext.destroy(this.proxy); - this.reader = this.writer = null; - this.purgeListeners(); - this.isDestroyed = true; - } - }, - - add : function(records) { - var i, len, record, index; - - records = [].concat(records); - if (records.length < 1) { - return; - } - - for (i = 0, len = records.length; i < len; i++) { - record = records[i]; - record.join(this); + me.setPosition(me.restorePos); + me.setSize(me.restoreSize); + + + delete me.restorePos; + delete me.restoreSize; + + me.maximized = false; + + me.el.enableShadow(true); + - if (record.dirty || record.phantom) { - this.modified.push(record); + if (me.dd) { + me.dd.enable(); } + + me.container.removeCls(Ext.baseCSSPrefix + 'window-maximized-ct'); + + me.doConstrain(); + me.fireEvent('restore', me); } - - index = this.data.length; - this.data.addAll(records); - - if (this.snapshot) { - this.snapshot.addAll(records); - } - - this.fireEvent('add', this, records, index); + return me; }, - addSorted : function(record){ - var index = this.findInsertIndex(record); - this.insert(index, record); - }, - + toggleMaximize: function() { + return this[this.maximized ? 'restore': 'maximize'](); + } + - doUpdate : function(rec){ - this.data.replace(rec.id, rec); - if(this.snapshot){ - this.snapshot.replace(rec.id, rec); +}); + +Ext.define('Ext.form.field.Base', { + extend: 'Ext.Component', + mixins: { + labelable: 'Ext.form.Labelable', + field: 'Ext.form.field.Field' + }, + alias: 'widget.field', + alternateClassName: ['Ext.form.Field', 'Ext.form.BaseField'], + requires: ['Ext.util.DelayedTask', 'Ext.XTemplate', 'Ext.layout.component.field.Field'], + + fieldSubTpl: [ + 'name="{name}" ', + 'size="{size}" ', + 'tabIndex="{tabIdx}" ', + 'class="{fieldCls} {typeCls}" autocomplete="off" />', + { + compiled: true, + disableFormats: true } - this.fireEvent('update', this, rec, Ext.data.Record.COMMIT); - }, + ], - remove : function(record){ - if(Ext.isArray(record)){ - Ext.each(record, function(r){ - this.remove(r); - }, this); - return; - } - var index = this.data.indexOf(record); - if(index > -1){ - record.join(null); - this.data.removeAt(index); - } - if(this.pruneModifiedRecords){ - this.modified.remove(record); - } - if(this.snapshot){ - this.snapshot.remove(record); - } - if(index > -1){ - this.fireEvent('remove', this, record, index); - } - }, - removeAt : function(index){ - this.remove(this.getAt(index)); - }, + inputType: 'text', - removeAll : function(silent){ - var items = []; - this.each(function(rec){ - items.push(rec); - }); - this.clearData(); - if(this.snapshot){ - this.snapshot.clear(); - } - if(this.pruneModifiedRecords){ - this.modified = []; - } - if (silent !== true) { - this.fireEvent('clear', this, items); - } - }, - onClear: function(store, records){ - Ext.each(records, function(rec, index){ - this.destroyRecord(this, rec, index); - }, this); - }, + invalidText : 'The value in this field is invalid', - insert : function(index, records) { - var i, len, record; - - records = [].concat(records); - for (i = 0, len = records.length; i < len; i++) { - record = records[i]; - - this.data.insert(index + i, record); - record.join(this); - - if (record.dirty || record.phantom) { - this.modified.push(record); - } - } - - if (this.snapshot) { - this.snapshot.addAll(records); - } - - this.fireEvent('add', this, records, index); - }, + fieldCls : Ext.baseCSSPrefix + 'form-field', - indexOf : function(record){ - return this.data.indexOf(record); - }, - indexOfId : function(id){ - return this.data.indexOfKey(id); - }, + focusCls : Ext.baseCSSPrefix + 'form-focus', - getById : function(id){ - return (this.snapshot || this.data).key(id); - }, + dirtyCls : Ext.baseCSSPrefix + 'form-dirty', - getAt : function(index){ - return this.data.itemAt(index); - }, + checkChangeEvents: Ext.isIE && (!document.documentMode || document.documentMode < 9) ? + ['change', 'propertychange'] : + ['change', 'input', 'textInput', 'keyup', 'dragdrop'], - getRange : function(start, end){ - return this.data.getRange(start, end); - }, + checkChangeBuffer: 50, + + componentLayout: 'field', - storeOptions : function(o){ - o = Ext.apply({}, o); - delete o.callback; - delete o.scope; - this.lastOptions = o; - }, + readOnly : false, - clearData: function(){ - this.data.each(function(rec) { - rec.join(null); - }); - this.data.clear(); - }, + readOnlyCls: Ext.baseCSSPrefix + 'form-readonly', - load : function(options) { - options = Ext.apply({}, options); - this.storeOptions(options); - if(this.sortInfo && this.remoteSort){ - var pn = this.paramNames; - options.params = Ext.apply({}, options.params); - options.params[pn.sort] = this.sortInfo.field; - options.params[pn.dir] = this.sortInfo.direction; - } - try { - return this.execute('read', null, options); - } catch(e) { - this.handleException(e); - return false; - } - }, - updateRecord : function(store, record, action) { - if (action == Ext.data.Record.EDIT && this.autoSave === true && (!record.phantom || (record.phantom && record.isValid()))) { - this.save(); - } - }, + validateOnBlur: true, - createRecords : function(store, records, index) { - var modified = this.modified, - length = records.length, - record, i; - - for (i = 0; i < length; i++) { - record = records[i]; - - if (record.phantom && record.isValid()) { - record.markDirty(); - - if (modified.indexOf(record) == -1) { - modified.push(record); - } - } - } - if (this.autoSave === true) { - this.save(); - } - }, + hasFocus : false, + + baseCls: Ext.baseCSSPrefix + 'field', + + maskOnDisable: false, - destroyRecord : function(store, record, index) { - if (this.modified.indexOf(record) != -1) { - this.modified.remove(record); - } - if (!record.phantom) { - this.removed.push(record); + initComponent : function() { + var me = this; + + me.callParent(); + + me.subTplData = me.subTplData || {}; + me.addEvents( + 'focus', + 'blur', - record.lastIndex = index; + 'specialkey' + ); - if (this.autoSave === true) { - this.save(); - } + + me.initLabelable(); + me.initField(); + + + if (!me.name) { + me.name = me.getInputId(); } }, - execute : function(action, rs, options, batch) { - - if (!Ext.data.Api.isAction(action)) { - throw new Ext.data.Api.Error('execute', action); - } - - options = Ext.applyIf(options||{}, { - params: {} - }); - if(batch !== undefined){ - this.addToBatch(batch); - } - - - var doRequest = true; + getInputId: function() { + return this.inputId || (this.inputId = Ext.id()); + }, - if (action === 'read') { - doRequest = this.fireEvent('beforeload', this, options); - Ext.applyIf(options.params, this.baseParams); - } - else { - - - if (this.writer.listful === true && this.restful !== true) { - rs = (Ext.isArray(rs)) ? rs : [rs]; - } - - else if (Ext.isArray(rs) && rs.length == 1) { - rs = rs.shift(); - } - - if ((doRequest = this.fireEvent('beforewrite', this, action, rs, options)) !== false) { - this.writer.apply(options.params, this.baseParams, action, rs); - } - } - if (doRequest !== false) { - - if (this.writer && this.proxy.url && !this.proxy.restful && !Ext.data.Api.hasUniqueUrl(this.proxy, action)) { - options.params.xaction = action; - } - - - - - - this.proxy.request(Ext.data.Api.actions[action], rs, options.params, this.reader, this.createCallback(action, rs, batch), this, options); - } - return doRequest; + + getSubTplData: function() { + var me = this, + type = me.inputType, + inputId = me.getInputId(); + + return Ext.applyIf(me.subTplData, { + id: inputId, + name: me.name || inputId, + type: type, + size: me.size || 20, + cls: me.cls, + fieldCls: me.fieldCls, + tabIdx: me.tabIndex, + typeCls: Ext.baseCSSPrefix + 'form-' + (type === 'password' ? 'text' : type) + }); }, - save : function() { - if (!this.writer) { - throw new Ext.data.Store.Error('writer-undefined'); - } + getSubTplMarkup: function() { + return this.getTpl('fieldSubTpl').apply(this.getSubTplData()); + }, - var queue = [], - len, - trans, - batch, - data = {}, - i; - - if(this.removed.length){ - queue.push(['destroy', this.removed]); + initRenderTpl: function() { + var me = this; + if (!me.hasOwnProperty('renderTpl')) { + me.renderTpl = me.getTpl('labelableRenderTpl'); } + return me.callParent(); + }, - - var rs = [].concat(this.getModifiedRecords()); - if(rs.length){ - - var phantoms = []; - for(i = rs.length-1; i >= 0; i--){ - if(rs[i].phantom === true){ - var rec = rs.splice(i, 1).shift(); - if(rec.isValid()){ - phantoms.push(rec); - } - }else if(!rs[i].isValid()){ - rs.splice(i,1); - } - } - - if(phantoms.length){ - queue.push(['create', phantoms]); - } - - - if(rs.length){ - queue.push(['update', rs]); - } - } - len = queue.length; - if(len){ - batch = ++this.batchCounter; - for(i = 0; i < len; ++i){ - trans = queue[i]; - data[trans[0]] = trans[1]; - } - if(this.fireEvent('beforesave', this, data) !== false){ - for(i = 0; i < len; ++i){ - trans = queue[i]; - this.doTransaction(trans[0], trans[1], batch); - } - return batch; - } - } - return -1; + initRenderData: function() { + return Ext.applyIf(this.callParent(), this.getLabelableRenderData()); }, - doTransaction : function(action, rs, batch) { - function transaction(records) { - try{ - this.execute(action, records, undefined, batch); - }catch (e){ - this.handleException(e); - } - } - if(this.batch === false){ - for(var i = 0, len = rs.length; i < len; i++){ - transaction.call(this, rs[i]); - } - }else{ - transaction.call(this, rs); + setFieldStyle: function(style) { + var me = this, + inputEl = me.inputEl; + if (inputEl) { + inputEl.applyStyles(style); } + me.fieldStyle = style; }, - addToBatch : function(batch){ - var b = this.batches, - key = this.batchKey + batch, - o = b[key]; + onRender : function() { + var me = this, + fieldStyle = me.fieldStyle, + renderSelectors = me.renderSelectors; - if(!o){ - b[key] = o = { - id: batch, - count: 0, - data: {} - }; + Ext.applyIf(renderSelectors, me.getLabelableSelectors()); + + Ext.applyIf(renderSelectors, { + + inputEl: '.' + me.fieldCls + }); + + me.callParent(arguments); + + + me.setRawValue(me.rawValue); + + if (me.readOnly) { + me.setReadOnly(true); } - ++o.count; + if (me.disabled) { + me.disable(); + } + if (fieldStyle) { + me.setFieldStyle(fieldStyle); + } + + me.renderActiveError(); }, - removeFromBatch : function(batch, action, data){ - var b = this.batches, - key = this.batchKey + batch, - o = b[key], - arr; + initAria: function() { + var me = this; + me.callParent(); + + me.getActionEl().dom.setAttribute('aria-describedby', Ext.id(me.errorEl)); + }, - if(o){ - arr = o.data[action] || []; - o.data[action] = arr.concat(data); - if(o.count === 1){ - data = o.data; - delete b[key]; - this.fireEvent('save', this, batch, data); - }else{ - --o.count; - } - } + getFocusEl: function() { + return this.inputEl; }, - - - createCallback : function(action, rs, batch) { - var actions = Ext.data.Api.actions; - return (action == 'read') ? this.loadRecords : function(data, response, success) { - - this['on' + Ext.util.Format.capitalize(action) + 'Records'](success, rs, [].concat(data)); - - if (success === true) { - this.fireEvent('write', this, action, data, response, rs); - } - this.removeFromBatch(batch, action, data); - }; + isFileUpload: function() { + return this.inputType === 'file'; }, - - - - clearModified : function(rs) { - if (Ext.isArray(rs)) { - for (var n=rs.length-1;n>=0;n--) { - this.modified.splice(this.modified.indexOf(rs[n]), 1); - } - } else { - this.modified.splice(this.modified.indexOf(rs), 1); + extractFileInput: function() { + var me = this, + fileInput = me.isFileUpload() ? me.inputEl.dom : null, + clone; + if (fileInput) { + clone = fileInput.cloneNode(true); + fileInput.parentNode.replaceChild(clone, fileInput); + me.inputEl = Ext.get(clone); } + return fileInput; }, - reMap : function(record) { - if (Ext.isArray(record)) { - for (var i = 0, len = record.length; i < len; i++) { - this.reMap(record[i]); + getSubmitData: function() { + var me = this, + data = null, + val; + if (!me.disabled && me.submitValue && !me.isFileUpload()) { + val = me.getSubmitValue(); + if (val !== null) { + data = {}; + data[me.getName()] = val; } - } else { - delete this.data.map[record._phid]; - this.data.map[record.id] = record; - var index = this.data.keys.indexOf(record._phid); - this.data.keys.splice(index, 1, record.id); - delete record._phid; } + return data; }, - onCreateRecords : function(success, rs, data) { - if (success === true) { - try { - this.reader.realize(rs, data); - this.reMap(rs); - } - catch (e) { - this.handleException(e); - if (Ext.isArray(rs)) { - - this.onCreateRecords(success, rs, data); - } - } - } + getSubmitValue: function() { + return this.processRawValue(this.getRawValue()); }, - onUpdateRecords : function(success, rs, data) { - if (success === true) { - try { - this.reader.update(rs, data); - } catch (e) { - this.handleException(e); - if (Ext.isArray(rs)) { - - this.onUpdateRecords(success, rs, data); - } - } - } + getRawValue: function() { + var me = this, + v = (me.inputEl ? me.inputEl.getValue() : Ext.value(me.rawValue, '')); + me.rawValue = v; + return v; }, - onDestroyRecords : function(success, rs, data) { + setRawValue: function(value) { + var me = this; + value = Ext.value(value, ''); + me.rawValue = value; + - rs = (rs instanceof Ext.data.Record) ? [rs] : [].concat(rs); - for (var i=0,len=rs.length;i=0;i--) { - this.insert(rs[i].lastIndex, rs[i]); - } + if (me.inputEl) { + me.inputEl.dom.value = value; } + return value; }, - handleException : function(e) { - - Ext.handleError(e); + valueToRaw: function(value) { + return '' + Ext.value(value, ''); }, - reload : function(options){ - this.load(Ext.applyIf(options||{}, this.lastOptions)); + rawToValue: function(rawValue) { + return rawValue; }, + processRawValue: function(value) { + return value; + }, + - loadRecords : function(o, options, success){ - var i, len; - - if (this.isDestroyed === true) { - return; - } - if(!o || success === false){ - if(success !== false){ - this.fireEvent('load', this, [], options); - } - if(options.callback){ - options.callback.call(options.scope || this, [], options, false, o); - } - return; - } - var r = o.records, t = o.totalRecords || r.length; - if(!options || options.add !== true){ - if(this.pruneModifiedRecords){ - this.modified = []; - } - for(i = 0, len = r.length; i < len; i++){ - r[i].join(this); - } - if(this.snapshot){ - this.data = this.snapshot; - delete this.snapshot; - } - this.clearData(); - this.data.addAll(r); - this.totalLength = t; - this.applySort(); - this.fireEvent('datachanged', this); - }else{ - var toAdd = [], - rec, - cnt = 0; - for(i = 0, len = r.length; i < len; ++i){ - rec = r[i]; - if(this.indexOfId(rec.id) > -1){ - this.doUpdate(rec); - }else{ - toAdd.push(rec); - ++cnt; - } - } - this.totalLength = Math.max(t, this.data.length + cnt); - this.add(toAdd); - } - this.fireEvent('load', this, r, options); - if(options.callback){ - options.callback.call(options.scope || this, r, options, true); - } + getValue: function() { + var me = this, + val = me.rawToValue(me.processRawValue(me.getRawValue())); + me.value = val; + return val; }, - loadData : function(o, append){ - var r = this.reader.readRecords(o); - this.loadRecords(r, {add: append}, true); + setValue: function(value) { + var me = this; + me.setRawValue(me.valueToRaw(value)); + return me.mixins.field.setValue.call(me, value); }, + - getCount : function(){ - return this.data.length || 0; + onDisable: function() { + var me = this, + inputEl = me.inputEl; + me.callParent(); + if (inputEl) { + inputEl.dom.disabled = true; + } }, - getTotalCount : function(){ - return this.totalLength || 0; + onEnable: function() { + var me = this, + inputEl = me.inputEl; + me.callParent(); + if (inputEl) { + inputEl.dom.disabled = false; + } }, - getSortState : function(){ - return this.sortInfo; + setReadOnly: function(readOnly) { + var me = this, + inputEl = me.inputEl; + if (inputEl) { + inputEl.dom.readOnly = readOnly; + inputEl.dom.setAttribute('aria-readonly', readOnly); + } + me[readOnly ? 'addCls' : 'removeCls'](me.readOnlyCls); + me.readOnly = readOnly; }, - applySort : function(){ - if ((this.sortInfo || this.multiSortInfo) && !this.remoteSort) { - this.sortData(); + fireKey: function(e){ + if(e.isSpecialKey()){ + this.fireEvent('specialkey', this, Ext.create('Ext.EventObjectImpl', e)); } }, - sortData : function() { - var sortInfo = this.hasMultiSort ? this.multiSortInfo : this.sortInfo, - direction = sortInfo.direction || "ASC", - sorters = sortInfo.sorters, - sortFns = []; + initEvents : function(){ + var me = this, + inputEl = me.inputEl, + onChangeTask, + onChangeEvent; + if (inputEl) { + me.mon(inputEl, Ext.EventManager.getKeyEvent(), me.fireKey, me); + me.mon(inputEl, 'focus', me.onFocus, me); - - if (!this.hasMultiSort) { - sorters = [{direction: direction, field: sortInfo.field}]; - } + + + me.mon(inputEl, 'blur', me.onBlur, me, me.inEditor ? {buffer:10} : null); - - for (var i=0, j = sorters.length; i < j; i++) { - sortFns.push(this.createSortFunction(sorters[i].field, sorters[i].direction)); - } - - if (sortFns.length == 0) { - return; + + onChangeTask = Ext.create('Ext.util.DelayedTask', me.checkChange, me); + me.onChangeEvent = onChangeEvent = function() { + onChangeTask.delay(me.checkChangeBuffer); + }; + Ext.each(me.checkChangeEvents, function(eventName) { + if (eventName === 'propertychange') { + me.usesPropertychange = true; + } + me.mon(inputEl, eventName, onChangeEvent); + }, me); } + me.callParent(); + }, - - - var directionModifier = direction.toUpperCase() == "DESC" ? -1 : 1; + doComponentLayout: function() { + var me = this, + inputEl = me.inputEl, + usesPropertychange = me.usesPropertychange, + ename = 'propertychange', + onChangeEvent = me.onChangeEvent; - var fn = function(r1, r2) { - var result = sortFns[0].call(this, r1, r2); - - - if (sortFns.length > 1) { - for (var i=1, j = sortFns.length; i < j; i++) { - result = result || sortFns[i].call(this, r1, r2); - } - } - - return directionModifier * result; - }; - - this.data.sort(direction, fn); - if (this.snapshot && this.snapshot != this.data) { - this.snapshot.sort(direction, fn); + + if (usesPropertychange) { + me.mun(inputEl, ename, onChangeEvent); + } + me.callParent(arguments); + if (usesPropertychange) { + me.mon(inputEl, ename, onChangeEvent); } }, - createSortFunction: function(field, direction) { - direction = direction || "ASC"; - var directionModifier = direction.toUpperCase() == "DESC" ? -1 : 1; + preFocus: Ext.emptyFn, - var sortType = this.fields.get(field).sortType; + + onFocus: function() { + var me = this, + focusCls = me.focusCls, + inputEl = me.inputEl; + me.preFocus(); + if (focusCls && inputEl) { + inputEl.addCls(focusCls); + } + if (!me.hasFocus) { + me.hasFocus = true; + me.fireEvent('focus', me); + } + }, - - - return function(r1, r2) { - var v1 = sortType(r1.data[field]), - v2 = sortType(r2.data[field]); + + beforeBlur : Ext.emptyFn, - return directionModifier * (v1 > v2 ? 1 : (v1 < v2 ? -1 : 0)); - }; + + onBlur : function(){ + var me = this, + focusCls = me.focusCls, + inputEl = me.inputEl; + me.beforeBlur(); + if (focusCls && inputEl) { + inputEl.removeCls(focusCls); + } + if (me.validateOnBlur) { + me.validate(); + } + me.hasFocus = false; + me.fireEvent('blur', me); + me.postBlur(); }, - setDefaultSort : function(field, dir) { - dir = dir ? dir.toUpperCase() : 'ASC'; - this.sortInfo = {field: field, direction: dir}; - this.sortToggle[field] = dir; - }, + postBlur : Ext.emptyFn, + - sort : function(fieldName, dir) { - if (Ext.isArray(arguments[0])) { - return this.multiSort.call(this, fieldName, dir); - } else { - return this.singleSort(fieldName, dir); - } + onDirtyChange: function(isDirty) { + this[isDirty ? 'addCls' : 'removeCls'](this.dirtyCls); }, + - singleSort: function(fieldName, dir) { - var field = this.fields.get(fieldName); - if (!field) { - return false; - } + isValid : function() { + var me = this; + return me.disabled || me.validateValue(me.processRawValue(me.getRawValue())); + }, - var name = field.name, - sortInfo = this.sortInfo || null, - sortToggle = this.sortToggle ? this.sortToggle[name] : null; - if (!dir) { - if (sortInfo && sortInfo.field == name) { - dir = (this.sortToggle[name] || 'ASC').toggle('ASC', 'DESC'); + + validateValue: function(value) { + var me = this, + errors = me.getErrors(value), + isValid = Ext.isEmpty(errors); + if (!me.preventMark) { + if (isValid) { + me.clearInvalid(); } else { - dir = field.sortDir; + me.markInvalid(errors); } } - this.sortToggle[name] = dir; - this.sortInfo = {field: name, direction: dir}; - this.hasMultiSort = false; - - if (this.remoteSort) { - if (!this.load(this.lastOptions)) { - if (sortToggle) { - this.sortToggle[name] = sortToggle; - } - if (sortInfo) { - this.sortInfo = sortInfo; - } - } - } else { - this.applySort(); - this.fireEvent('datachanged', this); - } - return true; + return isValid; }, - multiSort: function(sorters, direction) { - this.hasMultiSort = true; - direction = direction || "ASC"; - + markInvalid : function(errors) { - if (this.multiSortInfo && direction == this.multiSortInfo.direction) { - direction = direction.toggle("ASC", "DESC"); + var me = this, + oldMsg = me.getActiveError(); + me.setActiveErrors(Ext.Array.from(errors)); + if (oldMsg !== me.getActiveError()) { + me.doComponentLayout(); } + }, + + clearInvalid : function() { - this.multiSortInfo = { - sorters : sorters, - direction: direction - }; - - if (this.remoteSort) { - this.singleSort(sorters[0].field, sorters[0].direction); - - } else { - this.applySort(); - this.fireEvent('datachanged', this); + var me = this, + hadError = me.hasActiveError(); + me.unsetActiveError(); + if (hadError) { + me.doComponentLayout(); } }, - each : function(fn, scope){ - this.data.each(fn, scope); + renderActiveError: function() { + var me = this, + hasError = me.hasActiveError(); + if (me.inputEl) { + + me.inputEl[hasError ? 'addCls' : 'removeCls'](me.invalidCls + '-field'); + } + me.mixins.labelable.renderActiveError.call(me); }, + + getActionEl: function() { + return this.inputEl || this.el; + } + +}); + + +Ext.define('Ext.form.field.Text', { + extend:'Ext.form.field.Base', + alias: 'widget.textfield', + requires: ['Ext.form.field.VTypes', 'Ext.layout.component.field.Text'], + alternateClassName: ['Ext.form.TextField', 'Ext.form.Text'], + + + - getModifiedRecords : function(){ - return this.modified; - }, - sum : function(property, start, end){ - var rs = this.data.items, v = 0; - start = start || 0; - end = (end || end === 0) ? end : rs.length-1; + size: 20, - for(var i = start; i <= end; i++){ - v += (rs[i].data[property] || 0); - } - return v; - }, + - createFilterFn : function(property, value, anyMatch, caseSensitive, exactMatch){ - if(Ext.isEmpty(value, false)){ - return false; - } - value = this.data.createValueMatcher(value, anyMatch, caseSensitive, exactMatch); - return function(r) { - return value.test(r.data[property]); - }; - }, + growMin : 30, + + + growMax : 800, - createMultipleFilterFn: function(filters) { - return function(record) { - var isMatch = true; + growAppend: 'W', + + - for (var i=0, j = filters.length; i < j; i++) { - var filter = filters[i], - fn = filter.fn, - scope = filter.scope; + - isMatch = isMatch && fn.call(scope, record); - } + - return isMatch; - }; - }, + + 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', + + - filter : function(property, value, anyMatch, caseSensitive, exactMatch){ - var fn; - - if (Ext.isObject(property)) { - property = [property]; - } - if (Ext.isArray(property)) { - var filters = []; + + regexText : '', + + - - for (var i=0, j = property.length; i < j; i++) { - var filter = property[i], - func = filter.fn, - scope = filter.scope || this; + + emptyCls : Ext.baseCSSPrefix + 'form-empty-field', - - if (!Ext.isFunction(func)) { - func = this.createFilterFn(filter.property, filter.value, filter.anyMatch, filter.caseSensitive, filter.exactMatch); - } + ariaRole: 'textbox', - filters.push({fn: func, scope: scope}); - } + - fn = this.createMultipleFilterFn(filters); - } else { + componentLayout: 'textfield', + + initComponent : function(){ + this.callParent(); + this.addEvents( - fn = this.createFilterFn(property, value, anyMatch, caseSensitive, exactMatch); - } + 'autosize', - return fn ? this.filterBy(fn) : this.clearFilter(); + + 'keydown', + + 'keyup', + + 'keypress' + ); }, - filterBy : function(fn, scope){ - this.snapshot = this.snapshot || this.data; - this.data = this.queryBy(fn, scope || this); - this.fireEvent('datachanged', this); - }, + initEvents : function(){ + var me = this, + el = me.inputEl; + + me.callParent(); + if(me.selectOnFocus || me.emptyText){ + me.mon(el, 'mousedown', me.onMouseDown, me); + } + if(me.maskRe || (me.vtype && me.disableKeyFilter !== true && (me.maskRe = Ext.form.field.VTypes[me.vtype+'Mask']))){ + me.mon(el, 'keypress', me.filterKeys, me); + } - - clearFilter : function(suppressEvent){ - if(this.isFiltered()){ - this.data = this.snapshot; - delete this.snapshot; - if(suppressEvent !== true){ - this.fireEvent('datachanged', this); - } + if (me.enableKeyEvents) { + me.mon(el, { + scope: me, + keyup: me.onKeyUp, + keydown: me.onKeyDown, + keypress: me.onKeyPress + }); } }, - isFiltered : function(){ - return !!this.snapshot && this.snapshot != this.data; + isEqual: function(value1, value2) { + return String(Ext.value(value1, '')) === String(Ext.value(value2, '')); }, - query : function(property, value, anyMatch, caseSensitive){ - var fn = this.createFilterFn(property, value, anyMatch, caseSensitive); - return fn ? this.queryBy(fn) : this.data.clone(); + onChange: function() { + this.callParent(); + this.autoSize(); }, - - queryBy : function(fn, scope){ - var data = this.snapshot || this.data; - return data.filterBy(fn, scope||this); + afterRender: function(){ + var me = this; + if (me.enforceMaxLength) { + me.inputEl.dom.maxLength = me.maxLength; + } + me.applyEmptyText(); + me.autoSize(); + me.callParent(); }, - - find : function(property, value, start, anyMatch, caseSensitive){ - var fn = this.createFilterFn(property, value, anyMatch, caseSensitive); - return fn ? this.data.findIndexBy(fn, null, start) : -1; + onMouseDown: function(e){ + var me = this; + if(!me.hasFocus){ + me.mon(me.inputEl, 'mouseup', Ext.emptyFn, me, { single: true, preventDefault: true }); + } }, - findExact: function(property, value, start){ - return this.data.findIndexBy(function(rec){ - return rec.get(property) === value; - }, this, start); + processRawValue: function(value) { + var me = this, + stripRe = me.stripCharsRe, + newValue; + + if (stripRe) { + newValue = value.replace(stripRe, ''); + if (newValue !== value) { + me.setRawValue(newValue); + value = newValue; + } + } + return value; }, - findBy : function(fn, scope, start){ - return this.data.findIndexBy(fn, scope, start); + onDisable: function(){ + this.callParent(); + if (Ext.isIE) { + this.inputEl.dom.unselectable = 'on'; + } }, - collect : function(dataIndex, allowNull, bypassFilter){ - var d = (bypassFilter === true && this.snapshot) ? - this.snapshot.items : this.data.items; - var v, sv, r = [], l = {}; - for(var i = 0, len = d.length; i < len; i++){ - v = d[i].data[dataIndex]; - sv = String(v); - if((allowNull || !Ext.isEmpty(v)) && !l[sv]){ - l[sv] = true; - r[r.length] = v; - } + onEnable: function(){ + this.callParent(); + if (Ext.isIE) { + this.inputEl.dom.unselectable = ''; } - return r; + }, + + onKeyDown: function(e) { + this.fireEvent('keydown', this, e); + }, + + onKeyUp: function(e) { + this.fireEvent('keyup', this, e); + }, + + onKeyPress: function(e) { + this.fireEvent('keypress', this, e); }, - afterEdit : function(record){ - if(this.modified.indexOf(record) == -1){ - this.modified.push(record); + reset : function(){ + this.callParent(); + this.applyEmptyText(); + }, + + applyEmptyText : function(){ + var me = this, + emptyText = me.emptyText, + isEmpty; + + 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) { + me.inputEl.addCls(me.emptyCls); + } + + me.autoSize(); } - this.fireEvent('update', this, record, Ext.data.Record.EDIT); }, - afterReject : function(record){ - this.modified.remove(record); - this.fireEvent('update', this, record, Ext.data.Record.REJECT); + preFocus : function(){ + var me = this, + inputEl = me.inputEl, + emptyText = me.emptyText, + isEmpty; + + if (emptyText && !Ext.supports.Placeholder && inputEl.dom.value === emptyText) { + me.setRawValue(''); + isEmpty = true; + inputEl.removeCls(me.emptyCls); + } else if (Ext.supports.Placeholder) { + me.inputEl.removeCls(me.emptyCls); + } + if (me.selectOnFocus || isEmpty) { + inputEl.dom.select(); + } }, - - afterCommit : function(record){ - this.modified.remove(record); - this.fireEvent('update', this, record, Ext.data.Record.COMMIT); + onFocus: function() { + var me = this; + me.callParent(arguments); + if (me.emptyText) { + me.autoSize(); + } }, - commitChanges : function(){ - var modified = this.modified.slice(0), - length = modified.length, - i; - - for (i = 0; i < length; i++){ - modified[i].commit(); - } - - this.modified = []; - this.removed = []; + postBlur : function(){ + this.applyEmptyText(); }, - rejectChanges : function() { - var modified = this.modified.slice(0), - removed = this.removed.slice(0).reverse(), - mLength = modified.length, - rLength = removed.length, - i; - - for (i = 0; i < mLength; i++) { - modified[i].reject(); + filterKeys : function(e){ + if(e.ctrlKey){ + return; } - - for (i = 0; i < rLength; i++) { - this.insert(removed[i].lastIndex || 0, removed[i]); - removed[i].reject(); + var key = e.getKey(), + charCode = String.fromCharCode(e.getCharCode()); + + if(Ext.isGecko && (e.isNavKeyPress() || key === e.BACKSPACE || (key === e.DELETE && e.button === -1))){ + return; } - this.modified = []; - this.removed = []; - }, - - - onMetaChange : function(meta){ - this.recordType = this.reader.recordType; - this.fields = this.recordType.prototype.fields; - delete this.snapshot; - if(this.reader.meta.sortInfo){ - this.sortInfo = this.reader.meta.sortInfo; - }else if(this.sortInfo && !this.fields.get(this.sortInfo.field)){ - delete this.sortInfo; + if(!Ext.isGecko && e.isSpecialKey() && !charCode){ + return; } - if(this.writer){ - this.writer.meta = this.reader.meta; + if(!this.maskRe.test(charCode)){ + e.stopEvent(); } - this.modified = []; - this.fireEvent('metachange', this, this.reader.meta); }, - findInsertIndex : function(record){ - this.suspendEvents(); - var data = this.data.clone(); - this.data.add(record); - this.applySort(); - var index = this.data.indexOf(record); - this.data = data; - this.resumeEvents(); - return index; + getRawValue: function() { + var me = this, + v = me.callParent(); + if (v === me.emptyText) { + v = ''; + } + return v; }, - setBaseParam : function (name, value){ - this.baseParams = this.baseParams || {}; - this.baseParams[name] = value; - } -}); - -Ext.reg('store', Ext.data.Store); - + setValue: function(value) { + var me = this, + inputEl = me.inputEl; + + if (inputEl && me.emptyText && !Ext.isEmpty(value)) { + inputEl.removeCls(me.emptyCls); + } + + me.callParent(arguments); -Ext.data.Store.Error = Ext.extend(Ext.Error, { - name: 'Ext.data.Store' -}); -Ext.apply(Ext.data.Store.Error.prototype, { - lang: { - 'writer-undefined' : 'Attempted to execute a write-action without a DataWriter installed.' - } -}); + me.applyEmptyText(); + return me; + }, -Ext.data.Field = Ext.extend(Object, { - constructor : function(config){ - if(Ext.isString(config)){ - config = {name: config}; + getErrors: function(value) { + var me = this, + errors = me.callParent(arguments), + validator = me.validator, + emptyText = me.emptyText, + allowBlank = me.allowBlank, + vtype = me.vtype, + vtypes = Ext.form.field.VTypes, + regex = me.regex, + format = Ext.String.format, + msg; + + value = value || me.processRawValue(me.getRawValue()); + + if (Ext.isFunction(validator)) { + msg = validator.call(me, value); + if (msg !== true) { + errors.push(msg); + } } - Ext.apply(this, config); - - var types = Ext.data.Types, - st = this.sortType, - t; - if(this.type){ - if(Ext.isString(this.type)){ - this.type = Ext.data.Types[this.type.toUpperCase()] || types.AUTO; + if (value.length < 1 || value === emptyText) { + if (!allowBlank) { + errors.push(me.blankText); } - }else{ - this.type = types.AUTO; + + return errors; } - - if(Ext.isString(st)){ - this.sortType = Ext.data.SortTypes[st]; - }else if(Ext.isEmpty(st)){ - this.sortType = this.type.sortType; + if (value.length < me.minLength) { + errors.push(format(me.minLengthText, me.minLength)); } - if(!this.convert){ - this.convert = this.type.convert; + if (value.length > me.maxLength) { + errors.push(format(me.maxLengthText, me.maxLength)); } - }, - - - - - - dateFormat: null, - - - useNull: false, - - - defaultValue: "", - - mapping: null, - - sortType : null, - - sortDir : "ASC", - - allowBlank : true -}); - -Ext.data.DataReader = function(meta, recordType){ - - this.meta = meta; - - this.recordType = Ext.isArray(recordType) ? - Ext.data.Record.create(recordType) : recordType; - - - if (this.recordType){ - this.buildExtractors(); - } -}; -Ext.data.DataReader.prototype = { - - - getTotal: Ext.emptyFn, - - getRoot: Ext.emptyFn, - - getMessage: Ext.emptyFn, - - getSuccess: Ext.emptyFn, - - getId: Ext.emptyFn, - - buildExtractors : Ext.emptyFn, - - extractValues : Ext.emptyFn, - - - realize: function(rs, data){ - if (Ext.isArray(rs)) { - for (var i = rs.length - 1; i >= 0; i--) { - - if (Ext.isArray(data)) { - this.realize(rs.splice(i,1).shift(), data.splice(i,1).shift()); - } - else { - - - this.realize(rs.splice(i,1).shift(), data); - } + if (vtype) { + if(!vtypes[vtype](value, me)){ + errors.push(me.vtypeText || vtypes[vtype +'Text']); } } - else { - - if (Ext.isArray(data) && data.length == 1) { - data = data.shift(); - } - if (!this.isData(data)) { - - - throw new Ext.data.DataReader.Error('realize', rs); - } - rs.phantom = false; - rs._phid = rs.id; - rs.id = this.getId(data); - rs.data = data; - rs.commit(); + if (regex && !regex.test(value)) { + errors.push(me.regexText || me.invalidText); } + + return errors; }, - update : function(rs, data) { - if (Ext.isArray(rs)) { - for (var i=rs.length-1; i >= 0; i--) { - if (Ext.isArray(data)) { - this.update(rs.splice(i,1).shift(), data.splice(i,1).shift()); - } - else { - - - this.update(rs.splice(i,1).shift(), data); - } + selectText : function(start, end){ + var me = this, + v = me.getRawValue(), + doFocus = true, + el = me.inputEl.dom, + undef, + range; + + if (v.length > 0) { + start = start === undef ? 0 : start; + end = end === undef ? v.length : end; + if (el.setSelectionRange) { + el.setSelectionRange(start, end); + } + else if(el.createTextRange) { + range = el.createTextRange(); + range.moveStart('character', start); + range.moveEnd('character', end - v.length); + range.select(); } + doFocus = Ext.isGecko || Ext.isOpera; } - else { - - if (Ext.isArray(data) && data.length == 1) { - data = data.shift(); - } - if (this.isData(data)) { - rs.data = Ext.apply(rs.data, data); - } - rs.commit(); + if (doFocus) { + me.focus(); } }, - extractData : function(root, returnRecords) { - - var rawName = (this instanceof Ext.data.JsonReader) ? 'json' : 'node'; - - var rs = []; - - - - if (this.isData(root) && !(this instanceof Ext.data.XmlReader)) { - root = [root]; - } - var f = this.recordType.prototype.fields, - fi = f.items, - fl = f.length, - rs = []; - if (returnRecords === true) { - var Record = this.recordType; - for (var i = 0; i < root.length; i++) { - var n = root[i]; - var record = new Record(this.extractValues(n, fi, fl), this.getId(n)); - record[rawName] = n; - rs.push(record); - } - } - else { - for (var i = 0; i < root.length; i++) { - var data = this.extractValues(root[i], fi, fl); - data[this.meta.idProperty] = this.getId(root[i]); - rs.push(data); + autoSize: function() { + var me = this, + width; + if (me.grow && me.rendered) { + me.doComponentLayout(); + width = me.inputEl.getWidth(); + if (width !== me.lastInputWidth) { + me.fireEvent('autosize', width); + me.lastInputWidth = width; } } - return rs; }, - - isData : function(data) { - return (data && Ext.isObject(data) && !Ext.isEmpty(this.getId(data))) ? true : false; + initAria: function() { + this.callParent(); + this.getActionEl().dom.setAttribute('aria-required', this.allowBlank === false); }, - onMetaChange : function(meta){ - delete this.ef; - this.meta = meta; - this.recordType = Ext.data.Record.create(meta.fields); - this.buildExtractors(); + getBodyNaturalWidth: function() { + return Math.round(this.size * 6.5) + 20; } -}; - -Ext.data.DataReader.Error = Ext.extend(Ext.Error, { - constructor : function(message, arg) { - this.arg = arg; - Ext.Error.call(this, message); - }, - name: 'Ext.data.DataReader' -}); -Ext.apply(Ext.data.DataReader.Error.prototype, { - lang : { - 'update': "#update received invalid data from server. Please see docs for DataReader#update and review your DataReader configuration.", - 'realize': "#realize was called with invalid remote-data. Please see the docs for DataReader#realize and review your DataReader configuration.", - 'invalid-response': "#readResponse received an invalid response from the server." - } }); -Ext.data.DataWriter = function(config){ - Ext.apply(this, config); -}; -Ext.data.DataWriter.prototype = { - - - writeAllFields : false, - - listful : false, - - apply : function(params, baseParams, action, rs) { - var data = [], - renderer = action + 'Record'; - - if (Ext.isArray(rs)) { - Ext.each(rs, function(rec){ - data.push(this[renderer](rec)); - }, this); +Ext.define('Ext.form.field.TextArea', { + extend:'Ext.form.field.Text', + alias: ['widget.textareafield', 'widget.textarea'], + alternateClassName: 'Ext.form.TextArea', + requires: ['Ext.XTemplate', 'Ext.layout.component.field.TextArea'], + + fieldSubTpl: [ + '', + { + compiled: true, + disableFormats: true } - else if (rs instanceof Ext.data.Record) { - data = this[renderer](rs); - } - this.render(params, baseParams, data); - }, + ], - render : Ext.emptyFn, + growMin: 60, - updateRecord : Ext.emptyFn, + growMax: 1000, - createRecord : Ext.emptyFn, + growAppend: '\n-', - destroyRecord : Ext.emptyFn, + cols: 20, - toHash : function(rec, config) { - var map = rec.fields.map, - data = {}, - raw = (this.writeAllFields === false && rec.phantom === false) ? rec.getChanges() : rec.data, - m; - Ext.iterate(raw, function(prop, value){ - if((m = map[prop])){ - data[m.mapping ? m.mapping : m.name] = value; - } - }); - - - - if (rec.phantom) { - if (rec.fields.containsKey(this.meta.idProperty) && Ext.isEmpty(rec.data[this.meta.idProperty])) { - delete data[this.meta.idProperty]; - } - } else { - data[this.meta.idProperty] = rec.id; - } - return data; - }, + rows: 4, - toArray : function(data) { - var fields = []; - Ext.iterate(data, function(k, v) {fields.push({name: k, value: v});},this); - return fields; - } -}; -Ext.data.DataProxy = function(conn){ - - - conn = conn || {}; + enterIsSpecial: false, - - - - this.api = conn.api; - this.url = conn.url; - this.restful = conn.restful; - this.listeners = conn.listeners; + preventScrollbars: false, - this.prettyUrls = conn.prettyUrls; + componentLayout: 'textareafield', + onRender: function(ct, position) { + var me = this; + Ext.applyIf(me.subTplData, { + cols: me.cols, + rows: me.rows + }); - this.addEvents( - - 'exception', - - 'beforeload', - - 'load', - - 'loadexception', - - 'beforewrite', - - 'write' - ); - Ext.data.DataProxy.superclass.constructor.call(this); + me.callParent(arguments); + }, - try { - Ext.data.Api.prepare(this); - } catch (e) { - if (e instanceof Ext.data.Api.Error) { - e.toConsole(); - } - } - - Ext.data.DataProxy.relayEvents(this, ['beforewrite', 'write', 'exception']); -}; + afterRender: function(){ + var me = this; -Ext.extend(Ext.data.DataProxy, Ext.util.Observable, { - - restful: false, + me.callParent(arguments); - - setApi : function() { - if (arguments.length == 1) { - var valid = Ext.data.Api.isValid(arguments[0]); - if (valid === true) { - this.api = arguments[0]; - } - else { - throw new Ext.data.Api.Error('invalid', valid); - } - } - else if (arguments.length == 2) { - if (!Ext.data.Api.isAction(arguments[0])) { - throw new Ext.data.Api.Error('invalid', arguments[0]); + if (me.grow) { + if (me.preventScrollbars) { + me.inputEl.setStyle('overflow', 'hidden'); } - this.api[arguments[0]] = arguments[1]; + me.inputEl.setHeight(me.growMin); } - Ext.data.Api.prepare(this); }, - isApiAction : function(action) { - return (this.api[action]) ? true : false; - }, - - - request : function(action, rs, params, reader, callback, scope, options) { - if (!this.api[action] && !this.load) { - throw new Ext.data.DataProxy.Error('action-undefined', action); - } - params = params || {}; - if ((action === Ext.data.Api.actions.read) ? this.fireEvent("beforeload", this, params) : this.fireEvent("beforewrite", this, action, rs, params) !== false) { - this.doRequest.apply(this, arguments); - } - else { - callback.call(scope || this, null, options, false); + fireKey: function(e) { + if (e.isSpecialKey() && (this.enterIsSpecial || (e.getKey() !== e.ENTER || e.hasModifier()))) { + this.fireEvent('specialkey', this, e); } }, - - load : null, + autoSize: function() { + var me = this, + height; - - doRequest : function(action, rs, params, reader, callback, scope, options) { - - - - this.load(params, reader, callback, scope, options); + if (me.grow && me.rendered) { + me.doComponentLayout(); + height = me.inputEl.getHeight(); + if (height !== me.lastInputHeight) { + me.fireEvent('autosize', height); + me.lastInputHeight = height; + } + } }, - onRead : Ext.emptyFn, - - onWrite : Ext.emptyFn, - - buildUrl : function(action, record) { - record = record || null; - - - - - var url = (this.conn && this.conn.url) ? this.conn.url : (this.api[action]) ? this.api[action].url : this.url; - if (!url) { - throw new Ext.data.Api.Error('invalid-url', action); - } - - - - - - - - var provides = null; - var m = url.match(/(.*)(\.json|\.xml|\.html)$/); - if (m) { - provides = m[2]; - url = m[1]; - } - - if ((this.restful === true || this.prettyUrls === true) && record instanceof Ext.data.Record && !record.phantom) { - url += '/' + record.id; - } - return (provides === null) ? url : url + provides; + initAria: function() { + this.callParent(arguments); + this.getActionEl().dom.setAttribute('aria-multiline', true); }, - destroy: function(){ - this.purgeListeners(); + getBodyNaturalWidth: function() { + return Math.round(this.cols * 6.5) + 20; } -}); - - - -Ext.apply(Ext.data.DataProxy, Ext.util.Observable.prototype); -Ext.util.Observable.call(Ext.data.DataProxy); - -Ext.data.DataProxy.Error = Ext.extend(Ext.Error, { - constructor : function(message, arg) { - this.arg = arg; - Ext.Error.call(this, message); - }, - name: 'Ext.data.DataProxy' -}); -Ext.apply(Ext.data.DataProxy.Error.prototype, { - lang: { - 'action-undefined': "DataProxy attempted to execute an API-action but found an undefined url / function. Please review your Proxy url/api-configuration.", - 'api-invalid': 'Recieved an invalid API-configuration. Please ensure your proxy API-configuration contains only the actions from Ext.data.Api.actions.' - } }); -Ext.data.Request = function(params) { - Ext.apply(this, params); -}; -Ext.data.Request.prototype = { - - action : undefined, - - rs : undefined, - - params: undefined, - - callback : Ext.emptyFn, - - scope : undefined, +Ext.define('Ext.window.MessageBox', { + extend: 'Ext.window.Window', + + requires: [ + 'Ext.toolbar.Toolbar', + 'Ext.form.field.Text', + 'Ext.form.field.TextArea', + 'Ext.button.Button', + 'Ext.layout.container.Anchor', + 'Ext.layout.container.HBox', + 'Ext.ProgressBar' + ], - reader : undefined -}; + alternateClassName: 'Ext.MessageBox', + + alias: 'widget.messagebox', -Ext.data.Response = function(params) { - Ext.apply(this, params); -}; -Ext.data.Response.prototype = { - action: undefined, + OK : 1, - success : undefined, + YES : 2, - message : undefined, + NO : 4, - data: undefined, + CANCEL : 8, - raw: undefined, + OKCANCEL : 9, - records: undefined -}; - -Ext.data.ScriptTagProxy = function(config){ - Ext.apply(this, config); - - Ext.data.ScriptTagProxy.superclass.constructor.call(this, config); - - this.head = document.getElementsByTagName("head")[0]; - + YESNO : 6, -}; - -Ext.data.ScriptTagProxy.TRANS_ID = 1000; - -Ext.extend(Ext.data.ScriptTagProxy, Ext.data.DataProxy, { + YESNOCANCEL : 14, + INFO : 'ext-mb-info', - timeout : 30000, + WARNING : 'ext-mb-warning', - callbackParam : "callback", + QUESTION : 'ext-mb-question', - nocache : true, + ERROR : 'ext-mb-error', - doRequest : function(action, rs, params, reader, callback, scope, arg) { - var p = Ext.urlEncode(Ext.apply(params, this.extraParams)); - - var url = this.buildUrl(action, rs); - if (!url) { - throw new Ext.data.Api.Error('invalid-url', url); - } - url = Ext.urlAppend(url, p); - - if(this.nocache){ - url = Ext.urlAppend(url, '_dc=' + (new Date().getTime())); - } - var transId = ++Ext.data.ScriptTagProxy.TRANS_ID; - var trans = { - id : transId, - action: action, - cb : "stcCallback"+transId, - scriptId : "stcScript"+transId, - params : params, - arg : arg, - url : url, - callback : callback, - scope : scope, - reader : reader - }; - window[trans.cb] = this.createCallback(action, rs, trans); - url += String.format("&{0}={1}", this.callbackParam, trans.cb); - if(this.autoAbort !== false){ - this.abort(); - } + hideMode: 'offsets', + closeAction: 'hide', + resizable: false, + title: ' ', - trans.timeoutId = this.handleFailure.defer(this.timeout, this, [trans]); + width: 600, + height: 500, + minWidth: 250, + maxWidth: 600, + minHeight: 110, + maxHeight: 500, + constrain: true, - var script = document.createElement("script"); - script.setAttribute("src", url); - script.setAttribute("type", "text/javascript"); - script.setAttribute("id", trans.scriptId); - this.head.appendChild(script); + cls: Ext.baseCSSPrefix + 'message-box', - this.trans = trans; + layout: { + type: 'anchor' }, - createCallback : function(action, rs, trans) { - var self = this; - return function(res) { - self.trans = false; - self.destroyTrans(trans, true); - if (action === Ext.data.Api.actions.read) { - self.onRead.call(self, action, trans, res); - } else { - self.onWrite.call(self, action, trans, res, rs); - } - }; - }, + defaultTextHeight : 75, - onRead : function(action, trans, res) { - var result; - try { - result = trans.reader.readRecords(res); - }catch(e){ - - this.fireEvent("loadexception", this, trans, res, e); - - this.fireEvent('exception', this, 'response', action, trans, res, e); - trans.callback.call(trans.scope||window, null, trans.arg, false); - return; - } - if (result.success === false) { - - this.fireEvent('loadexception', this, trans, res); - - this.fireEvent('exception', this, 'remote', action, trans, res, null); - } else { - this.fireEvent("load", this, res, trans.arg); - } - trans.callback.call(trans.scope||window, result, trans.arg, result.success); - }, + minProgressWidth : 250, - onWrite : function(action, trans, response, rs) { - var reader = trans.reader; - try { - - var res = reader.readResponse(action, response); - } catch (e) { - this.fireEvent('exception', this, 'response', action, trans, res, e); - trans.callback.call(trans.scope||window, null, res, false); - return; - } - if(!res.success === true){ - this.fireEvent('exception', this, 'remote', action, trans, res, rs); - trans.callback.call(trans.scope||window, null, res, false); - return; - } - this.fireEvent("write", this, action, res.data, res, rs, trans.arg ); - trans.callback.call(trans.scope||window, res.data, res, true); - }, - + minPromptWidth: 250, - isLoading : function(){ - return this.trans ? true : false; + buttonText: { + ok: 'OK', + yes: 'Yes', + no: 'No', + cancel: 'Cancel' }, - - abort : function(){ - if(this.isLoading()){ - this.destroyTrans(this.trans); - } - }, + buttonIds: [ + 'ok', 'yes', 'no', 'cancel' + ], - - destroyTrans : function(trans, isLoaded){ - this.head.removeChild(document.getElementById(trans.scriptId)); - clearTimeout(trans.timeoutId); - if(isLoaded){ - window[trans.cb] = undefined; - try{ - delete window[trans.cb]; - }catch(e){} - }else{ - - window[trans.cb] = function(){ - window[trans.cb] = undefined; - try{ - delete window[trans.cb]; - }catch(e){} - }; - } + titleText: { + confirm: 'Confirm', + prompt: 'Prompt', + wait: 'Loading...', + alert: 'Attention' }, - - handleFailure : function(trans){ - this.trans = false; - this.destroyTrans(trans, false); - if (trans.action === Ext.data.Api.actions.read) { - - this.fireEvent("loadexception", this, null, trans.arg); - } + iconHeight: 35, - this.fireEvent('exception', this, 'response', trans.action, { - response: null, - options: trans.arg + makeButton: function(btnIdx) { + var btnId = this.buttonIds[btnIdx]; + return Ext.create('Ext.button.Button', { + handler: this.btnCallback, + itemId: btnId, + scope: this, + text: this.buttonText[btnId], + minWidth: 75 }); - trans.callback.call(trans.scope||window, null, trans.arg, false); }, - - destroy: function(){ - this.abort(); - Ext.data.ScriptTagProxy.superclass.destroy.call(this); - } -}); -Ext.data.HttpProxy = function(conn){ - Ext.data.HttpProxy.superclass.constructor.call(this, conn); - - - this.conn = conn; - - - - - - this.conn.url = null; - - this.useAjax = !conn || !conn.events; + btnCallback: function(btn) { + var me = this, + value, + field; - - var actions = Ext.data.Api.actions; - this.activeRequest = {}; - for (var verb in actions) { - this.activeRequest[actions[verb]] = undefined; - } -}; + if (me.cfg.prompt || me.cfg.multiline) { + if (me.cfg.multiline) { + field = me.textArea; + } else { + field = me.textField; + } + value = field.getValue(); + field.reset(); + } -Ext.extend(Ext.data.HttpProxy, Ext.data.DataProxy, { - - getConnection : function() { - return this.useAjax ? Ext.Ajax : this.conn; + + btn.blur(); + me.hide(); + me.userCallback(btn.itemId, value, me.cfg); }, - - setUrl : function(url, makePermanent) { - this.conn.url = url; - if (makePermanent === true) { - this.url = url; - this.api = null; - Ext.data.Api.prepare(this); - } + hide: function() { + var me = this; + me.dd.endDrag(); + me.progressBar.reset(); + me.removeCls(me.cfg.cls); + me.callParent(); }, - - doRequest : function(action, rs, params, reader, cb, scope, arg) { - var o = { - method: (this.api[action]) ? this.api[action]['method'] : undefined, - request: { - callback : cb, - scope : scope, - arg : arg - }, - reader: reader, - callback : this.createCallback(action, rs), - scope: this - }; + initComponent: function() { + var me = this, + i, button; - - - if (params.jsonData) { - o.jsonData = params.jsonData; - } else if (params.xmlData) { - o.xmlData = params.xmlData; - } else { - o.params = params || {}; - } - - - - this.conn.url = this.buildUrl(action, rs); + me.title = ' '; - if(this.useAjax){ + me.topContainer = Ext.create('Ext.container.Container', { + anchor: '100%', + style: { + padding: '10px', + overflow: 'hidden' + }, + items: [ + me.iconComponent = Ext.create('Ext.Component', { + cls: 'ext-mb-icon', + width: 50, + height: me.iconHeight, + style: { + 'float': 'left' + } + }), + me.promptContainer = Ext.create('Ext.container.Container', { + layout: { + type: 'anchor' + }, + items: [ + me.msg = Ext.create('Ext.Component', { + autoEl: { tag: 'span' }, + cls: 'ext-mb-text' + }), + me.textField = Ext.create('Ext.form.field.Text', { + anchor: '100%', + enableKeyEvents: true, + listeners: { + keydown: me.onPromptKey, + scope: me + } + }), + me.textArea = Ext.create('Ext.form.field.TextArea', { + anchor: '100%', + height: 75 + }) + ] + }) + ] + }); + me.progressBar = Ext.create('Ext.ProgressBar', { + anchor: '-10', + style: 'margin-left:10px' + }); - Ext.applyIf(o, this.conn); + me.items = [me.topContainer, me.progressBar]; - - if (this.activeRequest[action]) { - - - - - - } - this.activeRequest[action] = Ext.Ajax.request(o); - }else{ - this.conn.request(o); - } - this.conn.url = null; + me.msgButtons = []; + for (i = 0; i < 4; i++) { + button = me.makeButton(i); + me.msgButtons[button.itemId] = button; + me.msgButtons.push(button); + } + me.bottomTb = Ext.create('Ext.toolbar.Toolbar', { + ui: 'footer', + dock: 'bottom', + layout: { + pack: 'center' + }, + items: [ + me.msgButtons[0], + me.msgButtons[1], + me.msgButtons[2], + me.msgButtons[3] + ] + }); + me.dockedItems = [me.bottomTb]; + + me.callParent(); }, - - createCallback : function(action, rs) { - return function(o, success, response) { - this.activeRequest[action] = undefined; - if (!success) { - if (action === Ext.data.Api.actions.read) { - - - this.fireEvent('loadexception', this, o, response); - } - this.fireEvent('exception', this, 'response', action, o, response); - o.request.callback.call(o.request.scope, null, o.request.arg, false); - return; + onPromptKey: function(textField, e) { + var me = this, + blur; + + if (e.keyCode === Ext.EventObject.RETURN || e.keyCode === 10) { + if (me.msgButtons.ok.isVisible()) { + blur = true; + me.msgButtons.ok.handler.call(me, me.msgButtons.ok); + } else if (me.msgButtons.yes.isVisible()) { + me.msgButtons.yes.handler.call(me, me.msgButtons.yes); + blur = true; } - if (action === Ext.data.Api.actions.read) { - this.onRead(action, o, response); - } else { - this.onWrite(action, o, response, rs); + + if (blur) { + me.textField.blur(); } - }; + } }, - - onRead : function(action, o, response) { - var result; - try { - result = o.reader.read(response); - }catch(e){ - - - this.fireEvent('loadexception', this, o, response, e); + reconfigure: function(cfg) { + var me = this, + buttons = cfg.buttons || 0, + hideToolbar = true, + initialWidth = me.maxWidth, + i; - this.fireEvent('exception', this, 'response', action, o, response, e); - o.request.callback.call(o.request.scope, null, o.request.arg, false); - return; + cfg = cfg || {}; + me.cfg = cfg; + if (cfg.width) { + initialWidth = cfg.width; } - if (result.success === false) { - - - this.fireEvent('loadexception', this, o, response); - - var res = o.reader.readResponse(action, response); - this.fireEvent('exception', this, 'remote', action, o, res, null); - } - else { - this.fireEvent('load', this, o, o.request.arg); - } - - - o.request.callback.call(o.request.scope, result, o.request.arg, result.success); - }, - - onWrite : function(action, o, response, rs) { - var reader = o.reader; - var res; - try { - res = reader.readResponse(action, response); - } catch (e) { - this.fireEvent('exception', this, 'response', action, o, response, e); - o.request.callback.call(o.request.scope, null, o.request.arg, false); - return; - } - if (res.success === true) { - this.fireEvent('write', this, action, res.data, res, rs, o.request.arg); - } else { - this.fireEvent('exception', this, 'remote', action, o, res, rs); - } + delete me.defaultFocus; + me.animateTarget = cfg.animateTarget || undefined; + - o.request.callback.call(o.request.scope, res.data, res, res.success); - }, + me.modal = cfg.modal !== false; - - destroy: function(){ - if(!this.useAjax){ - this.conn.abort(); - }else if(this.activeRequest){ - var actions = Ext.data.Api.actions; - for (var verb in actions) { - if(this.activeRequest[actions[verb]]){ - Ext.Ajax.abort(this.activeRequest[actions[verb]]); - } - } + + if (cfg.title) { + me.setTitle(cfg.title||' '); } - Ext.data.HttpProxy.superclass.destroy.call(this); - } -}); -Ext.data.MemoryProxy = function(data){ - - var api = {}; - api[Ext.data.Api.actions.read] = true; - Ext.data.MemoryProxy.superclass.constructor.call(this, { - api: api - }); - this.data = data; -}; -Ext.extend(Ext.data.MemoryProxy, Ext.data.DataProxy, { - + if (!me.rendered) { + me.width = initialWidth; + me.render(Ext.getBody()); + } else { + me.setSize(initialWidth, me.maxHeight); + } + me.setPosition(-10000, -10000); - - doRequest : function(action, rs, params, reader, callback, scope, arg) { - params = params || {}; - var result; - try { - result = reader.readRecords(this.data); - }catch(e){ - - this.fireEvent("loadexception", this, null, arg, e); - - this.fireEvent('exception', this, 'response', action, arg, null, e); - callback.call(scope, null, arg, false); - return; + me.closable = cfg.closable && !cfg.wait; + if (cfg.closable === false) { + me.tools.close.hide(); + } else { + me.tools.close.show(); } - callback.call(scope, result, arg, true); - } -}); -Ext.data.Types = new function(){ - var st = Ext.data.SortTypes; - Ext.apply(this, { - - stripRe: /[\$,%]/g, - - - AUTO: { - convert: function(v){ return v; }, - sortType: st.none, - type: 'auto' - }, - STRING: { - convert: function(v){ return (v === undefined || v === null) ? '' : String(v); }, - sortType: st.asUCString, - type: 'string' - }, + if (!cfg.title && !me.closable) { + me.header.hide(); + } else { + me.header.show(); + } - 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' - }, - + me.liveDrag = !cfg.proxyDrag; + - BOOL: { - convert: function(v){ return v === true || v === 'true' || v == 1; }, - sortType: st.none, - type: 'bool' - }, + me.userCallback = Ext.Function.bind(cfg.callback ||cfg.fn || Ext.emptyFn, cfg.scope || Ext.global); + + me.setIcon(cfg.icon); + - 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 Date.parseDate(v, df); - } - var parsed = Date.parse(v); - return parsed ? new Date(parsed) : null; - }, - sortType: st.asDate, - type: 'date' + if (cfg.msg) { + me.msg.update(cfg.msg); + me.msg.show(); + } else { + me.msg.hide(); } - }); - - Ext.apply(this, { + - BOOLEAN: this.BOOL, + if (cfg.prompt || cfg.multiline) { + me.multiline = cfg.multiline; + if (cfg.multiline) { + me.textArea.setValue(cfg.value); + me.textArea.setHeight(cfg.defaultTextHeight || me.defaultTextHeight); + me.textArea.show(); + me.textField.hide(); + me.defaultFocus = me.textArea; + } else { + me.textField.setValue(cfg.value); + me.textArea.hide(); + me.textField.show(); + me.defaultFocus = me.textField; + } + } else { + me.textArea.hide(); + me.textField.hide(); + } + - INTEGER: this.INT, + if (cfg.progress || cfg.wait) { + me.progressBar.show(); + me.updateProgress(0, cfg.progressText); + if(cfg.wait === true){ + me.progressBar.wait(cfg.waitConfig); + } + } else { + me.progressBar.hide(); + } + - NUMBER: this.FLOAT - }); -}; -Ext.data.JsonWriter = Ext.extend(Ext.data.DataWriter, { - - encode : true, - - encodeDelete: false, - - constructor : function(config){ - Ext.data.JsonWriter.superclass.constructor.call(this, config); + for (i = 0; i < 4; i++) { + if (buttons & Math.pow(2, i)) { + + + if (!me.defaultFocus) { + me.defaultFocus = me.msgButtons[i]; + } + me.msgButtons[i].show(); + hideToolbar = false; + } else { + me.msgButtons[i].hide(); + } + } + + + if (hideToolbar) { + me.bottomTb.hide(); + } else { + me.bottomTb.show(); + } + me.hidden = true; }, - render : function(params, baseParams, data) { - if (this.encode === true) { + show: function(cfg) { + var me = this; - Ext.apply(params, baseParams); - params[this.meta.root] = Ext.encode(data); + me.reconfigure(cfg); + me.addCls(cfg.cls); + if (cfg.animateTarget) { + me.doAutoSize(false); + me.callParent(); } else { - - var jdata = Ext.apply({}, baseParams); - jdata[this.meta.root] = data; - params.jsonData = jdata; + me.callParent(); + me.doAutoSize(true); } + return me; }, - createRecord : function(rec) { - return this.toHash(rec); - }, - - updateRecord : function(rec) { - return this.toHash(rec); - + afterShow: function(){ + if (this.animateTarget) { + this.center(); + } + this.callParent(arguments); }, - - destroyRecord : function(rec){ - if(this.encodeDelete){ - var data = {}; - data[this.meta.idProperty] = rec.id; - return data; - }else{ - return rec.id; - } - } -}); -Ext.data.JsonReader = function(meta, recordType){ - meta = meta || {}; - - - - - Ext.applyIf(meta, { - idProperty: 'id', - successProperty: 'success', - totalProperty: 'total' - }); - Ext.data.JsonReader.superclass.constructor.call(this, meta, recordType || meta.fields); -}; -Ext.extend(Ext.data.JsonReader, Ext.data.DataReader, { - - - read : function(response){ - var json = response.responseText; - var o = Ext.decode(json); - if(!o) { - throw {message: 'JsonReader.read: Json object not found'}; - } - return this.readRecords(o); - }, + doAutoSize: function(center) { + var me = this, + icon = me.iconComponent, + iconHeight = me.iconHeight; - - - readResponse : function(action, response) { - var o = (response.responseText !== undefined) ? Ext.decode(response.responseText) : response; - if(!o) { - throw new Ext.data.JsonReader.Error('response'); + if (!Ext.isDefined(me.frameWidth)) { + me.frameWidth = me.el.getWidth() - me.body.getWidth(); } + + + icon.setHeight(iconHeight); - var root = this.getRoot(o); - if (action === Ext.data.Api.actions.create) { - var def = Ext.isDefined(root); - if (def && Ext.isEmpty(root)) { - throw new Ext.data.JsonReader.Error('root-empty', this.meta.root); - } - else if (!def) { - throw new Ext.data.JsonReader.Error('root-undefined-response', this.meta.root); - } - } + + me.minWidth = me.cfg.minWidth || Ext.getClass(this).prototype.minWidth; - var res = new Ext.data.Response({ - action: action, - success: this.getSuccess(o), - data: (root) ? this.extractData(root, false) : [], - message: this.getMessage(o), - raw: o - }); + + me.topContainer.doLayout(); + if (Ext.isIE6 || Ext.isIEQuirks) { + + + + me.textField.setCalculatedSize(9); + me.textArea.setCalculatedSize(9); + } + var width = me.cfg.width || me.msg.getWidth() + icon.getWidth() + 25, + height = (me.header.rendered ? me.header.getHeight() : 0) + + Math.max(me.promptContainer.getHeight(), icon.getHeight()) + + me.progressBar.getHeight() + + (me.bottomTb.rendered ? me.bottomTb.getHeight() : 0) + 20 ; - if (Ext.isEmpty(res.success)) { - throw new Ext.data.JsonReader.Error('successProperty-response', this.meta.successProperty); + icon.setHeight(Math.max(iconHeight, me.msg.getHeight())); + me.setSize(width + me.frameWidth, height + me.frameWidth); + if (center) { + me.center(); } - return res; + return me; + }, + + updateText: function(text) { + this.msg.update(text); + return this.doAutoSize(true); }, - readRecords : function(o){ - - this.jsonData = o; - if(o.metaData){ - this.onMetaChange(o.metaData); + setIcon : function(icon) { + var me = this; + me.iconComponent.removeCls(me.iconCls); + if (icon) { + me.iconComponent.show(); + me.iconComponent.addCls(Ext.baseCSSPrefix + 'dlg-icon'); + me.iconComponent.addCls(me.iconCls = icon); + } else { + me.iconComponent.removeCls(Ext.baseCSSPrefix + 'dlg-icon'); + me.iconComponent.hide(); } - var s = this.meta, Record = this.recordType, - f = Record.prototype.fields, fi = f.items, fl = f.length, v; + return me; + }, - var root = this.getRoot(o), c = root.length, totalRecords = c, success = true; - if(s.totalProperty){ - v = parseInt(this.getTotal(o), 10); - if(!isNaN(v)){ - totalRecords = v; - } - } - if(s.successProperty){ - v = this.getSuccess(o); - if(v === false || v === 'false'){ - success = false; - } + + updateProgress : function(value, progressText, msg){ + this.progressBar.updateProgress(value, progressText); + if (msg){ + this.updateText(msg); } + return this; + }, - - return { - success : success, - records : this.extractData(root, true), - totalRecords : totalRecords - }; + onEsc: function() { + if (this.closable !== false) { + this.callParent(arguments); + } }, - buildExtractors : function() { - if(this.ef){ - return; + confirm: function(cfg, msg, fn, scope) { + if (Ext.isString(cfg)) { + cfg = { + title: cfg, + icon: 'ext-mb-question', + msg: msg, + buttons: this.YESNO, + callback: fn, + scope: scope + }; } - var s = this.meta, Record = this.recordType, - f = Record.prototype.fields, fi = f.items, fl = f.length; + return this.show(cfg); + }, - if(s.totalProperty) { - this.getTotal = this.createAccessor(s.totalProperty); - } - if(s.successProperty) { - this.getSuccess = this.createAccessor(s.successProperty); - } - if (s.messageProperty) { - this.getMessage = this.createAccessor(s.messageProperty); - } - this.getRoot = s.root ? this.createAccessor(s.root) : function(p){return p;}; - if (s.id || s.idProperty) { - var g = this.createAccessor(s.id || s.idProperty); - this.getId = function(rec) { - var r = g(rec); - return (r === undefined || r === '') ? null : r; + + prompt : function(cfg, msg, fn, scope, multiline, value){ + if (Ext.isString(cfg)) { + cfg = { + prompt: true, + title: cfg, + minWidth: this.minPromptWidth, + msg: msg, + buttons: this.OKCANCEL, + callback: fn, + scope: scope, + multiline: multiline, + value: value }; - } else { - this.getId = function(){return null;}; } - var ef = []; - for(var i = 0; i < fl; i++){ - f = fi[i]; - var map = (f.mapping !== undefined && f.mapping !== null) ? f.mapping : f.name; - ef.push(this.createAccessor(map)); - } - this.ef = ef; + return this.show(cfg); }, - simpleAccess : function(obj, subsc) { - return obj[subsc]; + wait : function(cfg, title, config){ + if (Ext.isString(cfg)) { + cfg = { + title : title, + msg : cfg, + closable: false, + wait: true, + modal: true, + minWidth: this.minProgressWidth, + waitConfig: config + }; + } + return this.show(cfg); }, - createAccessor : function(){ - var re = /[\[\.]/; - return function(expr) { - if(Ext.isEmpty(expr)){ - return Ext.emptyFn; - } - if(Ext.isFunction(expr)){ - return expr; - } - var i = String(expr).search(re); - if(i >= 0){ - return new Function('obj', 'return obj' + (i > 0 ? '.' : '') + expr); - } - return function(obj){ - return obj[expr]; + alert: function(cfg, msg, fn, scope) { + if (Ext.isString(cfg)) { + cfg = { + title : cfg, + msg : msg, + buttons: this.OK, + fn: fn, + scope : scope, + minWidth: this.minWidth }; - - }; - }(), + } + return this.show(cfg); + }, - extractValues : function(data, items, len) { - var f, values = {}; - for(var j = 0; j < len; j++){ - f = items[j]; - var v = this.ef[j](data); - values[f.name] = f.convert((v !== undefined) ? v : f.defaultValue, data); + progress : function(cfg, msg, progressText){ + if (Ext.isString(cfg)) { + cfg = { + title: cfg, + msg: msg, + progressText: progressText + }; } - return values; + return this.show(cfg); } +}, function() { + Ext.MessageBox = Ext.Msg = new this(); }); -Ext.data.JsonReader.Error = Ext.extend(Ext.Error, { - constructor : function(message, arg) { - this.arg = arg; - Ext.Error.call(this, message); - }, - name : 'Ext.data.JsonReader' -}); -Ext.apply(Ext.data.JsonReader.Error.prototype, { - lang: { - 'response': 'An error occurred while json-decoding your server response', - 'successProperty-response': 'Could not locate your "successProperty" in your server response. Please review your JsonReader config to ensure the config-property "successProperty" matches the property in your server-response. See the JsonReader docs.', - 'root-undefined-config': 'Your JsonReader was configured without a "root" property. Please review your JsonReader config and make sure to define the root property. See the JsonReader docs.', - 'idProperty-undefined' : 'Your JsonReader was configured without an "idProperty" Please review your JsonReader configuration and ensure the "idProperty" is set (e.g.: "id"). See the JsonReader docs.', - 'root-empty': 'Data was expected to be returned by the server in the "root" property of the response. Please review your JsonReader configuration to ensure the "root" property matches that returned in the server-response. See JsonReader docs.' - } -}); -Ext.data.ArrayReader = Ext.extend(Ext.data.JsonReader, { - - - - - readRecords : function(o){ - this.arrayData = o; - var s = this.meta, - sid = s ? Ext.num(s.idIndex, s.id) : null, - recordType = this.recordType, - fields = recordType.prototype.fields, - records = [], - success = true, - v; - var root = this.getRoot(o); +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'], - for(var i = 0, len = root.length; i < len; i++) { - var n = root[i], - values = {}, - id = ((sid || sid === 0) && n[sid] !== undefined && n[sid] !== "" ? n[sid] : null); - for(var j = 0, jlen = fields.length; j < jlen; j++) { - var f = fields.items[j], - k = f.mapping !== undefined && f.mapping !== null ? f.mapping : j; - v = n[k] !== undefined ? n[k] : f.defaultValue; - v = f.convert(v, n); - values[f.name] = v; - } - var record = new recordType(values, id); - record.json = n; - records[records.length] = record; - } + constructor: function(owner, config) { + var me = this, + onItemAddOrRemove = me.onItemAddOrRemove; - var totalRecords = records.length; + + me.owner = owner; - if(s.totalProperty) { - v = parseInt(this.getTotal(o), 10); - if(!isNaN(v)) { - totalRecords = v; - } - } - if(s.successProperty){ - v = this.getSuccess(o); - if(v === false || v === 'false'){ - success = false; - } - } + + me.mon(owner, { + add: onItemAddOrRemove, + remove: onItemAddOrRemove, + scope: me + }); - return { - success : success, - records : records, - totalRecords : totalRecords - }; - } -}); -Ext.data.ArrayStore = Ext.extend(Ext.data.Store, { - - constructor: function(config){ - Ext.data.ArrayStore.superclass.constructor.call(this, Ext.apply(config, { - reader: new Ext.data.ArrayReader(config) - })); - }, + Ext.apply(me, config); - loadData : function(data, append){ - if(this.expandData === true){ - var r = []; - for(var i = 0, len = data.length; i < len; i++){ - r[r.length] = [data[i]]; - } - data = r; + + if (Ext.isString(me.paramOrder)) { + me.paramOrder = me.paramOrder.split(/[\s,|]/); } - Ext.data.ArrayStore.superclass.loadData.call(this, data, append); - } -}); -Ext.reg('arraystore', Ext.data.ArrayStore); + me.addEvents( + + 'beforeaction', + + 'actionfailed', + + 'actioncomplete', + + 'validitychange', + + 'dirtychange' + ); + me.callParent(); + }, -Ext.data.SimpleStore = Ext.data.ArrayStore; -Ext.reg('simplestore', Ext.data.SimpleStore); -Ext.data.JsonStore = Ext.extend(Ext.data.Store, { - constructor: function(config){ - Ext.data.JsonStore.superclass.constructor.call(this, Ext.apply(config, { - reader: new Ext.data.JsonReader(config) - })); - } -}); -Ext.reg('jsonstore', Ext.data.JsonStore); -Ext.data.XmlWriter = function(params) { - Ext.data.XmlWriter.superclass.constructor.apply(this, arguments); + initialize: function(){ + this.initialized = true; + this.onValidityChange(!this.hasInvalidField()); + }, + - this.tpl = (typeof(this.tpl) === 'string') ? new Ext.XTemplate(this.tpl).compile() : this.tpl.compile(); -}; -Ext.extend(Ext.data.XmlWriter, Ext.data.DataWriter, { - documentRoot: 'xrequest', - forceDocumentRoot: false, + - root: 'records', + - xmlVersion : '1.0', + - xmlEncoding: 'ISO-8859-15', + timeout: 30, + + - tpl: '<\u003fxml version="{version}" encoding="{encoding}"\u003f><{documentRoot}><{name}>{value}<{root}><{parent.record}><{name}>{value}', + + paramsAsHash: false, - render : function(params, baseParams, data) { - baseParams = this.toArray(baseParams); - params.xmlData = this.tpl.applyTemplate({ - version: this.xmlVersion, - encoding: this.xmlEncoding, - documentRoot: (baseParams.length > 0 || this.forceDocumentRoot === true) ? this.documentRoot : false, - record: this.meta.record, - root: this.root, - baseParams: baseParams, - records: (Ext.isArray(data[0])) ? data : [data] - }); - }, + waitTitle: 'Please Wait...', - createRecord : function(rec) { - return this.toArray(this.toHash(rec)); - }, + trackResetOnLoad: false, - updateRecord : function(rec) { - return this.toArray(this.toHash(rec)); - }, - destroyRecord : function(rec) { - var data = {}; - data[this.meta.idProperty] = rec.id; - return this.toArray(data); - } -}); -Ext.data.XmlReader = function(meta, recordType){ - meta = meta || {}; - Ext.applyIf(meta, { - idProperty: meta.idProperty || meta.idPath || meta.id, - successProperty: meta.successProperty || meta.success - }); + wasDirty: false, + - Ext.data.XmlReader.superclass.constructor.call(this, meta, recordType || meta.fields); -}; -Ext.extend(Ext.data.XmlReader, Ext.data.DataReader, { - read : function(response){ - var doc = response.responseXML; - if(!doc) { - throw {message: "XmlReader.read: XML Document not available"}; - } - return this.readRecords(doc); + destroy: function() { + this.clearListeners(); }, - readRecords : function(doc){ - - this.xmlData = doc; + onItemAddOrRemove: function(parent, child) { + var me = this, + isAdding = !!child.ownerCt, + isContainer = child.isContainer; - var root = doc.documentElement || doc, - q = Ext.DomQuery, - totalRecords = 0, - success = true; + function handleField(field) { + + me[isAdding ? 'mon' : 'mun'](field, { + validitychange: me.checkValidity, + dirtychange: me.checkDirty, + scope: me, + buffer: 100 + }); + + delete me._fields; + } - if(this.meta.totalProperty){ - totalRecords = this.getTotal(root, 0); + if (child.isFormField) { + handleField(child); } - if(this.meta.successProperty){ - success = this.getSuccess(root); + else if (isContainer) { + + Ext.Array.forEach(child.query('[isFormField]'), handleField); } - var records = this.extractData(q.select(this.meta.record, root), true); + + delete this._boundItems; - return { - success : success, - records : records, - totalRecords : totalRecords || records.length - }; + if (me.initialized) { + me.onValidityChange(!me.hasInvalidField()); + } }, - readResponse : function(action, response) { - var q = Ext.DomQuery, - doc = response.responseXML, - root = doc.documentElement || doc; - - - var res = new Ext.data.Response({ - action: action, - success : this.getSuccess(root), - message: this.getMessage(root), - data: this.extractData(q.select(this.meta.record, root) || q.select(this.meta.root, root), false), - raw: doc - }); - - if (Ext.isEmpty(res.success)) { - throw new Ext.data.DataReader.Error('successProperty-response', this.meta.successProperty); + getFields: function() { + var fields = this._fields; + if (!fields) { + fields = this._fields = Ext.create('Ext.util.MixedCollection'); + fields.addAll(this.owner.query('[isFormField]')); } + return fields; + }, - - if (action === Ext.data.Api.actions.create) { - var def = Ext.isDefined(res.data); - if (def && Ext.isEmpty(res.data)) { - throw new Ext.data.JsonReader.Error('root-empty', this.meta.root); - } - else if (!def) { - throw new Ext.data.JsonReader.Error('root-undefined-response', this.meta.root); - } + getBoundItems: function() { + var boundItems = this._boundItems; + if (!boundItems) { + boundItems = this._boundItems = Ext.create('Ext.util.MixedCollection'); + boundItems.addAll(this.owner.query('[formBind]')); } - return res; + return boundItems; }, - getSuccess : function() { - return true; + + hasInvalidField: function() { + return !!this.getFields().findBy(function(field) { + var preventMark = field.preventMark, + isValid; + field.preventMark = true; + isValid = field.isValid(); + field.preventMark = preventMark; + return !isValid; + }); }, - buildExtractors : function() { - if(this.ef){ - return; - } - var s = this.meta, - Record = this.recordType, - f = Record.prototype.fields, - fi = f.items, - fl = f.length; + isValid: function() { + var me = this, + invalid; + me.batchLayouts(function() { + invalid = me.getFields().filterBy(function(field) { + return !field.validate(); + }); + }); + return invalid.length < 1; + }, - if(s.totalProperty) { - this.getTotal = this.createAccessor(s.totalProperty); - } - if(s.successProperty) { - this.getSuccess = this.createAccessor(s.successProperty); - } - if (s.messageProperty) { - this.getMessage = this.createAccessor(s.messageProperty); - } - this.getRoot = function(res) { - return (!Ext.isEmpty(res[this.meta.record])) ? res[this.meta.record] : res[this.meta.root]; - }; - if (s.idPath || s.idProperty) { - var g = this.createAccessor(s.idPath || s.idProperty); - this.getId = function(rec) { - var id = g(rec) || rec.id; - return (id === undefined || id === '') ? null : id; - }; - } else { - this.getId = function(){return null;}; + + checkValidity: function() { + var me = this, + valid = !me.hasInvalidField(); + if (valid !== me.wasValid) { + me.onValidityChange(valid); + me.fireEvent('validitychange', me, valid); + me.wasValid = valid; } - var ef = []; - for(var i = 0; i < fl; i++){ - f = fi[i]; - var map = (f.mapping !== undefined && f.mapping !== null) ? f.mapping : f.name; - ef.push(this.createAccessor(map)); + }, + + + onValidityChange: function(valid) { + var boundItems = this.getBoundItems(); + if (boundItems) { + boundItems.each(function(cmp) { + if (cmp.disabled === valid) { + cmp.setDisabled(!valid); + } + }); } - this.ef = ef; }, - createAccessor : function(){ - var q = Ext.DomQuery; - return function(key) { - if (Ext.isFunction(key)) { - return key; - } - switch(key) { - case this.meta.totalProperty: - return function(root, def){ - return q.selectNumber(key, root, def); - }; - break; - case this.meta.successProperty: - return function(root, def) { - var sv = q.selectValue(key, root, true); - var success = sv !== false && sv !== 'false'; - return success; - }; - break; - default: - return function(root, def) { - return q.selectValue(key, root, def); - }; - break; - } - }; - }(), + isDirty: function() { + return !!this.getFields().findBy(function(f) { + return f.isDirty(); + }); + }, - extractValues : function(data, items, len) { - var f, values = {}; - for(var j = 0; j < len; j++){ - f = items[j]; - var v = this.ef[j](data); - values[f.name] = f.convert((v !== undefined) ? v : f.defaultValue, data); + checkDirty: function() { + var dirty = this.isDirty(); + if (dirty !== this.wasDirty) { + this.fireEvent('dirtychange', this, dirty); + this.wasDirty = dirty; } - return values; - } -}); -Ext.data.XmlStore = Ext.extend(Ext.data.Store, { - - constructor: function(config){ - Ext.data.XmlStore.superclass.constructor.call(this, Ext.apply(config, { - reader: new Ext.data.XmlReader(config) - })); - } -}); -Ext.reg('xmlstore', Ext.data.XmlStore); -Ext.data.GroupingStore = Ext.extend(Ext.data.Store, { + }, - constructor: function(config) { - config = config || {}; + hasUpload: function() { + return !!this.getFields().findBy(function(f) { + return f.isFileUpload(); + }); + }, - - - - - this.hasMultiSort = true; - this.multiSortInfo = this.multiSortInfo || {sorters: []}; + + doAction: function(action, options) { + if (Ext.isString(action)) { + action = Ext.ClassManager.instantiateByAlias('formaction.' + action, Ext.apply({}, options, {form: this})); + } + if (this.fireEvent('beforeaction', this, action) !== false) { + this.beforeAction(action); + Ext.defer(action.run, 100, action); + } + return this; + }, - var sorters = this.multiSortInfo.sorters, - groupField = config.groupField || this.groupField, - sortInfo = config.sortInfo || this.sortInfo, - groupDir = config.groupDir || this.groupDir; + + submit: function(options) { + return this.doAction(this.standardSubmit ? 'standardsubmit' : this.api ? 'directsubmit' : 'submit', options); + }, - - if(groupField){ - sorters.push({ - field : groupField, - direction: groupDir - }); - } + + load: function(options) { + return this.doAction(this.api ? 'directload' : 'load', options); + }, - - if (sortInfo) { - sorters.push(sortInfo); - } + + updateRecord: function(record) { + var fields = record.fields, + values = this.getFieldValues(), + name, + obj = {}; - Ext.data.GroupingStore.superclass.constructor.call(this, config); + fields.each(function(f) { + name = f.name; + if (name in values) { + obj[name] = values[name]; + } + }); - this.addEvents( - - 'groupchange' - ); + record.beginEdit(); + record.set(obj); + record.endEdit(); - this.applyGroupField(); + return this; }, + loadRecord: function(record) { + this._record = record; + return this.setValues(record.data); + }, - remoteGroup : false, - - groupOnSort:false, - - groupDir : 'ASC', + getRecord: function() { + return this._record; + }, - clearGrouping : function(){ - this.groupField = false; + beforeAction: function(action) { + var waitMsg = action.waitMsg, + maskCls = Ext.baseCSSPrefix + 'mask-loading', + waitMsgTarget; - if(this.remoteGroup){ - if(this.baseParams){ - delete this.baseParams.groupBy; - delete this.baseParams.groupDir; - } - var lo = this.lastOptions; - if(lo && lo.params){ - delete lo.params.groupBy; - delete lo.params.groupDir; + + this.getFields().each(function(f) { + if (f.isFormField && f.syncValue) { + f.syncValue(); } + }); - this.reload(); - }else{ - this.sort(); - this.fireEvent('datachanged', this); + if (waitMsg) { + waitMsgTarget = this.waitMsgTarget; + if (waitMsgTarget === true) { + this.owner.el.mask(waitMsg, maskCls); + } else if (waitMsgTarget) { + waitMsgTarget = this.waitMsgTarget = Ext.get(waitMsgTarget); + waitMsgTarget.mask(waitMsg, maskCls); + } else { + Ext.MessageBox.wait(waitMsg, action.waitTitle || this.waitTitle); + } } }, - groupBy : function(field, forceRegroup, direction) { - direction = direction ? (String(direction).toUpperCase() == 'DESC' ? 'DESC' : 'ASC') : this.groupDir; - - if (this.groupField == field && this.groupDir == direction && !forceRegroup) { - return; + afterAction: function(action, success) { + if (action.waitMsg) { + var MessageBox = Ext.MessageBox, + waitMsgTarget = this.waitMsgTarget; + if (waitMsgTarget === true) { + this.owner.el.unmask(); + } else if (waitMsgTarget) { + waitMsgTarget.unmask(); + } else { + MessageBox.updateProgress(1); + MessageBox.hide(); + } } - - - - var sorters = this.multiSortInfo.sorters; - if (sorters.length > 0 && sorters[0].field == this.groupField) { - sorters.shift(); + if (success) { + if (action.reset) { + this.reset(); + } + Ext.callback(action.success, action.scope || action, [this, action]); + this.fireEvent('actioncomplete', this, action); + } else { + Ext.callback(action.failure, action.scope || action, [this, action]); + this.fireEvent('actionfailed', this, action); } + }, - this.groupField = field; - this.groupDir = direction; - this.applyGroupField(); - var fireGroupEvent = function() { - this.fireEvent('groupchange', this, this.getGroupState()); - }; + + findField: function(id) { + return this.getFields().findBy(function(f) { + return f.id === id || f.getName() === id; + }); + }, - if (this.groupOnSort) { - this.sort(field, direction); - fireGroupEvent.call(this); - return; + + + markInvalid: function(errors) { + var me = this; + + function mark(fieldId, msg) { + var field = me.findField(fieldId); + if (field) { + field.markInvalid(msg); + } } - if (this.remoteGroup) { - this.on('load', fireGroupEvent, this, {single: true}); - this.reload(); - } else { - this.sort(sorters); - fireGroupEvent.call(this); + if (Ext.isArray(errors)) { + Ext.each(errors, function(err) { + mark(err.id, err.msg); + }); } + else if (errors instanceof Ext.data.Errors) { + errors.each(function(err) { + mark(err.field, err.message); + }); + } + else { + Ext.iterate(errors, mark); + } + return this; }, - - sort : function(fieldName, dir) { - if (this.remoteSort) { - return Ext.data.GroupingStore.superclass.sort.call(this, fieldName, dir); - } + setValues: function(values) { + var me = this; - var sorters = []; + function setVal(fieldId, val) { + var field = me.findField(fieldId); + if (field) { + field.setValue(val); + if (me.trackResetOnLoad) { + field.resetOriginalValue(); + } + } + } - - if (Ext.isArray(arguments[0])) { - sorters = arguments[0]; - } else if (fieldName == undefined) { + if (Ext.isArray(values)) { - - sorters = this.sortInfo ? [this.sortInfo] : []; + Ext.each(values, function(val) { + setVal(val.id, val.value); + }); } else { - - var field = this.fields.get(fieldName); - if (!field) return false; + Ext.iterate(values, setVal); + } + return this; + }, - var name = field.name, - sortInfo = this.sortInfo || null, - sortToggle = this.sortToggle ? this.sortToggle[name] : null; + + getValues: function(asString, dirtyOnly, includeEmptyText, useDataValues) { + var values = {}; - if (!dir) { - if (sortInfo && sortInfo.field == name) { - dir = (this.sortToggle[name] || 'ASC').toggle('ASC', 'DESC'); - } else { - dir = field.sortDir; + this.getFields().each(function(field) { + if (!dirtyOnly || field.isDirty()) { + var data = field[useDataValues ? 'getModelData' : 'getSubmitData'](includeEmptyText); + if (Ext.isObject(data)) { + Ext.iterate(data, function(name, val) { + if (includeEmptyText && val === '') { + val = field.emptyText || ''; + } + if (name in values) { + var bucket = values[name], + isArray = Ext.isArray; + if (!isArray(bucket)) { + bucket = values[name] = [bucket]; + } + if (isArray(val)) { + values[name] = bucket.concat(val); + } else { + bucket.push(val); + } + } else { + values[name] = val; + } + }); } } + }); - this.sortToggle[name] = dir; - this.sortInfo = {field: name, direction: dir}; - - sorters = [this.sortInfo]; - } - - - if (this.groupField) { - sorters.unshift({direction: this.groupDir, field: this.groupField}); + if (asString) { + values = Ext.Object.toQueryString(values); } - - return this.multiSort.call(this, sorters, dir); + return values; }, - applyGroupField: function(){ - if (this.remoteGroup) { - if(!this.baseParams){ - this.baseParams = {}; - } + getFieldValues: function(dirtyOnly) { + return this.getValues(false, dirtyOnly, false, true); + }, - Ext.apply(this.baseParams, { - groupBy : this.groupField, - groupDir: this.groupDir + + clearInvalid: function() { + var me = this; + me.batchLayouts(function() { + me.getFields().each(function(f) { + f.clearInvalid(); }); + }); + return me; + }, - var lo = this.lastOptions; - if (lo && lo.params) { - lo.params.groupDir = this.groupDir; + + reset: function() { + var me = this; + me.batchLayouts(function() { + me.getFields().each(function(f) { + f.reset(); + }); + }); + return me; + }, - - delete lo.params.groupBy; - } - } + + applyToFields: function(obj) { + this.getFields().each(function(f) { + Ext.apply(f, obj); + }); + return this; }, - applyGrouping : function(alwaysFireChange){ - if(this.groupField !== false){ - this.groupBy(this.groupField, true, this.groupDir); - return true; - }else{ - if(alwaysFireChange === true){ - this.fireEvent('datachanged', this); - } - return false; - } + applyIfToFields: function(obj) { + this.getFields().each(function(f) { + Ext.applyIf(f, obj); + }); + return this; }, - getGroupState : function(){ - return this.groupOnSort && this.groupField !== false ? - (this.sortInfo ? this.sortInfo.field : undefined) : this.groupField; + batchLayouts: function(fn) { + var me = this, + suspended = new Ext.util.HashMap(); + + + me.getFields().each(function(field) { + var ownerCt = field.ownerCt; + if (!suspended.contains(ownerCt)) { + suspended.add(ownerCt); + ownerCt.oldSuspendLayout = ownerCt.suspendLayout; + ownerCt.suspendLayout = true; + } + }); + + + fn(); + + + suspended.each(function(id, ct) { + ct.suspendLayout = ct.oldSuspendLayout; + delete ct.oldSuspendLayout; + }); + + + me.owner.doComponentLayout(); } }); -Ext.reg('groupingstore', Ext.data.GroupingStore); -Ext.data.DirectProxy = function(config){ - Ext.apply(this, config); - if(typeof this.paramOrder == 'string'){ - this.paramOrder = this.paramOrder.split(/[\s,|]/); - } - Ext.data.DirectProxy.superclass.constructor.call(this, config); -}; -Ext.extend(Ext.data.DirectProxy, Ext.data.DataProxy, { - - paramOrder: undefined, +Ext.define('Ext.form.FieldAncestor', { - paramsAsHash: true, + - directFn : undefined, + initFieldAncestor: function() { + var me = this, + onSubtreeChange = me.onFieldAncestorSubtreeChange; + + me.addEvents( + + 'fieldvaliditychange', + + + 'fielderrorchange' + ); + + + me.on('add', onSubtreeChange, me); + me.on('remove', onSubtreeChange, me); + + me.initFieldDefaults(); + }, - doRequest : function(action, rs, params, reader, callback, scope, options) { - var args = [], - directFn = this.api[action] || this.directFn; + initFieldDefaults: function() { + if (!this.fieldDefaults) { + this.fieldDefaults = {}; + } + }, - switch (action) { - case Ext.data.Api.actions.create: - args.push(params.jsonData); - break; - case Ext.data.Api.actions.read: - - if(directFn.directCfg.method.len > 0){ - if(this.paramOrder){ - for(var i = 0, len = this.paramOrder.length; i < len; i++){ - args.push(params[this.paramOrder[i]]); - } - }else if(this.paramsAsHash){ - args.push(params); - } + + onFieldAncestorSubtreeChange: function(parent, child) { + var me = this, + isAdding = !!child.ownerCt; + + function handleCmp(cmp) { + var isLabelable = cmp.isFieldLabelable, + isField = cmp.isFormField; + if (isLabelable || isField) { + if (isLabelable) { + me['onLabelable' + (isAdding ? 'Added' : 'Removed')](cmp); } - break; - case Ext.data.Api.actions.update: - args.push(params.jsonData); - break; - case Ext.data.Api.actions.destroy: - args.push(params.jsonData); - break; + if (isField) { + me['onField' + (isAdding ? 'Added' : 'Removed')](cmp); + } + } + else if (cmp.isContainer) { + Ext.Array.forEach(cmp.getRefItems(), handleCmp); + } } + handleCmp(child); + }, - var trans = { - params : params || {}, - request: { - callback : callback, - scope : scope, - arg : options - }, - reader: reader - }; + + onLabelableAdded: function(labelable) { + var me = this; - args.push(this.createCallback(action, rs, trans), this); - directFn.apply(window, args); + + me.mon(labelable, 'errorchange', me.handleFieldErrorChange, me, {buffer: 10}); + + labelable.setFieldDefaults(me.fieldDefaults); }, - createCallback : function(action, rs, trans) { + onFieldAdded: function(field) { var me = this; - return function(result, res) { - if (!res.status) { - - if (action === Ext.data.Api.actions.read) { - me.fireEvent("loadexception", me, trans, res, null); + me.mon(field, 'validitychange', me.handleFieldValidityChange, me); + }, + + + onLabelableRemoved: function(labelable) { + var me = this; + me.mun(labelable, 'errorchange', me.handleFieldErrorChange, me); + }, + + + onFieldRemoved: function(field) { + var me = this; + me.mun(field, 'validitychange', me.handleFieldValidityChange, me); + }, + + + handleFieldValidityChange: function(field, isValid) { + var me = this; + me.fireEvent('fieldvaliditychange', me, field, isValid); + me.onFieldValidityChange(); + }, + + + handleFieldErrorChange: function(labelable, activeError) { + var me = this; + me.fireEvent('fielderrorchange', me, labelable, activeError); + me.onFieldErrorChange(); + }, + + + onFieldValidityChange: Ext.emptyFn, + + + onFieldErrorChange: Ext.emptyFn + +}); + +Ext.define('Ext.layout.container.CheckboxGroup', { + extend: 'Ext.layout.container.Container', + alias: ['layout.checkboxgroup'], + + + onLayout: function() { + var numCols = this.getColCount(), + shadowCt = this.getShadowCt(), + owner = this.owner, + items = owner.items, + shadowItems = shadowCt.items, + numItems = items.length, + colIndex = 0, + i, numRows; + + + + + + + shadowItems.each(function(col) { + col.items.clear(); + }); + + + + while (shadowItems.length > numCols) { + shadowCt.remove(shadowItems.last()); + } + while (shadowItems.length < numCols) { + shadowCt.add({ + xtype: 'container', + cls: owner.groupCls, + flex: 1 + }); + } + + if (owner.vertical) { + numRows = Math.ceil(numItems / numCols); + for (i = 0; i < numItems; i++) { + if (i > 0 && i % numRows === 0) { + colIndex++; } - me.fireEvent('exception', me, 'remote', action, trans, res, null); - trans.request.callback.call(trans.request.scope, null, trans.request.arg, false); - return; + shadowItems.getAt(colIndex).items.add(items.getAt(i)); } - if (action === Ext.data.Api.actions.read) { - me.onRead(action, trans, result, res); - } else { - me.onWrite(action, trans, result, res, rs); + } else { + for (i = 0; i < numItems; i++) { + colIndex = i % numCols; + shadowItems.getAt(colIndex).items.add(items.getAt(i)); } - }; + } + + if (!shadowCt.rendered) { + shadowCt.render(this.getRenderTarget()); + } else { + + + shadowItems.each(function(col) { + var layout = col.getLayout(); + layout.renderItems(layout.getLayoutItems(), layout.getRenderTarget()); + }); + } + + shadowCt.doComponentLayout(); }, + - onRead : function(action, trans, result, res) { - var records; - try { - records = trans.reader.readRecords(result); - } - catch (ex) { - - this.fireEvent("loadexception", this, trans, res, ex); + renderItems: Ext.emptyFn, - this.fireEvent('exception', this, 'response', action, trans, res, ex); - trans.request.callback.call(trans.request.scope, null, trans.request.arg, false); - return; + + + getShadowCt: function() { + var me = this, + shadowCt = me.shadowCt, + owner, items, item, columns, columnsIsArray, numCols, i; + + if (!shadowCt) { + + owner = me.owner; + columns = owner.columns; + columnsIsArray = Ext.isArray(columns); + numCols = me.getColCount(); + items = []; + for(i = 0; i < numCols; i++) { + item = { + xtype: 'container', + cls: owner.groupCls + }; + if (columnsIsArray) { + + + if (columns[i] < 1) { + item.flex = columns[i]; + } else { + item.width = columns[i]; + } + } + else { + + item.flex = 1; + } + items.push(item); + } + + + shadowCt = me.shadowCt = Ext.createWidget('container', { + layout: 'hbox', + items: items, + ownerCt: owner + }); } - this.fireEvent("load", this, res, trans.request.arg); - trans.request.callback.call(trans.request.scope, records, trans.request.arg, true); + + return shadowCt; }, + + - onWrite : function(action, trans, result, res, rs) { - var data = trans.reader.extractData(trans.reader.getRoot(result), false); - var success = trans.reader.getSuccess(result); - success = (success !== false); - if (success){ - this.fireEvent("write", this, action, data, res, rs, trans.request.arg); - }else{ - this.fireEvent('exception', this, 'remote', action, trans, result, rs); - } - trans.request.callback.call(trans.request.scope, data, res, success); + getColCount: function() { + var owner = this.owner, + colsCfg = owner.columns; + return Ext.isArray(colsCfg) ? colsCfg.length : (Ext.isNumber(colsCfg) ? colsCfg : owner.items.length); } -}); -Ext.data.DirectStore = Ext.extend(Ext.data.Store, { - constructor : function(config){ - - var c = Ext.apply({}, { - batchTransactions: false - }, config); - Ext.data.DirectStore.superclass.constructor.call(this, Ext.apply(c, { - proxy: Ext.isDefined(c.proxy) ? c.proxy : new Ext.data.DirectProxy(Ext.copyTo({}, c, 'paramOrder,paramsAsHash,directFn,api')), - reader: (!Ext.isDefined(c.reader) && c.fields) ? new Ext.data.JsonReader(Ext.copyTo({}, c, 'totalProperty,root,idProperty'), c.fields) : c.reader - })); - } }); -Ext.reg('directstore', Ext.data.DirectStore); -Ext.Direct = Ext.extend(Ext.util.Observable, { - - - exceptions: { - TRANSPORT: 'xhr', - PARSE: 'parse', - LOGIN: 'login', - SERVER: 'exception' +Ext.define('Ext.form.FieldContainer', { + extend: 'Ext.container.Container', + mixins: { + labelable: 'Ext.form.Labelable', + fieldAncestor: 'Ext.form.FieldAncestor' }, + alias: 'widget.fieldcontainer', - - constructor: function(){ - this.addEvents( - - 'event', - - 'exception' - ); - this.transactions = {}; - this.providers = {}; - }, + componentLayout: 'field', - addProvider : function(provider){ - var a = arguments; - if(a.length > 1){ - for(var i = 0, len = a.length; i < len; i++){ - this.addProvider(a[i]); - } - return; - } + combineLabels: false, - - if(!provider.events){ - provider = new Ext.Direct.PROVIDERS[provider.type](provider); - } - provider.id = provider.id || Ext.id(); - this.providers[provider.id] = provider; + + labelConnector: ', ', - provider.on('data', this.onProviderData, this); - provider.on('exception', this.onProviderException, this); + + combineErrors: false, + + maskOnDisable: false, + initComponent: function() { + var me = this, + onSubCmpAddOrRemove = me.onSubCmpAddOrRemove; - if(!provider.isConnected()){ - provider.connect(); - } + + me.initLabelable(); + me.initFieldAncestor(); - return provider; + me.callParent(); }, - getProvider : function(id){ - return this.providers[id]; + onLabelableAdded: function(labelable) { + var me = this; + me.mixins.fieldAncestor.onLabelableAdded.call(this, labelable); + me.updateLabel(); }, - removeProvider : function(id){ - var provider = id.id ? id : this.providers[id]; - provider.un('data', this.onProviderData, this); - provider.un('exception', this.onProviderException, this); - delete this.providers[provider.id]; - return provider; + + onLabelableRemoved: function(labelable) { + var me = this; + me.mixins.fieldAncestor.onLabelableRemoved.call(this, labelable); + me.updateLabel(); }, - addTransaction: function(t){ - this.transactions[t.tid] = t; - return t; + onRender: function() { + var me = this, + renderSelectors = me.renderSelectors, + applyIf = Ext.applyIf; + + applyIf(renderSelectors, me.getLabelableSelectors()); + + me.callParent(arguments); }, - removeTransaction: function(t){ - delete this.transactions[t.tid || t]; - return t; + initRenderTpl: function() { + var me = this; + if (!me.hasOwnProperty('renderTpl')) { + me.renderTpl = me.getTpl('labelableRenderTpl'); + } + return me.callParent(); }, - getTransaction: function(tid){ - return this.transactions[tid.tid || tid]; + initRenderData: function() { + return Ext.applyIf(this.callParent(), this.getLabelableRenderData()); }, - onProviderData : function(provider, e){ - if(Ext.isArray(e)){ - for(var i = 0, len = e.length; i < len; i++){ - this.onProviderData(provider, e[i]); - } - return; + + getFieldLabel: function() { + var label = this.fieldLabel || ''; + if (!label && this.combineLabels) { + label = Ext.Array.map(this.query('[isFieldLabelable]'), function(field) { + return field.getFieldLabel(); + }).join(this.labelConnector); } - if(e.name && e.name != 'event' && e.name != 'exception'){ - this.fireEvent(e.name, e); - }else if(e.type == 'exception'){ - this.fireEvent('exception', e); + return label; + }, + + + updateLabel: function() { + var me = this, + label = me.labelEl; + if (label) { + label.update(me.getFieldLabel()); } - this.fireEvent('event', e, provider); }, - createEvent : function(response, extraProps){ - return new Ext.Direct.eventTypes[response.type](Ext.apply(response, extraProps)); - } -}); -Ext.Direct = new Ext.Direct(); + + onFieldErrorChange: function(field, activeError) { + if (this.combineErrors) { + var me = this, + oldError = me.getActiveError(), + invalidFields = Ext.Array.filter(me.query('[isFormField]'), function(field) { + return field.hasActiveError(); + }), + newErrors = me.getCombinedErrors(invalidFields); -Ext.Direct.TID = 1; -Ext.Direct.PROVIDERS = {}; -Ext.Direct.Transaction = function(config){ - Ext.apply(this, config); - this.tid = ++Ext.Direct.TID; - this.retryCount = 0; -}; -Ext.Direct.Transaction.prototype = { - send: function(){ - this.provider.queueTransaction(this); - }, + if (newErrors) { + me.setActiveErrors(newErrors); + } else { + me.unsetActiveError(); + } - retry: function(){ - this.retryCount++; - this.send(); + if (oldError !== me.getActiveError()) { + me.doComponentLayout(); + } + } }, - getProvider: function(){ - return this.provider; - } -};Ext.Direct.Event = function(config){ - Ext.apply(this, config); -}; - -Ext.Direct.Event.prototype = { - status: true, - getData: function(){ - return this.data; - } -}; + + getCombinedErrors: function(invalidFields) { + var forEach = Ext.Array.forEach, + errors = []; + forEach(invalidFields, function(field) { + forEach(field.getActiveErrors(), function(error) { + var label = field.getFieldLabel(); + errors.push((label ? label + ': ' : '') + error); + }); + }); + return errors; + }, -Ext.Direct.RemotingEvent = Ext.extend(Ext.Direct.Event, { - type: 'rpc', - getTransaction: function(){ - return this.transaction || Ext.Direct.getTransaction(this.tid); + getTargetEl: function() { + return this.bodyEl || this.callParent(); } }); -Ext.Direct.ExceptionEvent = Ext.extend(Ext.Direct.RemotingEvent, { - status: false, - type: 'exception' -}); -Ext.Direct.eventTypes = { - 'rpc': Ext.Direct.RemotingEvent, - 'event': Ext.Direct.Event, - 'exception': Ext.Direct.ExceptionEvent -}; +Ext.define('Ext.form.CheckboxGroup', { + extend:'Ext.form.FieldContainer', + mixins: { + field: 'Ext.form.field.Field' + }, + alias: 'widget.checkboxgroup', + requires: ['Ext.layout.container.CheckboxGroup', 'Ext.form.field.Base'], -Ext.direct.Provider = Ext.extend(Ext.util.Observable, { - - - priority: 1, - - - constructor : function(config){ - Ext.apply(this, config); - this.addEvents( - - 'connect', - - 'disconnect', - - 'data', - - 'exception' - ); - Ext.direct.Provider.superclass.constructor.call(this, config); - }, - isConnected: function(){ - return false; - }, + columns : 'auto', - connect: Ext.emptyFn, - - - disconnect: Ext.emptyFn -}); - -Ext.direct.JsonProvider = Ext.extend(Ext.direct.Provider, { - parseResponse: function(xhr){ - if(!Ext.isEmpty(xhr.responseText)){ - if(typeof xhr.responseText == 'object'){ - return xhr.responseText; - } - return Ext.decode(xhr.responseText); - } - return null; - }, + vertical : false, - getEvents: function(xhr){ - var data = null; - try{ - data = this.parseResponse(xhr); - }catch(e){ - var event = new Ext.Direct.ExceptionEvent({ - data: e, - xhr: xhr, - code: Ext.Direct.exceptions.PARSE, - message: 'Error parsing json response: \n\n ' + data - }); - return [event]; - } - var events = []; - if(Ext.isArray(data)){ - for(var i = 0, len = data.length; i < len; i++){ - events.push(Ext.Direct.createEvent(data[i])); - } - }else{ - events.push(Ext.Direct.createEvent(data)); - } - return events; - } -}); -Ext.direct.PollingProvider = Ext.extend(Ext.direct.JsonProvider, { - - - priority: 3, - - interval: 3000, + allowBlank : true, + blankText : "You must select at least one item in this group", + + defaultType : 'checkboxfield', + + groupCls : Ext.baseCSSPrefix + 'form-check-group', - constructor : function(config){ - Ext.direct.PollingProvider.superclass.constructor.call(this, config); - this.addEvents( - - 'beforepoll', - - 'poll' - ); - }, + fieldBodyCls: Ext.baseCSSPrefix + 'form-checkboxgroup-body', - isConnected: function(){ - return !!this.pollTask; + layout: 'checkboxgroup', + + initComponent: function() { + var me = this; + me.callParent(); + me.initField(); }, - connect: function(){ - if(this.url && !this.pollTask){ - this.pollTask = Ext.TaskMgr.start({ - run: function(){ - if(this.fireEvent('beforepoll', this) !== false){ - if(typeof this.url == 'function'){ - this.url(this.baseParams); - }else{ - Ext.Ajax.request({ - url: this.url, - callback: this.onData, - scope: this, - params: this.baseParams - }); - } - } - }, - interval: this.interval, - scope: this - }); - this.fireEvent('connect', this); - }else if(!this.url){ - throw 'Error initializing PollingProvider, no url configured.'; + initValue: function() { + var me = this, + valueCfg = me.value; + me.originalValue = me.lastValue = valueCfg || me.getValue(); + if (valueCfg) { + me.setValue(valueCfg); } }, - disconnect: function(){ - if(this.pollTask){ - Ext.TaskMgr.stop(this.pollTask); - delete this.pollTask; - this.fireEvent('disconnect', this); + onFieldAdded: function(field) { + var me = this; + if (field.isCheckbox) { + me.mon(field, 'change', me.checkChange, me); } + me.callParent(arguments); }, - - onData: function(opt, success, xhr){ - if(success){ - var events = this.getEvents(xhr); - for(var i = 0, len = events.length; i < len; i++){ - var e = events[i]; - this.fireEvent('data', this, e); - } - }else{ - var e = new Ext.Direct.ExceptionEvent({ - data: e, - code: Ext.Direct.exceptions.TRANSPORT, - message: 'Unable to connect to the server.', - xhr: xhr - }); - this.fireEvent('data', this, e); + onFieldRemoved: function(field) { + var me = this; + if (field.isCheckbox) { + me.mun(field, 'change', me.checkChange, me); } - } -}); + me.callParent(arguments); + }, -Ext.Direct.PROVIDERS['polling'] = Ext.direct.PollingProvider; -Ext.direct.RemotingProvider = Ext.extend(Ext.direct.JsonProvider, { - - - - - - - - - - enableBuffer: 10, - - - maxRetries: 1, - - timeout: undefined, - - constructor : function(config){ - Ext.direct.RemotingProvider.superclass.constructor.call(this, config); - this.addEvents( - - 'beforecall', - - 'call' - ); - this.namespace = (Ext.isString(this.namespace)) ? Ext.ns(this.namespace) : this.namespace || window; - this.transactions = {}; - this.callBuffer = []; + isEqual: function(value1, value2) { + var toQueryString = Ext.Object.toQueryString; + return toQueryString(value1) === toQueryString(value2); }, - initAPI : function(){ - var o = this.actions; - for(var c in o){ - var cls = this.namespace[c] || (this.namespace[c] = {}), - ms = o[c]; - for(var i = 0, len = ms.length; i < len; i++){ - var m = ms[i]; - cls[m.name] = this.createMethod(c, m); - } + getErrors: function() { + var errors = []; + if (!this.allowBlank && Ext.isEmpty(this.getChecked())) { + errors.push(this.blankText); } + return errors; }, - isConnected: function(){ - return !!this.connected; - }, - - connect: function(){ - if(this.url){ - this.initAPI(); - this.connected = true; - this.fireEvent('connect', this); - }else if(!this.url){ - throw 'Error initializing RemotingProvider, no url configured.'; - } + getBoxes: function() { + return this.query('[isCheckbox]'); }, - disconnect: function(){ - if(this.connected){ - this.connected = false; - this.fireEvent('disconnect', this); - } + + eachBox: function(fn, scope) { + Ext.Array.forEach(this.getBoxes(), fn, scope || this); }, - onData: function(opt, success, xhr){ - if(success){ - var events = this.getEvents(xhr); - for(var i = 0, len = events.length; i < len; i++){ - var e = events[i], - t = this.getTransaction(e); - this.fireEvent('data', this, e); - if(t){ - this.doCallback(t, e, true); - Ext.Direct.removeTransaction(t); - } - } - }else{ - var ts = [].concat(opt.ts); - for(var i = 0, len = ts.length; i < len; i++){ - var t = this.getTransaction(ts[i]); - if(t && t.retryCount < this.maxRetries){ - t.retry(); - }else{ - var e = new Ext.Direct.ExceptionEvent({ - data: e, - transaction: t, - code: Ext.Direct.exceptions.TRANSPORT, - message: 'Unable to connect to the server.', - xhr: xhr - }); - this.fireEvent('data', this, e); - if(t){ - this.doCallback(t, e, false); - Ext.Direct.removeTransaction(t); - } - } - } - } + + getChecked: function() { + return Ext.Array.filter(this.getBoxes(), function(cb) { + return cb.getValue(); + }); }, - getCallData: function(t){ - return { - action: t.action, - method: t.method, - data: t.data, - type: 'rpc', - tid: t.tid - }; + + isDirty: function(){ + return Ext.Array.some(this.getBoxes(), function(cb) { + return cb.isDirty(); + }); }, - doSend : function(data){ - var o = { - url: this.url, - callback: this.onData, - scope: this, - ts: data, - timeout: this.timeout - }, callData; - - if(Ext.isArray(data)){ - callData = []; - for(var i = 0, len = data.length; i < len; i++){ - callData.push(this.getCallData(data[i])); - } - }else{ - callData = this.getCallData(data); - } - - if(this.enableUrlEncode){ - var params = {}; - params[Ext.isString(this.enableUrlEncode) ? this.enableUrlEncode : 'data'] = Ext.encode(callData); - o.params = params; - }else{ - o.jsonData = callData; - } - Ext.Ajax.request(o); + + setReadOnly: function(readOnly) { + this.eachBox(function(cb) { + cb.setReadOnly(readOnly); + }); + this.readOnly = readOnly; }, - combineAndSend : function(){ - var len = this.callBuffer.length; - if(len > 0){ - this.doSend(len == 1 ? this.callBuffer[0] : this.callBuffer); - this.callBuffer = []; + + reset: function() { + var me = this, + hadError = me.hasActiveError(), + preventMark = me.preventMark; + me.preventMark = true; + me.batchChanges(function() { + me.eachBox(function(cb) { + cb.reset(); + }); + }); + me.preventMark = preventMark; + me.unsetActiveError(); + if (hadError) { + me.doComponentLayout(); } }, - queueTransaction: function(t){ - if(t.form){ - this.processForm(t); - return; - } - this.callBuffer.push(t); - if(this.enableBuffer){ - if(!this.callTask){ - this.callTask = new Ext.util.DelayedTask(this.combineAndSend, this); - } - this.callTask.delay(Ext.isNumber(this.enableBuffer) ? this.enableBuffer : 10); - }else{ - this.combineAndSend(); - } + + resetOriginalValue: function() { + + + Ext.defer(function() { + this.callParent(); + }, 1, this); }, - doCall : function(c, m, args){ - var data = null, hs = args[m.len], scope = args[m.len+1]; - if(m.len !== 0){ - data = args.slice(0, m.len); - } - - var t = new Ext.Direct.Transaction({ - provider: this, - args: args, - action: c, - method: m.name, - data: data, - cb: scope && Ext.isFunction(hs) ? hs.createDelegate(scope) : hs + + setValue: function(value) { + var me = this; + me.batchChanges(function() { + me.eachBox(function(cb) { + var name = cb.getName(), + cbValue = false; + if (value && name in value) { + if (Ext.isArray(value[name])) { + cbValue = Ext.Array.contains(value[name], cb.inputValue); + } else { + + cbValue = value[name]; + } + } + cb.setValue(cbValue); + }); }); - - if(this.fireEvent('beforecall', this, t, m) !== false){ - Ext.Direct.addTransaction(t); - this.queueTransaction(t); - this.fireEvent('call', this, t, m); - } + return me; }, - doForm : function(c, m, form, callback, scope){ - var t = new Ext.Direct.Transaction({ - provider: this, - action: c, - method: m.name, - args:[form, callback, scope], - cb: scope && Ext.isFunction(callback) ? callback.createDelegate(scope) : callback, - isForm: true - }); - if(this.fireEvent('beforecall', this, t, m) !== false){ - Ext.Direct.addTransaction(t); - var isUpload = String(form.getAttribute("enctype")).toLowerCase() == 'multipart/form-data', - params = { - extTID: t.tid, - extAction: c, - extMethod: m.name, - extType: 'rpc', - extUpload: String(isUpload) - }; - - - - Ext.apply(t, { - form: Ext.getDom(form), - isUpload: isUpload, - params: callback && Ext.isObject(callback.params) ? Ext.apply(params, callback.params) : params - }); - this.fireEvent('call', this, t, m); - this.processForm(t); - } - }, - processForm: function(t){ - Ext.Ajax.request({ - url: this.url, - params: t.params, - callback: this.onData, - scope: this, - form: t.form, - isUpload: t.isUpload, - ts: t + getValue: function() { + var values = {}; + this.eachBox(function(cb) { + var name = cb.getName(), + inputValue = cb.inputValue, + bucket; + if (cb.getValue()) { + if (name in values) { + bucket = values[name]; + if (!Ext.isArray(bucket)) { + bucket = values[name] = [bucket]; + } + bucket.push(inputValue); + } else { + values[name] = inputValue; + } + } }); + return values; }, - createMethod : function(c, m){ - var f; - if(!m.formHandler){ - f = function(){ - this.doCall(c, m, Array.prototype.slice.call(arguments, 0)); - }.createDelegate(this); - }else{ - f = function(form, callback, scope){ - this.doForm(c, m, form, callback, scope); - }.createDelegate(this); - } - f.directCfg = { - action: c, - method: m - }; - return f; + + getSubmitData: function() { + return null; }, - getTransaction: function(opt){ - return opt && opt.tid ? Ext.Direct.getTransaction(opt.tid) : null; + + getModelData: function() { + return null; }, - doCallback: function(t, e){ - var fn = e.status ? 'success' : 'failure'; - if(t && t.cb){ - var hs = t.cb, - result = Ext.isDefined(e.result) ? e.result : e.data; - if(Ext.isFunction(hs)){ - hs(result, e); - } else{ - Ext.callback(hs[fn], hs.scope, [result, e]); - Ext.callback(hs.callback, hs.scope, [result, e]); - } + validate: function() { + var me = this, + errors = me.getErrors(), + isValid = Ext.isEmpty(errors), + wasValid = !me.hasActiveError(); + + if (isValid) { + me.unsetActiveError(); + } else { + me.setActiveError(errors); } + if (isValid !== wasValid) { + me.fireEvent('validitychange', me, isValid); + me.doComponentLayout(); + } + + return isValid; } -}); -Ext.Direct.PROVIDERS['remoting'] = Ext.direct.RemotingProvider; -Ext.Resizable = Ext.extend(Ext.util.Observable, { - constructor: function(el, config){ - this.el = Ext.get(el); - if(config && config.wrap){ - config.resizeChild = this.el; - this.el = this.el.wrap(typeof config.wrap == 'object' ? config.wrap : {cls:'xresizable-wrap'}); - this.el.id = this.el.dom.id = config.resizeChild.id + '-rzwrap'; - this.el.setStyle('overflow', 'hidden'); - this.el.setPositioning(config.resizeChild.getPositioning()); - config.resizeChild.clearPositioning(); - if(!config.width || !config.height){ - var csize = config.resizeChild.getSize(); - this.el.setSize(csize.width, csize.height); - } - if(config.pinned && !config.adjustments){ - config.adjustments = 'auto'; - } - } +}, function() { - - this.proxy = this.el.createProxy({tag: 'div', cls: 'x-resizable-proxy', id: this.el.id + '-rzproxy'}, Ext.getBody()); - this.proxy.unselectable(); - this.proxy.enableDisplayMode('block'); + this.borrow(Ext.form.field.Base, ['markInvalid', 'clearInvalid']); - Ext.apply(this, config); +}); - if(this.pinned){ - this.disableTrackOver = true; - this.el.addClass('x-resizable-pinned'); - } - - var position = this.el.getStyle('position'); - if(position != 'absolute' && position != 'fixed'){ - this.el.setStyle('position', 'relative'); - } - if(!this.handles){ - this.handles = 's,e,se'; - if(this.multiDirectional){ - this.handles += ',n,w'; - } - } - if(this.handles == 'all'){ - this.handles = 'n s e w ne nw se sw'; - } - var hs = this.handles.split(/\s*?[,;]\s*?| /); - var ps = Ext.Resizable.positions; - for(var i = 0, len = hs.length; i < len; i++){ - if(hs[i] && ps[hs[i]]){ - var pos = ps[hs[i]]; - this[pos] = new Ext.Resizable.Handle(this, pos, this.disableTrackOver, this.transparent, this.handleCls); - } - } - - this.corner = this.southeast; - if(this.handles.indexOf('n') != -1 || this.handles.indexOf('w') != -1){ - this.updateBox = true; - } - this.activeHandle = null; +Ext.define('Ext.form.CheckboxManager', { + extend: 'Ext.util.MixedCollection', + singleton: true, - if(this.resizeChild){ - if(typeof this.resizeChild == 'boolean'){ - this.resizeChild = Ext.get(this.el.dom.firstChild, true); - }else{ - this.resizeChild = Ext.get(this.resizeChild, true); - } - } + getByName: function(name) { + return this.filterBy(function(item) { + return item.name == name; + }); + }, - if(this.adjustments == 'auto'){ - var rc = this.resizeChild; - var hw = this.west, he = this.east, hn = this.north, hs = this.south; - if(rc && (hw || hn)){ - rc.position('relative'); - rc.setLeft(hw ? hw.el.getWidth() : 0); - rc.setTop(hn ? hn.el.getHeight() : 0); - } - this.adjustments = [ - (he ? -he.el.getWidth() : 0) + (hw ? -hw.el.getWidth() : 0), - (hn ? -hn.el.getHeight() : 0) + (hs ? -hs.el.getHeight() : 0) -1 - ]; - } + getWithValue: function(name, value) { + return this.filterBy(function(item) { + return item.name == name && item.inputValue == value; + }); + }, - if(this.draggable){ - this.dd = this.dynamic ? - this.el.initDD(null) : this.el.initDDProxy(null, {dragElId: this.proxy.id}); - this.dd.setHandleElId(this.resizeChild ? this.resizeChild.id : this.el.id); - if(this.constrainTo){ - this.dd.constrainTo(this.constrainTo); - } - } + getChecked: function(name) { + return this.filterBy(function(item) { + return item.name == name && item.checked; + }); + } +}); - this.addEvents( - - 'beforeresize', - - 'resize' - ); - if(this.width !== null && this.height !== null){ - this.resizeTo(this.width, this.height); - }else{ - this.updateChildSize(); - } - if(Ext.isIE){ - this.el.dom.style.zoom = 1; - } - Ext.Resizable.superclass.constructor.call(this); - }, +Ext.define('Ext.form.FieldSet', { + extend: 'Ext.container.Container', + alias: 'widget.fieldset', + uses: ['Ext.form.field.Checkbox', 'Ext.panel.Tool', 'Ext.layout.container.Anchor', 'Ext.layout.component.FieldSet'], - adjustments : [0, 0], - - animate : false, - - - disableTrackOver : false, - - draggable: false, - - duration : 0.35, - - dynamic : false, - - easing : 'easeOutStrong', - - enabled : true, - - - handles : false, - - multiDirectional : false, - - height : null, - - width : null, - - heightIncrement : 0, - - widthIncrement : 0, - - minHeight : 5, - - minWidth : 5, - - maxHeight : 10000, - - maxWidth : 10000, - - minX: 0, - - minY: 0, + - pinned : false, + - preserveRatio : false, + - resizeChild : false, + - transparent: false, + collapsed: false, + + + baseCls: Ext.baseCSSPrefix + 'fieldset', + + layout: 'anchor', + componentLayout: 'fieldset', - resizeTo : function(width, height){ - this.el.setSize(width, height); - this.updateChildSize(); - this.fireEvent('resize', this, width, height, null); - }, + ariaRole: '', + renderTpl: ['
    '], - startSizing : function(e, handle){ - this.fireEvent('beforeresize', this, e); - if(this.enabled){ + maskOnDisable: false, - if(!this.overlay){ - this.overlay = this.el.createProxy({tag: 'div', cls: 'x-resizable-overlay', html: ' '}, Ext.getBody()); - this.overlay.unselectable(); - this.overlay.enableDisplayMode('block'); - this.overlay.on({ - scope: this, - mousemove: this.onMouseMove, - mouseup: this.onMouseUp - }); - } - this.overlay.setStyle('cursor', handle.el.getStyle('cursor')); + getElConfig: function(){ + return {tag: 'fieldset', id: this.id}; + }, - this.resizing = true; - this.startBox = this.el.getBox(); - this.startPoint = e.getXY(); - this.offsets = [(this.startBox.x + this.startBox.width) - this.startPoint[0], - (this.startBox.y + this.startBox.height) - this.startPoint[1]]; + initComponent: function() { + var me = this, + baseCls = me.baseCls; - this.overlay.setSize(Ext.lib.Dom.getViewWidth(true), Ext.lib.Dom.getViewHeight(true)); - this.overlay.show(); + me.callParent(); - if(this.constrainTo) { - var ct = Ext.get(this.constrainTo); - this.resizeRegion = ct.getRegion().adjust( - ct.getFrameWidth('t'), - ct.getFrameWidth('l'), - -ct.getFrameWidth('b'), - -ct.getFrameWidth('r') - ); - } + + me.initLegend(); - this.proxy.setStyle('visibility', 'hidden'); - this.proxy.show(); - this.proxy.setBox(this.startBox); - if(!this.dynamic){ - this.proxy.setStyle('visibility', 'visible'); - } - } - }, + + Ext.applyIf(me.renderSelectors, { + body: '.' + baseCls + '-body' + }); - - onMouseDown : function(handle, e){ - if(this.enabled){ - e.stopEvent(); - this.activeHandle = handle; - this.startSizing(e, handle); + if (me.collapsed) { + me.addCls(baseCls + '-collapsed'); + me.collapse(); } }, - onMouseUp : function(e){ - this.activeHandle = null; - var size = this.resizeElement(); - this.resizing = false; - this.handleOut(); - this.overlay.hide(); - this.proxy.hide(); - this.fireEvent('resize', this, size.width, size.height, e); + onRender: function(container, position) { + this.callParent(arguments); + + this.initLegend(); }, - updateChildSize : function(){ - if(this.resizeChild){ - var el = this.el; - var child = this.resizeChild; - var adj = this.adjustments; - if(el.dom.offsetWidth){ - var b = el.getSize(true); - child.setSize(b.width+adj[0], b.height+adj[1]); - } - - + initLegend: function() { + var me = this, + legendItems, + legend = me.legend; + + + if (!legend && (me.title || me.checkboxToggle || me.collapsible)) { + legendItems = []; + + if (me.checkboxToggle) { + legendItems.push(me.createCheckboxCmp()); + } - if(Ext.isIE){ - setTimeout(function(){ - if(el.dom.offsetWidth){ - var b = el.getSize(true); - child.setSize(b.width+adj[0], b.height+adj[1]); - } - }, 10); + else if (me.collapsible) { + legendItems.push(me.createToggleCmp()); } - } - }, - - snap : function(value, inc, min){ - if(!inc || !value){ - return value; - } - var newValue = value; - var m = value % inc; - if(m > 0){ - if(m > (inc/2)){ - newValue = value + (inc-m); - }else{ - newValue = value - m; - } - } - return Math.max(min, newValue); - }, + + legendItems.push(me.createTitleCmp()); - - resizeElement : function(){ - var box = this.proxy.getBox(); - if(this.updateBox){ - this.el.setBox(box, false, this.animate, this.duration, null, this.easing); - }else{ - this.el.setSize(box.width, box.height, this.animate, this.duration, null, this.easing); - } - this.updateChildSize(); - if(!this.dynamic){ - this.proxy.hide(); + legend = me.legend = Ext.create('Ext.container.Container', { + baseCls: me.baseCls + '-header', + ariaRole: '', + getElConfig: function(){ + return {tag: 'legend', cls: this.baseCls}; + }, + items: legendItems + }); } - if(this.draggable && this.constrainTo){ - this.dd.resetConstraints(); - this.dd.constrainTo(this.constrainTo); + + + if (legend && !legend.rendered && me.rendered) { + me.legend.render(me.el, me.body); } - return box; }, - constrain : function(v, diff, m, mx){ - if(v - diff < m){ - diff = v - m; - }else if(v - diff > mx){ - diff = v - mx; - } - return diff; + createTitleCmp: function() { + var me = this; + me.titleCmp = Ext.create('Ext.Component', { + html: me.title, + cls: me.baseCls + '-header-text' + }); + return me.titleCmp; + }, - onMouseMove : function(e){ - if(this.enabled && this.activeHandle){ - try{ - - if(this.resizeRegion && !this.resizeRegion.contains(e.getPoint())) { - return; - } + + createCheckboxCmp: function() { + var me = this, + suffix = '-checkbox'; - var curSize = this.curSize || this.startBox, - x = this.startBox.x, y = this.startBox.y, - ox = x, - oy = y, - w = curSize.width, - h = curSize.height, - ow = w, - oh = h, - mw = this.minWidth, - mh = this.minHeight, - mxw = this.maxWidth, - mxh = this.maxHeight, - wi = this.widthIncrement, - hi = this.heightIncrement, - eventXY = e.getXY(), - diffX = -(this.startPoint[0] - Math.max(this.minX, eventXY[0])), - diffY = -(this.startPoint[1] - Math.max(this.minY, eventXY[1])), - pos = this.activeHandle.position, - tw, - th; - - switch(pos){ - case 'east': - w += diffX; - w = Math.min(Math.max(mw, w), mxw); - break; - case 'south': - h += diffY; - h = Math.min(Math.max(mh, h), mxh); - break; - case 'southeast': - w += diffX; - h += diffY; - w = Math.min(Math.max(mw, w), mxw); - h = Math.min(Math.max(mh, h), mxh); - break; - case 'north': - diffY = this.constrain(h, diffY, mh, mxh); - y += diffY; - h -= diffY; - break; - case 'west': - diffX = this.constrain(w, diffX, mw, mxw); - x += diffX; - w -= diffX; - break; - case 'northeast': - w += diffX; - w = Math.min(Math.max(mw, w), mxw); - diffY = this.constrain(h, diffY, mh, mxh); - y += diffY; - h -= diffY; - break; - case 'northwest': - diffX = this.constrain(w, diffX, mw, mxw); - diffY = this.constrain(h, diffY, mh, mxh); - y += diffY; - h -= diffY; - x += diffX; - w -= diffX; - break; - case 'southwest': - diffX = this.constrain(w, diffX, mw, mxw); - h += diffY; - h = Math.min(Math.max(mh, h), mxh); - x += diffX; - w -= diffX; - break; + me.checkboxCmp = Ext.create('Ext.form.field.Checkbox', { + name: me.checkboxName || me.id + suffix, + cls: me.baseCls + '-header' + suffix, + checked: !me.collapsed, + listeners: { + change: me.onCheckChange, + scope: me } + }); + return me.checkboxCmp; + }, - var sw = this.snap(w, wi, mw); - var sh = this.snap(h, hi, mh); - if(sw != w || sh != h){ - switch(pos){ - case 'northeast': - y -= sh - h; - break; - case 'north': - y -= sh - h; - break; - case 'southwest': - x -= sw - w; - break; - case 'west': - x -= sw - w; - break; - case 'northwest': - x -= sw - w; - y -= sh - h; - break; - } - w = sw; - h = sh; - } - - if(this.preserveRatio){ - switch(pos){ - case 'southeast': - case 'east': - h = oh * (w/ow); - h = Math.min(Math.max(mh, h), mxh); - w = ow * (h/oh); - break; - case 'south': - w = ow * (h/oh); - w = Math.min(Math.max(mw, w), mxw); - h = oh * (w/ow); - break; - case 'northeast': - w = ow * (h/oh); - w = Math.min(Math.max(mw, w), mxw); - h = oh * (w/ow); - break; - case 'north': - tw = w; - w = ow * (h/oh); - w = Math.min(Math.max(mw, w), mxw); - h = oh * (w/ow); - x += (tw - w) / 2; - break; - case 'southwest': - h = oh * (w/ow); - h = Math.min(Math.max(mh, h), mxh); - tw = w; - w = ow * (h/oh); - x += tw - w; - break; - case 'west': - th = h; - h = oh * (w/ow); - h = Math.min(Math.max(mh, h), mxh); - y += (th - h) / 2; - tw = w; - w = ow * (h/oh); - x += tw - w; - break; - case 'northwest': - tw = w; - th = h; - h = oh * (w/ow); - h = Math.min(Math.max(mh, h), mxh); - w = ow * (h/oh); - y += th - h; - x += tw - w; - break; + - } - } - this.proxy.setBounds(x, y, w, h); - if(this.dynamic){ - this.resizeElement(); + + createToggleCmp: function() { + var me = this; + me.toggleCmp = Ext.create('Ext.panel.Tool', { + type: 'toggle', + handler: me.toggle, + scope: me + }); + return me.toggleCmp; + }, + + + setTitle: function(title) { + var me = this; + me.title = title; + me.initLegend(); + 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), + legend = this.legend; + + + if (legend) { + refItems.unshift(legend); + if (deep) { + refItems.unshift.apply(refItems, legend.getRefItems(true)); } - }catch(ex){} } + return refItems; }, - handleOver : function(){ - if(this.enabled){ - this.el.addClass('x-resizable-over'); - } + expand : function(){ + return this.setExpanded(true); }, - - handleOut : function(){ - if(!this.resizing){ - this.el.removeClass('x-resizable-over'); - } + + collapse : function() { + return this.setExpanded(false); }, - getEl : function(){ - return this.el; + setExpanded: function(expanded) { + var me = this, + checkboxCmp = me.checkboxCmp, + toggleCmp = me.toggleCmp; + + expanded = !!expanded; + + if (checkboxCmp) { + checkboxCmp.setValue(expanded); + } + + if (expanded) { + me.removeCls(me.baseCls + '-collapsed'); + } else { + me.addCls(me.baseCls + '-collapsed'); + } + me.collapsed = !expanded; + me.doComponentLayout(); + return me; }, - getResizeChild : function(){ - return this.resizeChild; + toggle: function() { + this.setExpanded(!!this.collapsed); }, - destroy : function(removeEl){ - Ext.destroy(this.dd, this.overlay, this.proxy); - this.overlay = null; - this.proxy = null; - - var ps = Ext.Resizable.positions; - for(var k in ps){ - if(typeof ps[k] != 'function' && this[ps[k]]){ - this[ps[k]].destroy(); - } - } - if(removeEl){ - this.el.update(''); - Ext.destroy(this.el); - this.el = null; - } - this.purgeListeners(); + onCheckChange: function(cmp, checked) { + this.setExpanded(checked); }, - syncHandleHeight : function(){ - var h = this.el.getHeight(true); - if(this.west){ - this.west.el.setHeight(h); - } - if(this.east){ - this.east.el.setHeight(h); + beforeDestroy : function() { + var legend = this.legend; + if (legend) { + legend.destroy(); } + this.callParent(); } }); - -Ext.Resizable.positions = { - n: 'north', s: 'south', e: 'east', w: 'west', se: 'southeast', sw: 'southwest', nw: 'northwest', ne: 'northeast' -}; - -Ext.Resizable.Handle = Ext.extend(Object, { - constructor : function(rz, pos, disableTrackOver, transparent, cls){ - if(!this.tpl){ - - var tpl = Ext.DomHelper.createTemplate( - {tag: 'div', cls: 'x-resizable-handle x-resizable-handle-{0}'} - ); - tpl.compile(); - Ext.Resizable.Handle.prototype.tpl = tpl; - } - this.position = pos; - this.rz = rz; - this.el = this.tpl.append(rz.el.dom, [this.position], true); - this.el.unselectable(); - if(transparent){ - this.el.setOpacity(0); - } - if(!Ext.isEmpty(cls)){ - this.el.addClass(cls); - } - this.el.on('mousedown', this.onMouseDown, this); - if(!disableTrackOver){ - this.el.on({ - scope: this, - mouseover: this.onMouseOver, - mouseout: this.onMouseOut - }); - } - }, +Ext.define('Ext.form.Label', { + extend:'Ext.Component', + alias: 'widget.label', + requires: ['Ext.util.Format'], - afterResize : function(rz){ - - }, - onMouseDown : function(e){ - this.rz.onMouseDown(this, e); - }, - onMouseOver : function(e){ - this.rz.handleOver(this, e); - }, - onMouseOut : function(e){ - this.rz.handleOut(this, e); + maskOnDisable: false, + getElConfig: function(){ + var me = this; + return { + tag: 'label', + id: me.id, + htmlFor: me.forId || '', + html: me.text ? Ext.util.Format.htmlEncode(me.text) : (me.html || '') + }; }, + - destroy : function(){ - Ext.destroy(this.el); - this.el = null; + setText : function(text, encode){ + var me = this; + + encode = encode !== false; + if(encode) { + me.text = text; + delete me.html; + } else { + me.html = text; + delete me.text; + } + + if(me.rendered){ + me.el.dom.innerHTML = encode !== false ? Ext.util.Format.htmlEncode(text) : text; + } + return this; } }); -Ext.Window = Ext.extend(Ext.Panel, { - - - - - - - - - - + + +Ext.define('Ext.form.Panel', { + extend:'Ext.panel.Panel', + mixins: { + fieldAncestor: 'Ext.form.FieldAncestor' + }, + alias: 'widget.form', + alternateClassName: ['Ext.FormPanel', 'Ext.form.FormPanel'], + requires: ['Ext.form.Basic', 'Ext.util.TaskRunner'], - baseCls : 'x-window', - - resizable : true, - - draggable : true, + - closable : true, + - closeAction : 'close', + layout: 'anchor', + + ariaRole: 'form', + + initComponent: function() { + var me = this; + + if (me.frame) { + me.border = false; + } + + me.initFieldAncestor(); + me.callParent(); + + me.relayEvents(me.form, [ + 'beforeaction', + 'actionfailed', + 'actioncomplete', + 'validitychange', + 'dirtychange' + ]); + + + if (me.pollForChanges) { + me.startPolling(me.pollInterval || 500); + } + }, + + initItems: function() { + + var me = this; + + me.form = me.createForm(); + me.callParent(); + me.form.initialize(); + }, + - constrain : false, + createForm: function() { + return Ext.create('Ext.form.Basic', this, Ext.applyIf({listeners: {}}, this.initialConfig)); + }, + - constrainHeader : false, + getForm: function() { + return this.form; + }, - plain : false, - minimizable : false, + loadRecord: function(record) { + return this.getForm().loadRecord(record); + }, - maximizable : false, - minHeight : 100, + getRecord: function() { + return this.getForm().getRecord(); + }, - minWidth : 200, - expandOnShow : true, + getValues: function() { + return this.getForm().getValues(); + }, + + beforeDestroy: function() { + this.stopPolling(); + this.form.destroy(); + this.callParent(); + }, + + load: function(options) { + this.form.load(options); + }, + - showAnimDuration: 0.25, + submit: function(options) { + this.form.submit(options); + }, + + disable: function(silent) { + this.callParent(arguments); + this.form.getFields().each(function(field) { + field.disable(); + }); + }, + - hideAnimDuration: 0.25, + enable: function(silent) { + this.callParent(arguments); + this.form.getFields().each(function(field) { + field.enable(); + }); + }, - collapsible : false, + startPolling: function(interval) { + this.stopPolling(); + var task = Ext.create('Ext.util.TaskRunner', interval); + task.start({ + interval: 0, + run: this.checkChange, + scope: this + }); + this.pollTask = task; + }, - initHidden : undefined, + stopPolling: function() { + var task = this.pollTask; + if (task) { + task.stopAll(); + delete this.pollTask; + } + }, - hidden : true, + checkChange: function() { + this.form.getFields().each(function(field) { + field.checkChange(); + }); + } +}); + + +Ext.define('Ext.form.RadioGroup', { + extend: 'Ext.form.CheckboxGroup', + alias: 'widget.radiogroup', + allowBlank : true, + blankText : 'You must select one item in this group', - elements : 'header,body', + defaultType : 'radiofield', - frame : true, - floating : true, + groupCls : Ext.baseCSSPrefix + 'form-radio-group', - - initComponent : function(){ - this.initTools(); - Ext.Window.superclass.initComponent.call(this); - this.addEvents( - - - - 'resize', - - 'maximize', - - 'minimize', - - 'restore' - ); - - if(Ext.isDefined(this.initHidden)){ - this.hidden = this.initHidden; - } - if(this.hidden === false){ - this.hidden = true; - this.show(); - } + getBoxes: function() { + return this.query('[isRadio]'); + } + +}); + + +Ext.define('Ext.form.RadioManager', { + extend: 'Ext.util.MixedCollection', + singleton: true, + + getByName: function(name) { + return this.filterBy(function(item) { + return item.name == name; + }); }, - - getState : function(){ - return Ext.apply(Ext.Window.superclass.getState.call(this) || {}, this.getBox(true)); + getWithValue: function(name, value) { + return this.filterBy(function(item) { + return item.name == name && item.inputValue == value; + }); }, - - onRender : function(ct, position){ - Ext.Window.superclass.onRender.call(this, ct, position); + getChecked: function(name) { + return this.findBy(function(item) { + return item.name == name && item.checked; + }); + } +}); - if(this.plain){ - this.el.addClass('x-window-plain'); - } - - this.focusEl = this.el.createChild({ - tag: 'a', href:'#', cls:'x-dlg-focus', - tabIndex:'-1', html: ' '}); - this.focusEl.swallowEvent('click', true); +Ext.define('Ext.form.action.DirectLoad', { + extend:'Ext.form.action.Load', + requires: ['Ext.direct.Manager'], + alternateClassName: 'Ext.form.Action.DirectLoad', + alias: 'formaction.directload', - this.proxy = this.el.createProxy('x-window-proxy'); - this.proxy.enableDisplayMode('block'); + type: 'directload', - if(this.modal){ - this.mask = this.container.createChild({cls:'ext-el-mask'}, this.el.dom); - this.mask.enableDisplayMode('block'); - this.mask.hide(); - this.mon(this.mask, 'click', this.focus, this); - } - if(this.maximizable){ - this.mon(this.header, 'dblclick', this.toggleMaximize, this); - } + run: function() { + this.form.api.load.apply(window, this.getArgs()); }, - initEvents : function(){ - Ext.Window.superclass.initEvents.call(this); - if(this.animateTarget){ - this.setAnimateTarget(this.animateTarget); - } - - if(this.resizable){ - this.resizer = new Ext.Resizable(this.el, { - minWidth: this.minWidth, - minHeight:this.minHeight, - handles: this.resizeHandles || 'all', - pinned: true, - resizeElement : this.resizerAction, - handleCls: 'x-window-handle' - }); - this.resizer.window = this; - this.mon(this.resizer, 'beforeresize', this.beforeResize, this); - } + getArgs: function() { + var me = this, + args = [], + form = me.form, + paramOrder = form.paramOrder, + params = me.getParams(), + i, len; - if(this.draggable){ - this.header.addClass('x-window-draggable'); - } - this.mon(this.el, 'mousedown', this.toFront, this); - this.manager = this.manager || Ext.WindowMgr; - this.manager.register(this); - if(this.maximized){ - this.maximized = false; - this.maximize(); + + if (paramOrder) { + for (i = 0, len = paramOrder.length; i < len; i++) { + args.push(params[paramOrder[i]]); + } } - if(this.closable){ - var km = this.getKeyMap(); - km.on(27, this.onEsc, this); - km.disable(); + + else if (form.paramsAsHash) { + args.push(params); } - }, - initDraggable : function(){ - this.dd = new Ext.Window.DD(this); - }, + args.push(me.onSuccess, me); - - onEsc : function(k, e){ - e.stopEvent(); - this[this.closeAction](); + return args; }, - beforeDestroy : function(){ - if(this.rendered){ - this.hide(); - this.clearAnchor(); - Ext.destroy( - this.focusEl, - this.resizer, - this.dd, - this.proxy, - this.mask - ); - } - Ext.Window.superclass.beforeDestroy.call(this); - }, - - onDestroy : function(){ - if(this.manager){ - this.manager.unregister(this); - } - Ext.Window.superclass.onDestroy.call(this); + + processResponse: function(result) { + return (this.result = result); }, - - initTools : function(){ - if(this.minimizable){ - this.addTool({ - id: 'minimize', - handler: this.minimize.createDelegate(this, []) - }); - } - if(this.maximizable){ - this.addTool({ - id: 'maximize', - handler: this.maximize.createDelegate(this, []) - }); - this.addTool({ - id: 'restore', - handler: this.restore.createDelegate(this, []), - hidden:true - }); - } - if(this.closable){ - this.addTool({ - id: 'close', - handler: this[this.closeAction].createDelegate(this, []) - }); + onSuccess: function(result, trans) { + if (trans.type == Ext.direct.Manager.self.exceptions.SERVER) { + result = {}; } - }, + this.callParent([result]); + } +}); - - resizerAction : function(){ - var box = this.proxy.getBox(); - this.proxy.hide(); - this.window.handleResize(box); - return box; + + + +Ext.define('Ext.form.action.DirectSubmit', { + extend:'Ext.form.action.Submit', + requires: ['Ext.direct.Manager'], + alternateClassName: 'Ext.form.Action.DirectSubmit', + alias: 'formaction.directsubmit', + + type: 'directsubmit', + + doSubmit: function() { + var me = this, + callback = Ext.Function.bind(me.onSuccess, me), + formEl = me.buildForm(); + me.form.api.submit(formEl, callback, me); + Ext.removeNode(formEl); }, - beforeResize : function(){ - this.resizer.minHeight = Math.max(this.minHeight, this.getFrameHeight() + 40); - this.resizer.minWidth = Math.max(this.minWidth, this.getFrameWidth() + 40); - this.resizeBox = this.el.getBox(); + + + processResponse: function(result) { + return (this.result = result); }, - - updateHandles : function(){ - if(Ext.isIE && this.resizer){ - this.resizer.syncHandleHeight(); - this.el.repaint(); + onSuccess: function(response, trans) { + if (trans.type === Ext.direct.Manager.self.exceptions.SERVER) { + response = {}; } - }, + this.callParent([response]); + } +}); + + +Ext.define('Ext.form.action.StandardSubmit', { + extend:'Ext.form.action.Submit', + alias: 'formaction.standardsubmit', - handleResize : function(box){ - var rz = this.resizeBox; - if(rz.x != box.x || rz.y != box.y){ - this.updateBox(box); - }else{ - this.setSize(box); - if (Ext.isIE6 && Ext.isStrict) { - this.doLayout(); - } - } - this.focus(); - this.updateHandles(); - this.saveState(); - }, - focus : function(){ - var f = this.focusEl, - db = this.defaultButton, - t = typeof db, - el, - ct; - if(Ext.isDefined(db)){ - if(Ext.isNumber(db) && this.fbar){ - f = this.fbar.items.get(db); - }else if(Ext.isString(db)){ - f = Ext.getCmp(db); - }else{ - f = db; - } - el = f.getEl(); - ct = Ext.getDom(this.container); - if (el && ct) { - if (ct != document.body && !Ext.lib.Region.getRegion(ct).contains(Ext.lib.Region.getRegion(el.dom))){ - return; - } - } + doSubmit: function() { + var form = this.buildForm(); + form.submit(); + Ext.removeNode(form); + } + +}); + + +Ext.define('Ext.form.field.Checkbox', { + extend: 'Ext.form.field.Base', + alias: ['widget.checkboxfield', 'widget.checkbox'], + alternateClassName: 'Ext.form.Checkbox', + requires: ['Ext.XTemplate', 'Ext.form.CheckboxManager'], + + fieldSubTpl: [ + '', + '', + '', + + + + 'tabIndex="{tabIdx}" ', + 'class="{fieldCls} {typeCls}" autocomplete="off" hidefocus="true" />', + '', + '', + '', + { + disableFormats: true, + compiled: true } - f = f || this.focusEl; - f.focus.defer(10, f); - }, + ], + + isCheckbox: true, - setAnimateTarget : function(el){ - el = Ext.get(el); - this.animateTarget = el; - }, + focusCls: Ext.baseCSSPrefix + 'form-cb-focus', - beforeShow : function(){ - delete this.el.lastXY; - delete this.el.lastLT; - if(this.x === undefined || this.y === undefined){ - var xy = this.el.getAlignToXY(this.container, 'c-c'); - var pos = this.el.translatePoints(xy[0], xy[1]); - this.x = this.x === undefined? pos.left : this.x; - this.y = this.y === undefined? pos.top : this.y; - } - this.el.setLeftTop(this.x, this.y); - if(this.expandOnShow){ - this.expand(false); - } + + fieldBodyCls: Ext.baseCSSPrefix + 'form-cb-wrap', - if(this.modal){ - Ext.getBody().addClass('x-body-masked'); - this.mask.setSize(Ext.lib.Dom.getViewWidth(true), Ext.lib.Dom.getViewHeight(true)); - this.mask.show(); - } - }, + + checked: false, - show : function(animateTarget, cb, scope){ - if(!this.rendered){ - this.render(Ext.getBody()); - } - if(this.hidden === false){ - this.toFront(); - return this; - } - if(this.fireEvent('beforeshow', this) === false){ - return this; - } - if(cb){ - this.on('show', cb, scope, {single:true}); - } - this.hidden = false; - if(Ext.isDefined(animateTarget)){ - this.setAnimateTarget(animateTarget); - } - this.beforeShow(); - if(this.animateTarget){ - this.animShow(); - }else{ - this.afterShow(); - } - return this; - }, + checkedCls: Ext.baseCSSPrefix + 'form-cb-checked', - afterShow : function(isAnim){ - if (this.isDestroyed){ - return false; - } - this.proxy.hide(); - this.el.setStyle('display', 'block'); - this.el.show(); - if(this.maximized){ - this.fitContainer(); - } - if(Ext.isMac && Ext.isGecko2){ - this.cascade(this.setAutoScroll); - } - if(this.monitorResize || this.modal || this.constrain || this.constrainHeader){ - Ext.EventManager.onWindowResize(this.onWindowResize, this); - } - this.doConstrain(); - this.doLayout(); - if(this.keyMap){ - this.keyMap.enable(); - } - this.toFront(); - this.updateHandles(); - if(isAnim && (Ext.isIE || Ext.isWebKit)){ - var sz = this.getSize(); - this.onResize(sz.width, sz.height); - } - this.onShow(); - this.fireEvent('show', this); - }, + + boxLabelCls: Ext.baseCSSPrefix + 'form-cb-label', - animShow : function(){ - this.proxy.show(); - this.proxy.setBox(this.animateTarget.getBox()); - this.proxy.setOpacity(0); - var b = this.getBox(); - this.el.setStyle('display', 'none'); - this.proxy.shift(Ext.apply(b, { - callback: this.afterShow.createDelegate(this, [true], false), - scope: this, - easing: 'easeNone', - duration: this.showAnimDuration, - opacity: 0.5 - })); - }, + boxLabelAlign: 'after', - hide : function(animateTarget, cb, scope){ - if(this.hidden || this.fireEvent('beforehide', this) === false){ - return this; - } - if(cb){ - this.on('hide', cb, scope, {single:true}); - } - this.hidden = true; - if(animateTarget !== undefined){ - this.setAnimateTarget(animateTarget); - } - if(this.modal){ - this.mask.hide(); - Ext.getBody().removeClass('x-body-masked'); - } - if(this.animateTarget){ - this.animHide(); - }else{ - this.el.hide(); - this.afterHide(); - } - return this; - }, + inputValue: 'on', - afterHide : function(){ - this.proxy.hide(); - if(this.monitorResize || this.modal || this.constrain || this.constrainHeader){ - Ext.EventManager.removeResizeListener(this.onWindowResize, this); - } - if(this.keyMap){ - this.keyMap.disable(); - } - this.onHide(); - this.fireEvent('hide', this); - }, - animHide : function(){ - this.proxy.setOpacity(0.5); - this.proxy.show(); - var tb = this.getBox(false); - this.proxy.setBox(tb); - this.el.hide(); - this.proxy.shift(Ext.apply(this.animateTarget.getBox(), { - callback: this.afterHide, - scope: this, - duration: this.hideAnimDuration, - easing: 'easeNone', - opacity: 0 - })); - }, - onShow : Ext.emptyFn, - onHide : Ext.emptyFn, + checkChangeEvents: [], + inputType: 'checkbox', + ariaRole: 'checkbox', - onWindowResize : function(){ - if(this.maximized){ - this.fitContainer(); - } - if(this.modal){ - this.mask.setSize('100%', '100%'); - var force = this.mask.dom.offsetHeight; - this.mask.setSize(Ext.lib.Dom.getViewWidth(true), Ext.lib.Dom.getViewHeight(true)); - } - this.doConstrain(); + onRe: /^on$/i, + + initComponent: function(){ + this.callParent(arguments); + this.getManager().add(this); }, - - doConstrain : function(){ - if(this.constrain || this.constrainHeader){ - var offsets; - if(this.constrain){ - offsets = { - right:this.el.shadowOffset, - left:this.el.shadowOffset, - bottom:this.el.shadowOffset - }; - }else { - var s = this.getSize(); - offsets = { - right:-(s.width - 100), - bottom:-(s.height - 25) - }; - } + initValue: function() { + var me = this, + checked = !!me.checked; - var xy = this.el.getConstrainToXY(this.container, true, offsets); - if(xy){ - this.setPosition(xy[0], xy[1]); - } - } + + me.originalValue = me.lastValue = checked; + + + me.setValue(checked); }, - ghost : function(cls){ - var ghost = this.createGhost(cls); - var box = this.getBox(true); - ghost.setLeftTop(box.x, box.y); - ghost.setWidth(box.width); - this.el.hide(); - this.activeGhost = ghost; - return ghost; + onRender : function(ct, position) { + var me = this; + Ext.applyIf(me.renderSelectors, { + + boxLabelEl: 'label.' + me.boxLabelCls + }); + Ext.applyIf(me.subTplData, { + boxLabel: me.boxLabel, + boxLabelCls: me.boxLabelCls, + boxLabelAlign: me.boxLabelAlign + }); + + me.callParent(arguments); + }, + + initEvents: function() { + var me = this; + me.callParent(); + me.mon(me.inputEl, 'click', me.onBoxClick, me); }, - unghost : function(show, matchPosition){ - if(!this.activeGhost) { - return; - } - if(show !== false){ - this.el.show(); - this.focus.defer(10, this); - if(Ext.isMac && Ext.isGecko2){ - this.cascade(this.setAutoScroll); - } - } - if(matchPosition !== false){ - this.setPosition(this.activeGhost.getLeft(true), this.activeGhost.getTop(true)); + onBoxClick: function(e) { + var me = this; + if (!me.disabled && !me.readOnly) { + this.setValue(!this.checked); } - this.activeGhost.hide(); - this.activeGhost.remove(); - delete this.activeGhost; }, - minimize : function(){ - this.fireEvent('minimize', this); - return this; + getRawValue: function() { + return this.checked; }, - close : function(){ - if(this.fireEvent('beforeclose', this) !== false){ - if(this.hidden){ - this.doClose(); - }else{ - this.hide(null, this.doClose, this); - } - } + getValue: function() { + return this.checked; }, - doClose : function(){ - this.fireEvent('close', this); - this.destroy(); + getSubmitValue: function() { + return this.checked ? this.inputValue : (this.uncheckedValue || null); }, - - maximize : function(){ - if(!this.maximized){ - this.expand(false); - this.restoreSize = this.getSize(); - this.restorePos = this.getPosition(true); - if (this.maximizable){ - this.tools.maximize.hide(); - this.tools.restore.show(); - } - this.maximized = true; - this.el.disableShadow(); + getModelData: function() { + return this.getSubmitData(); + }, - if(this.dd){ - this.dd.lock(); - } - if(this.collapsible){ - this.tools.toggle.hide(); - } - this.el.addClass('x-window-maximized'); - this.container.addClass('x-window-maximized-ct'); + + setRawValue: function(value) { + 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))); - this.setPosition(0, 0); - this.fitContainer(); - this.fireEvent('maximize', this); + if (inputEl) { + inputEl.dom.setAttribute('aria-checked', checked); + me[checked ? 'addCls' : 'removeCls'](me.checkedCls); } - return this; + + me.checked = me.rawValue = checked; + return checked; }, - restore : function(){ - if(this.maximized){ - var t = this.tools; - this.el.removeClass('x-window-maximized'); - if(t.restore){ - t.restore.hide(); - } - if(t.maximize){ - t.maximize.show(); - } - this.setPosition(this.restorePos[0], this.restorePos[1]); - this.setSize(this.restoreSize.width, this.restoreSize.height); - delete this.restorePos; - delete this.restoreSize; - this.maximized = false; - this.el.enableShadow(true); - - if(this.dd){ - this.dd.unlock(); - } - if(this.collapsible && t.toggle){ - t.toggle.show(); - } - this.container.removeClass('x-window-maximized-ct'); + setValue: function(checked) { + var me = this; - this.doConstrain(); - this.fireEvent('restore', this); + + + + + if (Ext.isArray(checked)) { + me.getManager().getByName(me.name).each(function(cb) { + cb.setValue(Ext.Array.contains(checked, cb.inputValue)); + }); + } else { + me.callParent(arguments); } - return this; + + return me; }, - toggleMaximize : function(){ - return this[this.maximized ? 'restore' : 'maximize'](); + valueToRaw: function(value) { + + return value; }, - fitContainer : function(){ - var vs = this.container.getViewSize(false); - this.setSize(vs.width, vs.height); + onChange: function(newVal, oldVal) { + var me = this, + handler = me.handler; + if (handler) { + handler.call(me.scope || me, me, newVal); + } + me.callParent(arguments); }, - - setZIndex : function(index){ - if(this.modal){ - this.mask.setStyle('z-index', index); - } - this.el.setZIndex(++index); - index += 5; + getManager: function() { + return Ext.form.CheckboxManager; + }, - if(this.resizer){ - this.resizer.proxy.setStyle('z-index', ++index); + onEnable: function() { + var me = this, + inputEl = me.inputEl; + me.callParent(); + if (inputEl) { + + inputEl.dom.disabled = me.readOnly; } + }, - this.lastZIndex = index; + setReadOnly: function(readOnly) { + var me = this, + inputEl = me.inputEl; + if (inputEl) { + + inputEl.dom.disabled = readOnly || me.disabled; + } + me.readOnly = readOnly; }, - alignTo : function(element, position, offsets){ - var xy = this.el.getAlignToXY(element, position, offsets); - this.setPagePosition(xy[0], xy[1]); - return this; - }, + getBodyNaturalWidth: function() { + var me = this, + bodyEl = me.bodyEl, + ws = 'white-space', + width; + bodyEl.setStyle(ws, 'nowrap'); + width = bodyEl.getWidth(); + bodyEl.setStyle(ws, ''); + return width; + } + +}); + + + +Ext.define('Ext.layout.component.field.Trigger', { - anchorTo : function(el, alignment, offsets, monitorScroll){ - this.clearAnchor(); - this.anchorTarget = { - el: el, - alignment: alignment, - offsets: offsets - }; - Ext.EventManager.onWindowResize(this.doAnchor, this); - var tm = typeof monitorScroll; - if(tm != 'undefined'){ - Ext.EventManager.on(window, 'scroll', this.doAnchor, this, - {buffer: tm == 'number' ? monitorScroll : 50}); - } - return this.doAnchor(); - }, + alias: ['layout.triggerfield'], + + extend: 'Ext.layout.component.field.Field', - doAnchor : function(){ - var o = this.anchorTarget; - this.alignTo(o.el, o.alignment, o.offsets); - return this; - }, + type: 'triggerfield', + + sizeBodyContents: function(width, height) { + var me = this, + owner = me.owner, + inputEl = owner.inputEl, + triggerWrap = owner.triggerWrap, + triggerWidth = owner.getTriggerWidth(); + + + + if (owner.hideTrigger || owner.readOnly || triggerWidth > 0) { + + + me.setElementSize(inputEl, Ext.isNumber(width) ? width - triggerWidth : width); - clearAnchor : function(){ - if(this.anchorTarget){ - Ext.EventManager.removeResizeListener(this.doAnchor, this); - Ext.EventManager.un(window, 'scroll', this.doAnchor, this); - delete this.anchorTarget; + + triggerWrap.setWidth(triggerWidth); } - return this; - }, + } +}); +Ext.define('Ext.view.View', { + extend: 'Ext.view.AbstractView', + alternateClassName: 'Ext.view.View', + alias: 'widget.dataview', - toFront : function(e){ - if(this.manager.bringToFront(this)){ - if(!e || !e.getTarget().focus){ - this.focus(); - } + inheritableStatics: { + EventMap: { + mousedown: 'MouseDown', + mouseup: 'MouseUp', + click: 'Click', + dblclick: 'DblClick', + contextmenu: 'ContextMenu', + mouseover: 'MouseOver', + mouseout: 'MouseOut', + mouseenter: 'MouseEnter', + mouseleave: 'MouseLeave', + keydown: 'KeyDown' } - return this; }, - - setActive : function(active){ - if(active){ - if(!this.maximized){ - this.el.enableShadow(true); - } - this.fireEvent('activate', this); - }else{ - this.el.disableShadow(); - this.fireEvent('deactivate', this); + addCmpEvents: function() { + this.addEvents( + + 'beforeitemmousedown', + + 'beforeitemmouseup', + + 'beforeitemmouseenter', + + 'beforeitemmouseleave', + + 'beforeitemclick', + + 'beforeitemdblclick', + + 'beforeitemcontextmenu', + + 'beforeitemkeydown', + + 'itemmousedown', + + 'itemmouseup', + + 'itemmouseenter', + + 'itemmouseleave', + + 'itemclick', + + 'itemdblclick', + + 'itemcontextmenu', + + 'itemkeydown', + + 'beforecontainermousedown', + + 'beforecontainermouseup', + + 'beforecontainermouseover', + + 'beforecontainermouseout', + + 'beforecontainerclick', + + 'beforecontainerdblclick', + + 'beforecontainercontextmenu', + + 'beforecontainerkeydown', + + 'containermouseup', + + 'containermouseover', + + 'containermouseout', + + 'containerclick', + + 'containerdblclick', + + 'containercontextmenu', + + 'containerkeydown', + + + 'selectionchange', + + 'beforeselect' + ); + }, + + afterRender: function(){ + var me = this, + listeners; + + me.callParent(); + + listeners = { + scope: me, + click: me.handleEvent, + mousedown: me.handleEvent, + mouseup: me.handleEvent, + dblclick: me.handleEvent, + contextmenu: me.handleEvent, + mouseover: me.handleEvent, + mouseout: me.handleEvent, + keydown: me.handleEvent + }; + + me.mon(me.getTargetEl(), listeners); + + if (me.store) { + me.bindStore(me.store, true); } }, - - toBack : function(){ - this.manager.sendToBack(this); - return this; + handleEvent: function(e) { + if (this.processUIEvent(e) !== false) { + this.processSpecialEvent(e); + } }, - - center : function(){ - var xy = this.el.getAlignToXY(this.container, 'c-c'); - this.setPagePosition(xy[0], xy[1]); - return this; - } - -}); -Ext.reg('window', Ext.Window); - - -Ext.Window.DD = Ext.extend(Ext.dd.DD, { + processItemEvent: Ext.emptyFn, + processContainerEvent: Ext.emptyFn, + processSpecialEvent: Ext.emptyFn, + + processUIEvent: function(e, type) { + type = type || e.type; + var me = this, + item = e.getTarget(me.getItemSelector(), me.getTargetEl()), + map = this.statics().EventMap, + index, record; + + 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 == 'keydown') { + record = me.getSelectionModel().getLastSelected(); + if (record) { + item = me.getNode(record); + } + } + } + + if (item) { + index = me.indexOf(item); + if (!record) { + record = me.getRecord(item); + } + + if (me.processItemEvent(type, record, item, index, e) === false) { + return false; + } + + type = me.isNewItemEvent(type, item, e); + if (type === 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) + ) { + return false; + } + + me.fireEvent('item' + type, me, record, item, index, e); + } + else { + if ( + (me.processContainerEvent(type, 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; + }, - constructor : function(win){ - this.win = win; - Ext.Window.DD.superclass.constructor.call(this, win.el.id, 'WindowDD-'+win.id); - this.setHandleElId(win.header.id); - this.scroll = false; + isNewItemEvent: function(type, item, e) { + var me = this, + overItem = me.mouseOverItem, + contains, + isItem; + + switch (type) { + case 'mouseover': + if (item === overItem) { + return false; + } + 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; + } + } + me.mouseOverItem = null; + return 'mouseleave'; + break; + } + return type; }, - moveOnly:true, - headerOffsets:[100, 25], - startDrag : function(){ - var w = this.win; - this.proxy = w.ghost(w.initialConfig.cls); - if(w.constrain !== false){ - var so = w.el.shadowOffset; - this.constrainTo(w.container, {right: so, left: so, bottom: so}); - }else if(w.constrainHeader !== false){ - var s = this.proxy.getSize(); - this.constrainTo(w.container, {right: -(s.width-this.headerOffsets[0]), bottom: -(s.height-this.headerOffsets[1])}); + + onItemMouseEnter: function(record, item, index, e) { + if (this.trackOver) { + this.highlightItem(item); } }, - b4Drag : Ext.emptyFn, - onDrag : function(e){ - this.alignElWithMouse(this.proxy, e.getPageX(), e.getPageY()); + + onItemMouseLeave : function(record, item, index, e) { + if (this.trackOver) { + this.clearHighlight(); + } }, - endDrag : function(e){ - this.win.unghost(); - this.win.saveState(); - } -}); - -Ext.WindowGroup = function(){ - var list = {}; - var accessList = []; - var front = null; - - var sortWindows = function(d1, d2){ - return (!d1._lastAccess || d1._lastAccess < d2._lastAccess) ? -1 : 1; - }; - + onItemMouseDown: Ext.emptyFn, + onItemMouseUp: Ext.emptyFn, + onItemClick: Ext.emptyFn, + onItemDblClick: Ext.emptyFn, + onItemContextMenu: Ext.emptyFn, + onItemKeyDown: Ext.emptyFn, + onBeforeItemMouseDown: Ext.emptyFn, + onBeforeItemMouseUp: Ext.emptyFn, + onBeforeItemMouseEnter: Ext.emptyFn, + onBeforeItemMouseLeave: Ext.emptyFn, + onBeforeItemClick: Ext.emptyFn, + onBeforeItemDblClick: Ext.emptyFn, + onBeforeItemContextMenu: Ext.emptyFn, + onBeforeItemKeyDown: Ext.emptyFn, - var orderWindows = function(){ - var a = accessList, len = a.length; - if(len > 0){ - a.sort(sortWindows); - var seed = a[0].manager.zseed; - for(var i = 0; i < len; i++){ - var win = a[i]; - if(win && !win.hidden){ - win.setZIndex(seed + (i*10)); - } - } - } - activateLast(); - }; - - var setActiveWin = function(win){ - if(win != front){ - if(front){ - front.setActive(false); - } - front = win; - if(win){ - win.setActive(true); - } - } - }; + onContainerMouseDown: Ext.emptyFn, + onContainerMouseUp: Ext.emptyFn, + onContainerMouseOver: Ext.emptyFn, + onContainerMouseOut: Ext.emptyFn, + onContainerClick: Ext.emptyFn, + onContainerDblClick: Ext.emptyFn, + onContainerContextMenu: Ext.emptyFn, + onContainerKeyDown: Ext.emptyFn, + onBeforeContainerMouseDown: Ext.emptyFn, + onBeforeContainerMouseUp: Ext.emptyFn, + onBeforeContainerMouseOver: Ext.emptyFn, + onBeforeContainerMouseOut: Ext.emptyFn, + onBeforeContainerClick: Ext.emptyFn, + onBeforeContainerDblClick: Ext.emptyFn, + onBeforeContainerContextMenu: Ext.emptyFn, + onBeforeContainerKeyDown: Ext.emptyFn, + + + highlightItem: function(item) { + var me = this; + me.clearHighlight(); + me.highlightedItem = item; + Ext.fly(item).addCls(me.overItemCls); + }, - var activateLast = function(){ - for(var i = accessList.length-1; i >=0; --i) { - if(!accessList[i].hidden){ - setActiveWin(accessList[i]); - return; - } + clearHighlight: function() { + var me = this, + highlighted = me.highlightedItem; + + if (highlighted) { + Ext.fly(highlighted).removeCls(me.overItemCls); + delete me.highlightedItem; } - - setActiveWin(null); - }; + }, - return { - - zseed : 9000, + refresh: function() { + this.clearHighlight(); + this.callParent(arguments); + } +}); - - register : function(win){ - if(win.manager){ - win.manager.unregister(win); - } - win.manager = this; +Ext.define('Ext.layout.component.BoundList', { + extend: 'Ext.layout.component.Component', + alias: 'layout.boundlist', - list[win.id] = win; - accessList.push(win); - win.on('hide', activateLast); - }, + type: 'component', - - unregister : function(win){ - delete win.manager; - delete list[win.id]; - win.un('hide', activateLast); - accessList.remove(win); - }, + beforeLayout: function() { + return this.callParent(arguments) || this.owner.refreshed > 0; + }, - - get : function(id){ - return typeof id == "object" ? id : list[id]; - }, + onLayout : function(width, height) { + var me = this, + owner = me.owner, + floating = owner.floating, + el = owner.el, + xy = el.getXY(), + isNumber = Ext.isNumber, + minWidth, maxWidth, minHeight, maxHeight, + naturalWidth, naturalHeight, constrainedWidth, constrainedHeight, undef; - - bringToFront : function(win){ - win = this.get(win); - if(win != front){ - win._lastAccess = new Date().getTime(); - orderWindows(); - return true; - } - return false; - }, + if (floating) { + + el.setXY([-9999,-9999]); + } - sendToBack : function(win){ - win = this.get(win); - win._lastAccess = -(new Date().getTime()); - orderWindows(); - return win; - }, + me.setTargetSize(width, height); - hideAll : function(){ - for(var id in list){ - if(list[id] && typeof list[id] != "function" && list[id].isVisible()){ - list[id].hide(); + if (!isNumber(width)) { + minWidth = owner.minWidth; + maxWidth = owner.maxWidth; + if (isNumber(minWidth) || isNumber(maxWidth)) { + naturalWidth = el.getWidth(); + if (naturalWidth < minWidth) { + constrainedWidth = minWidth; + } + else if (naturalWidth > maxWidth) { + constrainedWidth = maxWidth; + } + if (constrainedWidth) { + me.setTargetSize(constrainedWidth); } } - }, - - - getActive : function(){ - return front; - }, - + } - getBy : function(fn, scope){ - var r = []; - for(var i = accessList.length-1; i >=0; --i) { - var win = accessList[i]; - if(fn.call(scope||win, win) !== false){ - r.push(win); + if (!isNumber(height)) { + minHeight = owner.minHeight; + maxHeight = owner.maxHeight; + if (isNumber(minHeight) || isNumber(maxHeight)) { + naturalHeight = el.getHeight(); + if (naturalHeight < minHeight) { + constrainedHeight = minHeight; + } + else if (naturalHeight > maxHeight) { + constrainedHeight = maxHeight; + } + if (constrainedHeight) { + me.setTargetSize(undef, constrainedHeight); } } - return r; - }, + } + + if (floating) { + + el.setXY(xy); + } + }, + + afterLayout: function() { + var me = this, + toolbar = me.owner.pagingToolbar; + me.callParent(); + if (toolbar) { + toolbar.doComponentLayout(); + } + }, + + setTargetSize : function(width, height) { + var me = this, + owner = me.owner, + listHeight = null, + toolbar; - each : function(fn, scope){ - for(var id in list){ - if(list[id] && typeof list[id] != "function"){ - if(fn.call(scope || list[id], list[id]) === false){ - return; - } - } + if (Ext.isNumber(height)) { + listHeight = height - owner.el.getFrameWidth('tb'); + toolbar = owner.pagingToolbar; + if (toolbar) { + listHeight -= toolbar.getHeight(); } } - }; -}; + me.setElementSize(owner.listEl, null, listHeight); + me.callParent(arguments); + } +}); -Ext.WindowMgr = new Ext.WindowGroup(); -Ext.MessageBox = function(){ - var dlg, opt, mask, waitTimer, - bodyEl, msgEl, textboxEl, textareaEl, progressBar, pp, iconEl, spacerEl, - buttons, activeTextEl, bwidth, bufferIcon = '', iconCls = '', - buttonNames = ['ok', 'yes', 'no', 'cancel']; +Ext.define('Ext.toolbar.TextItem', { + extend: 'Ext.toolbar.Item', + requires: ['Ext.XTemplate'], + alias: 'widget.tbtext', + alternateClassName: 'Ext.Toolbar.TextItem', - var handleButton = function(button){ - buttons[button].blur(); - if(dlg.isVisible()){ - dlg.hide(); - handleHide(); - Ext.callback(opt.fn, opt.scope||window, [button, activeTextEl.dom.value, opt], 1); - } - }; - - var handleHide = function(){ - if(opt && opt.cls){ - dlg.el.removeClass(opt.cls); - } - progressBar.reset(); - }; + text: '', + + renderTpl: '{text}', + + baseCls: Ext.baseCSSPrefix + 'toolbar-text', + + onRender : function() { + Ext.apply(this.renderData, { + text: this.text + }); + this.callParent(arguments); + }, - var handleEsc = function(d, k, e){ - if(opt && opt.closable !== false){ - dlg.hide(); - handleHide(); + setText : function(t) { + if (this.rendered) { + this.el.update(t); + this.ownerCt.doLayout(); + } else { + this.text = t; } - if(e){ - e.stopEvent(); + } +}); + +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'], + alternateClassName: ['Ext.form.TriggerField', 'Ext.form.TwinTriggerField', 'Ext.form.Trigger'], + + fieldSubTpl: [ + 'name="{name}" ', + 'size="{size}" ', + 'tabIndex="{tabIdx}" ', + 'class="{fieldCls} {typeCls}" autocomplete="off" />', + '', + { + compiled: true, + disableFormats: true } - }; + ], - var updateButtons = function(b){ - var width = 0, - cfg; - if(!b){ - Ext.each(buttonNames, function(name){ - buttons[name].hide(); - }); - return width; - } - dlg.footer.dom.style.display = ''; - Ext.iterate(buttons, function(name, btn){ - cfg = b[name]; - if(cfg){ - btn.show(); - btn.setText(Ext.isString(cfg) ? cfg : Ext.MessageBox.buttonText[name]); - width += btn.getEl().getWidth() + 15; - }else{ - btn.hide(); - } - }); - return width; - }; - return { - - getDialog : function(titleText){ - if(!dlg){ - var btns = []; - - buttons = {}; - Ext.each(buttonNames, function(name){ - btns.push(buttons[name] = new Ext.Button({ - text: this.buttonText[name], - handler: handleButton.createCallback(name), - hideMode: 'offsets' - })); - }, this); - dlg = new Ext.Window({ - autoCreate : true, - title:titleText, - resizable:false, - constrain:true, - constrainHeader:true, - minimizable : false, - maximizable : false, - stateful: false, - modal: true, - shim:true, - buttonAlign:"center", - width:400, - height:100, - minHeight: 80, - plain:true, - footer:true, - closable:true, - close : function(){ - if(opt && opt.buttons && opt.buttons.no && !opt.buttons.cancel){ - handleButton("no"); - }else{ - handleButton("cancel"); - } - }, - fbar: new Ext.Toolbar({ - items: btns, - enableOverflow: false - }) - }); - dlg.render(document.body); - dlg.getEl().addClass('x-window-dlg'); - mask = dlg.mask; - bodyEl = dlg.body.createChild({ - html:'

    ' - }); - iconEl = Ext.get(bodyEl.dom.firstChild); - var contentEl = bodyEl.dom.childNodes[1]; - msgEl = Ext.get(contentEl.firstChild); - textboxEl = Ext.get(contentEl.childNodes[2].firstChild); - textboxEl.enableDisplayMode(); - textboxEl.addKeyListener([10,13], function(){ - if(dlg.isVisible() && opt && opt.buttons){ - if(opt.buttons.ok){ - handleButton("ok"); - }else if(opt.buttons.yes){ - handleButton("yes"); - } - } - }); - textareaEl = Ext.get(contentEl.childNodes[2].childNodes[1]); - textareaEl.enableDisplayMode(); - progressBar = new Ext.ProgressBar({ - renderTo:bodyEl - }); - bodyEl.createChild({cls:'x-clear'}); - } - return dlg; - }, + + triggerBaseCls: Ext.baseCSSPrefix + 'form-trigger', - - updateText : function(text){ - if(!dlg.isVisible() && !opt.width){ - dlg.setSize(this.maxWidth, 100); - } - - msgEl.update(text ? text + ' ' : ' '); + + triggerWrapCls: Ext.baseCSSPrefix + 'form-trigger-wrap', - var iw = iconCls != '' ? (iconEl.getWidth() + iconEl.getMargins('lr')) : 0, - mw = msgEl.getWidth() + msgEl.getMargins('lr'), - fw = dlg.getFrameWidth('lr'), - bw = dlg.body.getFrameWidth('lr'), - w; - - w = Math.max(Math.min(opt.width || iw+mw+fw+bw, opt.maxWidth || this.maxWidth), - Math.max(opt.minWidth || this.minWidth, bwidth || 0)); + + hideTrigger: false, - if(opt.prompt === true){ - activeTextEl.setWidth(w-iw-fw-bw); - } - if(opt.progress === true || opt.wait === true){ - progressBar.setSize(w-iw-fw-bw); - } - if(Ext.isIE && w == bwidth){ - w += 4; - } - msgEl.update(text || ' '); - dlg.setSize(w, 'auto').center(); - return this; - }, + + editable: true, - - updateProgress : function(value, progressText, msg){ - progressBar.updateProgress(value, progressText); - if(msg){ - this.updateText(msg); - } - return this; - }, + + readOnly: false, - - isVisible : function(){ - return dlg && dlg.isVisible(); - }, + - - hide : function(){ - var proxy = dlg ? dlg.activeGhost : null; - if(this.isVisible() || proxy){ - dlg.hide(); - handleHide(); - if (proxy){ - - - dlg.unghost(false, false); - } - } - return this; - }, + + repeatTriggerClick: false, - - show : function(options){ - if(this.isVisible()){ - this.hide(); - } - opt = options; - var d = this.getDialog(opt.title || " "); - d.setTitle(opt.title || " "); - var allowClose = (opt.closable !== false && opt.progress !== true && opt.wait !== true); - d.tools.close.setDisplayed(allowClose); - activeTextEl = textboxEl; - opt.prompt = opt.prompt || (opt.multiline ? true : false); - if(opt.prompt){ - if(opt.multiline){ - textboxEl.hide(); - textareaEl.show(); - textareaEl.setHeight(Ext.isNumber(opt.multiline) ? opt.multiline : this.defaultTextHeight); - activeTextEl = textareaEl; - }else{ - textboxEl.show(); - textareaEl.hide(); - } - }else{ - textboxEl.hide(); - textareaEl.hide(); - } - activeTextEl.dom.value = opt.value || ""; - if(opt.prompt){ - d.focusEl = activeTextEl; - }else{ - var bs = opt.buttons; - var db = null; - if(bs && bs.ok){ - db = buttons["ok"]; - }else if(bs && bs.yes){ - db = buttons["yes"]; - } - if (db){ - d.focusEl = db; - } - } - if(Ext.isDefined(opt.iconCls)){ - d.setIconClass(opt.iconCls); - } - this.setIcon(Ext.isDefined(opt.icon) ? opt.icon : bufferIcon); - bwidth = updateButtons(opt.buttons); - progressBar.setVisible(opt.progress === true || opt.wait === true); - this.updateProgress(0, opt.progressText); - this.updateText(opt.msg); - if(opt.cls){ - d.el.addClass(opt.cls); - } - d.proxyDrag = opt.proxyDrag === true; - d.modal = opt.modal !== false; - d.mask = opt.modal !== false ? mask : false; - if(!d.isVisible()){ - - document.body.appendChild(dlg.el.dom); - d.setAnimateTarget(opt.animEl); - - d.on('show', function(){ - if(allowClose === true){ - d.keyMap.enable(); - }else{ - d.keyMap.disable(); - } - }, this, {single:true}); - d.show(opt.animEl); - } - if(opt.wait === true){ - progressBar.wait(opt.waitConfig); - } - return this; - }, + + autoSize: Ext.emptyFn, + + monitorTab: true, + + mimicing: false, + + triggerIndexRe: /trigger-index-(\d+)/, - - setIcon : function(icon){ - if(!dlg){ - bufferIcon = icon; - return; - } - bufferIcon = undefined; - if(icon && icon != ''){ - iconEl.removeClass('x-hidden'); - iconEl.replaceClass(iconCls, icon); - bodyEl.addClass('x-dlg-icon'); - iconCls = icon; - }else{ - iconEl.replaceClass(iconCls, 'x-hidden'); - bodyEl.removeClass('x-dlg-icon'); - iconCls = ''; - } - return this; - }, + componentLayout: 'triggerfield', - - progress : function(title, msg, progressText){ - this.show({ - title : title, - msg : msg, - buttons: false, - progress:true, - closable:false, - minWidth: this.minProgressWidth, - progressText: progressText - }); - return this; - }, + initComponent: function() { + this.wrapFocusCls = this.triggerWrapCls + '-focus'; + this.callParent(arguments); + }, - - wait : function(msg, title, config){ - this.show({ - title : title, - msg : msg, - buttons: false, - closable:false, - wait:true, - modal:true, - minWidth: this.minProgressWidth, - waitConfig: config - }); - return this; - }, + + onRender: function(ct, position) { + var me = this, + triggerCls, + triggerBaseCls = me.triggerBaseCls, + triggerWrapCls = me.triggerWrapCls, + triggerConfigs = [], + i; - alert : function(title, msg, fn, scope){ - this.show({ - title : title, - msg : msg, - buttons: this.OK, - fn: fn, - scope : scope, - minWidth: this.minWidth - }); - return this; - }, - - confirm : function(title, msg, fn, scope){ - this.show({ - title : title, - msg : msg, - buttons: this.YESNO, - fn: fn, - scope : scope, - icon: this.QUESTION, - minWidth: this.minWidth - }); - return this; - }, + + + if (!me.trigger1Cls) { + me.trigger1Cls = me.triggerCls; + } - prompt : function(title, msg, fn, scope, multiline, value){ - this.show({ - title : title, - msg : msg, - buttons: this.OKCANCEL, - fn: fn, - minWidth: this.minPromptWidth, - scope : scope, - prompt:true, - multiline: multiline, - value: value + for (i = 0; (triggerCls = me['trigger' + (i + 1) + 'Cls']) || i < 1; i++) { + triggerConfigs.push({ + cls: [Ext.baseCSSPrefix + 'trigger-index-' + i, triggerBaseCls, triggerCls].join(' '), + role: 'button' }); - return this; - }, + } + triggerConfigs[i - 1].cls += ' ' + triggerBaseCls + '-last'; - - OK : {ok:true}, - - CANCEL : {cancel:true}, - - OKCANCEL : {ok:true, cancel:true}, - - YESNO : {yes:true, no:true}, - - YESNOCANCEL : {yes:true, no:true, cancel:true}, - - INFO : 'ext-mb-info', - - WARNING : 'ext-mb-warning', - - QUESTION : 'ext-mb-question', - - ERROR : 'ext-mb-error', + Ext.applyIf(me.renderSelectors, { + + triggerWrap: '.' + triggerWrapCls + }); + Ext.applyIf(me.subTplData, { + triggerWrapCls: triggerWrapCls, + triggerEl: Ext.core.DomHelper.markup(triggerConfigs), + clearCls: me.clearCls + }); + + me.callParent(arguments); - defaultTextHeight : 75, - - maxWidth : 600, - - minWidth : 100, - - minProgressWidth : 250, - - minPromptWidth: 250, - - buttonText : { - ok : "OK", - cancel : "Cancel", - yes : "Yes", - no : "No" - } - }; -}(); + me.triggerEl = Ext.select('.' + triggerBaseCls, true, me.triggerWrap.dom); + me.doc = Ext.isIE ? Ext.getBody() : Ext.getDoc(); + me.initTrigger(); + }, -Ext.Msg = Ext.MessageBox; -Ext.dd.PanelProxy = Ext.extend(Object, { + onEnable: function() { + this.callParent(); + this.triggerWrap.unmask(); + }, - constructor : function(panel, config){ - this.panel = panel; - this.id = this.panel.id +'-ddproxy'; - Ext.apply(this, config); + onDisable: function() { + this.callParent(); + this.triggerWrap.mask(); }, + afterRender: function() { + this.callParent(); + this.updateEditState(); + }, + + updateEditState: function() { + var me = this, + inputEl = me.inputEl, + triggerWrap = me.triggerWrap, + noeditCls = Ext.baseCSSPrefix + 'trigger-noedit', + displayed, + readOnly; + + if (me.rendered) { + if (me.readOnly) { + inputEl.addCls(noeditCls); + readOnly = true; + displayed = false; + } else { + if (me.editable) { + inputEl.removeCls(noeditCls); + readOnly = false; + } else { + inputEl.addCls(noeditCls); + readOnly = true; + } + displayed = !me.hideTrigger; + } + + triggerWrap.setDisplayed(displayed); + inputEl.dom.readOnly = readOnly; + me.doComponentLayout(); + } + }, + - insertProxy : true, + getTriggerWidth: function() { + var me = this, + triggerWrap = me.triggerWrap, + totalTriggerWidth = 0; + if (triggerWrap && !me.hideTrigger && !me.readOnly) { + me.triggerEl.each(function(trigger) { + totalTriggerWidth += trigger.getWidth(); + }); + totalTriggerWidth += me.triggerWrap.getFrameWidth('lr'); + } + return totalTriggerWidth; + }, + + setHideTrigger: function(hideTrigger) { + if (hideTrigger != this.hideTrigger) { + this.hideTrigger = hideTrigger; + this.updateEditState(); + } + }, - setStatus : Ext.emptyFn, - reset : Ext.emptyFn, - update : Ext.emptyFn, - stop : Ext.emptyFn, - sync: Ext.emptyFn, + setEditable: function(editable) { + if (editable != this.editable) { + this.editable = editable; + this.updateEditState(); + } + }, - getEl : function(){ - return this.ghost; + setReadOnly: function(readOnly) { + if (readOnly != this.readOnly) { + this.readOnly = readOnly; + this.updateEditState(); + } }, - getGhost : function(){ - return this.ghost; + initTrigger: function() { + var me = this, + triggerWrap = me.triggerWrap, + triggerEl = me.triggerEl; + + if (me.repeatTriggerClick) { + me.triggerRepeater = Ext.create('Ext.util.ClickRepeater', triggerWrap, { + preventDefault: true, + handler: function(cr, e) { + me.onTriggerWrapClick(e); + } + }); + } else { + me.mon(me.triggerWrap, 'click', me.onTriggerWrapClick, me); + } + + triggerEl.addClsOnOver(me.triggerBaseCls + '-over'); + triggerEl.each(function(el, c, i) { + el.addClsOnOver(me['trigger' + (i + 1) + 'Cls'] + '-over'); + }); + triggerEl.addClsOnClick(me.triggerBaseCls + '-click'); + triggerEl.each(function(el, c, i) { + el.addClsOnClick(me['trigger' + (i + 1) + 'Cls'] + '-click'); + }); }, - getProxy : function(){ - return this.proxy; + onDestroy: function() { + var me = this; + Ext.destroyMembers(me, 'triggerRepeater', 'triggerWrap', 'triggerEl'); + delete me.doc; + me.callParent(); }, - hide : function(){ - if(this.ghost){ - if(this.proxy){ - this.proxy.remove(); - delete this.proxy; + onFocus: function() { + var me = this; + this.callParent(); + if (!me.mimicing) { + me.bodyEl.addCls(me.wrapFocusCls); + me.mimicing = true; + me.mon(me.doc, 'mousedown', me.mimicBlur, me, { + delay: 10 + }); + if (me.monitorTab) { + me.on('specialkey', me.checkTab, me); } - this.panel.el.dom.style.display = ''; - this.ghost.remove(); - delete this.ghost; } }, - show : function(){ - if(!this.ghost){ - this.ghost = this.panel.createGhost(this.panel.initialConfig.cls, undefined, Ext.getBody()); - this.ghost.setXY(this.panel.el.getXY()); - if(this.insertProxy){ - this.proxy = this.panel.el.insertSibling({cls:'x-panel-dd-spacer'}); - this.proxy.setSize(this.panel.getSize()); - } - this.panel.el.dom.style.display = 'none'; + checkTab: function(me, e) { + if (!this.ignoreMonitorTab && e.getKey() == e.TAB) { + this.triggerBlur(); } }, - repair : function(xy, callback, scope){ - this.hide(); - if(typeof callback == "function"){ - callback.call(scope || this); + onBlur: Ext.emptyFn, + + + mimicBlur: function(e) { + if (!this.isDestroyed && !this.bodyEl.contains(e.target) && this.validateBlur(e)) { + this.triggerBlur(); } }, - moveProxy : function(parentNode, before){ - if(this.proxy){ - parentNode.insertBefore(this.proxy.dom, before); + triggerBlur: function() { + var me = this; + me.mimicing = false; + me.mun(me.doc, 'mousedown', me.mimicBlur, me); + if (me.monitorTab && me.inputEl) { + me.un('specialkey', me.checkTab, me); } - } -}); + Ext.form.field.Trigger.superclass.onBlur.call(me); + if (me.bodyEl) { + me.bodyEl.removeCls(me.wrapFocusCls); + } + }, + beforeBlur: Ext.emptyFn, -Ext.Panel.DD = Ext.extend(Ext.dd.DragSource, { - constructor : function(panel, cfg){ - this.panel = panel; - this.dragData = {panel: panel}; - this.proxy = new Ext.dd.PanelProxy(panel, cfg); - Ext.Panel.DD.superclass.constructor.call(this, panel.el, cfg); - var h = panel.header, - el = panel.body; - if(h){ - this.setHandleElId(h.id); - el = panel.header; - } - el.setStyle('cursor', 'move'); - this.scroll = false; - }, - showFrame: Ext.emptyFn, - startDrag: Ext.emptyFn, - b4StartDrag: function(x, y) { - this.proxy.show(); - }, - b4MouseDown: function(e) { - var x = e.getPageX(), - y = e.getPageY(); - this.autoOffset(x, y); - }, - onInitDrag : function(x, y){ - this.onStartDrag(x, y); + validateBlur: function(e) { return true; }, - createFrame : Ext.emptyFn, - getDragEl : function(e){ - return this.proxy.ghost.dom; - }, - endDrag : function(e){ - this.proxy.hide(); - this.panel.saveState(); - }, - autoOffset : function(x, y) { - x -= this.startPageX; - y -= this.startPageY; - this.setDelta(x, y); - } -}); -Ext.state.Provider = Ext.extend(Ext.util.Observable, { - constructor : function(){ - - this.addEvents("statechange"); - this.state = {}; - Ext.state.Provider.superclass.constructor.call(this); - }, - get : function(name, defaultValue){ - return typeof this.state[name] == "undefined" ? - defaultValue : this.state[name]; + onTriggerWrapClick: function(e) { + var me = this, + t = e && e.getTarget('.' + Ext.baseCSSPrefix + 'form-trigger', null), + match = t && t.className.match(me.triggerIndexRe), + idx, + triggerClickMethod; + + if (match && !me.readOnly) { + idx = parseInt(match[1], 10); + triggerClickMethod = me['onTrigger' + (idx + 1) + 'Click'] || me.onTriggerClick; + if (triggerClickMethod) { + triggerClickMethod.call(me, e); + } + } }, - clear : function(name){ - delete this.state[name]; - this.fireEvent("statechange", this, name, null); - }, + onTriggerClick: Ext.emptyFn - set : function(name, value){ - this.state[name] = value; - this.fireEvent("statechange", this, name, value); - }, + + +}); + + +Ext.define('Ext.form.field.Picker', { + extend: 'Ext.form.field.Trigger', + alias: 'widget.pickerfield', + alternateClassName: 'Ext.form.Picker', + requires: ['Ext.util.KeyNav'], - decodeValue : function(cookie){ - - var re = /^(a|n|d|b|s|o|e)\:(.*)$/, - matches = re.exec(unescape(cookie)), - all, - type, - v, - kv; - if(!matches || !matches[1]){ - return; - } - type = matches[1]; - v = matches[2]; - switch(type){ - case 'e': - return null; - case 'n': - return parseFloat(v); - case 'd': - return new Date(Date.parse(v)); - case 'b': - return (v == '1'); - case 'a': - all = []; - if(v != ''){ - Ext.each(v.split('^'), function(val){ - all.push(this.decodeValue(val)); - }, this); - } - return all; - case 'o': - all = {}; - if(v != ''){ - Ext.each(v.split('^'), function(val){ - kv = val.split('='); - all[kv[0]] = this.decodeValue(kv[1]); - }, this); - } - return all; - default: - return v; - } - }, + matchFieldWidth: true, - encodeValue : function(v){ - var enc, - flat = '', - i = 0, - len, - key; - if(v == null){ - return 'e:1'; - }else if(typeof v == 'number'){ - enc = 'n:' + v; - }else if(typeof v == 'boolean'){ - enc = 'b:' + (v ? '1' : '0'); - }else if(Ext.isDate(v)){ - enc = 'd:' + v.toGMTString(); - }else if(Ext.isArray(v)){ - for(len = v.length; i < len; i++){ - flat += this.encodeValue(v[i]); - if(i != len - 1){ - flat += '^'; - } - } - enc = 'a:' + flat; - }else if(typeof v == 'object'){ - for(key in v){ - if(typeof v[key] != 'function' && v[key] !== undefined){ - flat += key + '=' + this.encodeValue(v[key]) + '^'; - } - } - enc = 'o:' + flat.substring(0, flat.length-1); - }else{ - enc = 's:' + v; - } - return escape(enc); - } -}); + pickerAlign: 'tl-bl?', -Ext.state.Manager = function(){ - var provider = new Ext.state.Provider(); + - return { - - setProvider : function(stateProvider){ - provider = stateProvider; - }, + + openCls: Ext.baseCSSPrefix + 'pickerfield-open', + + + + + editable: true, + + + initComponent: function() { + this.callParent(); - get : function(key, defaultValue){ - return provider.get(key, defaultValue); - }, + this.addEvents( + + 'expand', + + 'collapse', + + 'select' + ); + }, + + + initEvents: function() { + var me = this; + me.callParent(); - set : function(key, value){ - provider.set(key, value); - }, + me.keyNav = Ext.create('Ext.util.KeyNav', me.inputEl, { + down: function() { + if (!me.isExpanded) { + + + me.onTriggerClick(); + } + }, + esc: me.collapse, + scope: me, + forceKeyDown: true + }); - clear : function(key){ - provider.clear(key); - }, + if (!me.editable) { + me.mon(me.inputEl, 'click', me.onTriggerClick, me); + } - getProvider : function(){ - return provider; + if (Ext.isGecko) { + me.inputEl.dom.setAttribute('autocomplete', 'off'); } - }; -}(); + }, + -Ext.state.CookieProvider = Ext.extend(Ext.state.Provider, { - constructor : function(config){ - Ext.state.CookieProvider.superclass.constructor.call(this); - this.path = "/"; - this.expires = new Date(new Date().getTime()+(1000*60*60*24*7)); - this.domain = null; - this.secure = false; - Ext.apply(this, config); - this.state = this.readCookies(); + expand: function() { + var me = this, + bodyEl, picker, collapseIf; + + if (me.rendered && !me.isExpanded && !me.isDestroyed) { + bodyEl = me.bodyEl; + picker = me.getPicker(); + collapseIf = me.collapseIf; + + + picker.show(); + me.isExpanded = true; + me.alignPicker(); + bodyEl.addCls(me.openCls); + + + me.mon(Ext.getDoc(), { + mousewheel: collapseIf, + mousedown: collapseIf, + scope: me + }); + + me.fireEvent('expand', me); + me.onExpand(); + } }, + + onExpand: Ext.emptyFn, + + alignPicker: function() { + var me = this, + picker, isAbove, + aboveSfx = '-above'; + + if (this.isExpanded) { + picker = me.getPicker(); + if (me.matchFieldWidth) { + + picker.setSize(me.bodyEl.getWidth(), picker.store && picker.store.getCount() ? null : 0); + } + if (picker.isFloating()) { + picker.alignTo(me.inputEl, me.pickerAlign, me.pickerOffset); + + + + isAbove = picker.el.getY() < me.inputEl.getY(); + me.bodyEl[isAbove ? 'addCls' : 'removeCls'](me.openCls + aboveSfx); + picker.el[isAbove ? 'addCls' : 'removeCls'](picker.baseCls + aboveSfx); + } + } + }, + - set : function(name, value){ - if(typeof value == "undefined" || value === null){ - this.clear(name); - return; + collapse: function() { + if (this.isExpanded && !this.isDestroyed) { + var me = this, + openCls = me.openCls, + picker = me.picker, + doc = Ext.getDoc(), + collapseIf = me.collapseIf, + aboveSfx = '-above'; + + + picker.hide(); + me.isExpanded = false; + + + me.bodyEl.removeCls([openCls, openCls + aboveSfx]); + picker.el.removeCls(picker.baseCls + aboveSfx); + + + doc.un('mousewheel', collapseIf, me); + doc.un('mousedown', collapseIf, me); + + me.fireEvent('collapse', me); + me.onCollapse(); } - this.setCookie(name, value); - Ext.state.CookieProvider.superclass.set.call(this, name, value); }, + onCollapse: Ext.emptyFn, + + - clear : function(name){ - this.clearCookie(name); - Ext.state.CookieProvider.superclass.clear.call(this, name); + collapseIf: function(e) { + var me = this; + if (!me.isDestroyed && !e.within(me.bodyEl, false, true) && !e.within(me.picker.el, false, true)) { + me.collapse(); + } }, - readCookies : function(){ - var cookies = {}, - c = document.cookie + ";", - re = /\s?(.*?)=(.*?);/g, - matches, - name, - value; - while((matches = re.exec(c)) != null){ - name = matches[1]; - value = matches[2]; - if(name && name.substring(0,3) == "ys-"){ - cookies[name.substr(3)] = this.decodeValue(value); + getPicker: function() { + var me = this; + return me.picker || (me.picker = me.createPicker()); + }, + + + createPicker: Ext.emptyFn, + + + onTriggerClick: function() { + var me = this; + if (!me.readOnly && !me.disabled) { + if (me.isExpanded) { + me.collapse(); + } else { + me.expand(); } + me.inputEl.focus(); } - return cookies; }, - - setCookie : function(name, value){ - document.cookie = "ys-"+ name + "=" + this.encodeValue(value) + - ((this.expires == null) ? "" : ("; expires=" + this.expires.toGMTString())) + - ((this.path == null) ? "" : ("; path=" + this.path)) + - ((this.domain == null) ? "" : ("; domain=" + this.domain)) + - ((this.secure == true) ? "; secure" : ""); + mimicBlur: function(e) { + var me = this, + picker = me.picker; + + if (!picker || !e.within(picker.el, false, true)) { + me.callParent(arguments); + } }, - - clearCookie : function(name){ - document.cookie = "ys-" + name + "=null; expires=Thu, 01-Jan-70 00:00:01 GMT" + - ((this.path == null) ? "" : ("; path=" + this.path)) + - ((this.domain == null) ? "" : ("; domain=" + this.domain)) + - ((this.secure == true) ? "; secure" : ""); + onDestroy : function(){ + var me = this; + Ext.destroy(me.picker, me.keyNav); + me.callParent(); } + }); -Ext.DataView = Ext.extend(Ext.BoxComponent, { - - - - - - - - - - selectedClass : "x-view-selected", + + + +Ext.define('Ext.form.field.Spinner', { + extend: 'Ext.form.field.Trigger', + alias: 'widget.spinnerfield', + alternateClassName: 'Ext.form.Spinner', + requires: ['Ext.util.KeyNav'], + + trigger1Cls: Ext.baseCSSPrefix + 'form-spinner-up', + trigger2Cls: Ext.baseCSSPrefix + 'form-spinner-down', + - emptyText : "", + spinUpEnabled: true, - deferEmptyText: true, + spinDownEnabled: true, + - trackOver: false, + keyNavEnabled: true, + + mouseWheelEnabled: true, + - blockRefresh: false, + repeatTriggerClick: true, - last: false, + onSpinUp: Ext.emptyFn, - initComponent : function(){ - Ext.DataView.superclass.initComponent.call(this); - if(Ext.isString(this.tpl) || Ext.isArray(this.tpl)){ - this.tpl = new Ext.XTemplate(this.tpl); - } + onSpinDown: Ext.emptyFn, + + initComponent: function() { + this.callParent(); this.addEvents( - "beforeclick", - - "click", - - "mouseenter", - - "mouseleave", - - "containerclick", - - "dblclick", - - "contextmenu", - - "containercontextmenu", + 'spin', + - "selectionchange", + 'spinup', - "beforeselect" + 'spindown' ); - - this.store = Ext.StoreMgr.lookup(this.store); - this.all = new Ext.CompositeElementLite(); - this.selected = new Ext.CompositeElementLite(); }, - afterRender : function(){ - Ext.DataView.superclass.afterRender.call(this); + onRender: function() { + var me = this, + triggers; - this.mon(this.getTemplateTarget(), { - "click": this.onClick, - "dblclick": this.onDblClick, - "contextmenu": this.onContextMenu, - scope:this - }); + me.callParent(arguments); + triggers = me.triggerEl; + + + me.spinUpEl = triggers.item(0); + + me.spinDownEl = triggers.item(1); + + + me.setSpinUpEnabled(me.spinUpEnabled); + me.setSpinDownEnabled(me.spinDownEnabled); - if(this.overClass || this.trackOver){ - this.mon(this.getTemplateTarget(), { - "mouseover": this.onMouseOver, - "mouseout": this.onMouseOut, - scope:this + + if (me.keyNavEnabled) { + me.spinnerKeyNav = Ext.create('Ext.util.KeyNav', me.inputEl, { + scope: me, + up: me.spinUp, + down: me.spinDown }); } - if(this.store){ - this.bindStore(this.store, true); + + if (me.mouseWheelEnabled) { + me.mon(me.bodyEl, 'mousewheel', me.onMouseWheel, me); } }, - refresh : function() { - this.clearSelections(false, true); - var el = this.getTemplateTarget(), - records = this.store.getRange(); - - el.update(''); - if(records.length < 1){ - if(!this.deferEmptyText || this.hasSkippedEmptyText){ - el.update(this.emptyText); - } - this.all.clear(); - }else{ - this.tpl.overwrite(el, this.collectData(records, 0)); - this.all.fill(Ext.query(this.itemSelector, el.dom)); - this.updateIndexes(0); - } - this.hasSkippedEmptyText = true; + getTriggerWidth: function() { + return this.hideTrigger || this.readOnly ? 0 : this.spinUpEl.getWidth() + this.triggerWrap.getFrameWidth('lr'); }, - getTemplateTarget: function(){ - return this.el; + + onTrigger1Click: function() { + this.spinUp(); }, - prepareData : function(data){ - return data; + onTrigger2Click: function() { + this.spinDown(); }, - collectData : function(records, startIndex){ - var r = [], - i = 0, - len = records.length; - for(; i < len; i++){ - r[r.length] = this.prepareData(records[i].data, startIndex + i, records[i]); + spinUp: function() { + var me = this; + if (me.spinUpEnabled && !me.disabled) { + me.fireEvent('spin', me, 'up'); + me.fireEvent('spinup', me); + me.onSpinUp(); } - return r; }, - bufferRender : function(records, index){ - var div = document.createElement('div'); - this.tpl.overwrite(div, this.collectData(records, index)); - return Ext.query(this.itemSelector, div); + spinDown: function() { + var me = this; + if (me.spinDownEnabled && !me.disabled) { + me.fireEvent('spin', me, 'down'); + me.fireEvent('spindown', me); + me.onSpinDown(); + } }, - onUpdate : function(ds, record){ - var index = this.store.indexOf(record); - if(index > -1){ - var sel = this.isSelected(index), - original = this.all.elements[index], - node = this.bufferRender([record], index)[0]; - - this.all.replaceElement(index, node, true); - if(sel){ - this.selected.replaceElement(original, node); - this.all.item(index).addClass(this.selectedClass); - } - this.updateIndexes(index, index); + setSpinUpEnabled: function(enabled) { + var me = this, + wasEnabled = me.spinUpEnabled; + me.spinUpEnabled = enabled; + if (wasEnabled !== enabled && me.rendered) { + me.spinUpEl[enabled ? 'removeCls' : 'addCls'](me.trigger1Cls + '-disabled'); } }, - onAdd : function(ds, records, index){ - if(this.all.getCount() === 0){ - this.refresh(); - return; - } - var nodes = this.bufferRender(records, index), 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); + setSpinDownEnabled: function(enabled) { + var me = this, + wasEnabled = me.spinDownEnabled; + me.spinDownEnabled = enabled; + if (wasEnabled !== enabled && me.rendered) { + me.spinDownEl[enabled ? 'removeCls' : 'addCls'](me.trigger2Cls + '-disabled'); } - this.updateIndexes(index); }, - onRemove : function(ds, record, index){ - this.deselect(index); - this.all.removeElement(index, true); - this.updateIndexes(index); - if (this.store.getCount() === 0){ - this.refresh(); + onMouseWheel: function(e) { + var me = this, + delta; + if (me.hasFocus) { + delta = e.getWheelDelta(); + if (delta > 0) { + me.spinUp(); + } + else if (delta < 0) { + me.spinDown(); + } + e.stopEvent(); } }, - - refreshNode : function(index){ - this.onUpdate(this.store, this.store.getAt(index)); - }, + onDestroy: function() { + Ext.destroyMembers(this, 'spinnerKeyNav', 'spinUpEl', 'spinDownEl'); + this.callParent(); + } + +}); + +Ext.define('Ext.form.field.Number', { + extend:'Ext.form.field.Spinner', + alias: 'widget.numberfield', + alternateClassName: ['Ext.form.NumberField', 'Ext.form.Number'], - updateIndexes : function(startIndex, endIndex){ - var ns = this.all.elements; - startIndex = startIndex || 0; - endIndex = endIndex || ((endIndex === 0) ? 0 : (ns.length - 1)); - for(var i = startIndex; i <= endIndex; i++){ - ns[i].viewIndex = i; - } - }, + - getStore : function(){ - return this.store; - }, + allowDecimals : true, - bindStore : function(store, initial){ - if(!initial && this.store){ - if(store !== this.store && this.store.autoDestroy){ - this.store.destroy(); - }else{ - this.store.un("beforeload", this.onBeforeLoad, this); - this.store.un("datachanged", this.onDataChanged, this); - this.store.un("add", this.onAdd, this); - this.store.un("remove", this.onRemove, this); - this.store.un("update", this.onUpdate, this); - this.store.un("clear", this.refresh, this); - } - if(!store){ - this.store = null; - } - } - if(store){ - store = Ext.StoreMgr.lookup(store); - store.on({ - scope: this, - beforeload: this.onBeforeLoad, - datachanged: this.onDataChanged, - add: this.onAdd, - remove: this.onRemove, - update: this.onUpdate, - clear: this.refresh - }); - } - this.store = store; - if(store){ - this.refresh(); - } - }, + decimalSeparator : '.', + + decimalPrecision : 2, + - onDataChanged: function() { - if (this.blockRefresh !== true) { - this.refresh.apply(this, arguments); - } - }, + minValue: Number.NEGATIVE_INFINITY, - findItemFromChild : function(node){ - return Ext.fly(node).findParent(this.itemSelector, this.getTemplateTarget()); - }, + maxValue: Number.MAX_VALUE, - onClick : function(e){ - var item = e.getTarget(this.itemSelector, this.getTemplateTarget()), - index; - if(item){ - index = this.indexOf(item); - if(this.onItemClick(item, index, e) !== false){ - this.fireEvent("click", this, index, item, e); - } - }else{ - if(this.fireEvent("containerclick", this, e) !== false){ - this.onContainerClick(e); - } - } - }, + step: 1, - onContainerClick : function(e){ - this.clearSelections(); - }, + + minText : 'The minimum value for this field is {0}', - onContextMenu : function(e){ - var item = e.getTarget(this.itemSelector, this.getTemplateTarget()); - if(item){ - this.fireEvent("contextmenu", this, this.indexOf(item), item, e); - }else{ - this.fireEvent("containercontextmenu", this, e); - } - }, + maxText : 'The maximum value for this field is {0}', - onDblClick : function(e){ - var item = e.getTarget(this.itemSelector, this.getTemplateTarget()); - if(item){ - this.fireEvent("dblclick", this, this.indexOf(item), item, e); - } - }, + nanText : '{0} is not a valid number', - onMouseOver : function(e){ - var item = e.getTarget(this.itemSelector, this.getTemplateTarget()); - if(item && item !== this.lastItem){ - this.lastItem = item; - Ext.fly(item).addClass(this.overClass); - this.fireEvent("mouseenter", this, this.indexOf(item), item, e); - } - }, + negativeText : 'The value cannot be negative', - onMouseOut : function(e){ - if(this.lastItem){ - if(!e.within(this.lastItem, true, true)){ - Ext.fly(this.lastItem).removeClass(this.overClass); - this.fireEvent("mouseleave", this, this.indexOf(this.lastItem), this.lastItem, e); - delete this.lastItem; - } - } - }, + baseChars : '0123456789', - onItemClick : function(item, index, e){ - if(this.fireEvent("beforeclick", this, index, item, e) === false){ - return false; + autoStripChars: false, + + initComponent: function() { + var me = this, + allowed; + + this.callParent(); + + me.setMinValue(me.minValue); + me.setMaxValue(me.maxValue); + + + allowed = me.baseChars + ''; + if (me.allowDecimals) { + allowed += me.decimalSeparator; } - if(this.multiSelect){ - this.doMultiSelection(item, index, e); - e.preventDefault(); - }else if(this.singleSelect){ - this.doSingleSelection(item, index, e); - e.preventDefault(); + if (me.minValue < 0) { + allowed += '-'; + } + allowed = Ext.String.escapeRegex(allowed); + me.maskRe = new RegExp('[' + allowed + ']'); + if (me.autoStripChars) { + me.stripCharsRe = new RegExp('[^' + allowed + ']', 'gi'); } - return true; }, - doSingleSelection : function(item, index, e){ - if(e.ctrlKey && this.isSelected(index)){ - this.deselect(index); - }else{ - this.select(index, false); + getErrors: function(value) { + var me = this, + errors = me.callParent(arguments), + format = Ext.String.format, + num; + + value = Ext.isDefined(value) ? value : this.processRawValue(this.getRawValue()); + + if (value.length < 1) { + return errors; } - }, - - doMultiSelection : function(item, index, e){ - if(e.shiftKey && this.last !== false){ - var last = this.last; - this.selectRange(last, index, e.ctrlKey); - this.last = last; - }else{ - if((e.ctrlKey||this.simpleSelect) && this.isSelected(index)){ - this.deselect(index); - }else{ - this.select(index, e.ctrlKey || e.shiftKey || this.simpleSelect); - } + value = String(value).replace(me.decimalSeparator, '.'); + + if(isNaN(value)){ + errors.push(format(me.nanText, value)); } - }, - - getSelectionCount : function(){ - return this.selected.getCount(); - }, + num = me.parseValue(value); - - getSelectedNodes : function(){ - return this.selected.elements; - }, + if (me.minValue === 0 && num < 0) { + errors.push(this.negativeText); + } + else if (num < me.minValue) { + errors.push(format(me.minText, me.minValue)); + } - - getSelectedIndexes : function(){ - var indexes = [], - selected = this.selected.elements, - i = 0, - len = selected.length; - - for(; i < len; i++){ - indexes.push(selected[i].viewIndex); + if (num > me.maxValue) { + errors.push(format(me.maxText, me.maxValue)); } - return indexes; - }, - - getSelectedRecords : function(){ - return this.getRecords(this.selected.elements); - }, - - getRecords : function(nodes){ - var records = [], - i = 0, - len = nodes.length; - - for(; i < len; i++){ - records[records.length] = this.store.getAt(nodes[i].viewIndex); - } - return records; + return errors; }, - - getRecord : function(node){ - return this.store.getAt(node.viewIndex); + rawToValue: function(rawValue) { + return this.fixPrecision(this.parseValue(rawValue)) || rawValue || null; }, - - clearSelections : function(suppressEvent, skipUpdate){ - if((this.multiSelect || this.singleSelect) && this.selected.getCount() > 0){ - if(!skipUpdate){ - this.selected.removeClass(this.selectedClass); - } - this.selected.clear(); - this.last = false; - if(!suppressEvent){ - this.fireEvent("selectionchange", this, this.selected.elements); - } - } + valueToRaw: function(value) { + var me = this, + decimalSeparator = me.decimalSeparator; + value = me.parseValue(value); + value = me.fixPrecision(value); + value = Ext.isNumber(value) ? value : parseFloat(String(value).replace(decimalSeparator, '.')); + value = isNaN(value) ? '' : String(value).replace('.', decimalSeparator); + return value; }, - - isSelected : function(node){ - return this.selected.contains(this.getNode(node)); - }, + onChange: function() { + var me = this, + value = me.getValue(), + valueIsNull = value === null; - - deselect : function(node){ - if(this.isSelected(node)){ - node = this.getNode(node); - this.selected.removeElement(node); - if(this.last == node.viewIndex){ - this.last = false; - } - Ext.fly(node).removeClass(this.selectedClass); - this.fireEvent("selectionchange", this, this.selected.elements); - } + me.callParent(arguments); + + + me.setSpinUpEnabled(valueIsNull || value < me.maxValue); + me.setSpinDownEnabled(valueIsNull || value > me.minValue); }, - select : function(nodeInfo, keepExisting, suppressEvent){ - if(Ext.isArray(nodeInfo)){ - if(!keepExisting){ - this.clearSelections(true); - } - for(var i = 0, len = nodeInfo.length; i < len; i++){ - this.select(nodeInfo[i], true, true); - } - if(!suppressEvent){ - this.fireEvent("selectionchange", this, this.selected.elements); - } - } else{ - var node = this.getNode(nodeInfo); - if(!keepExisting){ - this.clearSelections(true); - } - if(node && !this.isSelected(node)){ - if(this.fireEvent("beforeselect", this, node, this.selected.elements) !== false){ - Ext.fly(node).addClass(this.selectedClass); - this.selected.add(node); - this.last = node.viewIndex; - if(!suppressEvent){ - this.fireEvent("selectionchange", this, this.selected.elements); - } - } - } - } + setMinValue : function(value) { + this.minValue = Ext.Number.from(value, Number.NEGATIVE_INFINITY); }, - selectRange : function(start, end, keepExisting){ - if(!keepExisting){ - this.clearSelections(true); - } - this.select(this.getNodes(start, end), true); + setMaxValue: function(value) { + this.maxValue = Ext.Number.from(value, Number.MAX_VALUE); }, - getNode : function(nodeInfo){ - if(Ext.isString(nodeInfo)){ - return document.getElementById(nodeInfo); - }else if(Ext.isNumber(nodeInfo)){ - return this.all.elements[nodeInfo]; - }else if(nodeInfo instanceof Ext.data.Record){ - var idx = this.store.indexOf(nodeInfo); - return this.all.elements[idx]; - } - return nodeInfo; + parseValue : function(value) { + value = parseFloat(String(value).replace(this.decimalSeparator, '.')); + return isNaN(value) ? null : value; }, - getNodes : function(start, end){ - var ns = this.all.elements, - nodes = [], - i; - - start = start || 0; - end = !Ext.isDefined(end) ? Math.max(ns.length - 1, 0) : end; - if(start <= end){ - for(i = start; i <= end && ns[i]; i++){ - nodes.push(ns[i]); - } - } else{ - for(i = start; i >= end && ns[i]; i--){ - nodes.push(ns[i]); - } + fixPrecision : function(value) { + var me = this, + nan = isNaN(value), + precision = me.decimalPrecision; + + if (nan || !value) { + return nan ? '' : value; + } else if (!me.allowDecimals || precision <= 0) { + precision = 0; } - return nodes; + + return parseFloat(Ext.Number.toFixed(parseFloat(value), precision)); }, - - indexOf : function(node){ - node = this.getNode(node); - if(Ext.isNumber(node.viewIndex)){ - return node.viewIndex; + beforeBlur : function() { + var me = this, + v = me.parseValue(me.getRawValue()); + + if (!Ext.isEmpty(v)) { + me.setValue(v); } - return this.all.indexOf(node); }, - - onBeforeLoad : function(){ - if(this.loadingText){ - this.clearSelections(false, true); - this.getTemplateTarget().update('
    '+this.loadingText+'
    '); - this.all.clear(); + onSpinUp: function() { + var me = this; + if (!me.readOnly) { + me.setValue(Ext.Number.constrain(me.getValue() + me.step, me.minValue, me.maxValue)); } }, - onDestroy : function(){ - this.all.clear(); - this.selected.clear(); - Ext.DataView.superclass.onDestroy.call(this); - this.bindStore(null); + onSpinDown: function() { + var me = this; + if (!me.readOnly) { + me.setValue(Ext.Number.constrain(me.getValue() - me.step, me.minValue, me.maxValue)); + } } }); -Ext.DataView.prototype.setStore = Ext.DataView.prototype.bindStore; - -Ext.reg('dataview', Ext.DataView); - -Ext.list.ListView = Ext.extend(Ext.DataView, { +Ext.define('Ext.toolbar.Paging', { + extend: 'Ext.toolbar.Toolbar', + alias: 'widget.pagingtoolbar', + alternateClassName: 'Ext.PagingToolbar', + requires: ['Ext.toolbar.TextItem', 'Ext.form.field.Number'], + + + displayInfo: false, + prependButtons: false, + displayMsg : 'Displaying {0} - {1} of {2}', + + emptyMsg : 'No data to display', - itemSelector: 'dl', + beforePageText : 'Page', - selectedClass:'x-list-selected', + afterPageText : 'of {0}', - overClass:'x-list-over', + firstText : 'First Page', + prevText : 'Previous Page', - scrollOffset : undefined, + nextText : 'Next Page', - columnResize: true, + lastText : 'Last Page', + refreshText : 'Refresh', - columnSort: true, + inputItemWidth : 30, - - maxColumnWidth: Ext.isIE ? 99 : 100, + getPagingItems: function() { + var me = this; + + return [{ + itemId: 'first', + tooltip: me.firstText, + overflowText: me.firstText, + iconCls: Ext.baseCSSPrefix + 'tbar-page-first', + disabled: true, + handler: me.moveFirst, + scope: me + },{ + itemId: 'prev', + tooltip: me.prevText, + overflowText: me.prevText, + iconCls: Ext.baseCSSPrefix + 'tbar-page-prev', + disabled: true, + handler: me.movePrevious, + scope: me + }, + '-', + me.beforePageText, + { + xtype: 'numberfield', + itemId: 'inputItem', + name: 'inputItem', + cls: Ext.baseCSSPrefix + 'tbar-page-number', + allowDecimals: false, + minValue: 1, + hideTrigger: true, + enableKeyEvents: true, + selectOnFocus: true, + submitValue: false, + width: me.inputItemWidth, + margins: '-1 2 3 2', + listeners: { + scope: me, + keydown: me.onPagingKeyDown, + blur: me.onPagingBlur + } + },{ + xtype: 'tbtext', + itemId: 'afterTextItem', + text: Ext.String.format(me.afterPageText, 1) + }, + '-', + { + itemId: 'next', + tooltip: me.nextText, + overflowText: me.nextText, + iconCls: Ext.baseCSSPrefix + 'tbar-page-next', + disabled: true, + handler: me.moveNext, + scope: me + },{ + itemId: 'last', + tooltip: me.lastText, + overflowText: me.lastText, + iconCls: Ext.baseCSSPrefix + 'tbar-page-last', + disabled: true, + handler: me.moveLast, + scope: me + }, + '-', + { + itemId: 'refresh', + tooltip: me.refreshText, + overflowText: me.refreshText, + iconCls: Ext.baseCSSPrefix + 'tbar-loading', + handler: me.doRefresh, + scope: me + }]; + }, initComponent : function(){ - if(this.columnResize){ - this.colResizer = new Ext.list.ColumnResizer(this.colResizer); - this.colResizer.init(this); - } - if(this.columnSort){ - this.colSorter = new Ext.list.Sorter(this.columnSort); - this.colSorter.init(this); - } - if(!this.internalTpl){ - this.internalTpl = new Ext.XTemplate( - '
    ', - '', - '
    ', - '{header}', - '
    ', - '
    ', - '
    ', - '
    ', - '
    ', - '
    ' - ); + var me = this, + pagingItems = me.getPagingItems(), + userItems = me.items || me.buttons || []; + + if (me.prependButtons) { + me.items = userItems.concat(pagingItems); + } else { + me.items = pagingItems.concat(userItems); } - if(!this.tpl){ - this.tpl = new Ext.XTemplate( - '', - '
    ', - '', - '
    ', - ' class="{cls}">', - '{[values.tpl.apply(parent)]}', - '
    ', - '
    ', - '
    ', - '
    ', - '
    ' - ); - }; - - var cs = this.columns, - allocatedWidth = 0, - colsWithWidth = 0, - len = cs.length, - columns = []; - - for(var i = 0; i < len; i++){ - var c = cs[i]; - if(!c.isColumn) { - c.xtype = c.xtype ? (/^lv/.test(c.xtype) ? c.xtype : 'lv' + c.xtype) : 'lvcolumn'; - c = Ext.create(c); - } - if(c.width) { - allocatedWidth += c.width*100; - if(allocatedWidth > this.maxColumnWidth){ - c.width -= (allocatedWidth - this.maxColumnWidth) / 100; - } - colsWithWidth++; - } - columns.push(c); + delete me.buttons; + + if (me.displayInfo) { + me.items.push('->'); + me.items.push({xtype: 'tbtext', itemId: 'displayItem'}); } - - cs = this.columns = columns; - - if(colsWithWidth < len){ - var remaining = len - colsWithWidth; - if(allocatedWidth < this.maxColumnWidth){ - var perCol = ((this.maxColumnWidth-allocatedWidth) / remaining)/100; - for(var j = 0; j < len; j++){ - var c = cs[j]; - if(!c.width){ - c.width = perCol; - } - } + me.callParent(); + + me.addEvents( + + 'change', + + 'beforechange' + ); + me.on('afterlayout', me.onLoad, me, {single: true}); + + me.bindStore(me.store, true); + }, + + updateInfo : function(){ + var me = this, + displayItem = me.child('#displayItem'), + store = me.store, + pageData = me.getPageData(), + count, msg; + + if (displayItem) { + count = store.getCount(); + if (count === 0) { + msg = me.emptyMsg; + } else { + msg = Ext.String.format( + me.displayMsg, + pageData.fromRecord, + pageData.toRecord, + pageData.total + ); } + displayItem.setText(msg); + me.doComponentLayout(); } - Ext.list.ListView.superclass.initComponent.call(this); }, - onRender : function(){ - this.autoEl = { - cls: 'x-list-wrap' - }; - Ext.list.ListView.superclass.onRender.apply(this, arguments); - - this.internalTpl.overwrite(this.el, {columns: this.columns}); - - this.innerBody = Ext.get(this.el.dom.childNodes[1].firstChild); - this.innerHd = Ext.get(this.el.dom.firstChild.firstChild); - - if(this.hideHeaders){ - this.el.dom.firstChild.style.display = 'none'; + + onLoad : function(){ + var me = this, + pageData, + currPage, + pageCount, + afterText; + + if (!me.rendered) { + return; } - }, - getTemplateTarget : function(){ - return this.innerBody; + pageData = me.getPageData(); + currPage = pageData.currentPage; + pageCount = pageData.pageCount; + afterText = Ext.String.format(me.afterPageText, isNaN(pageCount) ? 1 : pageCount); + + me.child('#afterTextItem').setText(afterText); + me.child('#inputItem').setValue(currPage); + me.child('#first').setDisabled(currPage === 1); + me.child('#prev').setDisabled(currPage === 1); + me.child('#next').setDisabled(currPage === pageCount); + me.child('#last').setDisabled(currPage === pageCount); + me.child('#refresh').enable(); + me.updateInfo(); + me.fireEvent('change', me, pageData); }, - collectData : function(){ - var rs = Ext.list.ListView.superclass.collectData.apply(this, arguments); + getPageData : function(){ + var store = this.store, + totalCount = store.getTotalCount(); + return { - columns: this.columns, - rows: rs + total : totalCount, + currentPage : store.currentPage, + pageCount: Math.ceil(totalCount / store.pageSize), + + fromRecord: ((store.currentPage - 1) * store.pageSize) + 1, + toRecord: Math.min(store.currentPage * store.pageSize, totalCount) + }; }, - verifyInternalSize : function(){ - if(this.lastSize){ - this.onResize(this.lastSize.width, this.lastSize.height); + + onLoadError : function(){ + if (!this.rendered) { + return; } + this.child('#refresh').enable(); }, - onResize : function(w, h){ - var body = this.innerBody.dom, - header = this.innerHd.dom, - scrollWidth = w - Ext.num(this.scrollOffset, Ext.getScrollBarWidth()) + 'px', - parentNode; + readPageFromInput : function(pageData){ + var v = this.child('#inputItem').getValue(), + pageNum = parseInt(v, 10); - if(!body){ - return; - } - parentNode = body.parentNode; - if(Ext.isNumber(w)){ - if(this.reserveScrollOffset || ((parentNode.offsetWidth - parentNode.clientWidth) > 10)){ - body.style.width = scrollWidth; - header.style.width = scrollWidth; - }else{ - body.style.width = w + 'px'; - header.style.width = w + 'px'; - setTimeout(function(){ - if((parentNode.offsetWidth - parentNode.clientWidth) > 10){ - body.style.width = scrollWidth; - header.style.width = scrollWidth; - } - }, 10); - } - } - if(Ext.isNumber(h)){ - parentNode.style.height = Math.max(0, h - header.parentNode.offsetHeight) + 'px'; + if (!v || isNaN(pageNum)) { + this.child('#inputItem').setValue(pageData.currentPage); + return false; } + return pageNum; }, - updateIndexes : function(){ - Ext.list.ListView.superclass.updateIndexes.apply(this, arguments); - this.verifyInternalSize(); + onPagingFocus : function(){ + this.child('#inputItem').select(); }, - findHeaderIndex : function(header){ - header = header.dom || header; - var parentNode = header.parentNode, - children = parentNode.parentNode.childNodes, - i = 0, - c; - for(; c = children[i]; i++){ - if(c == parentNode){ - return i; + + onPagingBlur : function(e){ + var curPage = this.getPageData().currentPage; + this.child('#inputItem').setValue(curPage); + }, + + + onPagingKeyDown : function(field, e){ + var k = e.getKey(), + pageData = this.getPageData(), + increment = e.shiftKey ? 10 : 1, + pageNum, + me = this; + + if (k == e.RETURN) { + e.stopEvent(); + pageNum = me.readPageFromInput(pageData); + if (pageNum !== false) { + pageNum = Math.min(Math.max(1, pageNum), pageData.total); + if(me.fireEvent('beforechange', me, pageNum) !== false){ + me.store.loadPage(pageNum); + } + } + } else if (k == e.HOME || k == e.END) { + e.stopEvent(); + pageNum = k == e.HOME ? 1 : pageData.pageCount; + field.setValue(pageNum); + } else if (k == e.UP || k == e.PAGEUP || k == e.DOWN || k == e.PAGEDOWN) { + e.stopEvent(); + pageNum = me.readPageFromInput(pageData); + if (pageNum) { + if (k == e.DOWN || k == e.PAGEDOWN) { + increment *= -1; + } + pageNum += increment; + if (pageNum >= 1 && pageNum <= pageData.pages) { + field.setValue(pageNum); + } } } - return -1; }, - setHdWidths : function(){ - var els = this.innerHd.dom.getElementsByTagName('div'), - i = 0, - columns = this.columns, - len = columns.length; - - for(; i < len; i++){ - els[i].style.width = (columns[i].width*100) + '%'; + + beforeLoad : function(){ + if(this.rendered && this.refresh){ + this.refresh.disable(); } - } -}); - -Ext.reg('listview', Ext.list.ListView); - + }, -Ext.ListView = Ext.list.ListView; -Ext.list.Column = Ext.extend(Object, { - isColumn: true, + doLoad : function(start){ + if(this.fireEvent('beforechange', this, o) !== false){ + this.store.load(); + } + }, + - - align: 'left', - - header: '', + moveFirst : function(){ + var me = this; + if(me.fireEvent('beforechange', me, 1) !== false){ + me.store.loadPage(1); + } + }, + + movePrevious : function(){ + var me = this, + prev = me.store.currentPage - 1; - width: null, + if(me.fireEvent('beforechange', me, prev) !== false){ + me.store.previousPage(); + } + }, - cls: '', - + moveNext : function(){ + var me = this; + if(me.fireEvent('beforechange', me, me.store.currentPage + 1) !== false){ + me.store.nextPage(); + } + }, + + moveLast : function(){ + var me = this, + last = this.getPageData().pageCount; + + if(me.fireEvent('beforechange', me, last) !== false){ + me.store.loadPage(last); + } + }, + doRefresh : function(){ + var me = this, + current = me.store.currentPage; + + if(me.fireEvent('beforechange', me, current) !== false){ + me.store.loadPage(current); + } + }, + - constructor : function(c){ - if(!c.tpl){ - c.tpl = new Ext.XTemplate('{' + c.dataIndex + '}'); + bindStore : function(store, initial){ + var me = this; + + if (!initial && me.store) { + if(store !== me.store && me.store.autoDestroy){ + me.store.destroy(); + }else{ + me.store.un('beforeload', me.beforeLoad, me); + me.store.un('load', me.onLoad, me); + me.store.un('exception', me.onLoadError, me); + } + if(!store){ + me.store = null; + } } - else if(Ext.isString(c.tpl)){ - c.tpl = new Ext.XTemplate(c.tpl); + if (store) { + store = Ext.data.StoreManager.lookup(store); + store.on({ + scope: me, + beforeload: me.beforeLoad, + load: me.onLoad, + exception: me.onLoadError + }); } - - Ext.apply(this, c); - } -}); + me.store = store; + }, -Ext.reg('lvcolumn', Ext.list.Column); + + unbind : function(store){ + this.bindStore(null); + }, + + bind : function(store){ + this.bindStore(store); + }, -Ext.list.NumberColumn = Ext.extend(Ext.list.Column, { - - format: '0,000.00', - constructor : function(c) { - c.tpl = c.tpl || new Ext.XTemplate('{' + c.dataIndex + ':number("' + (c.format || this.format) + '")}'); - Ext.list.NumberColumn.superclass.constructor.call(this, c); + onDestroy : function(){ + this.bindStore(null); + this.callParent(); } }); -Ext.reg('lvnumbercolumn', Ext.list.NumberColumn); - - -Ext.list.DateColumn = Ext.extend(Ext.list.Column, { - format: 'm/d/Y', - constructor : function(c) { - c.tpl = c.tpl || new Ext.XTemplate('{' + c.dataIndex + ':date("' + (c.format || this.format) + '")}'); - Ext.list.DateColumn.superclass.constructor.call(this, c); - } -}); -Ext.reg('lvdatecolumn', Ext.list.DateColumn); +Ext.define('Ext.view.BoundList', { + extend: 'Ext.view.View', + alias: 'widget.boundlist', + alternateClassName: 'Ext.BoundList', + requires: ['Ext.layout.component.BoundList', 'Ext.toolbar.Paging'], -Ext.list.BooleanColumn = Ext.extend(Ext.list.Column, { - - trueText: 'true', - - falseText: 'false', - undefinedText: ' ', + pageSize: 0, + - constructor : function(c) { - c.tpl = c.tpl || new Ext.XTemplate('{' + c.dataIndex + ':this.format}'); - - var t = this.trueText, f = this.falseText, u = this.undefinedText; - c.tpl.format = function(v){ - if(v === undefined){ - return u; - } - if(!v || v === 'false'){ - return f; - } - return t; - }; - - Ext.list.DateColumn.superclass.constructor.call(this, c); - } -}); -Ext.reg('lvbooleancolumn', Ext.list.BooleanColumn); -Ext.list.ColumnResizer = Ext.extend(Ext.util.Observable, { - minPct: .05, + autoScroll: true, + baseCls: Ext.baseCSSPrefix + 'boundlist', + listItemCls: '', + shadow: false, + trackOver: true, + refreshed: 0, - constructor: function(config){ - Ext.apply(this, config); - Ext.list.ColumnResizer.superclass.constructor.call(this); - }, - init : function(listView){ - this.view = listView; - listView.on('render', this.initEvents, this); - }, + ariaRole: 'listbox', - initEvents : function(view){ - view.mon(view.innerHd, 'mousemove', this.handleHdMove, this); - this.tracker = new Ext.dd.DragTracker({ - onBeforeStart: this.onBeforeStart.createDelegate(this), - onStart: this.onStart.createDelegate(this), - onDrag: this.onDrag.createDelegate(this), - onEnd: this.onEnd.createDelegate(this), - tolerance: 3, - autoStart: 300 - }); - this.tracker.initEl(view.innerHd); - view.on('beforedestroy', this.tracker.destroy, this.tracker); - }, - - handleHdMove : function(e, t){ - var handleWidth = 5, - x = e.getPageX(), - header = e.getTarget('em', 3, true); - if(header){ - var region = header.getRegion(), - style = header.dom.style, - parentNode = header.dom.parentNode; - - if(x - region.left <= handleWidth && parentNode != parentNode.parentNode.firstChild){ - this.activeHd = Ext.get(parentNode.previousSibling.firstChild); - style.cursor = Ext.isWebKit ? 'e-resize' : 'col-resize'; - } else if(region.right - x <= handleWidth && parentNode != parentNode.parentNode.lastChild.previousSibling){ - this.activeHd = header; - style.cursor = Ext.isWebKit ? 'w-resize' : 'col-resize'; - } else{ - delete this.activeHd; - style.cursor = ''; - } - } - }, + componentLayout: 'boundlist', - onBeforeStart : function(e){ - this.dragHd = this.activeHd; - return !!this.dragHd; - }, + renderTpl: ['
    '], - onStart: function(e){ - + initComponent: function() { var me = this, - view = me.view, - dragHeader = me.dragHd, - x = me.tracker.getXY()[0]; - - me.proxy = view.el.createChild({cls:'x-list-resizer'}); - me.dragX = dragHeader.getX(); - me.headerIndex = view.findHeaderIndex(dragHeader); - - me.headersDisabled = view.disableHeaders; - view.disableHeaders = true; - - me.proxy.setHeight(view.el.getHeight()); - me.proxy.setX(me.dragX); - me.proxy.setWidth(x - me.dragX); + baseCls = me.baseCls, + itemCls = baseCls + '-item'; + me.itemCls = itemCls; + me.selectedItemCls = baseCls + '-selected'; + me.overItemCls = baseCls + '-item-over'; + me.itemSelector = "." + itemCls; + + if (me.floating) { + me.addCls(baseCls + '-floating'); + } + - this.setBoundaries(); - }, - - - setBoundaries: function(relativeX){ - var view = this.view, - headerIndex = this.headerIndex, - width = view.innerHd.getWidth(), - relativeX = view.innerHd.getX(), - minWidth = Math.ceil(width * this.minPct), - maxWidth = width - minWidth, - numColumns = view.columns.length, - headers = view.innerHd.select('em', true), - minX = minWidth + relativeX, - maxX = maxWidth + relativeX, - header; - - if (numColumns == 2) { - this.minX = minX; - this.maxX = maxX; - }else{ - header = headers.item(headerIndex + 2); - this.minX = headers.item(headerIndex).getX() + minWidth; - this.maxX = header ? header.getX() - minWidth : maxX; - if (headerIndex == 0) { - - this.minX = minX; - } else if (headerIndex == numColumns - 2) { - - this.maxX = maxX; - } + me.tpl = Ext.create('Ext.XTemplate', + '
      ', + '
    • ' + me.getInnerTpl(me.displayField) + '
    • ', + '
    ' + ); + + if (me.pageSize) { + me.pagingToolbar = me.createPagingToolbar(); + } + + me.callParent(); + + Ext.applyIf(me.renderSelectors, { + listEl: '.list-ct' + }); + }, + + createPagingToolbar: function() { + return Ext.widget('pagingtoolbar', { + pageSize: this.pageSize, + store: this.store, + border: false + }); + }, + + onRender: function() { + var me = this, + toolbar = me.pagingToolbar; + me.callParent(arguments); + if (toolbar) { + toolbar.render(me.el); } }, - onDrag: function(e){ + bindStore : function(store, initial) { var me = this, - cursorX = me.tracker.getXY()[0].constrain(me.minX, me.maxX); - - me.proxy.setWidth(cursorX - this.dragX); + toolbar = me.pagingToolbar; + me.callParent(arguments); + if (toolbar) { + toolbar.bindStore(store, initial); + } }, - onEnd: function(e){ + getTargetEl: function() { + return this.listEl || this.el; + }, + + getInnerTpl: function(displayField) { + return '{' + displayField + '}'; + }, + + refresh: function() { + var me = this; + me.callParent(); + if (me.isVisible()) { + me.refreshed++; + me.doComponentLayout(); + me.refreshed--; + } + }, + + initAria: function() { + this.callParent(); - var newWidth = this.proxy.getWidth(), - index = this.headerIndex, - view = this.view, - columns = view.columns, - width = view.innerHd.getWidth(), - newPercent = Math.ceil(newWidth * view.maxColumnWidth / width) / 100, - disabled = this.headersDisabled, - headerCol = columns[index], - otherCol = columns[index + 1], - totalPercent = headerCol.width + otherCol.width; - - this.proxy.remove(); - - headerCol.width = newPercent; - otherCol.width = totalPercent - newPercent; - - delete this.dragHd; - view.setHdWidths(); - view.refresh(); + var selModel = this.getSelectionModel(), + mode = selModel.getSelectionMode(), + actionEl = this.getActionEl(); - setTimeout(function(){ - view.disableHeaders = disabled; - }, 100); + + if (mode !== 'SINGLE') { + actionEl.dom.setAttribute('aria-multiselectable', true); + } + }, + + onDestroy: function() { + Ext.destroyMembers(this, 'pagingToolbar', 'listEl'); + this.callParent(); } }); -Ext.ListView.ColumnResizer = Ext.list.ColumnResizer; -Ext.list.Sorter = Ext.extend(Ext.util.Observable, { +Ext.define('Ext.view.BoundListKeyNav', { + extend: 'Ext.util.KeyNav', + requires: 'Ext.view.BoundList', + - sortClasses : ["sort-asc", "sort-desc"], - constructor: function(config){ - Ext.apply(this, config); - Ext.list.Sorter.superclass.constructor.call(this); + constructor: function(el, config) { + var me = this; + me.boundList = config.boundList; + me.callParent([el, Ext.apply({}, config, me.defaultHandlers)]); }, - init : function(listView){ - this.view = listView; - listView.on('render', this.initEvents, this); - }, + defaultHandlers: { + up: function() { + var me = this, + boundList = me.boundList, + allItems = boundList.all, + oldItem = boundList.highlightedItem, + oldItemIdx = oldItem ? boundList.indexOf(oldItem) : -1, + newItemIdx = oldItemIdx > 0 ? oldItemIdx - 1 : allItems.getCount() - 1; + me.highlightAt(newItemIdx); + }, - initEvents : function(view){ - view.mon(view.innerHd, 'click', this.onHdClick, this); - view.innerHd.setStyle('cursor', 'pointer'); - view.mon(view.store, 'datachanged', this.updateSortState, this); - this.updateSortState.defer(10, this, [view.store]); - }, + down: function() { + var me = this, + boundList = me.boundList, + allItems = boundList.all, + oldItem = boundList.highlightedItem, + oldItemIdx = oldItem ? boundList.indexOf(oldItem) : -1, + newItemIdx = oldItemIdx < allItems.getCount() - 1 ? oldItemIdx + 1 : 0; + me.highlightAt(newItemIdx); + }, - updateSortState : function(store){ - var state = store.getSortState(); - if(!state){ - return; - } - this.sortState = state; - var cs = this.view.columns, sortColumn = -1; - for(var i = 0, len = cs.length; i < len; i++){ - if(cs[i].dataIndex == state.field){ - sortColumn = i; - break; - } - } - if(sortColumn != -1){ - var sortDir = state.direction; - this.updateSortIcon(sortColumn, sortDir); + pageup: function() { + + }, + + pagedown: function() { + + }, + + home: function() { + this.highlightAt(0); + }, + + end: function() { + var me = this; + me.highlightAt(me.boundList.all.getCount() - 1); + }, + + enter: function(e) { + this.selectHighlighted(e); } }, - updateSortIcon : function(col, dir){ - var sc = this.sortClasses; - var hds = this.view.innerHd.select('em').removeClass(sc); - hds.item(col).addClass(sc[dir == "DESC" ? 1 : 0]); + + highlightAt: function(index) { + var boundList = this.boundList, + item = boundList.all.item(index); + if (item) { + item = item.dom; + boundList.highlightItem(item); + boundList.getTargetEl().scrollChildIntoView(item, false); + } }, - onHdClick : function(e){ - var hd = e.getTarget('em', 3); - if(hd && !this.view.disableHeaders){ - var index = this.view.findHeaderIndex(hd); - this.view.store.sort(this.view.columns[index].dataIndex); + + selectHighlighted: function(e) { + var me = this, + boundList = me.boundList, + highlighted = boundList.highlightedItem, + selModel = boundList.getSelectionModel(); + if (highlighted) { + selModel.selectWithEvent(boundList.getRecord(highlighted), e); } } + }); +Ext.define('Ext.form.field.ComboBox', { + extend:'Ext.form.field.Picker', + requires: ['Ext.util.DelayedTask', 'Ext.EventObject', 'Ext.view.BoundList', 'Ext.view.BoundListKeyNav', 'Ext.data.StoreManager'], + alternateClassName: 'Ext.form.ComboBox', + alias: ['widget.combobox', 'widget.combo'], + + + triggerCls: Ext.baseCSSPrefix + 'form-arrow-trigger', -Ext.ListView.Sorter = Ext.list.Sorter; -Ext.TabPanel = Ext.extend(Ext.Panel, { + + multiSelect: false, + - deferredRender : true, + delimiter: ', ', + - tabWidth : 120, + displayField: 'text', + - minTabWidth : 30, + - resizeTabs : false, + triggerAction: 'all', + - enableTabScroll : false, + allQuery: '', + - scrollIncrement : 0, + queryParam: 'query', + - scrollRepeatInterval : 400, + queryMode: 'remote', + + queryCaching: true, + - scrollDuration : 0.35, + pageSize: 0, + - animScroll : true, + - tabPosition : 'top', + - baseCls : 'x-tab-panel', + autoSelect: true, + - autoTabs : false, + typeAhead: false, + - autoTabSelector : 'div.x-tab', + typeAheadDelay: 250, + - activeTab : undefined, + selectOnTab: true, + - tabMargin : 2, + forceSelection: false, + - plain : false, + - wheelIncrement : 20, - idDelimiter : '__', + defaultListConfig: { + emptyText: '', + loadingText: 'Loading...', + loadingHeight: 70, + minWidth: 70, + maxHeight: 300, + shadow: 'sides' + }, - itemCls : 'x-tab-item', - elements : 'body', - headerAsText : false, - frame : false, - hideBorders :true, - initComponent : function(){ - this.frame = false; - Ext.TabPanel.superclass.initComponent.call(this); + ignoreSelection: 0, + + initComponent: function() { + var me = this, + isDefined = Ext.isDefined, + store = me.store, + transform = me.transform, + transformSelect, isLocalMode; + + if (!store && !transform) { + Ext.Error.raise('Either a valid store, or a HTML select to transform, must be configured on the combo.'); + } + if (me.typeAhead && me.multiSelect) { + Ext.Error.raise('typeAhead and multiSelect are mutually exclusive options -- please remove one of them.'); + } + if (me.typeAhead && !me.editable) { + Ext.Error.raise('If typeAhead is enabled the combo must be editable: true -- please change one of those settings.'); + } + if (me.selectOnFocus && !me.editable) { + Ext.Error.raise('If selectOnFocus is enabled the combo must be editable: true -- please change one of those settings.'); + } + this.addEvents( - 'beforetabchange', + - 'tabchange', + 'beforequery', + - 'contextmenu' + 'select' ); - - this.setLayout(new Ext.layout.CardLayout(Ext.apply({ - layoutOnCardChange: this.layoutOnTabChange, - deferredRender: this.deferredRender - }, this.layoutConfig))); - if(this.tabPosition == 'top'){ - this.elements += ',header'; - this.stripTarget = 'header'; - }else { - this.elements += ',footer'; - this.stripTarget = 'footer'; + + if (!store && transform) { + transformSelect = Ext.getDom(transform); + if (transformSelect) { + store = Ext.Array.map(Ext.Array.from(transformSelect.options), function(option) { + return [option.value, option.text]; + }); + if (!me.name) { + me.name = transformSelect.name; + } + if (!('value' in me)) { + me.value = transformSelect.value; + } + } } - if(!this.stack){ - this.stack = Ext.TabPanel.AccessStack(); + + me.bindStore(store, true); + store = me.store; + if (store.autoCreated) { + me.queryMode = 'local'; + me.valueField = me.displayField = 'field1'; + if (!store.expanded) { + me.displayField = 'field2'; + } } - this.initItems(); - }, - - onRender : function(ct, position){ - Ext.TabPanel.superclass.onRender.call(this, ct, position); - if(this.plain){ - var pos = this.tabPosition == 'top' ? 'header' : 'footer'; - this[pos].addClass('x-tab-panel-'+pos+'-plain'); + if (!isDefined(me.valueField)) { + me.valueField = me.displayField; } - var st = this[this.stripTarget]; - - this.stripWrap = st.createChild({cls:'x-tab-strip-wrap', cn:{ - tag:'ul', cls:'x-tab-strip x-tab-strip-'+this.tabPosition}}); + isLocalMode = me.queryMode === 'local'; + if (!isDefined(me.queryDelay)) { + me.queryDelay = isLocalMode ? 10 : 500; + } + if (!isDefined(me.minChars)) { + me.minChars = isLocalMode ? 0 : 4; + } - var beforeEl = (this.tabPosition=='bottom' ? this.stripWrap : null); - st.createChild({cls:'x-tab-strip-spacer'}, beforeEl); - this.strip = new Ext.Element(this.stripWrap.dom.firstChild); + if (!me.displayTpl) { + me.displayTpl = Ext.create('Ext.XTemplate', + '' + + '{[typeof values === "string" ? values : values.' + me.displayField + ']}' + + '' + me.delimiter + '' + + '' + ); + } else if (Ext.isString(me.displayTpl)) { + me.displayTpl = Ext.create('Ext.XTemplate', me.displayTpl); + } - - this.edge = this.strip.createChild({tag:'li', cls:'x-tab-edge', cn: [{tag: 'span', cls: 'x-tab-strip-text', cn: ' '}]}); - this.strip.createChild({cls:'x-clear'}); + me.callParent(); - this.body.addClass('x-tab-panel-body-'+this.tabPosition); + me.doQueryTask = Ext.create('Ext.util.DelayedTask', me.doRawQuery, me); - if(!this.itemTpl){ - var tt = new Ext.Template( - '
  • ', - '', - '{text}', - '
  • ' - ); - tt.disableFormats = true; - tt.compile(); - Ext.TabPanel.prototype.itemTpl = tt; + if (me.store.getCount() > 0) { + me.setValue(me.value); } - this.items.each(this.initTab, this); + + if (transformSelect) { + me.render(transformSelect.parentNode, transformSelect); + Ext.removeNode(transformSelect); + delete me.renderTo; + } }, - - afterRender : function(){ - Ext.TabPanel.superclass.afterRender.call(this); - if(this.autoTabs){ - this.readTabs(false); - } - if(this.activeTab !== undefined){ - var item = Ext.isObject(this.activeTab) ? this.activeTab : this.items.get(this.activeTab); - delete this.activeTab; - this.setActiveTab(item); + beforeBlur: function() { + var me = this; + me.doQueryTask.cancel(); + if (me.forceSelection) { + me.assertValue(); + } else { + me.collapse(); } }, - initEvents : function(){ - Ext.TabPanel.superclass.initEvents.call(this); - this.mon(this.strip, { - scope: this, - mousedown: this.onStripMouseDown, - contextmenu: this.onStripContextMenu - }); - if(this.enableTabScroll){ - this.mon(this.strip, 'mousewheel', this.onWheel, this); + assertValue: function() { + var me = this, + value = me.getRawValue(), + rec; + + if (me.multiSelect) { + + + if (value !== me.getDisplayValue()) { + me.setValue(me.lastSelection); + } + } else { + + + rec = me.findRecordByDisplay(value); + if (rec) { + me.select(rec); + } else { + me.setValue(me.lastSelection); + } } + me.collapse(); }, - - findTargets : function(e){ - var item = null, - itemEl = e.getTarget('li:not(.x-tab-edge)', this.strip); + onTypeAhead: function() { + var me = this, + displayField = me.displayField, + record = me.store.findRecord(displayField, me.getRawValue()), + boundList = me.getPicker(), + newValue, len, selStart; - if(itemEl){ - item = this.getComponent(itemEl.id.split(this.idDelimiter)[1]); - if(item.disabled){ - return { - close : null, - item : null, - el : null - }; + if (record) { + newValue = record.get(displayField); + len = newValue.length; + selStart = me.getRawValue().length; + + boundList.highlightItem(boundList.getNode(record)); + + if (selStart !== 0 && selStart !== len) { + me.setRawValue(newValue); + me.selectText(selStart, newValue.length); } } - return { - close : e.getTarget('.x-tab-strip-close', this.strip), - item : item, - el : itemEl - }; }, - onStripMouseDown : function(e){ - if(e.button !== 0){ - return; - } - e.preventDefault(); - var t = this.findTargets(e); - if(t.close){ - if (t.item.fireEvent('beforeclose', t.item) !== false) { - t.item.fireEvent('close', t.item); - this.remove(t.item); + + resetToDefault: function() { + + }, + + bindStore: function(store, initial) { + var me = this, + oldStore = me.store; + + + + if (oldStore && !initial) { + if (oldStore !== store && oldStore.autoDestroy) { + oldStore.destroy(); + } else { + oldStore.un({ + scope: me, + load: me.onLoad, + exception: me.collapse + }); + } + if (!store) { + me.store = null; + if (me.picker) { + me.picker.bindStore(null); + } } - return; } - if(t.item && t.item != this.activeTab){ - this.setActiveTab(t.item); + if (store) { + if (!initial) { + me.resetToDefault(); + } + + me.store = Ext.data.StoreManager.lookup(store); + me.store.on({ + scope: me, + load: me.onLoad, + exception: me.collapse + }); + + if (me.picker) { + me.picker.bindStore(store); + } } }, - - onStripContextMenu : function(e){ - e.preventDefault(); - var t = this.findTargets(e); - if(t.item){ - this.fireEvent('contextmenu', this, t.item, e); + onLoad: function() { + var me = this, + value = me.value; + + me.syncSelection(); + if (me.picker && !me.picker.getSelectionModel().hasSelection()) { + me.doAutoSelect(); } }, - readTabs : function(removeExisting){ - if(removeExisting === true){ - this.items.each(function(item){ - this.remove(item); - }, this); - } - var tabs = this.el.query(this.autoTabSelector); - for(var i = 0, len = tabs.length; i < len; i++){ - var tab = tabs[i], - title = tab.getAttribute('title'); - tab.removeAttribute('title'); - this.add({ - title: title, - contentEl: tab - }); - } + doRawQuery: function() { + this.doQuery(this.getRawValue()); }, - initTab : function(item, index){ - var before = this.strip.dom.childNodes[index], - p = this.getTemplateArgs(item), - el = before ? - this.itemTpl.insertBefore(before, p) : - this.itemTpl.append(this.strip, p), - cls = 'x-tab-strip-over', - tabEl = Ext.get(el); + doQuery: function(queryString, forceAll) { + queryString = queryString || ''; - tabEl.hover(function(){ - if(!item.disabled){ - tabEl.addClass(cls); - } - }, function(){ - tabEl.removeClass(cls); - }); + + + var me = this, + qe = { + query: queryString, + forceAll: forceAll, + combo: me, + cancel: false + }, + store = me.store, + isLocalMode = me.queryMode === 'local'; - if(item.tabTip){ - tabEl.child('span.x-tab-strip-text', true).qtip = item.tabTip; + if (me.fireEvent('beforequery', qe) === false || qe.cancel) { + return false; } - item.tabEl = el; - tabEl.select('a').on('click', function(e){ - if(!e.getPageX()){ - this.onStripMouseDown(e); - } - }, this, {preventDefault: true}); + queryString = qe.query; + forceAll = qe.forceAll; - item.on({ - scope: this, - disable: this.onItemDisabled, - enable: this.onItemEnabled, - titlechange: this.onItemTitleChanged, - iconchange: this.onItemIconChanged, - beforeshow: this.onBeforeShowItem - }); - }, + + if (forceAll || (queryString.length >= me.minChars)) { + + me.expand(); + + if (!me.queryCaching || me.lastQuery !== queryString) { + me.lastQuery = queryString; + store.clearFilter(!forceAll); + if (isLocalMode) { + if (!forceAll) { + store.filter(me.displayField, queryString); + } + } else { + store.load({ + params: me.getParams(queryString) + }); + } + } + + if (me.getRawValue() !== me.getDisplayValue()) { + me.ignoreSelection++; + me.picker.getSelectionModel().deselectAll(); + me.ignoreSelection--; + } - - getTemplateArgs : function(item) { - var cls = item.closable ? 'x-tab-strip-closable' : ''; - if(item.disabled){ - cls += ' x-item-disabled'; - } - if(item.iconCls){ - cls += ' x-tab-with-icon'; - } - if(item.tabCls){ - cls += ' ' + item.tabCls; + if (isLocalMode) { + me.doAutoSelect(); + } + if (me.typeAhead) { + me.doTypeAhead(); + } } - - return { - id: this.id + this.idDelimiter + item.getItemId(), - text: item.title, - cls: cls, - iconCls: item.iconCls || '' - }; + return true; }, - onAdd : function(c){ - Ext.TabPanel.superclass.onAdd.call(this, c); - if(this.rendered){ - var items = this.items; - this.initTab(c, items.indexOf(c)); - this.delegateUpdates(); + getParams: function(queryString) { + var p = {}, + pageSize = this.pageSize; + p[this.queryParam] = queryString; + if (pageSize) { + p.start = 0; + p.limit = pageSize; } + return p; }, - onBeforeAdd : function(item){ - var existing = item.events ? (this.items.containsKey(item.getItemId()) ? item : null) : this.items.get(item); - if(existing){ - this.setActiveTab(item); - return false; - } - Ext.TabPanel.superclass.onBeforeAdd.apply(this, arguments); - var es = item.elements; - item.elements = es ? es.replace(',header', '') : es; - item.border = (item.border === true); - }, - - - onRemove : function(c){ - var te = Ext.get(c.tabEl); - - if(te){ - te.select('a').removeAllListeners(); - Ext.destroy(te); - } - Ext.TabPanel.superclass.onRemove.call(this, c); - this.stack.remove(c); - delete c.tabEl; - c.un('disable', this.onItemDisabled, this); - c.un('enable', this.onItemEnabled, this); - c.un('titlechange', this.onItemTitleChanged, this); - c.un('iconchange', this.onItemIconChanged, this); - c.un('beforeshow', this.onBeforeShowItem, this); - if(c == this.activeTab){ - var next = this.stack.next(); - if(next){ - this.setActiveTab(next); - }else if(this.items.getCount() > 0){ - this.setActiveTab(0); - }else{ - this.setActiveTab(null); + doAutoSelect: function() { + var me = this, + picker = me.picker, + lastSelected, itemNode; + if (picker && me.autoSelect && me.store.getCount() > 0) { + + lastSelected = picker.getSelectionModel().lastSelected; + itemNode = picker.getNode(lastSelected || 0); + if (itemNode) { + picker.highlightItem(itemNode); + picker.listEl.scrollChildIntoView(itemNode, false); } } - if(!this.destroying){ - this.delegateUpdates(); - } }, - - onBeforeShowItem : function(item){ - if(item != this.activeTab){ - this.setActiveTab(item); - return false; + doTypeAhead: function() { + if (!this.typeAheadTask) { + this.typeAheadTask = Ext.create('Ext.util.DelayedTask', this.onTypeAhead, this); + } + if (this.lastKey != Ext.EventObject.BACKSPACE && this.lastKey != Ext.EventObject.DELETE) { + this.typeAheadTask.delay(this.typeAheadDelay); } }, - - onItemDisabled : function(item){ - var el = this.getTabEl(item); - if(el){ - Ext.fly(el).addClass('x-item-disabled'); + onTriggerClick: function() { + var me = this; + if (!me.readOnly && !me.disabled) { + if (me.isExpanded) { + me.collapse(); + } else { + me.onFocus({}); + if (me.triggerAction === 'all') { + me.doQuery(me.allQuery, true); + } else { + me.doQuery(me.getRawValue()); + } + } + me.inputEl.focus(); } - this.stack.remove(item); }, + - onItemEnabled : function(item){ - var el = this.getTabEl(item); - if(el){ - Ext.fly(el).removeClass('x-item-disabled'); + onKeyUp: function(e, t) { + var me = this, + key = e.getKey(); + + if (!me.readOnly && !me.disabled && me.editable) { + me.lastKey = key; + + + + + if (!e.isSpecialKey() || key == e.BACKSPACE || key == e.DELETE) { + me.doQueryTask.delay(me.queryDelay); + } } }, - - onItemTitleChanged : function(item){ - var el = this.getTabEl(item); - if(el){ - Ext.fly(el).child('span.x-tab-strip-text', true).innerHTML = item.title; - } + initEvents: function() { + var me = this; + me.callParent(); + + + me.mon(me.inputEl, 'keyup', me.onKeyUp, me); + }, + + createPicker: function() { + var me = this, + picker, + menuCls = Ext.baseCSSPrefix + 'menu', + opts = Ext.apply({ + selModel: { + mode: me.multiSelect ? 'SIMPLE' : 'SINGLE' + }, + floating: true, + hidden: true, + ownerCt: me.ownerCt, + cls: me.el.up('.' + menuCls) ? menuCls : '', + store: me.store, + displayField: me.displayField, + focusOnToFront: false, + pageSize: me.pageSize + }, me.listConfig, me.defaultListConfig); + + picker = me.picker = Ext.create('Ext.view.BoundList', opts); + + me.mon(picker, { + itemclick: me.onItemClick, + refresh: me.onListRefresh, + scope: me + }); + + me.mon(picker.getSelectionModel(), { + selectionChange: me.onListSelectionChange, + scope: me + }); + + return picker; }, + onListRefresh: function() { + this.alignPicker(); + this.syncSelection(); + }, - onItemIconChanged : function(item, iconCls, oldCls){ - var el = this.getTabEl(item); - if(el){ - el = Ext.get(el); - el.child('span.x-tab-strip-text').replaceClass(oldCls, iconCls); - el[Ext.isEmpty(iconCls) ? 'removeClass' : 'addClass']('x-tab-with-icon'); + onItemClick: function(picker, record){ + + var me = this, + lastSelection = me.lastSelection, + valueField = me.valueField, + selected; + + if (!me.multiSelect && lastSelection) { + selected = lastSelection[0]; + if (record.get(valueField) === selected.get(valueField)) { + me.collapse(); + } + } + }, + + onListSelectionChange: function(list, selectedRecords) { + var me = this; + + + if (!me.ignoreSelection && me.isExpanded) { + if (!me.multiSelect) { + Ext.defer(me.collapse, 1, me); + } + me.setValue(selectedRecords, false); + if (selectedRecords.length > 0) { + me.fireEvent('select', me, selectedRecords); + } + me.inputEl.focus(); } }, - getTabEl : function(item){ - var c = this.getComponent(item); - return c ? c.tabEl : null; + onExpand: function() { + var me = this, + keyNav = me.listKeyNav, + selectOnTab = me.selectOnTab, + picker = me.getPicker(); + + + if (keyNav) { + keyNav.enable(); + } else { + keyNav = me.listKeyNav = Ext.create('Ext.view.BoundListKeyNav', this.inputEl, { + boundList: picker, + forceKeyDown: true, + tab: function(e) { + if (selectOnTab) { + this.selectHighlighted(e); + me.triggerBlur(); + } + + return true; + } + }); + } + + + if (selectOnTab) { + me.ignoreMonitorTab = true; + } + + Ext.defer(keyNav.enable, 1, keyNav); + me.inputEl.focus(); }, - onResize : function(){ - Ext.TabPanel.superclass.onResize.apply(this, arguments); - this.delegateUpdates(); + onCollapse: function() { + var me = this, + keyNav = me.listKeyNav; + if (keyNav) { + keyNav.disable(); + me.ignoreMonitorTab = false; + } }, - beginUpdate : function(){ - this.suspendUpdates = true; + select: function(r) { + this.setValue(r, true); }, - endUpdate : function(){ - this.suspendUpdates = false; - this.delegateUpdates(); + findRecord: function(field, value) { + var ds = this.store, + idx = ds.findExact(field, value); + return idx !== -1 ? ds.getAt(idx) : false; + }, + findRecordByValue: function(value) { + return this.findRecord(this.valueField, value); + }, + findRecordByDisplay: function(value) { + return this.findRecord(this.displayField, value); }, - hideTabStripItem : function(item){ - item = this.getComponent(item); - var el = this.getTabEl(item); - if(el){ - el.style.display = 'none'; - this.delegateUpdates(); + setValue: function(value, doSelect) { + var me = this, + valueNotFoundText = me.valueNotFoundText, + inputEl = me.inputEl, + i, len, record, + models = [], + displayTplData = [], + processedValue = []; + + if (me.store.loading) { + + me.value = value; + return me; } - this.stack.remove(item); - }, - - unhideTabStripItem : function(item){ - item = this.getComponent(item); - var el = this.getTabEl(item); - if(el){ - el.style.display = ''; - this.delegateUpdates(); + + value = Ext.Array.from(value); + + + for (i = 0, len = value.length; i < len; i++) { + record = value[i]; + if (!record || !record.isModel) { + record = me.findRecordByValue(record); + } + + if (record) { + models.push(record); + displayTplData.push(record.data); + processedValue.push(record.get(me.valueField)); + } + + + else { + + if (Ext.isDefined(valueNotFoundText)) { + displayTplData.push(valueNotFoundText); + } + processedValue.push(value[i]); + } } - }, - - delegateUpdates : function(){ - var rendered = this.rendered; - if(this.suspendUpdates){ - return; + + me.value = me.multiSelect ? processedValue : processedValue[0]; + if (!Ext.isDefined(me.value)) { + me.value = null; } - if(this.resizeTabs && rendered){ - this.autoSizeTabs(); + me.displayTplData = displayTplData; + me.lastSelection = me.valueModels = models; + + if (inputEl && me.emptyText && !Ext.isEmpty(value)) { + inputEl.removeCls(me.emptyCls); } - if(this.enableTabScroll && rendered){ - this.autoScrollTabs(); + + + me.setRawValue(me.getDisplayValue()); + me.checkChange(); + + if (doSelect !== false) { + me.syncSelection(); } + me.applyEmptyText(); + + return me; }, - autoSizeTabs : function(){ - var count = this.items.length, - ce = this.tabPosition != 'bottom' ? 'header' : 'footer', - ow = this[ce].dom.offsetWidth, - aw = this[ce].dom.clientWidth; + getDisplayValue: function() { + return this.displayTpl.apply(this.displayTplData); + }, - if(!this.resizeTabs || count < 1 || !aw){ - return; - } + getValue: function() { + + + + var me = this, + picker = me.picker, + rawValue = me.getRawValue(), + value = me.value; - var each = Math.max(Math.min(Math.floor((aw-4) / count) - this.tabMargin, this.tabWidth), this.minTabWidth); - this.lastTabWidth = each; - var lis = this.strip.query('li:not(.x-tab-edge)'); - for(var i = 0, len = lis.length; i < len; i++) { - var li = lis[i], - inner = Ext.fly(li).child('.x-tab-strip-inner', true), - tw = li.offsetWidth, - iw = inner.offsetWidth; - inner.style.width = (each - (tw-iw)) + 'px'; + if (me.getDisplayValue() !== rawValue) { + value = rawValue; + me.value = me.displayTplData = me.valueModels = null; + if (picker) { + me.ignoreSelection++; + picker.getSelectionModel().deselectAll(); + me.ignoreSelection--; + } } + + return value; }, - - adjustBodyWidth : function(w){ - if(this.header){ - this.header.setWidth(w); - } - if(this.footer){ - this.footer.setWidth(w); - } - return w; + getSubmitValue: function() { + return this.getValue(); }, - - setActiveTab : function(item){ - item = this.getComponent(item); - if(this.fireEvent('beforetabchange', this, item, this.activeTab) === false){ - return; - } - if(!this.rendered){ - this.activeTab = item; - return; + isEqual: function(v1, v2) { + var fromArray = Ext.Array.from, + i, len; + + v1 = fromArray(v1); + v2 = fromArray(v2); + len = v1.length; + + if (len !== v2.length) { + return false; } - if(this.activeTab != item){ - if(this.activeTab){ - var oldEl = this.getTabEl(this.activeTab); - if(oldEl){ - Ext.fly(oldEl).removeClass('x-tab-strip-active'); - } - } - this.activeTab = item; - if(item){ - var el = this.getTabEl(item); - Ext.fly(el).addClass('x-tab-strip-active'); - this.stack.add(item); - this.layout.setActiveItem(item); - - this.delegateUpdates(); - if(this.scrolling){ - this.scrollToTab(item, this.animScroll); - } + for(i = 0; i < len; i++) { + if (v2[i] !== v1[i]) { + return false; } - this.fireEvent('tabchange', this, item); } - }, - - getActiveTab : function(){ - return this.activeTab || null; + return true; }, - getItem : function(item){ - return this.getComponent(item); + clearValue: function() { + this.setValue([]); }, - autoScrollTabs : function(){ - this.pos = this.tabPosition=='bottom' ? this.footer : this.header; - var count = this.items.length, - ow = this.pos.dom.offsetWidth, - tw = this.pos.dom.clientWidth, - wrap = this.stripWrap, - wd = wrap.dom, - cw = wd.offsetWidth, - pos = this.getScrollPos(), - l = this.edge.getOffsetsTo(this.stripWrap)[0] + pos; + syncSelection: function() { + var me = this, + ExtArray = Ext.Array, + picker = me.picker, + selection, selModel; + if (picker) { + + selection = []; + ExtArray.forEach(me.valueModels || [], function(value) { + if (value && value.isModel && me.store.indexOf(value) >= 0) { + selection.push(value); + } + }); - if(!this.enableTabScroll || cw < 20){ - return; - } - if(count == 0 || l <= tw){ - wd.scrollLeft = 0; - wrap.setWidth(tw); - if(this.scrolling){ - this.scrolling = false; - this.pos.removeClass('x-tab-scrolling'); - this.scrollLeft.hide(); - this.scrollRight.hide(); - - if(Ext.isAir || Ext.isWebKit){ - wd.style.marginLeft = ''; - wd.style.marginRight = ''; - } - } - }else{ - if(!this.scrolling){ - this.pos.addClass('x-tab-scrolling'); - - if(Ext.isAir || Ext.isWebKit){ - wd.style.marginLeft = '18px'; - wd.style.marginRight = '18px'; - } - } - tw -= wrap.getMargins('lr'); - wrap.setWidth(tw > 20 ? tw : 20); - if(!this.scrolling){ - if(!this.scrollLeft){ - this.createScrollers(); - }else{ - this.scrollLeft.show(); - this.scrollRight.show(); - } - } - this.scrolling = true; - if(pos > (l-tw)){ - wd.scrollLeft = l-tw; - }else{ - this.scrollToTab(this.activeTab, false); + me.ignoreSelection++; + selModel = picker.getSelectionModel(); + selModel.deselectAll(); + if (selection.length) { + selModel.select(selection); } - this.updateScrollButtons(); + me.ignoreSelection--; } + } +}); + + +Ext.define('Ext.picker.Month', { + extend: 'Ext.Component', + requires: ['Ext.XTemplate', 'Ext.util.ClickRepeater', 'Ext.Date', 'Ext.button.Button'], + alias: 'widget.monthpicker', + alternateClassName: 'Ext.MonthPicker', + + renderTpl: [ + '
    ', + '
    ', + '', + '', + '', + '
    ', + '
    ', + '
    ', + '', + '', + '
    ', + '', + '', + '', + '
    ', + '
    ', + '
    ', + '', + '
    ', + '
    ' + ], + + + okText: 'OK', + + + cancelText: 'Cancel', + + + baseCls: Ext.baseCSSPrefix + 'monthpicker', + + + showButtons: true, + + + + + + width: 175, + + height: 195, + + + + totalYears: 10, + yearOffset: 5, + monthOffset: 6, + + + initComponent: function(){ + var me = this; + + me.selectedCls = me.baseCls + '-selected'; + me.addEvents( + + 'cancelclick', + + + 'monthclick', + + + 'monthdblclick', + + + 'okclick', + + + 'select', + + + 'yearclick', + + + 'yeardblclick' + ); + + me.setValue(me.value); + me.activeYear = me.getYear(new Date().getFullYear() - 4, -4); + this.callParent(); }, - createScrollers : function(){ - this.pos.addClass('x-tab-scrolling-' + this.tabPosition); - var h = this.stripWrap.dom.offsetHeight; + onRender: function(ct, position){ + var me = this, + i = 0, + months = [], + shortName = Ext.Date.getShortMonthName, + monthLen = me.monthOffset; - - var sl = this.pos.insertFirst({ - cls:'x-tab-scroller-left' + for (; i < monthLen; ++i) { + months.push(shortName(i), shortName(i + monthLen)); + } + + Ext.apply(me.renderData, { + months: months, + years: me.getYears(), + showButtons: me.showButtons }); - sl.setHeight(h); - sl.addClassOnOver('x-tab-scroller-left-over'); - this.leftRepeater = new Ext.util.ClickRepeater(sl, { - interval : this.scrollRepeatInterval, - handler: this.onScrollLeft, - scope: this + + Ext.apply(me.renderSelectors, { + bodyEl: '.' + me.baseCls + '-body', + prevEl: '.' + me.baseCls + '-yearnav-prev', + nextEl: '.' + me.baseCls + '-yearnav-next', + buttonsEl: '.' + me.baseCls + '-buttons' }); - this.scrollLeft = sl; + this.callParent([ct, position]); + }, + + + afterRender: function(){ + var me = this, + body = me.bodyEl, + buttonsEl = me.buttonsEl; + + me.callParent(); + + me.mon(body, 'click', me.onBodyClick, me); + me.mon(body, 'dblclick', me.onBodyClick, me); - var sr = this.pos.insertFirst({ - cls:'x-tab-scroller-right' + me.years = body.select('.' + me.baseCls + '-year a'); + me.months = body.select('.' + me.baseCls + '-month a'); + + if (me.showButtons) { + me.okBtn = Ext.create('Ext.button.Button', { + text: me.okText, + renderTo: buttonsEl, + handler: me.onOkClick, + scope: me + }); + me.cancelBtn = Ext.create('Ext.button.Button', { + text: me.cancelText, + renderTo: buttonsEl, + handler: me.onCancelClick, + scope: me + }); + } + + me.backRepeater = Ext.create('Ext.util.ClickRepeater', me.prevEl, { + handler: Ext.Function.bind(me.adjustYear, me, [-me.totalYears]) }); - sr.setHeight(h); - sr.addClassOnOver('x-tab-scroller-right-over'); - this.rightRepeater = new Ext.util.ClickRepeater(sr, { - interval : this.scrollRepeatInterval, - handler: this.onScrollRight, - scope: this + + me.prevEl.addClsOnOver(me.baseCls + '-yearnav-prev-over'); + me.nextRepeater = Ext.create('Ext.util.ClickRepeater', me.nextEl, { + handler: Ext.Function.bind(me.adjustYear, me, [me.totalYears]) }); - this.scrollRight = sr; + me.nextEl.addClsOnOver(me.baseCls + '-yearnav-next-over'); + me.updateBody(); }, - getScrollWidth : function(){ - return this.edge.getOffsetsTo(this.stripWrap)[0] + this.getScrollPos(); - }, + setValue: function(value){ + var me = this, + active = me.activeYear, + offset = me.monthOffset, + year, + index; - - getScrollPos : function(){ - return parseInt(this.stripWrap.dom.scrollLeft, 10) || 0; - }, + if (!value) { + me.value = [null, null]; + } else if (Ext.isDate(value)) { + me.value = [value.getMonth(), value.getFullYear()]; + } else { + me.value = [value[0], value[1]]; + } - - getScrollArea : function(){ - return parseInt(this.stripWrap.dom.clientWidth, 10) || 0; + if (me.rendered) { + year = me.value[1]; + if (year !== null) { + if ((year < active || year > active + me.yearOffset)) { + me.activeYear = year - me.yearOffset + 1; + } + } + me.updateBody(); + } + + return me; }, - getScrollAnim : function(){ - return {duration:this.scrollDuration, callback: this.updateScrollButtons, scope: this}; + getValue: function(){ + return this.value; }, - getScrollIncrement : function(){ - return this.scrollIncrement || (this.resizeTabs ? this.lastTabWidth+2 : 100); + hasSelection: function(){ + var value = this.value; + return value[0] !== null && value[1] !== null; }, + getYears: function(){ + var me = this, + offset = me.yearOffset, + start = me.activeYear, + end = start + offset, + i = start, + years = []; - scrollToTab : function(item, animate){ - if(!item){ - return; - } - var el = this.getTabEl(item), - pos = this.getScrollPos(), - area = this.getScrollArea(), - left = Ext.fly(el).getOffsetsTo(this.stripWrap)[0] + pos, - right = left + el.offsetWidth; - if(left < pos){ - this.scrollTo(left, animate); - }else if(right > (pos + area)){ - this.scrollTo(right - area, animate); + for (; i < end; ++i) { + years.push(i, i + offset); } + + return years; }, - scrollTo : function(pos, animate){ - this.stripWrap.scrollTo('left', pos, animate ? this.getScrollAnim() : false); - if(!animate){ - this.updateScrollButtons(); + updateBody: function(){ + var me = this, + years = me.years, + months = me.months, + yearNumbers = me.getYears(), + cls = me.selectedCls, + value = me.getYear(null), + month = me.value[0], + monthOffset = me.monthOffset, + year; + + if (me.rendered) { + years.removeCls(cls); + months.removeCls(cls); + years.each(function(el, all, index){ + year = yearNumbers[index]; + el.dom.innerHTML = year; + if (year == value) { + el.dom.className = cls; + } + }); + if (month !== null) { + if (month < monthOffset) { + month = month * 2; + } else { + month = (month - monthOffset) * 2 + 1; + } + months.item(month).addCls(cls); + } } }, - onWheel : function(e){ - var d = e.getWheelDelta()*this.wheelIncrement*-1; - e.stopEvent(); + + getYear: function(defaultValue, offset) { + var year = this.value[1]; + offset = offset || 0; + return year === null ? defaultValue : year + offset; + }, - var pos = this.getScrollPos(), - newpos = pos + d, - sw = this.getScrollWidth()-this.getScrollArea(); + + onBodyClick: function(e, t) { + var me = this, + isDouble = e.type == 'dblclick'; - var s = Math.max(0, Math.min(sw, newpos)); - if(s != pos){ - this.scrollTo(s, false); + if (e.getTarget('.' + me.baseCls + '-month')) { + e.stopEvent(); + me.onMonthClick(t, isDouble); + } else if (e.getTarget('.' + me.baseCls + '-year')) { + e.stopEvent(); + me.onYearClick(t, isDouble); } }, - onScrollRight : function(){ - var sw = this.getScrollWidth()-this.getScrollArea(), - pos = this.getScrollPos(), - s = Math.min(sw, pos + this.getScrollIncrement()); - if(s != pos){ - this.scrollTo(s, this.animScroll); + adjustYear: function(offset){ + if (typeof offset != 'number') { + offset = this.totalYears; } + this.activeYear += offset; + this.updateBody(); }, - onScrollLeft : function(){ - var pos = this.getScrollPos(), - s = Math.max(0, pos - this.getScrollIncrement()); - if(s != pos){ - this.scrollTo(s, this.animScroll); - } + onOkClick: function(){ + this.fireEvent('okclick', this, this.value); }, - updateScrollButtons : function(){ - var pos = this.getScrollPos(); - this.scrollLeft[pos === 0 ? 'addClass' : 'removeClass']('x-tab-scroller-left-disabled'); - this.scrollRight[pos >= (this.getScrollWidth()-this.getScrollArea()) ? 'addClass' : 'removeClass']('x-tab-scroller-right-disabled'); + onCancelClick: function(){ + this.fireEvent('cancelclick', this); }, - beforeDestroy : function() { - Ext.destroy(this.leftRepeater, this.rightRepeater); - this.deleteMembers('strip', 'edge', 'scrollLeft', 'scrollRight', 'stripWrap'); - this.activeTab = null; - Ext.TabPanel.superclass.beforeDestroy.apply(this); - } + onMonthClick: function(target, isDouble){ + var me = this; + me.value[0] = me.resolveOffset(me.months.indexOf(target), me.monthOffset); + me.updateBody(); + me.fireEvent('month' + (isDouble ? 'dbl' : '') + 'click', me, me.value); + me.fireEvent('select', me, me.value); + }, + onYearClick: function(target, isDouble){ + var me = this; + me.value[1] = me.activeYear + me.resolveOffset(me.years.indexOf(target), me.yearOffset); + me.updateBody(); + me.fireEvent('year' + (isDouble ? 'dbl' : '') + 'click', me, me.value); + me.fireEvent('select', me, me.value); + + }, + + resolveOffset: function(index, offset){ + if (index % 2 === 0) { + return (index / 2); + } else { + return offset + Math.floor(index / 2); + } + }, + + beforeDestroy: function(){ + var me = this; + me.years = me.months = null; + Ext.destroyMembers('backRepeater', 'nextRepeater', 'okBtn', 'cancelBtn'); + this.callParent(); + } +}); + + +Ext.define('Ext.picker.Date', { + extend: 'Ext.Component', + requires: [ + 'Ext.XTemplate', + 'Ext.button.Button', + 'Ext.button.Split', + 'Ext.util.ClickRepeater', + 'Ext.util.KeyNav', + 'Ext.EventObject', + 'Ext.fx.Manager', + 'Ext.picker.Month' + ], + alias: 'widget.datepicker', + alternateClassName: 'Ext.DatePicker', + + renderTpl: [ + '
    ', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '{#:this.isEndOfWeek}', + '', + '', + '', + '', + '', + '', + '', + '
    ', + { + firstInitial: function(value) { + return value.substr(0,1); + }, + isEndOfWeek: function(value) { + + + value--; + var end = value % 7 === 0 && value !== 0; + return end ? '' : ''; + }, + longDay: function(value){ + return Ext.Date.format(value, this.longDayFormat); + } + } + ], + + ariaTitle: 'Date Picker', + todayText : 'Today', + todayTip : '{0} (Spacebar)', + minText : 'This date is before the minimum date', + maxText : 'This date is after the maximum date', + disabledDaysText : 'Disabled', -}); -Ext.reg('tabpanel', Ext.TabPanel); - - -Ext.TabPanel.prototype.activate = Ext.TabPanel.prototype.setActiveTab; - - -Ext.TabPanel.AccessStack = function(){ - var items = []; - return { - add : function(item){ - items.push(item); - if(items.length > 10){ - items.shift(); - } - }, - - remove : function(item){ - var s = []; - for(var i = 0, len = items.length; i < len; i++) { - if(items[i] != item){ - s.push(items[i]); - } - } - items = s; - }, - - next : function(){ - return items.pop(); - } - }; -}; - -Ext.Button = Ext.extend(Ext.BoxComponent, { + disabledDatesText : 'Disabled', - hidden : false, - disabled : false, - pressed : false, - + nextText : 'Next Month (Control+Right)', - + prevText : 'Previous Month (Control+Left)', - + monthYearText : 'Choose a month (Control+Up/Down to move years)', - enableToggle : false, + startDay : 0, + showToday : true, - menuAlign : 'tl-bl?', - - type : 'button', - menuClassTarget : 'tr:nth(2)', + disableAnim: true, - clickEvent : 'click', + baseCls: Ext.baseCSSPrefix + 'datepicker', - handleMouseEvents : true, - tooltipType : 'qtip', - buttonSelector : 'button:first-child', + longDayFormat: 'F d, Y', - scale : 'small', + focusOnShow: false, - iconAlign : 'left', - - arrowAlign : 'right', + focusOnSelect: true, + + width: 178, + initHour: 12, + + numDays: 42, + - + initComponent : function() { + var me = this, + clearTime = Ext.Date.clearTime; - initComponent : function(){ - if(this.menu){ - this.menu = Ext.menu.MenuMgr.get(this.menu); - this.menu.ownerCt = this; - } - - Ext.Button.superclass.initComponent.call(this); + me.selectedCls = me.baseCls + '-selected'; + me.disabledCellCls = me.baseCls + '-disabled'; + me.prevCls = me.baseCls + '-prevday'; + me.activeCls = me.baseCls + '-active'; + me.nextCls = me.baseCls + '-prevday'; + me.todayCls = me.baseCls + '-today'; + me.dayNames = me.dayNames.slice(me.startDay).concat(me.dayNames.slice(0, me.startDay)); + this.callParent(); - this.addEvents( - - 'click', - - 'toggle', - - 'mouseover', - - 'mouseout', - - 'menushow', - - 'menuhide', - - 'menutriggerover', + me.value = me.value ? + clearTime(me.value, true) : clearTime(new Date()); + + me.addEvents( - 'menutriggerout' + 'select' ); - - if (this.menu){ - this.menu.ownerCt = undefined; - } - if(Ext.isString(this.toggleGroup)){ - this.enableToggle = true; - } - }, - - getTemplateArgs : function(){ - return [this.type, 'x-btn-' + this.scale + ' x-btn-icon-' + this.scale + '-' + this.iconAlign, this.getMenuClass(), this.cls, this.id]; + me.initDisabledDays(); }, - setButtonClass : function(){ - if(this.useSetClass){ - if(!Ext.isEmpty(this.oldCls)){ - this.el.removeClass([this.oldCls, 'x-btn-pressed']); - } - this.oldCls = (this.iconCls || this.icon) ? (this.text ? 'x-btn-text-icon' : 'x-btn-icon') : 'x-btn-noicon'; - this.el.addClass([this.oldCls, this.pressed ? 'x-btn-pressed' : null]); - } - }, + onRender : function(container, position){ + - - getMenuClass : function(){ - return this.menu ? (this.arrowAlign != 'bottom' ? 'x-btn-arrow' : 'x-btn-arrow-bottom') : ''; - }, + var me = this, + days = new Array(me.numDays), + today = Ext.Date.format(new Date(), me.format); - - onRender : function(ct, position){ - if(!this.template){ - if(!Ext.Button.buttonTemplate){ - - Ext.Button.buttonTemplate = new Ext.Template( - '', - '', - '', - '', - '
      
      
      
    '); - Ext.Button.buttonTemplate.compile(); - } - this.template = Ext.Button.buttonTemplate; - } + Ext.applyIf(me, { + renderData: {}, + renderSelectors: {} + }); - var btn, targs = this.getTemplateArgs(); + Ext.apply(me.renderData, { + dayNames: me.dayNames, + ariaTitle: me.ariaTitle, + value: me.value, + showToday: me.showToday, + prevText: me.prevText, + nextText: me.nextText, + days: days + }); + me.getTpl('renderTpl').longDayFormat = me.longDayFormat; + + Ext.apply(me.renderSelectors, { + eventEl: 'table.' + me.baseCls + '-inner', + prevEl: '.' + me.baseCls + '-prev a', + nextEl: '.' + me.baseCls + '-next a', + middleBtnEl: '.' + me.baseCls + '-month', + footerEl: '.' + me.baseCls + '-footer' + }); - if(position){ - btn = this.template.insertBefore(position, targs, true); - }else{ - btn = this.template.append(ct, targs, true); - } - - this.btnEl = btn.child(this.buttonSelector); - this.mon(this.btnEl, { - scope: this, - focus: this.onFocus, - blur: this.onBlur + this.callParent(arguments); + me.el.unselectable(); + + me.cells = me.eventEl.select('tbody td'); + me.textNodes = me.eventEl.query('tbody td span'); + + me.monthBtn = Ext.create('Ext.button.Split', { + text: '', + tooltip: me.monthYearText, + renderTo: me.middleBtnEl }); + - this.initButtonEl(btn, this.btnEl); - Ext.ButtonToggleMgr.register(this); + me.todayBtn = Ext.create('Ext.button.Button', { + renderTo: me.footerEl, + text: Ext.String.format(me.todayText, today), + tooltip: Ext.String.format(me.todayTip, today), + handler: me.selectToday, + scope: me + }); }, - initButtonEl : function(btn, btnEl){ - this.el = btn; - this.setIcon(this.icon); - this.setText(this.text); - this.setIconClass(this.iconCls); - if(Ext.isDefined(this.tabIndex)){ - btnEl.dom.tabIndex = this.tabIndex; - } - if(this.tooltip){ - this.setTooltip(this.tooltip, true); - } + initEvents: function(){ + var me = this, + eDate = Ext.Date, + day = eDate.DAY; - if(this.handleMouseEvents){ - this.mon(btn, { - scope: this, - mouseover: this.onMouseOver, - mousedown: this.onMouseDown - }); + this.callParent(); - - - } + me.prevRepeater = Ext.create('Ext.util.ClickRepeater', me.prevEl, { + handler: me.showPrevMonth, + scope: me, + preventDefault: true, + stopDefault: true + }); - if(this.menu){ - this.mon(this.menu, { - scope: this, - show: this.onMenuShow, - hide: this.onMenuHide - }); - } + me.nextRepeater = Ext.create('Ext.util.ClickRepeater', me.nextEl, { + handler: me.showNextMonth, + scope: me, + preventDefault:true, + stopDefault:true + }); - if(this.repeat){ - var repeater = new Ext.util.ClickRepeater(btn, Ext.isObject(this.repeat) ? this.repeat : {}); - this.mon(repeater, 'click', this.onRepeatClick, this); - }else{ - this.mon(btn, this.clickEvent, this.onClick, this); - } - }, + me.keyNav = Ext.create('Ext.util.KeyNav', me.eventEl, Ext.apply({ + scope: me, + 'left' : function(e){ + if(e.ctrlKey){ + me.showPrevMonth(); + }else{ + me.update(eDate.add(me.activeDate, day, -1)); + } + }, - - afterRender : function(){ - Ext.Button.superclass.afterRender.call(this); - this.useSetClass = true; - this.setButtonClass(); - this.doc = Ext.getDoc(); - this.doAutoWidth(); - }, + 'right' : function(e){ + if(e.ctrlKey){ + me.showNextMonth(); + }else{ + me.update(eDate.add(me.activeDate, day, 1)); + } + }, - - setIconClass : function(cls){ - this.iconCls = cls; - if(this.el){ - this.btnEl.dom.className = ''; - this.btnEl.addClass(['x-btn-text', cls || '']); - this.setButtonClass(); - } - return this; - }, + 'up' : function(e){ + if(e.ctrlKey){ + me.showNextYear(); + }else{ + me.update(eDate.add(me.activeDate, day, -7)); + } + }, - - setTooltip : function(tooltip, initial){ - if(this.rendered){ - if(!initial){ - this.clearTip(); - } - if(Ext.isObject(tooltip)){ - Ext.QuickTips.register(Ext.apply({ - target: this.btnEl.id - }, tooltip)); - this.tooltip = tooltip; - }else{ - this.btnEl.dom[this.tooltipType] = tooltip; + 'down' : function(e){ + if(e.ctrlKey){ + me.showPrevYear(); + }else{ + me.update(eDate.add(me.activeDate, day, 7)); + } + }, + 'pageUp' : me.showNextMonth, + 'pageDown' : me.showPrevMonth, + 'enter' : function(e){ + e.stopPropagation(); + return true; } - }else{ - this.tooltip = tooltip; + }, me.keyNavConfig)); + + if(me.showToday){ + me.todayKeyListener = me.eventEl.addKeyListener(Ext.EventObject.SPACE, me.selectToday, me); } - return this; + me.mon(me.eventEl, 'mousewheel', me.handleMouseWheel, me); + me.mon(me.eventEl, 'click', me.handleDateClick, me, {delegate: 'a.' + me.baseCls + '-date'}); + me.mon(me.monthBtn, 'click', me.showMonthPicker, me); + me.mon(me.monthBtn, 'arrowclick', me.showMonthPicker, me); + me.update(me.value); }, - clearTip : function(){ - if(Ext.isObject(this.tooltip)){ - Ext.QuickTips.unregister(this.btnEl); + initDisabledDays : function(){ + var me = this, + dd = me.disabledDates, + re = '(?:', + len; + + if(!me.disabledDatesRE && dd){ + len = dd.length - 1; + + Ext.each(dd, function(d, i){ + re += Ext.isDate(d) ? '^' + Ext.String.escapeRegex(Ext.Date.dateFormat(d, me.format)) + '$' : dd[i]; + if(i != len){ + re += '|'; + } + }, me); + me.disabledDatesRE = new RegExp(re + ')'); } }, - beforeDestroy : function(){ - if(this.rendered){ - this.clearTip(); - } - if(this.menu && this.destroyMenu !== false) { - Ext.destroy(this.btnEl, this.menu); + setDisabledDates : function(dd){ + var me = this; + + if(Ext.isArray(dd)){ + me.disabledDates = dd; + me.disabledDatesRE = null; + }else{ + me.disabledDatesRE = dd; } - Ext.destroy(this.repeater); + me.initDisabledDays(); + me.update(me.value, true); + return me; }, - onDestroy : function(){ - if(this.rendered){ - this.doc.un('mouseover', this.monitorMouseOver, this); - this.doc.un('mouseup', this.onMouseUp, this); - delete this.doc; - delete this.btnEl; - Ext.ButtonToggleMgr.unregister(this); - } - Ext.Button.superclass.onDestroy.call(this); + setDisabledDays : function(dd){ + this.disabledDays = dd; + return this.update(this.value, true); }, - doAutoWidth : function(){ - if(this.autoWidth !== false && this.el && this.text && this.width === undefined){ - this.el.setWidth('auto'); - if(Ext.isIE7 && Ext.isStrict){ - var ib = this.btnEl; - if(ib && ib.getWidth() > 20){ - ib.clip(); - ib.setWidth(Ext.util.TextMetrics.measure(ib, this.text).width+ib.getFrameWidth('lr')); - } - } - if(this.minWidth){ - if(this.el.getWidth() < this.minWidth){ - this.el.setWidth(this.minWidth); - } - } - } + setMinDate : function(dt){ + this.minDate = dt; + return this.update(this.value, true); }, - setHandler : function(handler, scope){ - this.handler = handler; - this.scope = scope; - return this; + setMaxDate : function(dt){ + this.maxDate = dt; + return this.update(this.value, true); }, - setText : function(text){ - this.text = text; - if(this.el){ - this.btnEl.update(text || ' '); - this.setButtonClass(); - } - this.doAutoWidth(); - return this; + setValue : function(value){ + this.value = Ext.Date.clearTime(value, true); + return this.update(this.value); }, - setIcon : function(icon){ - this.icon = icon; - if(this.el){ - this.btnEl.setStyle('background-image', icon ? 'url(' + icon + ')' : ''); - this.setButtonClass(); - } - return this; + getValue : function(){ + return this.value; }, - getText : function(){ - return this.text; + focus : function(){ + this.update(this.activeDate); }, - toggle : function(state, suppressEvent){ - state = state === undefined ? !this.pressed : !!state; - if(state != this.pressed){ - if(this.rendered){ - this.el[state ? 'addClass' : 'removeClass']('x-btn-pressed'); - } - this.pressed = state; - if(!suppressEvent){ - this.fireEvent('toggle', this, state); - if(this.toggleHandler){ - this.toggleHandler.call(this.scope || this, this, state); - } - } - } - return this; + onEnable: function(){ + this.callParent(); + this.setDisabledStatus(false); + this.update(this.activeDate); + }, onDisable : function(){ - this.onDisableChange(true); + this.callParent(); + this.setDisabledStatus(true); }, - onEnable : function(){ - this.onDisableChange(false); - }, + setDisabledStatus : function(disabled){ + var me = this; - onDisableChange : function(disabled){ - if(this.el){ - if(!Ext.isIE6 || !this.text){ - this.el[disabled ? 'addClass' : 'removeClass'](this.disabledClass); - } - this.el.dom.disabled = disabled; + me.keyNav.setDisabled(disabled); + me.prevRepeater.setDisabled(disabled); + me.nextRepeater.setDisabled(disabled); + if (me.showToday) { + me.todayKeyListener.setDisabled(disabled); + me.todayBtn.setDisabled(disabled); } - this.disabled = disabled; }, - showMenu : function(){ - if(this.rendered && this.menu){ - if(this.tooltip){ - Ext.QuickTips.getQuickTip().cancelShow(this.btnEl); - } - if(this.menu.isVisible()){ - this.menu.hide(); - } - this.menu.ownerCt = this; - this.menu.show(this.el, this.menuAlign); - } - return this; + getActive: function(){ + return this.activeDate || me.value; }, - hideMenu : function(){ - if(this.hasVisibleMenu()){ - this.menu.hide(); + runAnimation: function(isHide){ + var options = { + target: this.monthPicker, + duration: 200 + }; + + Ext.fx.Manager.run(); + if (isHide) { + + } else { + } - return this; + Ext.create('Ext.fx.Anim', options); }, - hasVisibleMenu : function(){ - return this.menu && this.menu.ownerCt == this && this.menu.isVisible(); - }, - - - onRepeatClick : function(repeat, e){ - this.onClick(e); - }, + hideMonthPicker : function(){ + var me = this, + picker = me.monthPicker; - - onClick : function(e){ - if(e){ - e.preventDefault(); - } - if(e.button !== 0){ - return; - } - if(!this.disabled){ - this.doToggle(); - if(this.menu && !this.hasVisibleMenu() && !this.ignoreNextClick){ - this.showMenu(); - } - this.fireEvent('click', this, e); - if(this.handler){ - - this.handler.call(this.scope || this, this, e); + if (picker) { + if (me.disableAnim) { + picker.hide(); + } else { + this.runAnimation(true); } } - }, - - - doToggle: function(){ - if (this.enableToggle && (this.allowDepress !== false || !this.pressed)) { - this.toggle(); - } + return me; }, - isMenuTriggerOver : function(e, internal){ - return this.menu && !internal; - }, + showMonthPicker : function(){ - - isMenuTriggerOut : function(e, internal){ - return this.menu && !internal; - }, + var me = this, + picker, + size, + top, + left; - - onMouseOver : function(e){ - if(!this.disabled){ - var internal = e.within(this.el, true); - if(!internal){ - this.el.addClass('x-btn-over'); - if(!this.monitoringMouseOver){ - this.doc.on('mouseover', this.monitorMouseOver, this); - this.monitoringMouseOver = true; - } - this.fireEvent('mouseover', this, e); - } - if(this.isMenuTriggerOver(e, internal)){ - this.fireEvent('menutriggerover', this, this.menu, e); - } - } - }, - - monitorMouseOver : function(e){ - if(e.target != this.el.dom && !e.within(this.el)){ - if(this.monitoringMouseOver){ - this.doc.un('mouseover', this.monitorMouseOver, this); - this.monitoringMouseOver = false; + if (me.rendered && !me.disabled) { + size = me.getSize(); + picker = me.createMonthPicker(); + picker.show(); + picker.setSize(size); + picker.setValue(me.getActive()); + + if (me.disableAnim) { + picker.setPosition(-1, -1); + } else { + me.runAnimation(false); } - this.onMouseOut(e); } + return me; }, - onMouseOut : function(e){ - var internal = e.within(this.el) && e.target != this.el.dom; - this.el.removeClass('x-btn-over'); - this.fireEvent('mouseout', this, e); - if(this.isMenuTriggerOut(e, internal)){ - this.fireEvent('menutriggerout', this, this.menu, e); - } - }, + createMonthPicker: function(){ + var me = this, + picker = me.monthPicker; - focus : function() { - this.btnEl.focus(); - }, + if (!picker) { + me.monthPicker = picker = Ext.create('Ext.picker.Month', { + renderTo: me.el, + floating: true, + shadow: false, + listeners: { + scope: me, + cancelclick: me.onCancelClick, + okclick: me.onOkClick, + yeardblclick: me.onOkClick, + monthdblclick: me.onOkClick + } + }); - blur : function() { - this.btnEl.blur(); + me.on('beforehide', me.hideMonthPicker, me); + } + return picker; }, - onFocus : function(e){ - if(!this.disabled){ - this.el.addClass('x-btn-focus'); + onOkClick: function(picker, value){ + var me = this, + month = value[0], + year = value[1], + date = new Date(year, month, me.getActive().getDate()); + + if (date.getMonth() !== month) { + + date = new Date(year, month, 1).getLastDateOfMonth(); } + me.update(date); + me.hideMonthPicker(); }, + - onBlur : function(e){ - this.el.removeClass('x-btn-focus'); + onCancelClick: function(){ + this.hideMonthPicker(); }, - getClickEl : function(e, isUp){ - return this.el; + showPrevMonth : function(e){ + return this.update(Ext.Date.add(this.activeDate, Ext.Date.MONTH, -1)); }, - onMouseDown : function(e){ - if(!this.disabled && e.button === 0){ - this.getClickEl(e).addClass('x-btn-click'); - this.doc.on('mouseup', this.onMouseUp, this); - } + showNextMonth : function(e){ + return this.update(Ext.Date.add(this.activeDate, Ext.Date.MONTH, 1)); }, + - onMouseUp : function(e){ - if(e.button === 0){ - this.getClickEl(e, true).removeClass('x-btn-click'); - this.doc.un('mouseup', this.onMouseUp, this); - } + showPrevYear : function(){ + this.update(Ext.Date.add(this.activeDate, Ext.Date.YEAR, -1)); }, + - onMenuShow : function(e){ - if(this.menu.ownerCt == this){ - this.menu.ownerCt = this; - this.ignoreNextClick = 0; - this.el.addClass('x-btn-menu-active'); - this.fireEvent('menushow', this, this.menu); - } + showNextYear : function(){ + this.update(Ext.Date.add(this.activeDate, Ext.Date.YEAR, 1)); }, + - onMenuHide : function(e){ - if(this.menu.ownerCt == this){ - this.el.removeClass('x-btn-menu-active'); - this.ignoreNextClick = this.restoreClick.defer(250, this); - this.fireEvent('menuhide', this, this.menu); - delete this.menu.ownerCt; + handleMouseWheel : function(e){ + e.stopEvent(); + if(!this.disabled){ + var delta = e.getWheelDelta(); + if(delta > 0){ + this.showPrevMonth(); + } else if(delta < 0){ + this.showNextMonth(); + } } }, - restoreClick : function(){ - this.ignoreNextClick = 0; - } - - - - - - - -}); -Ext.reg('button', Ext.Button); - - -Ext.ButtonToggleMgr = function(){ - var groups = {}; - - function toggleGroup(btn, state){ - if(state){ - var g = groups[btn.toggleGroup]; - for(var i = 0, l = g.length; i < l; i++){ - if(g[i] != btn){ - g[i].toggle(false); - } - } - } - } - - return { - register : function(btn){ - if(!btn.toggleGroup){ - return; - } - var g = groups[btn.toggleGroup]; - if(!g){ - g = groups[btn.toggleGroup] = []; - } - g.push(btn); - btn.on('toggle', toggleGroup); - }, - - unregister : function(btn){ - if(!btn.toggleGroup){ - return; - } - var g = groups[btn.toggleGroup]; - if(g){ - g.remove(btn); - btn.un('toggle', toggleGroup); - } - }, - - - getPressed : function(group){ - var g = groups[group]; - if(g){ - for(var i = 0, len = g.length; i < len; i++){ - if(g[i].pressed === true){ - return g[i]; - } - } - } - return null; - } - }; -}(); - -Ext.SplitButton = Ext.extend(Ext.Button, { - - arrowSelector : 'em', - split: true, - - - initComponent : function(){ - Ext.SplitButton.superclass.initComponent.call(this); - - this.addEvents("arrowclick"); - }, + handleDateClick : function(e, t){ + var me = this, + handler = me.handler; - - onRender : function(){ - Ext.SplitButton.superclass.onRender.apply(this, arguments); - if(this.arrowTooltip){ - this.el.child(this.arrowSelector).dom[this.tooltipType] = this.arrowTooltip; + e.stopEvent(); + if(!me.disabled && t.dateValue && !Ext.fly(t.parentNode).hasCls(me.disabledCellCls)){ + me.cancelFocus = me.focusOnSelect === false; + me.setValue(new Date(t.dateValue)); + delete me.cancelFocus; + me.fireEvent('select', me, me.value); + if (handler) { + handler.call(me.scope || me, me, me.value); + } + + + + + me.onSelect(); } }, - setArrowHandler : function(handler, scope){ - this.arrowHandler = handler; - this.scope = scope; + onSelect: function() { + if (this.hideOnSelect) { + this.hide(); + } }, - getMenuClass : function(){ - return 'x-btn-split' + (this.arrowAlign == 'bottom' ? '-bottom' : ''); - }, + + selectToday : function(){ + var me = this, + btn = me.todayBtn, + handler = me.handler; - isClickOnArrow : function(e){ - if (this.arrowAlign != 'bottom') { - var visBtn = this.el.child('em.x-btn-split'); - var right = visBtn.getRegion().right - visBtn.getPadding('r'); - return e.getPageX() > right; - } else { - return e.getPageY() > this.btnEl.getRegion().bottom; - } + if(btn && !btn.disabled){ + me.setValue(Ext.Date.clearTime(new Date())); + me.fireEvent('select', me, me.value); + if (handler) { + handler.call(me.scope || me, me, me.value); + } + me.onSelect(); + } + return me; }, - onClick : function(e, t){ - e.preventDefault(); - if(!this.disabled){ - if(this.isClickOnArrow(e)){ - if(this.menu && !this.menu.isVisible() && !this.ignoreNextClick){ - this.showMenu(); - } - this.fireEvent("arrowclick", this, e); - if(this.arrowHandler){ - this.arrowHandler.call(this.scope || this, this, e); - } - }else{ - this.doToggle(); - this.fireEvent("click", this, e); - if(this.handler){ - this.handler.call(this.scope || this, this, e); + selectedUpdate: function(date, active){ + var me = this, + t = date.getTime(), + cells = me.cells, + cls = me.selectedCls; + + cells.removeCls(cls); + cells.each(function(c){ + if (c.dom.firstChild.dateValue == t) { + me.el.dom.setAttribute('aria-activedescendent', c.dom.id); + c.addCls(cls); + if(me.isVisible() && !me.cancelFocus){ + Ext.fly(c.dom.firstChild).focus(50); } + return false; } - } + }, this); }, - isMenuTriggerOver : function(e){ - return this.menu && e.target.tagName == this.arrowSelector; - }, + fullUpdate: function(date, active){ + var me = this, + cells = me.cells.elements, + textNodes = me.textNodes, + disabledCls = me.disabledCellCls, + eDate = Ext.Date, + i = 0, + extraDays = 0, + visible = me.isVisible(), + sel = +eDate.clearTime(date, true), + today = +eDate.clearTime(new Date()), + min = me.minDate ? eDate.clearTime(me.minDate, true) : Number.NEGATIVE_INFINITY, + max = me.maxDate ? eDate.clearTime(me.maxDate, true) : Number.POSITIVE_INFINITY, + ddMatch = me.disabledDatesRE, + ddText = me.disabledDatesText, + ddays = me.disabledDays ? me.disabledDays.join('') : false, + ddaysText = me.disabledDaysText, + format = me.format, + days = eDate.getDaysInMonth(date), + firstOfMonth = eDate.getFirstDateOfMonth(date), + startingPos = firstOfMonth.getDay() - me.startDay, + previousMonth = eDate.add(date, eDate.MONTH, -1), + longDayFormat = me.longDayFormat, + prevStart, + current, + disableToday, + tempDate, + setCellClass, + html, + cls, + formatValue, + value; - - isMenuTriggerOut : function(e, internal){ - return this.menu && e.target.tagName != this.arrowSelector; - } -}); + if (startingPos < 0) { + startingPos += 7; + } -Ext.reg('splitbutton', Ext.SplitButton); -Ext.CycleButton = Ext.extend(Ext.SplitButton, { - - - - - - + days += startingPos; + prevStart = eDate.getDaysInMonth(previousMonth) - startingPos; + current = new Date(previousMonth.getFullYear(), previousMonth.getMonth(), prevStart, me.initHour); - - getItemText : function(item){ - if(item && this.showText === true){ - var text = ''; - if(this.prependText){ - text += this.prependText; + if (me.showToday) { + tempDate = eDate.clearTime(new Date()); + disableToday = (tempDate < min || tempDate > max || + (ddMatch && format && ddMatch.test(eDate.dateFormat(tempDate, format))) || + (ddays && ddays.indexOf(tempDate.getDay()) != -1)); + + if (!me.disabled) { + me.todayBtn.setDisabled(disableToday); + me.todayKeyListener.setDisabled(disableToday); } - text += item.text; - return text; } - return undefined; - }, - - setActiveItem : function(item, suppressEvent){ - if(!Ext.isObject(item)){ - item = this.menu.getComponent(item); - } - if(item){ - if(!this.rendered){ - this.text = this.getItemText(item); - this.iconCls = item.iconCls; - }else{ - var t = this.getItemText(item); - if(t){ - this.setText(t); + setCellClass = function(cell){ + value = +eDate.clearTime(current, true); + cell.title = eDate.format(current, longDayFormat); + + cell.firstChild.dateValue = value; + if(value == today){ + cell.className += ' ' + me.todayCls; + cell.title = me.todayText; + } + if(value == sel){ + cell.className += ' ' + me.selectedCls; + me.el.dom.setAttribute('aria-activedescendant', cell.id); + if (visible && me.floating) { + Ext.fly(cell.firstChild).focus(50); } - this.setIconClass(item.iconCls); } - this.activeItem = item; - if(!item.checked){ - item.setChecked(true, false); + + if(value < min) { + cell.className = disabledCls; + cell.title = me.minText; + return; + } + if(value > max) { + cell.className = disabledCls; + cell.title = me.maxText; + return; + } + if(ddays){ + if(ddays.indexOf(current.getDay()) != -1){ + cell.title = ddaysText; + cell.className = disabledCls; + } } - if(this.forceIcon){ - this.setIconClass(this.forceIcon); + if(ddMatch && format){ + formatValue = eDate.dateFormat(current, format); + if(ddMatch.test(formatValue)){ + cell.title = ddText.replace('%0', formatValue); + cell.className = disabledCls; + } } - if(!suppressEvent){ - this.fireEvent('change', this, item); + }; + + for(; i < me.numDays; ++i) { + if (i < startingPos) { + html = (++prevStart); + cls = me.prevCls; + } else if (i >= days) { + html = (++extraDays); + cls = me.nextCls; + } else { + html = i - startingPos + 1; + cls = me.activeCls; } + textNodes[i].innerHTML = html; + cells[i].className = cls; + current.setDate(current.getDate() + 1); + setCellClass(cells[i]); } - }, - - getActiveItem : function(){ - return this.activeItem; + me.monthBtn.setText(me.monthNames[date.getMonth()] + ' ' + date.getFullYear()); }, - initComponent : function(){ - this.addEvents( - - "change" - ); - - if(this.changeHandler){ - this.on('change', this.changeHandler, this.scope||this); - delete this.changeHandler; - } - - this.itemCount = this.items.length; + update : function(date, forceRefresh){ + var me = this, + active = me.activeDate; - this.menu = {cls:'x-cycle-menu', items:[]}; - var checked = 0; - Ext.each(this.items, function(item, i){ - Ext.apply(item, { - group: item.group || this.id, - itemIndex: i, - checkHandler: this.checkHandler, - scope: this, - checked: item.checked || false - }); - this.menu.items.push(item); - if(item.checked){ - checked = i; + if (me.rendered) { + me.activeDate = date; + if(!forceRefresh && active && me.el && active.getMonth() == date.getMonth() && active.getFullYear() == date.getFullYear()){ + me.selectedUpdate(date, active); + } else { + me.fullUpdate(date, active); } - }, this); - Ext.CycleButton.superclass.initComponent.call(this); - this.on('click', this.toggleSelected, this); - this.setActiveItem(checked, true); + } + return me; }, - checkHandler : function(item, pressed){ - if(pressed){ - this.setActiveItem(item); + beforeDestroy : function() { + var me = this; + + if (me.rendered) { + Ext.destroy( + me.todayKeyListener, + me.keyNav, + me.monthPicker, + me.monthBtn, + me.nextRepeater, + me.prevRepeater, + me.todayBtn + ); + delete me.textNodes; + delete me.cells.elements; } }, - toggleSelected : function(){ - var m = this.menu; - m.render(); - - if(!m.hasLayout){ - m.doLayout(); - } - - var nextIdx, checkItem; - for (var i = 1; i < this.itemCount; i++) { - nextIdx = (this.activeItem.itemIndex + i) % this.itemCount; - - checkItem = m.items.itemAt(nextIdx); - - if (!checkItem.disabled) { - checkItem.setChecked(true); - break; - } - } - } -}); -Ext.reg('cycle', Ext.CycleButton); -Ext.Toolbar = function(config){ - if(Ext.isArray(config)){ - config = {items: config, layout: 'toolbar'}; - } else { - config = Ext.apply({ - layout: 'toolbar' - }, config); - if(config.buttons) { - config.items = config.buttons; + onShow: function() { + this.callParent(arguments); + if (this.focusOnShow) { + this.focus(); } } - Ext.Toolbar.superclass.constructor.call(this, config); -}; +}, -(function(){ -var T = Ext.Toolbar; +function() { + var proto = this.prototype; + + proto.monthNames = Ext.Date.monthNames; -Ext.extend(T, Ext.Container, { + proto.dayNames = Ext.Date.dayNames; - defaultType: 'button', + proto.format = Ext.Date.defaultFormat; +}); - - enableOverflow : false, +Ext.define('Ext.form.field.Date', { + extend:'Ext.form.field.Picker', + alias: 'widget.datefield', + requires: ['Ext.picker.Date'], + alternateClassName: ['Ext.form.DateField', 'Ext.form.Date'], + + + format : "m/d/Y", + + altFormats : "m/d/Y|n/j/Y|n/j/y|m/j/y|n/d/y|m/j/Y|n/d/Y|m-d-y|m-d-Y|m/d|m-d|md|mdy|mdY|d|Y-m-d|n-j|n/j", + + disabledDaysText : "Disabled", + + disabledDatesText : "Disabled", + + minText : "The date in this field must be equal to or after {0}", + + maxText : "The date in this field must be equal to or before {0}", + + invalidText : "{0} is not a valid date - it must be in the format {1}", + + triggerCls : Ext.baseCSSPrefix + 'form-date-trigger', + + showToday : true, + + + + + + + initTime: '12', - trackMenus : true, - internalDefaults: {removeMode: 'container', hideParent: true}, - toolbarCls: 'x-toolbar', + initTimeFormat: 'H', + matchFieldWidth: false, + + startDay: 0, + initComponent : function(){ - T.superclass.initComponent.call(this); + var me = this, + isString = Ext.isString, + min, max; - - this.addEvents('overflowchange'); + min = me.minValue; + max = me.maxValue; + if(isString(min)){ + me.minValue = me.parseDate(min); + } + if(isString(max)){ + me.maxValue = me.parseDate(max); + } + me.disabledDatesRE = null; + me.initDisabledDays(); + + me.callParent(); }, - - onRender : function(ct, position){ - if(!this.el){ - if(!this.autoCreate){ - this.autoCreate = { - cls: this.toolbarCls + ' x-small-editor' - }; - } - this.el = ct.createChild(Ext.apply({ id: this.id },this.autoCreate), position); - Ext.Toolbar.superclass.onRender.apply(this, arguments); + initValue: function() { + var me = this, + value = me.value; + + + if (Ext.isString(value)) { + me.value = me.rawToValue(value); } + + me.callParent(); }, + initDisabledDays : function(){ + if(this.disabledDates){ + var dd = this.disabledDates, + len = dd.length - 1, + re = "(?:"; - - lookupComponent : function(c){ - if(Ext.isString(c)){ - if(c == '-'){ - c = new T.Separator(); - }else if(c == ' '){ - c = new T.Spacer(); - }else if(c == '->'){ - c = new T.Fill(); - }else{ - c = new T.TextItem(c); - } - this.applyDefaults(c); - }else{ - if(c.isFormField || c.render){ - c = this.createComponent(c); - }else if(c.tag){ - c = new T.Item({autoEl: c}); - }else if(c.tagName){ - c = new T.Item({el:c}); - }else if(Ext.isObject(c)){ - c = c.xtype ? this.createComponent(c) : this.constructButton(c); - } + Ext.each(dd, function(d, i){ + re += Ext.isDate(d) ? '^' + Ext.String.escapeRegex(d.dateFormat(this.format)) + '$' : dd[i]; + if (i !== len) { + re += '|'; + } + }, this); + this.disabledDatesRE = new RegExp(re + ')'); } - return c; }, - applyDefaults : function(c){ - if(!Ext.isString(c)){ - c = Ext.Toolbar.superclass.applyDefaults.call(this, c); - var d = this.internalDefaults; - if(c.events){ - Ext.applyIf(c.initialConfig, d); - Ext.apply(c, d); - }else{ - Ext.applyIf(c, d); - } + setDisabledDates : function(dd){ + var me = this, + picker = me.picker; + + me.disabledDates = dd; + me.initDisabledDays(); + if (picker) { + picker.setDisabledDates(me.disabledDatesRE); } - return c; }, - addSeparator : function(){ - return this.add(new T.Separator()); + setDisabledDays : function(dd){ + var picker = this.picker; + + this.disabledDays = dd; + if (picker) { + picker.setDisabledDays(dd); + } }, - addSpacer : function(){ - return this.add(new T.Spacer()); + setMinValue : function(dt){ + var me = this, + picker = me.picker, + minValue = (Ext.isString(dt) ? me.parseDate(dt) : dt); + + me.minValue = minValue; + if (picker) { + picker.minText = Ext.String.format(me.minText, me.formatDate(me.minValue)); + picker.setMinDate(minValue); + } }, - addFill : function(){ - this.add(new T.Fill()); + setMaxValue : function(dt){ + var me = this, + picker = me.picker, + maxValue = (Ext.isString(dt) ? me.parseDate(dt) : dt); + + me.maxValue = maxValue; + if (picker) { + picker.maxText = Ext.String.format(me.maxText, me.formatDate(me.maxValue)); + picker.setMaxDate(maxValue); + } }, - addElement : function(el){ - return this.addItem(new T.Item({el:el})); - }, + getErrors: function(value) { + var me = this, + format = Ext.String.format, + clearTime = Ext.Date.clearTime, + errors = me.callParent(arguments), + disabledDays = me.disabledDays, + disabledDatesRE = me.disabledDatesRE, + minValue = me.minValue, + maxValue = me.maxValue, + len = disabledDays ? disabledDays.length : 0, + i = 0, + svalue, + fvalue, + day, + time; - - addItem : function(item){ - return this.add.apply(this, arguments); - }, + value = me.formatDate(value || me.processRawValue(me.getRawValue())); - - addButton : function(config){ - if(Ext.isArray(config)){ - var buttons = []; - for(var i = 0, len = config.length; i < len; i++) { - buttons.push(this.addButton(config[i])); + if (value === null || value.length < 1) { + return errors; + } + + svalue = value; + value = me.parseDate(value); + if (!value) { + errors.push(format(me.invalidText, svalue, me.format)); + return errors; + } + + time = value.getTime(); + if (minValue && time < clearTime(minValue).getTime()) { + errors.push(format(me.minText, me.formatDate(minValue))); + } + + if (maxValue && time > clearTime(maxValue).getTime()) { + errors.push(format(me.maxText, me.formatDate(maxValue))); + } + + if (disabledDays) { + day = value.getDay(); + + for(; i < len; i++) { + if (day === disabledDays[i]) { + errors.push(me.disabledDaysText); + break; + } } - return buttons; } - return this.add(this.constructButton(config)); + + fvalue = me.formatDate(value); + if (disabledDatesRE && disabledDatesRE.test(fvalue)) { + errors.push(format(me.disabledDatesText, fvalue)); + } + + return errors; }, - - addText : function(text){ - return this.addItem(new T.TextItem(text)); + rawToValue: function(rawValue) { + return this.parseDate(rawValue) || rawValue || null; }, - - addDom : function(config){ - return this.add(new T.Item({autoEl: config})); + valueToRaw: function(value) { + return this.formatDate(this.parseDate(value)); }, - addField : function(field){ - return this.add(field); - }, - insertButton : function(index, item){ - if(Ext.isArray(item)){ - var buttons = []; - for(var i = 0, len = item.length; i < len; i++) { - buttons.push(this.insertButton(index + i, item[i])); + safeParse : function(value, format) { + var me = this, + utilDate = Ext.Date, + parsedDate, + result = null; + + if (utilDate.formatContainsHourInfo(format)) { + + result = utilDate.parse(value, format); + } else { + + parsedDate = utilDate.parse(value + ' ' + me.initTime, format + ' ' + me.initTimeFormat); + if (parsedDate) { + result = utilDate.clearTime(parsedDate); } - return buttons; } - return Ext.Toolbar.superclass.insert.call(this, index, item); + return result; }, - - trackMenu : function(item, remove){ - if(this.trackMenus && item.menu){ - var method = remove ? 'mun' : 'mon'; - this[method](item, 'menutriggerover', this.onButtonTriggerOver, this); - this[method](item, 'menushow', this.onButtonMenuShow, this); - this[method](item, 'menuhide', this.onButtonMenuHide, this); - } - }, - - constructButton : function(item){ - var b = item.events ? item : this.createComponent(item, item.split ? 'splitbutton' : this.defaultType); - return b; + getSubmitValue: function() { + var me = this, + format = me.submitFormat || me.format, + value = me.getValue(); + + return value ? Ext.Date.format(value, format) : null; }, - onAdd : function(c){ - Ext.Toolbar.superclass.onAdd.call(this); - this.trackMenu(c); - if(this.disabled){ - c.disable(); + parseDate : function(value) { + if(!value || Ext.isDate(value)){ + return value; } - }, - - onRemove : function(c){ - Ext.Toolbar.superclass.onRemove.call(this); - if (c == this.activeMenuBtn) { - delete this.activeMenuBtn; + var me = this, + val = me.safeParse(value, me.format), + altFormats = me.altFormats, + altFormatsArray = me.altFormatsArray, + i = 0, + len; + + if (!val && altFormats) { + altFormatsArray = altFormatsArray || altFormats.split('|'); + len = altFormatsArray.length; + for (; i < len && !val; ++i) { + val = me.safeParse(value, altFormatsArray[i]); + } } - this.trackMenu(c, true); + return val; }, - onDisable : function(){ - this.items.each(function(item){ - if(item.disable){ - item.disable(); - } - }); + formatDate : function(date){ + return Ext.isDate(date) ? Ext.Date.dateFormat(date, this.format) : date; }, - - onEnable : function(){ - this.items.each(function(item){ - if(item.enable){ - item.enable(); - } + createPicker: function() { + var me = this, + format = Ext.String.format; + + return Ext.create('Ext.picker.Date', { + ownerCt: this.ownerCt, + renderTo: document.body, + floating: true, + hidden: true, + focusOnShow: true, + minDate: me.minValue, + maxDate: me.maxValue, + disabledDatesRE: me.disabledDatesRE, + disabledDatesText: me.disabledDatesText, + disabledDays: me.disabledDays, + disabledDaysText: me.disabledDaysText, + format: me.format, + showToday: me.showToday, + startDay: me.startDay, + minText: format(me.minText, me.formatDate(me.minValue)), + maxText: format(me.maxText, me.formatDate(me.maxValue)), + listeners: { + scope: me, + select: me.onSelect + }, + keyNavConfig: { + esc: function() { + me.collapse(); + } + } }); }, - - onButtonTriggerOver : function(btn){ - if(this.activeMenuBtn && this.activeMenuBtn != btn){ - this.activeMenuBtn.hideMenu(); - btn.showMenu(); - this.activeMenuBtn = btn; - } + onSelect: function(m, d) { + this.setValue(d); + this.fireEvent('select', this, d); + this.collapse(); }, - onButtonMenuShow : function(btn){ - this.activeMenuBtn = btn; + onExpand: function() { + var me = this, + value = me.getValue(); + me.picker.setValue(value instanceof Date ? value : new Date()); }, - onButtonMenuHide : function(btn){ - delete this.activeMenuBtn; - } -}); -Ext.reg('toolbar', Ext.Toolbar); - + onCollapse: function() { + this.focus(false, 60); + }, -T.Item = Ext.extend(Ext.BoxComponent, { - hideParent: true, - enable:Ext.emptyFn, - disable:Ext.emptyFn, - focus:Ext.emptyFn -}); -Ext.reg('tbitem', T.Item); - - -T.Separator = Ext.extend(T.Item, { - onRender : function(ct, position){ - this.el = ct.createChild({tag:'span', cls:'xtb-sep'}, position); + beforeBlur : function(){ + var v = this.parseDate(this.getRawValue()); + if(v){ + this.setValue(v); + } } -}); -Ext.reg('tbseparator', T.Separator); - -T.Spacer = Ext.extend(T.Item, { - - onRender : function(ct, position){ - this.el = ct.createChild({tag:'div', cls:'xtb-spacer', style: this.width?'width:'+this.width+'px':''}, position); - } -}); -Ext.reg('tbspacer', T.Spacer); - - -T.Fill = Ext.extend(T.Item, { - render : Ext.emptyFn, - isFill : true + + }); -Ext.reg('tbfill', T.Fill); - -T.TextItem = Ext.extend(T.Item, { - - constructor: function(config){ - T.TextItem.superclass.constructor.call(this, Ext.isString(config) ? {text: config} : config); - }, +Ext.define('Ext.form.field.Display', { + extend:'Ext.form.field.Base', + alias: 'widget.displayfield', + requires: ['Ext.util.Format', 'Ext.XTemplate'], + alternateClassName: ['Ext.form.DisplayField', 'Ext.form.Display'], + fieldSubTpl: [ + '
    ', + { + compiled: true, + disableFormats: true + } + ], - onRender : function(ct, position) { - this.autoEl = {cls: 'xtb-text', html: this.text || ''}; - T.TextItem.superclass.onRender.call(this, ct, position); - }, + fieldCls: Ext.baseCSSPrefix + 'form-display-field', - setText : function(t) { - if(this.rendered){ - this.el.update(t); - }else{ - this.text = t; - } - } -}); -Ext.reg('tbtext', T.TextItem); + htmlEncode: false, + validateOnChange: false, -T.Button = Ext.extend(Ext.Button, {}); -T.SplitButton = Ext.extend(Ext.SplitButton, {}); -Ext.reg('tbbutton', T.Button); -Ext.reg('tbsplit', T.SplitButton); + initEvents: Ext.emptyFn, -})(); + submitValue: false, -Ext.ButtonGroup = Ext.extend(Ext.Panel, { - - - baseCls: 'x-btn-group', - - layout:'table', - defaultType: 'button', - - frame: true, - internalDefaults: {removeMode: 'container', hideParent: true}, + isValid: function() { + return true; + }, - initComponent : function(){ - this.layoutConfig = this.layoutConfig || {}; - Ext.applyIf(this.layoutConfig, { - columns : this.columns - }); - if(!this.title){ - this.addClass('x-btn-group-notitle'); - } - this.on('afterlayout', this.onAfterLayout, this); - Ext.ButtonGroup.superclass.initComponent.call(this); + validate: function() { + return true; }, - applyDefaults : function(c){ - c = Ext.ButtonGroup.superclass.applyDefaults.call(this, c); - var d = this.internalDefaults; - if(c.events){ - Ext.applyIf(c.initialConfig, d); - Ext.apply(c, d); - }else{ - Ext.applyIf(c, d); + getRawValue: function() { + return this.rawValue; + }, + + setRawValue: function(value) { + var me = this; + value = Ext.value(value, ''); + me.rawValue = value; + if (me.rendered) { + me.inputEl.dom.innerHTML = me.htmlEncode ? Ext.util.Format.htmlEncode(value) : value; } - return c; + return value; }, - onAfterLayout : function(){ - var bodyWidth = this.body.getFrameWidth('lr') + this.body.dom.firstChild.offsetWidth; - this.body.setWidth(bodyWidth); - this.el.setWidth(bodyWidth + this.getFrameWidth()); - } -}); - -Ext.reg('buttongroup', Ext.ButtonGroup); - -(function() { - -var T = Ext.Toolbar; + getContentTarget: function() { + return this.inputEl; + } -Ext.PagingToolbar = Ext.extend(Ext.Toolbar, { - - - - pageSize : 20, - - displayMsg : 'Displaying {0} - {1} of {2}', - - emptyMsg : 'No data to display', - - beforePageText : 'Page', - - afterPageText : 'of {0}', - firstText : 'First Page', - prevText : 'Previous Page', - nextText : 'Next Page', - lastText : 'Last Page', - refreshText : 'Refresh', +}); - - +Ext.define("Ext.form.field.File", { + extend: 'Ext.form.field.Text', + alias: ['widget.filefield', 'widget.fileuploadfield'], + alternateClassName: ['Ext.form.FileUploadField', 'Ext.ux.form.FileUploadField', 'Ext.form.File'], + uses: ['Ext.button.Button', 'Ext.layout.component.field.File'], - - initComponent : function(){ - var pagingItems = [this.first = new T.Button({ - tooltip: this.firstText, - overflowText: this.firstText, - iconCls: 'x-tbar-page-first', - disabled: true, - handler: this.moveFirst, - scope: this - }), this.prev = new T.Button({ - tooltip: this.prevText, - overflowText: this.prevText, - iconCls: 'x-tbar-page-prev', - disabled: true, - handler: this.movePrevious, - scope: this - }), '-', this.beforePageText, - this.inputItem = new Ext.form.NumberField({ - cls: 'x-tbar-page-number', - allowDecimals: false, - allowNegative: false, - enableKeyEvents: true, - selectOnFocus: true, - submitValue: false, - listeners: { - scope: this, - keydown: this.onPagingKeyDown, - blur: this.onPagingBlur - } - }), this.afterTextItem = new T.TextItem({ - text: String.format(this.afterPageText, 1) - }), '-', this.next = new T.Button({ - tooltip: this.nextText, - overflowText: this.nextText, - iconCls: 'x-tbar-page-next', - disabled: true, - handler: this.moveNext, - scope: this - }), this.last = new T.Button({ - tooltip: this.lastText, - overflowText: this.lastText, - iconCls: 'x-tbar-page-last', - disabled: true, - handler: this.moveLast, - scope: this - }), '-', this.refresh = new T.Button({ - tooltip: this.refreshText, - overflowText: this.refreshText, - iconCls: 'x-tbar-loading', - handler: this.doRefresh, - scope: this - })]; - - - var userItems = this.items || this.buttons || []; - if (this.prependButtons) { - this.items = userItems.concat(pagingItems); - }else{ - this.items = pagingItems.concat(userItems); - } - delete this.buttons; - if(this.displayInfo){ - this.items.push('->'); - this.items.push(this.displayItem = new T.TextItem({})); - } - Ext.PagingToolbar.superclass.initComponent.call(this); - this.addEvents( - - 'change', - - 'beforechange' - ); - this.on('afterlayout', this.onFirstLayout, this, {single: true}); - this.cursor = 0; - this.bindStore(this.store, true); - }, + buttonText: 'Browse...', - onFirstLayout : function(){ - if(this.dsLoaded){ - this.onLoad.apply(this, this.dsLoaded); - } - }, + buttonOnly: false, - updateInfo : function(){ - if(this.displayItem){ - var count = this.store.getCount(); - var msg = count == 0 ? - this.emptyMsg : - String.format( - this.displayMsg, - this.cursor+1, this.cursor+count, this.store.getTotalCount() - ); - this.displayItem.setText(msg); - } - }, + buttonMargin: 3, - onLoad : function(store, r, o){ - if(!this.rendered){ - this.dsLoaded = [store, r, o]; - return; - } - var p = this.getParams(); - this.cursor = (o.params && o.params[p.start]) ? o.params[p.start] : 0; - var d = this.getPageData(), ap = d.activePage, ps = d.pages; - - this.afterTextItem.setText(String.format(this.afterPageText, d.pages)); - this.inputItem.setValue(ap); - this.first.setDisabled(ap == 1); - this.prev.setDisabled(ap == 1); - this.next.setDisabled(ap == ps); - this.last.setDisabled(ap == ps); - this.refresh.enable(); - this.updateInfo(); - this.fireEvent('change', this, d); - }, - getPageData : function(){ - var total = this.store.getTotalCount(); - return { - total : total, - activePage : Math.ceil((this.cursor+this.pageSize)/this.pageSize), - pages : total < this.pageSize ? 1 : Math.ceil(total/this.pageSize) - }; - }, - changePage : function(page){ - this.doLoad(((page-1) * this.pageSize).constrain(0, this.store.getTotalCount())); - }, - onLoadError : function(){ - if(!this.rendered){ - return; - } - this.refresh.enable(); - }, - readPage : function(d){ - var v = this.inputItem.getValue(), pageNum; - if (!v || isNaN(pageNum = parseInt(v, 10))) { - this.inputItem.setValue(d.activePage); - return false; - } - return pageNum; - }, + fieldBodyCls: Ext.baseCSSPrefix + 'form-file-wrap', - onPagingFocus : function(){ - this.inputItem.select(); - }, - onPagingBlur : function(e){ - this.inputItem.setValue(this.getPageData().activePage); - }, + readOnly: true, + componentLayout: 'filefield', - onPagingKeyDown : function(field, e){ - var k = e.getKey(), d = this.getPageData(), pageNum; - if (k == e.RETURN) { - e.stopEvent(); - pageNum = this.readPage(d); - if(pageNum !== false){ - pageNum = Math.min(Math.max(1, pageNum), d.pages) - 1; - this.doLoad(pageNum * this.pageSize); - } - }else if (k == e.HOME || k == e.END){ - e.stopEvent(); - pageNum = k == e.HOME ? 1 : d.pages; - field.setValue(pageNum); - }else if (k == e.UP || k == e.PAGEUP || k == e.DOWN || k == e.PAGEDOWN){ - e.stopEvent(); - if((pageNum = this.readPage(d))){ - var increment = e.shiftKey ? 10 : 1; - if(k == e.DOWN || k == e.PAGEDOWN){ - increment *= -1; - } - pageNum += increment; - if(pageNum >= 1 & pageNum <= d.pages){ - field.setValue(pageNum); - } - } - } - }, + onRender: function() { + var me = this, + inputEl; - - getParams : function(){ - - return this.paramNames || this.store.paramNames; - }, + me.callParent(arguments); - - beforeLoad : function(){ - if(this.rendered && this.refresh){ - this.refresh.disable(); + me.createButton(); + me.createFileInput(); + + + + if (me.disabled) { + me.disableItems(); } - }, - - doLoad : function(start){ - var o = {}, pn = this.getParams(); - o[pn.start] = start; - o[pn.limit] = this.pageSize; - if(this.fireEvent('beforechange', this, o) !== false){ - this.store.load({params:o}); + inputEl = me.inputEl; + inputEl.dom.removeAttribute('name'); + if (me.buttonOnly) { + inputEl.setDisplayed(false); } }, - moveFirst : function(){ - this.doLoad(0); + createButton: function() { + var me = this; + me.button = Ext.widget('button', Ext.apply({ + renderTo: me.bodyEl, + text: me.buttonText, + cls: Ext.baseCSSPrefix + 'form-file-btn', + preventDefault: false, + ownerCt: me, + style: me.buttonOnly ? '' : 'margin-left:' + me.buttonMargin + 'px' + }, me.buttonConfig)); }, - movePrevious : function(){ - this.doLoad(Math.max(0, this.cursor-this.pageSize)); + createFileInput : function() { + var me = this; + me.fileInputEl = me.button.el.createChild({ + name: me.getName(), + cls: Ext.baseCSSPrefix + 'form-file-input', + tag: 'input', + type: 'file', + size: 1 + }).on('change', me.onFileChange, me); }, - moveNext : function(){ - this.doLoad(this.cursor+this.pageSize); + onFileChange: function() { + this.lastValue = null; + Ext.form.field.File.superclass.setValue.call(this, this.fileInputEl.dom.value); }, - moveLast : function(){ - var total = this.store.getTotalCount(), - extra = total % this.pageSize; + setValue: Ext.emptyFn, - this.doLoad(extra ? (total - extra) : total - this.pageSize); + reset : function(){ + this.fileInputEl.remove(); + this.createFileInput(); + this.callParent(); }, - - doRefresh : function(){ - this.doLoad(this.cursor); + onDisable: function(){ + this.callParent(); + this.disableItems(); }, - - bindStore : function(store, initial){ - var doLoad; - if(!initial && this.store){ - if(store !== this.store && this.store.autoDestroy){ - this.store.destroy(); - }else{ - this.store.un('beforeload', this.beforeLoad, this); - this.store.un('load', this.onLoad, this); - this.store.un('exception', this.onLoadError, this); - } - if(!store){ - this.store = null; - } - } - if(store){ - store = Ext.StoreMgr.lookup(store); - store.on({ - scope: this, - beforeload: this.beforeLoad, - load: this.onLoad, - exception: this.onLoadError - }); - doLoad = true; - } - this.store = store; - if(doLoad){ - this.onLoad(store, null, {}); + disableItems: function(){ + var file = this.fileInputEl, + button = this.button; + + if (file) { + file.dom.disabled = true; } + if (button) { + button.disable(); + } }, - - unbind : function(store){ - this.bindStore(null); + onEnable: function(){ + var me = this; + me.callParent(); + me.fileInputEl.dom.disabled = false; + me.button.enable(); }, - - bind : function(store){ - this.bindStore(store); + isFileUpload: function() { + return true; }, - - onDestroy : function(){ - this.bindStore(null); - Ext.PagingToolbar.superclass.onDestroy.call(this); - } -}); - -})(); -Ext.reg('paging', Ext.PagingToolbar); -Ext.History = (function () { - var iframe, hiddenField; - var ready = false; - var currentToken; - - function getHash() { - var href = location.href, i = href.indexOf("#"); - return i >= 0 ? href.substr(i + 1) : null; - } - - function doSave() { - hiddenField.value = currentToken; - } - - function handleStateChange(token) { - currentToken = token; - Ext.History.fireEvent('change', token); - } + extractFileInput: function() { + var fileInput = this.fileInputEl.dom; + this.reset(); + return fileInput; + }, - function updateIFrame (token) { - var html = ['
    ',Ext.util.Format.htmlEncode(token),'
    '].join(''); - try { - var doc = iframe.contentWindow.document; - doc.open(); - doc.write(html); - doc.close(); - return true; - } catch (e) { - return false; - } + onDestroy: function(){ + Ext.destroyMembers(this, 'fileInputEl', 'button'); + this.callParent(); } - function checkIFrame() { - if (!iframe.contentWindow || !iframe.contentWindow.document) { - setTimeout(checkIFrame, 10); - return; - } - - var doc = iframe.contentWindow.document; - var elem = doc.getElementById("state"); - var token = elem ? elem.innerText : null; - - var hash = getHash(); - - setInterval(function () { - - doc = iframe.contentWindow.document; - elem = doc.getElementById("state"); - - var newtoken = elem ? elem.innerText : null; - - var newHash = getHash(); - - if (newtoken !== token) { - token = newtoken; - handleStateChange(token); - top.location.hash = token; - hash = token; - doSave(); - } else if (newHash !== hash) { - hash = newHash; - updateIFrame(newHash); - } - - }, 50); - - ready = true; - Ext.History.fireEvent('ready', Ext.History); - } +}); - function startUp() { - currentToken = hiddenField.value ? hiddenField.value : getHash(); - if (Ext.isIE) { - checkIFrame(); - } else { - var hash = getHash(); - setInterval(function () { - var newHash = getHash(); - if (newHash !== hash) { - hash = newHash; - handleStateChange(hash); - doSave(); - } - }, 50); - ready = true; - Ext.History.fireEvent('ready', Ext.History); - } - } +Ext.define('Ext.form.field.Hidden', { + extend:'Ext.form.field.Base', + alias: ['widget.hiddenfield', 'widget.hidden'], + alternateClassName: 'Ext.form.Hidden', - return { - - fieldId: 'x-history-field', - - iframeId: 'x-history-frame', + + inputType : 'hidden', + hideLabel: true, + + initComponent: function(){ + this.formItemCls += '-hidden'; + this.callParent(); + }, - events:{}, + + initEvents: Ext.emptyFn, + setSize : Ext.emptyFn, + setWidth : Ext.emptyFn, + setHeight : Ext.emptyFn, + setPosition : Ext.emptyFn, + setPagePosition : Ext.emptyFn, + markInvalid : Ext.emptyFn, + clearInvalid : Ext.emptyFn +}); - - init: function (onReady, scope) { - if(ready) { - Ext.callback(onReady, scope, [this]); - return; - } - if(!Ext.isReady){ - Ext.onReady(function(){ - Ext.History.init(onReady, scope); - }); - return; - } - hiddenField = Ext.getDom(Ext.History.fieldId); - if (Ext.isIE) { - iframe = Ext.getDom(Ext.History.iframeId); - } - this.addEvents( - - 'ready', - - 'change' - ); - if(onReady){ - this.on('ready', onReady, scope, {single:true}); - } - startUp(); - }, - - add: function (token, preventDup) { - if(preventDup !== false){ - if(this.getToken() == token){ - return true; - } - } - if (Ext.isIE) { - return updateIFrame(token); - } else { - top.location.hash = token; - return true; - } - }, +Ext.define('Ext.picker.Color', { + extend: 'Ext.Component', + requires: 'Ext.XTemplate', + alias: 'widget.colorpicker', + alternateClassName: 'Ext.ColorPalette', + + + componentCls : Ext.baseCSSPrefix + 'color-picker', + + + selectedCls: Ext.baseCSSPrefix + 'color-picker-selected', + + + value : null, + + + clickEvent :'click', - - back: function(){ - history.go(-1); - }, + + allowReselect : false, - - forward: function(){ - history.go(1); - }, + + colors : [ + '000000', '993300', '333300', '003300', '003366', '000080', '333399', '333333', + '800000', 'FF6600', '808000', '008000', '008080', '0000FF', '666699', '808080', + 'FF0000', 'FF9900', '99CC00', '339966', '33CCCC', '3366FF', '800080', '969696', + 'FF00FF', 'FFCC00', 'FFFF00', '00FF00', '00FFFF', '00CCFF', '993366', 'C0C0C0', + 'FF99CC', 'FFCC99', 'FFFF99', 'CCFFCC', 'CCFFFF', '99CCFF', 'CC99FF', 'FFFFFF' + ], - - getToken: function() { - return ready ? currentToken : getHash(); - } - }; -})(); -Ext.apply(Ext.History, new Ext.util.Observable()); -Ext.Tip = Ext.extend(Ext.Panel, { - minWidth : 40, + colorRe: /(?:^|\s)color-(.{6})(?:\s|$)/, - maxWidth : 300, + constructor: function() { + this.renderTpl = Ext.create('Ext.XTemplate', ' '); + this.callParent(arguments); + }, - shadow : "sides", - defaultAlign : "tl-bl?", - autoRender: true, - quickShowInterval : 250, + initComponent : function(){ + var me = this; + + this.callParent(arguments); + me.addEvents( + + 'select' + ); - - frame:true, - hidden:true, - baseCls: 'x-tip', - floating:{shadow:true,shim:true,useDisplay:true,constrain:false}, - autoHeight:true, + if (me.handler) { + me.on('select', me.handler, me.scope, true); + } + }, - closeAction: 'hide', - initComponent : function(){ - Ext.Tip.superclass.initComponent.call(this); - if(this.closable && !this.title){ - this.elements += ',header'; + onRender : function(container, position){ + var me = this, + clickEvent = me.clickEvent; + + Ext.apply(me.renderData, { + itemCls: me.itemCls, + colors: me.colors + }); + this.callParent(arguments); + + me.mon(me.el, clickEvent, me.handleClick, me, {delegate: 'a'}); + + if(clickEvent != 'click'){ + me.mon(me.el, 'click', Ext.emptyFn, me, {delegate: 'a', stopEvent: true}); } }, afterRender : function(){ - Ext.Tip.superclass.afterRender.call(this); - if(this.closable){ - this.addTool({ - id: 'close', - handler: this[this.closeAction], - scope: this - }); + var me = this, + value; + + this.callParent(arguments); + if (me.value) { + value = me.value; + me.value = null; + me.select(value, true); } }, - showAt : function(xy){ - Ext.Tip.superclass.show.call(this); - if(this.measureWidth !== false && (!this.initialConfig || typeof this.initialConfig.width != 'number')){ - this.doAutoWidth(); - } - if(this.constrainPosition){ - xy = this.el.adjustForConstraints(xy); + handleClick : function(event, target){ + var me = this, + color; + + event.stopEvent(); + if (!me.disabled) { + color = target.className.match(me.colorRe)[1]; + me.select(color.toUpperCase()); } - this.setPagePosition(xy[0], xy[1]); }, - doAutoWidth : function(adjust){ - adjust = adjust || 0; - var bw = this.body.getTextWidth(); - if(this.title){ - bw = Math.max(bw, this.header.child('span').getTextWidth(this.title)); + select : function(color, suppressEvent){ + + var me = this, + selectedCls = me.selectedCls, + value = me.value, + el; + + color = color.replace('#', ''); + if (!me.rendered) { + me.value = color; + return; } - bw += this.getFrameWidth() + (this.closable ? 20 : 0) + this.body.getPadding("lr") + adjust; - this.setWidth(bw.constrain(this.minWidth, this.maxWidth)); - if(Ext.isIE7 && !this.repainted){ - this.el.repaint(); - this.repainted = true; - } - }, + if (color != value || me.allowReselect) { + el = me.el; - - showBy : function(el, pos){ - if(!this.rendered){ - this.render(Ext.getBody()); + if (me.value) { + el.down('a.color-' + value).removeCls(selectedCls); + } + el.down('a.color-' + color).addCls(selectedCls); + me.value = color; + if (suppressEvent !== true) { + me.fireEvent('select', me, color); + } } - this.showAt(this.el.getAlignToXY(el, pos || this.defaultAlign)); }, - - initDraggable : function(){ - this.dd = new Ext.Tip.DD(this, typeof this.draggable == 'boolean' ? null : this.draggable); - this.header.addClass('x-tip-draggable'); + + + getValue: function(){ + return this.value || null; } }); -Ext.reg('tip', Ext.Tip); -Ext.Tip.DD = function(tip, config){ - Ext.apply(this, config); - this.tip = tip; - Ext.Tip.DD.superclass.constructor.call(this, tip.el.id, 'WindowDD-'+tip.id); - this.setHandleElId(tip.header.id); - this.scroll = false; -}; +Ext.define('Ext.layout.component.field.HtmlEditor', { + extend: 'Ext.layout.component.field.Field', + alias: ['layout.htmleditor'], -Ext.extend(Ext.Tip.DD, Ext.dd.DD, { - moveOnly:true, - scroll:false, - headerOffsets:[100, 25], - startDrag : function(){ - this.tip.el.disableShadow(); - }, - endDrag : function(e){ - this.tip.el.enableShadow(true); + type: 'htmleditor', + + sizeBodyContents: function(width, height) { + var me = this, + owner = me.owner, + bodyEl = owner.bodyEl, + toolbar = owner.getToolbar(), + textarea = owner.textareaEl, + iframe = owner.iframeEl, + editorHeight; + + if (Ext.isNumber(width)) { + width -= bodyEl.getFrameWidth('lr'); + } + toolbar.setWidth(width); + textarea.setWidth(width); + iframe.setWidth(width); + + + if (Ext.isNumber(height)) { + editorHeight = height - toolbar.getHeight() - bodyEl.getFrameWidth('tb'); + textarea.setHeight(editorHeight); + iframe.setHeight(editorHeight); + } } }); -Ext.ToolTip = Ext.extend(Ext.Tip, { + +Ext.define('Ext.form.field.HtmlEditor', { + extend:'Ext.Component', + mixins: { + labelable: 'Ext.form.Labelable', + field: 'Ext.form.field.Field' + }, + alias: 'widget.htmleditor', + alternateClassName: 'Ext.form.HtmlEditor', + requires: [ + 'Ext.tip.QuickTipManager', + 'Ext.picker.Color', + 'Ext.toolbar.Item', + 'Ext.toolbar.Toolbar', + 'Ext.util.Format', + 'Ext.layout.component.field.HtmlEditor' + ], + + fieldSubTpl: [ + '
    ', + '', + '', + { + compiled: true, + disableFormats: true + } + ], + + enableFormat : true, + + enableFontSize : true, + enableColors : true, + enableAlignments : true, - showDelay : 500, + enableLists : true, - hideDelay : 200, + enableSourceEdit : true, - dismissDelay : 5000, + enableLinks : true, + enableFont : true, - trackMouse : false, + createLinkText : 'Please enter the URL for the link:', - anchorToTarget : true, + defaultLinkValue : 'http:/'+'/', - anchorOffset : 0, + fontFamilies : [ + 'Arial', + 'Courier New', + 'Tahoma', + 'Times New Roman', + 'Verdana' + ], + defaultFont: 'tahoma', + defaultValue: (Ext.isOpera || Ext.isIE6) ? ' ' : '​', - - targetCounter : 0, + fieldBodyCls: Ext.baseCSSPrefix + 'html-editor-wrap', - constrainPosition : false, + componentLayout: 'htmleditor', - initComponent : function(){ - Ext.ToolTip.superclass.initComponent.call(this); - this.lastActive = new Date(); - this.initTarget(this.target); - this.origAnchor = this.anchor; - }, + initialized : false, + activated : false, + sourceEditMode : false, + iframePad:3, + hideMode:'offsets', + maskOnDisable: true, - onRender : function(ct, position){ - Ext.ToolTip.superclass.onRender.call(this, ct, position); - this.anchorCls = 'x-tip-anchor-' + this.getAnchorPosition(); - this.anchorEl = this.el.createChild({ - cls: 'x-tip-anchor ' + this.anchorCls - }); - }, - - afterRender : function(){ - Ext.ToolTip.superclass.afterRender.call(this); - this.anchorEl.setStyle('z-index', this.el.getZIndex() + 1).setVisibilityMode(Ext.Element.DISPLAY); - }, + initComponent : function(){ + var me = this; - - initTarget : function(target){ - var t; - if((t = Ext.get(target))){ - if(this.target){ - var tg = Ext.get(this.target); - this.mun(tg, 'mouseover', this.onTargetOver, this); - this.mun(tg, 'mouseout', this.onTargetOut, this); - this.mun(tg, 'mousemove', this.onMouseMove, this); - } - this.mon(t, { - mouseover: this.onTargetOver, - mouseout: this.onTargetOut, - mousemove: this.onMouseMove, - scope: this - }); - this.target = t; - } - if(this.anchor){ - this.anchorTarget = this.target; - } + me.addEvents( + + 'initialize', + + 'activate', + + 'beforesync', + + 'beforepush', + + 'sync', + + 'push', + + 'editmodechange' + ); + + me.callParent(arguments); + + + me.initLabelable(); + me.initField(); }, - onMouseMove : function(e){ - var t = this.delegate ? e.getTarget(this.delegate) : this.triggerElement = true; - if (t) { - this.targetXY = e.getXY(); - if (t === this.triggerElement) { - if(!this.hidden && this.trackMouse){ - this.setPagePosition(this.getTargetXY()); - } - } else { - this.hide(); - this.lastActive = new Date(0); - this.onTargetOver(e); - } - } else if (!this.closable && this.isVisible()) { - this.hide(); + createToolbar : function(editor){ + var me = this, + items = [], + tipsEnabled = Ext.tip.QuickTipManager && Ext.tip.QuickTipManager.isEnabled(), + baseCSSPrefix = Ext.baseCSSPrefix, + fontSelectItem, toolbar, undef; + + function btn(id, toggle, handler){ + return { + itemId : id, + cls : baseCSSPrefix + 'btn-icon', + iconCls: baseCSSPrefix + 'edit-'+id, + enableToggle:toggle !== false, + scope: editor, + handler:handler||editor.relayBtnCmd, + clickEvent:'mousedown', + tooltip: tipsEnabled ? editor.buttonTips[id] || undef : undef, + overflowText: editor.buttonTips[id].title || undef, + tabIndex:-1 + }; } - }, - - getTargetXY : function(){ - if(this.delegate){ - this.anchorTarget = this.triggerElement; - } - if(this.anchor){ - this.targetCounter++; - var offsets = this.getOffsets(), - xy = (this.anchorToTarget && !this.trackMouse) ? this.el.getAlignToXY(this.anchorTarget, this.getAnchorAlign()) : this.targetXY, - dw = Ext.lib.Dom.getViewWidth() - 5, - dh = Ext.lib.Dom.getViewHeight() - 5, - de = document.documentElement, - bd = document.body, - scrollX = (de.scrollLeft || bd.scrollLeft || 0) + 5, - scrollY = (de.scrollTop || bd.scrollTop || 0) + 5, - axy = [xy[0] + offsets[0], xy[1] + offsets[1]], - sz = this.getSize(); - - this.anchorEl.removeClass(this.anchorCls); - if(this.targetCounter < 2){ - if(axy[0] < scrollX){ - if(this.anchorToTarget){ - this.defaultAlign = 'l-r'; - if(this.mouseOffset){this.mouseOffset[0] *= -1;} - } - this.anchor = 'left'; - return this.getTargetXY(); - } - if(axy[0]+sz.width > dw){ - if(this.anchorToTarget){ - this.defaultAlign = 'r-l'; - if(this.mouseOffset){this.mouseOffset[0] *= -1;} - } - this.anchor = 'right'; - return this.getTargetXY(); - } - if(axy[1] < scrollY){ - if(this.anchorToTarget){ - this.defaultAlign = 't-b'; - if(this.mouseOffset){this.mouseOffset[1] *= -1;} + if (me.enableFont && !Ext.isSafari2) { + fontSelectItem = Ext.widget('component', { + renderTpl: [ + '' + ], + renderData: { + cls: baseCSSPrefix + 'font-select', + fonts: me.fontFamilies, + defaultFont: me.defaultFont + }, + renderSelectors: { + selectEl: 'select' + }, + onDisable: function() { + var selectEl = this.selectEl; + if (selectEl) { + selectEl.dom.disabled = true; } - this.anchor = 'top'; - return this.getTargetXY(); - } - if(axy[1]+sz.height > dh){ - if(this.anchorToTarget){ - this.defaultAlign = 'b-t'; - if(this.mouseOffset){this.mouseOffset[1] *= -1;} + Ext.Component.superclass.onDisable.apply(this, arguments); + }, + onEnable: function() { + var selectEl = this.selectEl; + if (selectEl) { + selectEl.dom.disabled = false; } - this.anchor = 'bottom'; - return this.getTargetXY(); + Ext.Component.superclass.onEnable.apply(this, arguments); } - } + }); - this.anchorCls = 'x-tip-anchor-'+this.getAnchorPosition(); - this.anchorEl.addClass(this.anchorCls); - this.targetCounter = 0; - return axy; - }else{ - var mouseOffset = this.getMouseOffset(); - return [this.targetXY[0]+mouseOffset[0], this.targetXY[1]+mouseOffset[1]]; + items.push( + fontSelectItem, + '-' + ); } - }, - getMouseOffset : function(){ - var offset = this.anchor ? [0,0] : [15,18]; - if(this.mouseOffset){ - offset[0] += this.mouseOffset[0]; - offset[1] += this.mouseOffset[1]; + if (me.enableFormat) { + items.push( + btn('bold'), + btn('italic'), + btn('underline') + ); } - return offset; - }, - - getAnchorPosition : function(){ - if(this.anchor){ - this.tipAnchor = this.anchor.charAt(0); - }else{ - var m = this.defaultAlign.match(/^([a-z]+)-([a-z]+)(\?)?$/); - if(!m){ - throw 'AnchorTip.defaultAlign is invalid'; - } - this.tipAnchor = m[1].charAt(0); + if (me.enableFontSize) { + items.push( + '-', + btn('increasefontsize', false, me.adjustFont), + btn('decreasefontsize', false, me.adjustFont) + ); } - switch(this.tipAnchor){ - case 't': return 'top'; - case 'b': return 'bottom'; - case 'r': return 'right'; + if (me.enableColors) { + items.push( + '-', { + itemId: 'forecolor', + cls: baseCSSPrefix + 'btn-icon', + iconCls: baseCSSPrefix + 'edit-forecolor', + overflowText: editor.buttonTips.forecolor.title, + tooltip: tipsEnabled ? editor.buttonTips.forecolor || undef : undef, + tabIndex:-1, + menu : Ext.widget('menu', { + plain: true, + items: [{ + xtype: 'colorpicker', + allowReselect: true, + focus: Ext.emptyFn, + value: '000000', + plain: true, + clickEvent: 'mousedown', + handler: function(cp, color) { + me.execCmd('forecolor', Ext.isWebKit || Ext.isIE ? '#'+color : color); + me.deferFocus(); + this.up('menu').hide(); + } + }] + }) + }, { + itemId: 'backcolor', + cls: baseCSSPrefix + 'btn-icon', + iconCls: baseCSSPrefix + 'edit-backcolor', + overflowText: editor.buttonTips.backcolor.title, + tooltip: tipsEnabled ? editor.buttonTips.backcolor || undef : undef, + tabIndex:-1, + menu : Ext.widget('menu', { + plain: true, + items: [{ + xtype: 'colorpicker', + focus: Ext.emptyFn, + value: 'FFFFFF', + plain: true, + allowReselect: true, + clickEvent: 'mousedown', + handler: function(cp, color) { + if (Ext.isGecko) { + me.execCmd('useCSS', false); + me.execCmd('hilitecolor', color); + me.execCmd('useCSS', true); + me.deferFocus(); + } else { + me.execCmd(Ext.isOpera ? 'hilitecolor' : 'backcolor', Ext.isWebKit || Ext.isIE ? '#'+color : color); + me.deferFocus(); + } + this.up('menu').hide(); + } + }] + }) + } + ); } - return 'left'; - }, - - getAnchorAlign : function(){ - switch(this.anchor){ - case 'top' : return 'tl-bl'; - case 'left' : return 'tl-tr'; - case 'right': return 'tr-tl'; - default : return 'bl-tl'; + if (me.enableAlignments) { + items.push( + '-', + btn('justifyleft'), + btn('justifycenter'), + btn('justifyright') + ); } - }, - - getOffsets : function(){ - var offsets, - ap = this.getAnchorPosition().charAt(0); - if(this.anchorToTarget && !this.trackMouse){ - switch(ap){ - case 't': - offsets = [0, 9]; - break; - case 'b': - offsets = [0, -13]; - break; - case 'r': - offsets = [-13, 0]; - break; - default: - offsets = [9, 0]; - break; + if (!Ext.isSafari2) { + if (me.enableLinks) { + items.push( + '-', + btn('createlink', false, me.createLink) + ); } - }else{ - switch(ap){ - case 't': - offsets = [-15-this.anchorOffset, 30]; - break; - case 'b': - offsets = [-19-this.anchorOffset, -13-this.el.dom.offsetHeight]; - break; - case 'r': - offsets = [-15-this.el.dom.offsetWidth, -13-this.anchorOffset]; - break; - default: - offsets = [25, -13-this.anchorOffset]; - break; + + if (me.enableLists) { + items.push( + '-', + btn('insertorderedlist'), + btn('insertunorderedlist') + ); + } + if (me.enableSourceEdit) { + items.push( + '-', + btn('sourceedit', true, function(btn){ + me.toggleSourceEdit(!me.sourceEditMode); + }) + ); } } - var mouseOffset = this.getMouseOffset(); - offsets[0] += mouseOffset[0]; - offsets[1] += mouseOffset[1]; - return offsets; - }, + + toolbar = Ext.widget('toolbar', { + renderTo: me.toolbarWrap, + enableOverflow: true, + items: items + }); - - onTargetOver : function(e){ - if(this.disabled || e.within(this.target.dom, true)){ - return; - } - var t = e.getTarget(this.delegate); - if (t) { - this.triggerElement = t; - this.clearTimer('hide'); - this.targetXY = e.getXY(); - this.delayShow(); - } - }, + if (fontSelectItem) { + me.fontSelect = fontSelectItem.selectEl; - - delayShow : function(){ - if(this.hidden && !this.showTimer){ - if(this.lastActive.getElapsed() < this.quickShowInterval){ - this.show(); - }else{ - this.showTimer = this.show.defer(this.showDelay, this); - } - }else if(!this.hidden && this.autoHide !== false){ - this.show(); + me.mon(me.fontSelect, 'change', function(){ + me.relayCmd('fontname', me.fontSelect.dom.value); + me.deferFocus(); + }); } - }, - - onTargetOut : function(e){ - if(this.disabled || e.within(this.target.dom, true)){ - return; - } - this.clearTimer('show'); - if(this.autoHide !== false){ - this.delayHide(); - } + + me.mon(toolbar.el, 'click', function(e){ + e.preventDefault(); + }); + + me.toolbar = toolbar; }, - - delayHide : function(){ - if(!this.hidden && !this.hideTimer){ - this.hideTimer = this.hide.defer(this.hideDelay, this); - } + onDisable: function() { + this.bodyEl.mask(); + this.callParent(arguments); }, - - hide: function(){ - this.clearTimer('dismiss'); - this.lastActive = new Date(); - if(this.anchorEl){ - this.anchorEl.hide(); - } - Ext.ToolTip.superclass.hide.call(this); - delete this.triggerElement; + onEnable: function() { + this.bodyEl.unmask(); + this.callParent(arguments); }, - show : function(){ - if(this.anchor){ - - - this.showAt([-1000,-1000]); - this.origConstrainPosition = this.constrainPosition; - this.constrainPosition = false; - this.anchor = this.origAnchor; - } - this.showAt(this.getTargetXY()); + setReadOnly: function(readOnly) { + var me = this, + textareaEl = me.textareaEl, + iframeEl = me.iframeEl, + body; - if(this.anchor){ - this.anchorEl.show(); - this.syncAnchor(); - this.constrainPosition = this.origConstrainPosition; - }else{ - this.anchorEl.hide(); - } - }, + me.readOnly = readOnly; - - showAt : function(xy){ - this.lastActive = new Date(); - this.clearTimers(); - Ext.ToolTip.superclass.showAt.call(this, xy); - if(this.dismissDelay && this.autoHide !== false){ - this.dismissTimer = this.hide.defer(this.dismissDelay, this); - } - if(this.anchor && !this.anchorEl.isVisible()){ - this.syncAnchor(); - this.anchorEl.show(); - }else{ - this.anchorEl.hide(); + if (textareaEl) { + textareaEl.dom.readOnly = readOnly; } - }, - - syncAnchor : function(){ - var anchorPos, targetPos, offset; - switch(this.tipAnchor.charAt(0)){ - case 't': - anchorPos = 'b'; - targetPos = 'tl'; - offset = [20+this.anchorOffset, 2]; - break; - case 'r': - anchorPos = 'l'; - targetPos = 'tr'; - offset = [-2, 11+this.anchorOffset]; - break; - case 'b': - anchorPos = 't'; - targetPos = 'bl'; - offset = [20+this.anchorOffset, -2]; - break; - default: - anchorPos = 'r'; - targetPos = 'tl'; - offset = [2, 11+this.anchorOffset]; - break; + if (me.initialized) { + body = me.getEditorBody(); + if (Ext.isIE) { + + iframeEl.setDisplayed(false); + body.contentEditable = !readOnly; + iframeEl.setDisplayed(true); + } else { + me.setDesignMode(!readOnly); + } + if (body) { + body.style.cursor = readOnly ? 'default' : 'text'; + } + me.disableItems(readOnly); } - this.anchorEl.alignTo(this.el, anchorPos+'-'+targetPos, offset); }, - setPagePosition : function(x, y){ - Ext.ToolTip.superclass.setPagePosition.call(this, x, y); - if(this.anchor){ - this.syncAnchor(); - } + getDocMarkup: function() { + var me = this, + h = me.iframeEl.getHeight() - me.iframePad * 2; + return Ext.String.format('', me.iframePad, h); }, - clearTimer : function(name){ - name = name + 'Timer'; - clearTimeout(this[name]); - delete this[name]; + getEditorBody: function() { + var doc = this.getDoc(); + return doc.body || doc.documentElement; }, - clearTimers : function(){ - this.clearTimer('show'); - this.clearTimer('dismiss'); - this.clearTimer('hide'); + getDoc: function() { + return (!Ext.isIE && this.iframeEl.dom.contentDocument) || this.getWin().document; }, - onShow : function(){ - Ext.ToolTip.superclass.onShow.call(this); - Ext.getDoc().on('mousedown', this.onDocMouseDown, this); + getWin: function() { + return Ext.isIE ? this.iframeEl.dom.contentWindow : window.frames[this.iframeEl.dom.name]; }, - onHide : function(){ - Ext.ToolTip.superclass.onHide.call(this); - Ext.getDoc().un('mousedown', this.onDocMouseDown, this); + onRender: function() { + var me = this, + renderSelectors = me.renderSelectors; + + Ext.applyIf(renderSelectors, me.getLabelableSelectors()); + + Ext.applyIf(renderSelectors, { + toolbarWrap: 'div.' + Ext.baseCSSPrefix + 'html-editor-tb', + iframeEl: 'iframe', + textareaEl: 'textarea' + }); + + me.callParent(arguments); + + me.textareaEl.dom.value = me.value || ''; + + + me.monitorTask = Ext.TaskManager.start({ + run: me.checkDesignMode, + scope: me, + interval:100 + }); + + me.createToolbar(me); + me.disableItems(true); }, - - onDocMouseDown : function(e){ - if(this.autoHide !== true && !this.closable && !e.within(this.el.dom)){ - this.disable(); - this.doEnable.defer(100, this); + initRenderTpl: function() { + var me = this; + if (!me.hasOwnProperty('renderTpl')) { + me.renderTpl = me.getTpl('labelableRenderTpl'); } + return me.callParent(); }, - - - doEnable : function(){ - if(!this.isDestroyed){ - this.enable(); - } + + initRenderData: function() { + return Ext.applyIf(this.callParent(), this.getLabelableRenderData()); }, - - onDisable : function(){ - this.clearTimers(); - this.hide(); + getSubTplData: function() { + var cssPrefix = Ext.baseCSSPrefix; + return { + toolbarWrapCls: cssPrefix + 'html-editor-tb', + textareaCls: cssPrefix + 'hidden', + iframeName: Ext.id(), + iframeSrc: Ext.SSL_SECURE_URL, + size: 'height:100px;' + }; }, - - adjustPosition : function(x, y){ - if(this.contstrainPosition){ - var ay = this.targetXY[1], h = this.getSize().height; - if(y <= ay && (y+h) >= ay){ - y = ay-h-5; - } - } - return {x : x, y: y}; + getSubTplMarkup: function() { + return this.getTpl('fieldSubTpl').apply(this.getSubTplData()); }, - - beforeDestroy : function(){ - this.clearTimers(); - Ext.destroy(this.anchorEl); - delete this.anchorEl; - delete this.target; - delete this.anchorTarget; - delete this.triggerElement; - Ext.ToolTip.superclass.beforeDestroy.call(this); + + getBodyNaturalWidth: function() { + return 565; }, - - onDestroy : function(){ - Ext.getDoc().un('mousedown', this.onDocMouseDown, this); - Ext.ToolTip.superclass.onDestroy.call(this); - } -}); + initFrameDoc: function() { + var me = this, + doc, task; -Ext.reg('tooltip', Ext.ToolTip); -Ext.QuickTip = Ext.extend(Ext.ToolTip, { - - - interceptTitles : false, + Ext.TaskManager.stop(me.monitorTask); - - tagConfig : { - namespace : "ext", - attribute : "qtip", - width : "qwidth", - target : "target", - title : "qtitle", - hide : "hide", - cls : "qclass", - align : "qalign", - anchor : "anchor" + doc = me.getDoc(); + me.win = me.getWin(); + + doc.open(); + doc.write(me.getDocMarkup()); + doc.close(); + + task = { + run: function() { + var doc = me.getDoc(); + if (doc.body || doc.readyState === 'complete') { + Ext.TaskManager.stop(task); + me.setDesignMode(true); + Ext.defer(me.initEditor, 10, me); + } + }, + interval : 10, + duration:10000, + scope: me + }; + Ext.TaskManager.start(task); }, - - initComponent : function(){ - this.target = this.target || Ext.getDoc(); - this.targets = this.targets || {}; - Ext.QuickTip.superclass.initComponent.call(this); + checkDesignMode: function() { + var me = this, + doc = me.getDoc(); + if (doc && (!doc.editorInitialized || me.getDesignMode() !== 'on')) { + me.initFrameDoc(); + } }, - register : function(config){ - var cs = Ext.isArray(config) ? config : arguments; - for(var i = 0, len = cs.length; i < len; i++){ - var c = cs[i]; - var target = c.target; - if(target){ - if(Ext.isArray(target)){ - for(var j = 0, jlen = target.length; j < jlen; j++){ - this.targets[Ext.id(target[j])] = c; - } - } else{ - this.targets[Ext.id(target)] = c; - } + setDesignMode: function(mode) { + var me = this, + doc = me.getDoc(); + if (doc) { + if (me.readOnly) { + mode = false; } + doc.designMode = (/on|true/i).test(String(mode).toLowerCase()) ?'on':'off'; } }, - unregister : function(el){ - delete this.targets[Ext.id(el)]; + getDesignMode: function() { + var doc = this.getDoc(); + return !doc ? '' : String(doc.designMode).toLowerCase(); }, - - - cancelShow: function(el){ - var at = this.activeTarget; - el = Ext.get(el).dom; - if(this.isVisible()){ - if(at && at.el == el){ - this.hide(); + + disableItems: function(disabled) { + this.getToolbar().items.each(function(item){ + if(item.getItemId() !== 'sourceedit'){ + item.setDisabled(disabled); } - }else if(at && at.el == el){ - this.clearTimer('show'); - } - }, - - getTipCfg: function(e) { - var t = e.getTarget(), - ttp, - cfg; - if(this.interceptTitles && t.title && Ext.isString(t.title)){ - ttp = t.title; - t.qtip = ttp; - t.removeAttribute("title"); - e.preventDefault(); - }else{ - cfg = this.tagConfig; - ttp = t.qtip || Ext.fly(t).getAttribute(cfg.attribute, cfg.namespace); - } - return ttp; + }); }, - onTargetOver : function(e){ - if(this.disabled){ - return; - } - this.targetXY = e.getXY(); - var t = e.getTarget(); - if(!t || t.nodeType !== 1 || t == document || t == document.body){ - return; + toggleSourceEdit: function(sourceEditMode) { + var me = this, + iframe = me.iframeEl, + textarea = me.textareaEl, + hiddenCls = Ext.baseCSSPrefix + 'hidden', + btn = me.getToolbar().getComponent('sourceedit'); + + if (!Ext.isBoolean(sourceEditMode)) { + sourceEditMode = !me.sourceEditMode; } - if(this.activeTarget && ((t == this.activeTarget.el) || Ext.fly(this.activeTarget.el).contains(t))){ - this.clearTimer('hide'); - this.show(); - return; + me.sourceEditMode = sourceEditMode; + + if (btn.pressed !== sourceEditMode) { + btn.toggle(sourceEditMode); } - if(t && this.targets[t.id]){ - this.activeTarget = this.targets[t.id]; - this.activeTarget.el = t; - this.anchor = this.activeTarget.anchor; - if(this.anchor){ - this.anchorTarget = t; - } - this.delayShow(); - return; + if (sourceEditMode) { + me.disableItems(true); + me.syncValue(); + iframe.addCls(hiddenCls); + textarea.removeCls(hiddenCls); + textarea.dom.removeAttribute('tabIndex'); + textarea.focus(); } - var ttp, et = Ext.fly(t), cfg = this.tagConfig, ns = cfg.namespace; - if(ttp = this.getTipCfg(e)){ - var autoHide = et.getAttribute(cfg.hide, ns); - this.activeTarget = { - el: t, - text: ttp, - width: et.getAttribute(cfg.width, ns), - autoHide: autoHide != "user" && autoHide !== 'false', - title: et.getAttribute(cfg.title, ns), - cls: et.getAttribute(cfg.cls, ns), - align: et.getAttribute(cfg.align, ns) - - }; - this.anchor = et.getAttribute(cfg.anchor, ns); - if(this.anchor){ - this.anchorTarget = t; + else { + if (me.initialized) { + me.disableItems(me.readOnly); } - this.delayShow(); + me.pushValue(); + iframe.removeCls(hiddenCls); + textarea.addCls(hiddenCls); + textarea.dom.setAttribute('tabIndex', -1); + me.deferFocus(); } + me.fireEvent('editmodechange', me, sourceEditMode); + me.doComponentLayout(); }, - onTargetOut : function(e){ - - - if (this.activeTarget && e.within(this.activeTarget.el) && !this.getTipCfg(e)) { - return; + createLink : function() { + var url = prompt(this.createLinkText, this.defaultLinkValue); + if (url && url !== 'http:/'+'/') { + this.relayCmd('createlink', url); } + }, + + clearInvalid: Ext.emptyFn, - this.clearTimer('show'); - if(this.autoHide !== false){ - this.delayHide(); + + setValue: function(value) { + var me = this, + textarea = me.textareaEl; + me.mixins.field.setValue.call(me, value); + if (value === null || value === undefined) { + value = ''; } + if (textarea) { + textarea.dom.value = value; + } + me.pushValue(); + return this; }, - showAt : function(xy){ - var t = this.activeTarget; - if(t){ - if(!this.rendered){ - this.render(Ext.getBody()); - this.activeTarget = t; - } - if(t.width){ - this.setWidth(t.width); - this.body.setWidth(this.adjustBodyWidth(t.width - this.getFrameWidth())); - this.measureWidth = false; - } else{ - this.measureWidth = true; - } - this.setTitle(t.title || ''); - this.body.update(t.text); - this.autoHide = t.autoHide; - this.dismissDelay = t.dismissDelay || this.dismissDelay; - if(this.lastCls){ - this.el.removeClass(this.lastCls); - delete this.lastCls; - } - if(t.cls){ - this.el.addClass(t.cls); - this.lastCls = t.cls; - } - if(this.anchor){ - this.constrainPosition = false; - }else if(t.align){ - xy = this.el.getAlignToXY(t.el, t.align); - this.constrainPosition = false; - }else{ - this.constrainPosition = true; - } + cleanHtml: function(html) { + html = String(html); + if (Ext.isWebKit) { + html = html.replace(/\sclass="(?:Apple-style-span|khtml-block-placeholder)"/gi, ''); } - Ext.QuickTip.superclass.showAt.call(this, xy); + + + if (html.charCodeAt(0) === this.defaultValue.replace(/\D/g, '')) { + html = html.substring(1); + } + return html; }, - hide: function(){ - delete this.activeTarget; - Ext.QuickTip.superclass.hide.call(this); - } -}); -Ext.reg('quicktip', Ext.QuickTip); -Ext.QuickTips = function(){ - var tip, - disabled = false; - - return { - - init : function(autoRender){ - if(!tip){ - if(!Ext.isReady){ - Ext.onReady(function(){ - Ext.QuickTips.init(autoRender); - }); - return; - } - tip = new Ext.QuickTip({ - elements:'header,body', - disabled: disabled - }); - if(autoRender !== false){ - tip.render(Ext.getBody()); + syncValue : function(){ + var me = this, + body, html, bodyStyle, match; + if (me.initialized) { + body = me.getEditorBody(); + html = body.innerHTML; + if (Ext.isWebKit) { + bodyStyle = body.getAttribute('style'); + match = bodyStyle.match(/text-align:(.*?);/i); + if (match && match[1]) { + html = '
    ' + html + '
    '; } } - }, - - - ddDisable : function(){ - - if(tip && !disabled){ - tip.disable(); - } - }, - - - ddEnable : function(){ - - if(tip && !disabled){ - tip.enable(); - } - }, - - - enable : function(){ - if(tip){ - tip.enable(); - } - disabled = false; - }, - - - disable : function(){ - if(tip){ - tip.disable(); + html = me.cleanHtml(html); + if (me.fireEvent('beforesync', me, html) !== false) { + me.textareaEl.dom.value = html; + me.fireEvent('sync', me, html); } - disabled = true; - }, - - - isEnabled : function(){ - return tip !== undefined && !tip.disabled; - }, - - - getQuickTip : function(){ - return tip; - }, - - - register : function(){ - tip.register.apply(tip, arguments); - }, - - - unregister : function(){ - tip.unregister.apply(tip, arguments); - }, - - - tips : function(){ - tip.register.apply(tip, arguments); } - }; -}(); -Ext.slider.Tip = Ext.extend(Ext.Tip, { - minWidth: 10, - offsets : [0, -10], - - init: function(slider) { - slider.on({ - scope : this, - dragstart: this.onSlide, - drag : this.onSlide, - dragend : this.hide, - destroy : this.destroy - }); }, + - - onSlide : function(slider, e, thumb) { - this.show(); - this.body.update(this.getText(thumb)); - this.doAutoWidth(); - this.el.alignTo(thumb.el, 'b-t?', this.offsets); + getValue : function() { + var me = this, + value; + if (!me.sourceEditMode) { + me.syncValue(); + } + value = me.rendered ? me.textareaEl.dom.value : me.value; + me.value = value; + return value; }, - getText : function(thumb) { - return String(thumb.value); - } -}); - - -Ext.ux.SliderTip = Ext.slider.Tip; -Ext.tree.TreePanel = Ext.extend(Ext.Panel, { - rootVisible : true, - animate : Ext.enableFx, - lines : true, - enableDD : false, - hlDrop : Ext.enableFx, - pathSeparator : '/', + pushValue: function() { + var me = this, + v; + if(me.initialized){ + v = me.textareaEl.dom.value || ''; + if (!me.activated && v.length < 1) { + v = me.defaultValue; + } + if (me.fireEvent('beforepush', me, v) !== false) { + me.getEditorBody().innerHTML = v; + if (Ext.isGecko) { + + me.setDesignMode(false); + me.setDesignMode(true); + } + me.fireEvent('push', me, v); + } + } + }, - bubbleEvents : [], - - initComponent : function(){ - Ext.tree.TreePanel.superclass.initComponent.call(this); + deferFocus : function(){ + this.focus(false, true); + }, - if(!this.eventModel){ - this.eventModel = new Ext.tree.TreeEventModel(this); - } + getFocusEl: function() { + var me = this, + win = me.win; + return win && !me.sourceEditMode ? win : me.textareaEl; + }, + + initEditor : function(){ - var l = this.loader; - if(!l){ - l = new Ext.tree.TreeLoader({ - dataUrl: this.dataUrl, - requestMethod: this.requestMethod - }); - }else if(Ext.isObject(l) && !l.load){ - l = new Ext.tree.TreeLoader(l); - } - this.loader = l; + try { + var me = this, + dbody = me.getEditorBody(), + ss = me.textareaEl.getStyles('font-size', 'font-family', 'background-image', 'background-repeat', 'background-color', 'color'), + doc, + fn; - this.nodeHash = {}; + ss['background-attachment'] = 'fixed'; + dbody.bgProperties = 'fixed'; - - if(this.root){ - var r = this.root; - delete this.root; - this.setRootNode(r); - } + Ext.core.DomHelper.applyStyles(dbody, ss); + doc = me.getDoc(); - this.addEvents( + if (doc) { + try { + Ext.EventManager.removeAll(doc); + } catch(e) {} + } - 'append', - - 'remove', - - 'movenode', - - 'insert', - - 'beforeappend', - - 'beforeremove', - - 'beforemovenode', - - 'beforeinsert', + fn = Ext.Function.bind(me.onEditorEvent, me); + Ext.EventManager.on(doc, { + mousedown: fn, + dblclick: fn, + click: fn, + keyup: fn, + buffer:100 + }); - 'beforeload', - - 'load', - - 'textchange', - - 'beforeexpandnode', - - 'beforecollapsenode', - - 'expandnode', - - 'disabledchange', - - 'collapsenode', - - 'beforeclick', - - 'click', - - 'containerclick', - - 'checkchange', - 'beforedblclick', - 'dblclick', - 'containerdblclick', - - 'contextmenu', - - 'containercontextmenu', - - 'beforechildrenrendered', - - 'startdrag', - - 'enddrag', - - 'dragdrop', - 'beforenodedrop', + fn = me.onRelayedEvent; + Ext.EventManager.on(doc, { + mousedown: fn, + mousemove: fn, + mouseup: fn, + click: fn, + dblclick: fn, + scope: me + }); + + if (Ext.isGecko) { + Ext.EventManager.on(doc, 'keypress', me.applyCommand, me); + } + if (me.fixKeys) { + Ext.EventManager.on(doc, 'keydown', me.fixKeys, me); + } + - 'nodedrop', - - 'nodedragover' - ); - if(this.singleExpand){ - this.on('beforeexpandnode', this.restrictExpand, this); - } - }, + Ext.EventManager.on(window, 'unload', me.beforeDestroy, me); + doc.editorInitialized = true; - - proxyNodeEvent : function(ename, a1, a2, a3, a4, a5, a6){ - if(ename == 'collapse' || ename == 'expand' || ename == 'beforecollapse' || ename == 'beforeexpand' || ename == 'move' || ename == 'beforemove'){ - ename = ename+'node'; + me.initialized = true; + me.pushValue(); + me.setReadOnly(me.readOnly); + me.fireEvent('initialize', me); + } catch(ex) { + } - - return this.fireEvent(ename, a1, a2, a3, a4, a5, a6); }, - - getRootNode : function(){ - return this.root; - }, + beforeDestroy : function(){ + var me = this, + monitorTask = me.monitorTask, + doc, prop; - - setRootNode : function(node){ - this.destroyRoot(); - if(!node.render){ - node = this.loader.createNode(node); + if (monitorTask) { + Ext.TaskManager.stop(monitorTask); } - this.root = node; - node.ownerTree = this; - node.isRoot = true; - this.registerNode(node); - if(!this.rootVisible){ - var uiP = node.attributes.uiProvider; - node.ui = uiP ? new uiP(node) : new Ext.tree.RootTreeNodeUI(node); - } - if(this.innerCt){ - this.clearInnerCt(); - this.renderRoot(); - } - return node; - }, - - clearInnerCt : function(){ - this.innerCt.update(''); - }, - - - renderRoot : function(){ - this.root.render(); - if(!this.rootVisible){ - this.root.renderChildren(); + if (me.rendered) { + try { + doc = me.getDoc(); + if (doc) { + Ext.EventManager.removeAll(doc); + for (prop in doc) { + if (doc.hasOwnProperty(prop)) { + delete doc[prop]; + } + } + } + } catch(e) { + + } + Ext.destroyMembers('tb', 'toolbarWrap', 'iframeEl', 'textareaEl'); } + me.callParent(); }, - getNodeById : function(id){ - return this.nodeHash[id]; - }, - - - registerNode : function(node){ - this.nodeHash[node.id] = node; - }, + onRelayedEvent: function (event) { + - - unregisterNode : function(node){ - delete this.nodeHash[node.id]; + var iframeEl = this.iframeEl, + iframeXY = iframeEl.getXY(), + eventXY = event.getXY(); + + + + event.xy = [iframeXY[0] + eventXY[0], iframeXY[1] + eventXY[1]]; + + event.injectEvent(iframeEl); + + event.xy = eventXY; }, - toString : function(){ - return '[Tree'+(this.id?' '+this.id:'')+']'; + onFirstFocus : function(){ + var me = this, + selection, range; + me.activated = true; + me.disableItems(me.readOnly); + if (Ext.isGecko) { + me.win.focus(); + selection = me.win.getSelection(); + if (!selection.focusNode || selection.focusNode.nodeType !== 3) { + range = selection.getRangeAt(0); + range.selectNodeContents(me.getEditorBody()); + range.collapse(true); + me.deferFocus(); + } + try { + me.execCmd('useCSS', true); + me.execCmd('styleWithCSS', false); + } catch(e) { + + } + } + me.fireEvent('activate', me); }, - restrictExpand : function(node){ - var p = node.parentNode; - if(p){ - if(p.expandedChild && p.expandedChild.parentNode == p){ - p.expandedChild.collapse(); + adjustFont: function(btn) { + var adjust = btn.getItemId() === 'increasefontsize' ? 1 : -1, + size = this.getDoc().queryCommandValue('FontSize') || '2', + isPxSize = Ext.isString(size) && size.indexOf('px') !== -1, + isSafari; + size = parseInt(size, 10); + if (isPxSize) { + + + if (size <= 10) { + size = 1 + adjust; + } + else if (size <= 13) { + size = 2 + adjust; + } + else if (size <= 16) { + size = 3 + adjust; + } + else if (size <= 18) { + size = 4 + adjust; + } + else if (size <= 24) { + size = 5 + adjust; + } + else { + size = 6 + adjust; + } + size = Ext.Number.constrain(size, 1, 6); + } else { + isSafari = Ext.isSafari; + if (isSafari) { + adjust *= 2; } - p.expandedChild = node; + size = Math.max(1, size + adjust) + (isSafari ? 'px' : 0); } + this.execCmd('FontSize', size); }, - getChecked : function(a, startNode){ - startNode = startNode || this.root; - var r = []; - var f = function(){ - if(this.attributes.checked){ - r.push(!a ? this : (a == 'id' ? this.id : this.attributes[a])); - } - }; - startNode.cascade(f); - return r; + onEditorEvent: function(e) { + this.updateToolbar(); }, - getLoader : function(){ - return this.loader; + updateToolbar: function() { + var me = this, + btns, doc, name, fontSelect; + + if (me.readOnly) { + return; + } + + if (!me.activated) { + me.onFirstFocus(); + return; + } + + btns = me.getToolbar().items.map; + doc = me.getDoc(); + + if (me.enableFont && !Ext.isSafari2) { + name = (doc.queryCommandValue('FontName') || me.defaultFont).toLowerCase(); + fontSelect = me.fontSelect.dom; + if (name !== fontSelect.value) { + fontSelect.value = name; + } + } + + function updateButtons() { + Ext.Array.forEach(Ext.Array.toArray(arguments), function(name) { + btns[name].toggle(doc.queryCommandState(name)); + }); + } + if(me.enableFormat){ + updateButtons('bold', 'italic', 'underline'); + } + if(me.enableAlignments){ + updateButtons('justifyleft', 'justifycenter', 'justifyright'); + } + if(!Ext.isSafari2 && me.enableLists){ + updateButtons('insertorderedlist', 'insertunorderedlist'); + } + + Ext.menu.Manager.hideAll(); + + me.syncValue(); }, - expandAll : function(){ - this.root.expand(true); + relayBtnCmd: function(btn) { + this.relayCmd(btn.getItemId()); }, - collapseAll : function(){ - this.root.collapse(true); + relayCmd: function(cmd, value) { + Ext.defer(function() { + var me = this; + me.focus(); + me.execCmd(cmd, value); + me.updateToolbar(); + }, 10, this); }, - getSelectionModel : function(){ - if(!this.selModel){ - this.selModel = new Ext.tree.DefaultSelectionModel(); - } - return this.selModel; + execCmd : function(cmd, value){ + var me = this, + doc = me.getDoc(), + undef; + doc.execCommand(cmd, false, value === undef ? null : value); + me.syncValue(); }, - expandPath : function(path, attr, callback){ - if(Ext.isEmpty(path)){ - if(callback){ - callback(false, undefined); - } - return; - } - attr = attr || 'id'; - var keys = path.split(this.pathSeparator); - var curNode = this.root; - if(curNode.attributes[attr] != keys[1]){ - if(callback){ - callback(false, null); - } - return; - } - var index = 1; - var f = function(){ - if(++index == keys.length){ - if(callback){ - callback(true, curNode); + applyCommand : function(e){ + if (e.ctrlKey) { + var me = this, + c = e.getCharCode(), cmd; + if (c > 0) { + c = String.fromCharCode(c); + switch (c) { + case 'b': + cmd = 'bold'; + break; + case 'i': + cmd = 'italic'; + break; + case 'u': + cmd = 'underline'; + break; } - return; - } - var c = curNode.findChild(attr, keys[index]); - if(!c){ - if(callback){ - callback(false, curNode); + if (cmd) { + me.win.focus(); + me.execCmd(cmd); + me.deferFocus(); + e.preventDefault(); } - return; } - curNode = c; - c.expand(false, false, f); - }; - curNode.expand(false, false, f); + } }, - selectPath : function(path, attr, callback){ - if(Ext.isEmpty(path)){ - if(callback){ - callback(false, undefined); + insertAtCursor : function(text){ + var me = this, + range; + + if (me.activated) { + me.win.focus(); + if (Ext.isIE) { + range = me.getDoc().selection.createRange(); + if (range) { + range.pasteHTML(text); + me.syncValue(); + me.deferFocus(); + } + }else{ + me.execCmd('InsertHTML', text); + me.deferFocus(); } - return; } - attr = attr || 'id'; - var keys = path.split(this.pathSeparator), - v = keys.pop(); - if(keys.length > 1){ - var f = function(success, node){ - if(success && node){ - var n = node.findChild(attr, v); - if(n){ - n.select(); - if(callback){ - callback(true, n); - } - }else if(callback){ - callback(false, n); + }, + + + fixKeys: function() { + if (Ext.isIE) { + return function(e){ + var me = this, + k = e.getKey(), + doc = me.getDoc(), + range, target; + if (k === e.TAB) { + e.stopEvent(); + range = doc.selection.createRange(); + if(range){ + range.collapse(true); + range.pasteHTML('    '); + me.deferFocus(); } - }else{ - if(callback){ - callback(false, n); + } + else if (k === e.ENTER) { + range = doc.selection.createRange(); + if (range) { + target = range.parentElement(); + if(!target || target.tagName.toLowerCase() !== 'li'){ + e.stopEvent(); + range.pasteHTML('
    '); + range.collapse(false); + range.select(); + } } } }; - this.expandPath(keys.join(this.pathSeparator), attr, f); - }else{ - this.root.select(); - if(callback){ - callback(true, this.root); - } } - }, - - - getTreeEl : function(){ - return this.body; - }, - - - onRender : function(ct, position){ - Ext.tree.TreePanel.superclass.onRender.call(this, ct, position); - this.el.addClass('x-tree'); - this.innerCt = this.body.createChild({tag:'ul', - cls:'x-tree-root-ct ' + - (this.useArrows ? 'x-tree-arrows' : this.lines ? 'x-tree-lines' : 'x-tree-no-lines')}); - }, - - initEvents : function(){ - Ext.tree.TreePanel.superclass.initEvents.call(this); - - if(this.containerScroll){ - Ext.dd.ScrollManager.register(this.body); - } - if((this.enableDD || this.enableDrop) && !this.dropZone){ - - this.dropZone = new Ext.tree.TreeDropZone(this, this.dropConfig || { - ddGroup: this.ddGroup || 'TreeDD', appendOnly: this.ddAppendOnly === true - }); + if (Ext.isOpera) { + return function(e){ + var me = this; + if (e.getKey() === e.TAB) { + e.stopEvent(); + me.win.focus(); + me.execCmd('InsertHTML','    '); + me.deferFocus(); + } + }; } - if((this.enableDD || this.enableDrag) && !this.dragZone){ - - this.dragZone = new Ext.tree.TreeDragZone(this, this.dragConfig || { - ddGroup: this.ddGroup || 'TreeDD', - scroll: this.ddScroll - }); + + if (Ext.isWebKit) { + return function(e){ + var me = this, + k = e.getKey(); + if (k === e.TAB) { + e.stopEvent(); + me.execCmd('InsertText','\t'); + me.deferFocus(); + } + else if (k === e.ENTER) { + e.stopEvent(); + me.execCmd('InsertHtml','

    '); + me.deferFocus(); + } + }; } - this.getSelectionModel().init(this); - }, + + return null; + }(), - afterRender : function(){ - Ext.tree.TreePanel.superclass.afterRender.call(this); - this.renderRoot(); + getToolbar : function(){ + return this.toolbar; }, - beforeDestroy : function(){ - if(this.rendered){ - Ext.dd.ScrollManager.unregister(this.body); - Ext.destroy(this.dropZone, this.dragZone); - } - this.destroyRoot(); - Ext.destroy(this.loader); - this.nodeHash = this.root = this.loader = null; - Ext.tree.TreePanel.superclass.beforeDestroy.call(this); - }, - - destroyRoot : function(){ - if(this.root && this.root.destroy){ - this.root.destroy(true); + buttonTips : { + bold : { + title: 'Bold (Ctrl+B)', + text: 'Make the selected text bold.', + cls: Ext.baseCSSPrefix + 'html-editor-tip' + }, + italic : { + title: 'Italic (Ctrl+I)', + text: 'Make the selected text italic.', + cls: Ext.baseCSSPrefix + 'html-editor-tip' + }, + underline : { + title: 'Underline (Ctrl+U)', + text: 'Underline the selected text.', + cls: Ext.baseCSSPrefix + 'html-editor-tip' + }, + increasefontsize : { + title: 'Grow Text', + text: 'Increase the font size.', + cls: Ext.baseCSSPrefix + 'html-editor-tip' + }, + decreasefontsize : { + title: 'Shrink Text', + text: 'Decrease the font size.', + cls: Ext.baseCSSPrefix + 'html-editor-tip' + }, + backcolor : { + title: 'Text Highlight Color', + text: 'Change the background color of the selected text.', + cls: Ext.baseCSSPrefix + 'html-editor-tip' + }, + forecolor : { + title: 'Font Color', + text: 'Change the color of the selected text.', + cls: Ext.baseCSSPrefix + 'html-editor-tip' + }, + justifyleft : { + title: 'Align Text Left', + text: 'Align text to the left.', + cls: Ext.baseCSSPrefix + 'html-editor-tip' + }, + justifycenter : { + title: 'Center Text', + text: 'Center text in the editor.', + cls: Ext.baseCSSPrefix + 'html-editor-tip' + }, + justifyright : { + title: 'Align Text Right', + text: 'Align text to the right.', + cls: Ext.baseCSSPrefix + 'html-editor-tip' + }, + insertunorderedlist : { + title: 'Bullet List', + text: 'Start a bulleted list.', + cls: Ext.baseCSSPrefix + 'html-editor-tip' + }, + insertorderedlist : { + title: 'Numbered List', + text: 'Start a numbered list.', + cls: Ext.baseCSSPrefix + 'html-editor-tip' + }, + createlink : { + title: 'Hyperlink', + text: 'Make the selected text a hyperlink.', + cls: Ext.baseCSSPrefix + 'html-editor-tip' + }, + sourceedit : { + title: 'Source Edit', + text: 'Switch to source editing mode.', + cls: Ext.baseCSSPrefix + 'html-editor-tip' } } @@ -33546,5722 +71601,5378 @@ Ext.tree.TreePanel = Ext.extend(Ext.Panel, { - - - - - - - - - - - - - - +}); +Ext.define('Ext.form.field.Radio', { + extend:'Ext.form.field.Checkbox', + alias: ['widget.radiofield', 'widget.radio'], + alternateClassName: 'Ext.form.Radio', + requires: ['Ext.form.RadioManager'], - - - - - - - - - - - - - - - - -}); + isRadio: true, -Ext.tree.TreePanel.nodeTypes = {}; + -Ext.reg('treepanel', Ext.tree.TreePanel);Ext.tree.TreeEventModel = function(tree){ - this.tree = tree; - this.tree.on('render', this.initEvents, this); -}; + + inputType: 'radio', + ariaRole: 'radio', -Ext.tree.TreeEventModel.prototype = { - initEvents : function(){ - var t = this.tree; + + getGroupValue: function() { + var selected = this.getManager().getChecked(this.name); + return selected ? selected.inputValue : null; + }, - if(t.trackMouseOver !== false){ - t.mon(t.innerCt, { - scope: this, - mouseover: this.delegateOver, - mouseout: this.delegateOut - }); + + onBoxClick: function(e) { + var me = this; + if (!me.disabled && !me.readOnly) { + this.setValue(true); } - t.mon(t.getTreeEl(), { - scope: this, - click: this.delegateClick, - dblclick: this.delegateDblClick, - contextmenu: this.delegateContextMenu - }); }, - getNode : function(e){ - var t; - if(t = e.getTarget('.x-tree-node-el', 10)){ - var id = Ext.fly(t, '_treeEvents').getAttribute('tree-node-id', 'ext'); - if(id){ - return this.tree.getNodeById(id); + + setValue: function(v) { + var me = this, + active; + + if (Ext.isBoolean(v)) { + me.callParent(arguments); + } else { + active = me.getManager().getWithValue(me.name, v).getAt(0); + if (active) { + active.setValue(true); } } - return null; + return me; }, - getNodeTarget : function(e){ - var t = e.getTarget('.x-tree-node-icon', 1); - if(!t){ - t = e.getTarget('.x-tree-node-el', 6); - } - return t; + + getSubmitValue: function() { + return this.checked ? this.inputValue : null; }, - delegateOut : function(e, t){ - if(!this.beforeEvent(e)){ - return; - } - if(e.getTarget('.x-tree-ec-icon', 1)){ - var n = this.getNode(e); - this.onIconOut(e, n); - if(n == this.lastEcOver){ - delete this.lastEcOver; - } - } - if((t = this.getNodeTarget(e)) && !e.within(t, true)){ - this.onNodeOut(e, this.getNode(e)); + + onChange: function(newVal, oldVal) { + var me = this; + me.callParent(arguments); + + if (newVal) { + this.getManager().getByName(me.name).each(function(item){ + if (item !== me) { + item.setValue(false); + } + }, me); } }, - delegateOver : function(e, t){ - if(!this.beforeEvent(e)){ - return; - } - if(Ext.isGecko && !this.trackingDoc){ - Ext.getBody().on('mouseover', this.trackExit, this); - this.trackingDoc = true; - } - if(this.lastEcOver){ - this.onIconOut(e, this.lastEcOver); - delete this.lastEcOver; - } - if(e.getTarget('.x-tree-ec-icon', 1)){ - this.lastEcOver = this.getNode(e); - this.onIconOver(e, this.lastEcOver); - } - if(t = this.getNodeTarget(e)){ - this.onNodeOver(e, this.getNode(e)); - } + + beforeDestroy: function(){ + this.callParent(); + this.getManager().removeAtKey(this.id); }, - trackExit : function(e){ - if(this.lastOverNode){ - if(this.lastOverNode.ui && !e.within(this.lastOverNode.ui.getEl())){ - this.onNodeOut(e, this.lastOverNode); - } - delete this.lastOverNode; - Ext.getBody().un('mouseover', this.trackExit, this); - this.trackingDoc = false; - } + + getManager: function() { + return Ext.form.RadioManager; + } +}); - }, - delegateClick : function(e, t){ - if(this.beforeEvent(e)){ - if(e.getTarget('input[type=checkbox]', 1)){ - this.onCheckboxClick(e, this.getNode(e)); - }else if(e.getTarget('.x-tree-ec-icon', 1)){ - this.onIconClick(e, this.getNode(e)); - }else if(this.getNodeTarget(e)){ - this.onNodeClick(e, this.getNode(e)); - } - }else{ - this.checkContainerEvent(e, 'click'); - } - }, +Ext.define('Ext.picker.Time', { + extend: 'Ext.view.BoundList', + alias: 'widget.timepicker', + requires: ['Ext.data.Store', 'Ext.Date'], - delegateDblClick : function(e, t){ - if(this.beforeEvent(e)){ - if(this.getNodeTarget(e)){ - this.onNodeDblClick(e, this.getNode(e)); - } - }else{ - this.checkContainerEvent(e, 'dblclick'); - } - }, + - delegateContextMenu : function(e, t){ - if(this.beforeEvent(e)){ - if(this.getNodeTarget(e)){ - this.onNodeContextMenu(e, this.getNode(e)); - } - }else{ - this.checkContainerEvent(e, 'contextmenu'); - } - }, - checkContainerEvent: function(e, type){ - if(this.disabled){ - e.stopEvent(); - return false; - } - this.onContainerEvent(e, type); - }, - onContainerEvent: function(e, type){ - this.tree.fireEvent('container' + type, this.tree, e); - }, + + increment: 15, - onNodeClick : function(e, node){ - node.ui.onClick(e); - }, + + format : "g:i A", - onNodeOver : function(e, node){ - this.lastOverNode = node; - node.ui.onOver(e); - }, + + displayField: 'disp', - onNodeOut : function(e, node){ - node.ui.onOut(e); - }, + + initDate: [2008,1,1], - onIconOver : function(e, node){ - node.ui.addClass('x-tree-ec-over'); - }, + componentCls: Ext.baseCSSPrefix + 'timepicker', - onIconOut : function(e, node){ - node.ui.removeClass('x-tree-ec-over'); - }, + + loadingText: '', - onIconClick : function(e, node){ - node.ui.ecClick(e); - }, + initComponent: function() { + var me = this, + dateUtil = Ext.Date, + clearTime = dateUtil.clearTime, + initDate = me.initDate.join('/'); - onCheckboxClick : function(e, node){ - node.ui.onCheckChange(e); + + me.absMin = clearTime(new Date(initDate)); + me.absMax = dateUtil.add(clearTime(new Date(initDate)), 'mi', (24 * 60) - 1); + + me.store = me.createStore(); + me.updateList(); + + this.callParent(); }, - onNodeDblClick : function(e, node){ - node.ui.onDblClick(e); + + setMinValue: function(value) { + this.minValue = value; + this.updateList(); }, - onNodeContextMenu : function(e, node){ - node.ui.onContextMenu(e); + + setMaxValue: function(value) { + this.maxValue = value; + this.updateList(); }, - beforeEvent : function(e){ - var node = this.getNode(e); - if(this.disabled || !node || !node.ui){ - e.stopEvent(); - return false; - } - return true; + + normalizeDate: function(date) { + var initDate = this.initDate; + date.setFullYear(initDate[0], initDate[1] - 1, initDate[2]); + return date; }, - disable: function(){ - this.disabled = true; + + updateList: function() { + var me = this, + min = me.normalizeDate(me.minValue || me.absMin), + max = me.normalizeDate(me.maxValue || me.absMax); + + me.store.filterBy(function(record) { + var date = record.get('date'); + return date >= min && date <= max; + }); }, - enable: function(){ - this.disabled = false; - } -}; -Ext.tree.DefaultSelectionModel = Ext.extend(Ext.util.Observable, { - constructor : function(config){ - this.selNode = null; - - this.addEvents( - - 'selectionchange', + createStore: function() { + var me = this, + utilDate = Ext.Date, + times = [], + min = me.absMin, + max = me.absMax; - - 'beforeselect' - ); + while(min <= max){ + times.push({ + disp: utilDate.dateFormat(min, me.format), + date: min + }); + min = utilDate.add(min, 'mi', me.increment); + } + + return Ext.create('Ext.data.Store', { + fields: ['disp', 'date'], + data: times + }); + } + +}); + + +Ext.define('Ext.form.field.Time', { + extend:'Ext.form.field.Picker', + alias: 'widget.timefield', + requires: ['Ext.form.field.Date', 'Ext.picker.Time', 'Ext.view.BoundListKeyNav', 'Ext.Date'], + alternateClassName: ['Ext.form.TimeField', 'Ext.form.Time'], - Ext.apply(this, config); - Ext.tree.DefaultSelectionModel.superclass.constructor.call(this); - }, - init : function(tree){ - this.tree = tree; - tree.mon(tree.getTreeEl(), 'keydown', this.onKeyDown, this); - tree.on('click', this.onNodeClick, this); - }, + triggerCls: Ext.baseCSSPrefix + 'form-time-trigger', + - onNodeClick : function(node, e){ - this.select(node); - }, + + - select : function(node, selectNextNode){ - - if (!Ext.fly(node.ui.wrap).isVisible() && selectNextNode) { - return selectNextNode.call(this, node); - } - var last = this.selNode; - if(node == last){ - node.ui.onSelectedChange(true); - }else if(this.fireEvent('beforeselect', this, node, last) !== false){ - if(last && last.ui){ - last.ui.onSelectedChange(false); - } - this.selNode = node; - node.ui.onSelectedChange(true); - this.fireEvent('selectionchange', this, node, last); - } - return node; - }, + minText : "The time in this field must be equal to or after {0}", + + maxText : "The time in this field must be equal to or before {0}", + - unselect : function(node, silent){ - if(this.selNode == node){ - this.clearSelections(silent); - } - }, + invalidText : "{0} is not a valid time", + + format : "g:i A", + - clearSelections : function(silent){ - var n = this.selNode; - if(n){ - n.ui.onSelectedChange(false); - this.selNode = null; - if(silent !== true){ - this.fireEvent('selectionchange', this, null); - } - } - return n; - }, + + altFormats : "g:ia|g:iA|g:i a|g:i A|h:i|g:i|H:i|ga|ha|gA|h a|g a|g A|gi|hi|gia|hia|g|H|gi a|hi a|giA|hiA|gi A|hi A", + - getSelectedNode : function(){ - return this.selNode; - }, + increment: 15, + + pickerMaxHeight: 300, + - isSelected : function(node){ - return this.selNode == node; - }, + selectOnTab: true, - selectPrevious : function( s){ - if(!(s = s || this.selNode || this.lastSelNode)){ - return null; + initDate: '1/1/2008', + initDateFormat: 'j/n/Y', + + + initComponent: function() { + var me = this, + min = me.minValue, + max = me.maxValue; + if (min) { + me.setMinValue(min); } - - var ps = s.previousSibling; - if(ps){ - if(!ps.isExpanded() || ps.childNodes.length < 1){ - return this.select(ps, this.selectPrevious); - } else{ - var lc = ps.lastChild; - while(lc && lc.isExpanded() && Ext.fly(lc.ui.wrap).isVisible() && lc.childNodes.length > 0){ - lc = lc.lastChild; - } - return this.select(lc, this.selectPrevious); - } - } else if(s.parentNode && (this.tree.rootVisible || !s.parentNode.isRoot)){ - return this.select(s.parentNode, this.selectPrevious); + if (max) { + me.setMaxValue(max); } - return null; + this.callParent(); }, - - selectNext : function( s){ - if(!(s = s || this.selNode || this.lastSelNode)){ - return null; - } - - if(s.firstChild && s.isExpanded() && Ext.fly(s.ui.wrap).isVisible()){ - return this.select(s.firstChild, this.selectNext); - }else if(s.nextSibling){ - return this.select(s.nextSibling, this.selectNext); - }else if(s.parentNode){ - var newS = null; - s.parentNode.bubble(function(){ - if(this.nextSibling){ - newS = this.getOwnerTree().selModel.select(this.nextSibling, this.selectNext); - return false; - } - }); - return newS; - } - return null; - }, + initValue: function() { + var me = this, + value = me.value; - onKeyDown : function(e){ - var s = this.selNode || this.lastSelNode; - var sm = this; - if(!s){ - return; + if (Ext.isString(value)) { + me.value = me.rawToValue(value); } - var k = e.getKey(); - switch(k){ - case e.DOWN: - e.stopEvent(); - this.selectNext(); - break; - case e.UP: - e.stopEvent(); - this.selectPrevious(); - break; - case e.RIGHT: - e.preventDefault(); - if(s.hasChildNodes()){ - if(!s.isExpanded()){ - s.expand(); - }else if(s.firstChild){ - this.select(s.firstChild, e); - } - } - break; - case e.LEFT: - e.preventDefault(); - if(s.hasChildNodes() && s.isExpanded()){ - s.collapse(); - }else if(s.parentNode && (this.tree.rootVisible || s.parentNode != this.tree.getRootNode())){ - this.select(s.parentNode, e); - } - break; - }; - } -}); - -Ext.tree.MultiSelectionModel = Ext.extend(Ext.util.Observable, { - - constructor : function(config){ - this.selNodes = []; - this.selMap = {}; - this.addEvents( - - 'selectionchange' - ); - Ext.apply(this, config); - Ext.tree.MultiSelectionModel.superclass.constructor.call(this); + me.callParent(); }, + - init : function(tree){ - this.tree = tree; - tree.mon(tree.getTreeEl(), 'keydown', this.onKeyDown, this); - tree.on('click', this.onNodeClick, this); + setMinValue: function(value) { + var me = this, + picker = me.picker; + me.setLimit(value, true); + if (picker) { + picker.setMinValue(me.minValue); + } }, + - onNodeClick : function(node, e){ - if(e.ctrlKey && this.isSelected(node)){ - this.unselect(node); - }else{ - this.select(node, e, e.ctrlKey); + setMaxValue: function(value) { + var me = this, + picker = me.picker; + me.setLimit(value, false); + if (picker) { + picker.setMaxValue(me.maxValue); } }, + - - select : function(node, e, keepExisting){ - if(keepExisting !== true){ - this.clearSelections(true); + setLimit: function(value, isMin) { + var me = this, + d, val; + if (Ext.isString(value)) { + d = me.parseDate(value); } - if(this.isSelected(node)){ - this.lastSelNode = node; - return node; + else if (Ext.isDate(value)) { + d = value; } - this.selNodes.push(node); - this.selMap[node.id] = node; - this.lastSelNode = node; - node.ui.onSelectedChange(true); - this.fireEvent('selectionchange', this, this.selNodes); - return node; - }, - - - unselect : function(node){ - if(this.selMap[node.id]){ - node.ui.onSelectedChange(false); - var sn = this.selNodes; - var index = sn.indexOf(node); - if(index != -1){ - this.selNodes.splice(index, 1); - } - delete this.selMap[node.id]; - this.fireEvent('selectionchange', this, this.selNodes); + if (d) { + val = Ext.Date.clearTime(new Date(me.initDate)); + val.setHours(d.getHours(), d.getMinutes(), d.getSeconds(), d.getMilliseconds()); + me[isMin ? 'minValue' : 'maxValue'] = val; } }, - - - clearSelections : function(suppressEvent){ - var sn = this.selNodes; - if(sn.length > 0){ - for(var i = 0, len = sn.length; i < len; i++){ - sn[i].ui.onSelectedChange(false); - } - this.selNodes = []; - this.selMap = {}; - if(suppressEvent !== true){ - this.fireEvent('selectionchange', this, this.selNodes); - } - } + + rawToValue: function(rawValue) { + return this.parseDate(rawValue) || rawValue || null; }, - - - isSelected : function(node){ - return this.selMap[node.id] ? true : false; + + valueToRaw: function(value) { + return this.formatDate(this.parseDate(value)); }, + - - getSelectedNodes : function(){ - return this.selNodes.concat([]); - }, + getErrors: function(value) { + var me = this, + format = Ext.String.format, + errors = me.callParent(arguments), + minValue = me.minValue, + maxValue = me.maxValue, + date; - onKeyDown : Ext.tree.DefaultSelectionModel.prototype.onKeyDown, + value = me.formatDate(value || me.processRawValue(me.getRawValue())); - selectNext : Ext.tree.DefaultSelectionModel.prototype.selectNext, + if (value === null || value.length < 1) { + return errors; + } + + date = me.parseDate(value); + if (!date) { + errors.push(format(me.invalidText, value, me.format)); + return errors; + } + + if (minValue && date < minValue) { + errors.push(format(me.minText, me.formatDate(minValue))); + } + + if (maxValue && date > maxValue) { + errors.push(format(me.maxText, me.formatDate(maxValue))); + } + + return errors; + }, + + formatDate: function() { + return Ext.form.field.Date.prototype.formatDate.apply(this, arguments); + }, - selectPrevious : Ext.tree.DefaultSelectionModel.prototype.selectPrevious -}); -Ext.data.Tree = Ext.extend(Ext.util.Observable, { - constructor: function(root){ - this.nodeHash = {}; - - this.root = null; - if(root){ - this.setRootNode(root); + parseDate: function(value) { + if (!value || Ext.isDate(value)) { + return value; } - this.addEvents( - - "append", - - "remove", - - "move", - - "insert", - - "beforeappend", - - "beforeremove", + + var me = this, + val = me.safeParse(value, me.format), + altFormats = me.altFormats, + altFormatsArray = me.altFormatsArray, + i = 0, + len; + + if (!val && altFormats) { + altFormatsArray = altFormatsArray || altFormats.split('|'); + len = altFormatsArray.length; + for (; i < len && !val; ++i) { + val = me.safeParse(value, altFormatsArray[i]); + } + } + return val; + }, + + safeParse: function(value, format){ + var me = this, + utilDate = Ext.Date, + parsedDate, + result = null; + + if (utilDate.formatContainsDateInfo(format)) { - "beforemove", + result = utilDate.parse(value, format); + } else { - "beforeinsert" - ); - Ext.data.Tree.superclass.constructor.call(this); + parsedDate = utilDate.parse(me.initDate + ' ' + value, me.initDateFormat + ' ' + format); + if (parsedDate) { + result = parsedDate; + } + } + return result; }, - - - pathSeparator: "/", - proxyNodeEvent : function(){ - return this.fireEvent.apply(this, arguments); + getSubmitValue: function() { + var me = this, + format = me.submitFormat || me.format, + value = me.getValue(); + + return value ? Ext.Date.format(value, format) : null; }, - getRootNode : function(){ - return this.root; + createPicker: function() { + var me = this, + picker = Ext.create('Ext.picker.Time', { + selModel: { + mode: 'SINGLE' + }, + floating: true, + hidden: true, + minValue: me.minValue, + maxValue: me.maxValue, + increment: me.increment, + format: me.format, + ownerCt: this.ownerCt, + renderTo: document.body, + maxHeight: me.pickerMaxHeight, + focusOnToFront: false + }); + + me.mon(picker.getSelectionModel(), { + selectionchange: me.onListSelect, + scope: me + }); + + return picker; }, - setRootNode : function(node){ - this.root = node; - node.ownerTree = this; - node.isRoot = true; - this.registerNode(node); - return node; - }, + onExpand: function() { + var me = this, + keyNav = me.pickerKeyNav, + selectOnTab = me.selectOnTab, + picker = me.getPicker(), + lastSelected = picker.getSelectionModel().lastSelected, + itemNode; + + if (!keyNav) { + keyNav = me.pickerKeyNav = Ext.create('Ext.view.BoundListKeyNav', this.inputEl, { + boundList: picker, + forceKeyDown: true, + tab: function(e) { + if (selectOnTab) { + this.selectHighlighted(e); + me.triggerBlur(); + } + + return true; + } + }); + + if (selectOnTab) { + me.ignoreMonitorTab = true; + } + } + Ext.defer(keyNav.enable, 1, keyNav); - - getNodeById : function(id){ - return this.nodeHash[id]; + + if (lastSelected) { + itemNode = picker.getNode(lastSelected); + if (itemNode) { + picker.highlightItem(itemNode); + picker.el.scrollChildIntoView(itemNode, false); + } + } }, - registerNode : function(node){ - this.nodeHash[node.id] = node; + onCollapse: function() { + var me = this, + keyNav = me.pickerKeyNav; + if (keyNav) { + keyNav.disable(); + me.ignoreMonitorTab = false; + } }, - unregisterNode : function(node){ - delete this.nodeHash[node.id]; - }, - - toString : function(){ - return "[Tree"+(this.id?" "+this.id:"")+"]"; + onListSelect: function(list, recordArray) { + var me = this, + record = recordArray[0], + val = record ? record.get('date') : null; + me.setValue(val); + me.fireEvent('select', me, val); + me.picker.clearHighlight(); + me.collapse(); + me.inputEl.focus(); } }); -Ext.data.Node = Ext.extend(Ext.util.Observable, { - - constructor: function(attributes){ - - this.attributes = attributes || {}; - this.leaf = this.attributes.leaf; - - this.id = this.attributes.id; - if(!this.id){ - this.id = Ext.id(null, "xnode-"); - this.attributes.id = this.id; - } - - this.childNodes = []; - - this.parentNode = null; - - this.firstChild = null; - - this.lastChild = null; - - this.previousSibling = null; - - this.nextSibling = null; - this.addEvents({ - - "append" : true, - - "remove" : true, - - "move" : true, - - "insert" : true, - - "beforeappend" : true, - - "beforeremove" : true, - - "beforemove" : true, - - "beforeinsert" : true - }); - this.listeners = this.attributes.listeners; - Ext.data.Node.superclass.constructor.call(this); +Ext.define('Ext.grid.CellEditor', { + extend: 'Ext.Editor', + constructor: function(config) { + if (config.field) { + config.field.monitorTab = false; + } + config.autoSize = { + width: 'boundEl' + }; + this.callParent(arguments); }, - fireEvent : function(evtName){ - - if(Ext.data.Node.superclass.fireEvent.apply(this, arguments) === false){ - return false; + onShow: function() { + var first = this.boundEl.first(); + if (first) { + first.hide(); } - - var ot = this.getOwnerTree(); - if(ot){ - if(ot.proxyNodeEvent.apply(ot, arguments) === false){ - return false; - } + this.callParent(arguments); + }, + + + onHide: function() { + var first = this.boundEl.first(); + if (first) { + first.show(); } - return true; + this.callParent(arguments); }, - - isLeaf : function(){ - return this.leaf === true; + + afterRender: function() { + this.callParent(arguments); + var field = this.field; + if (field.isXType('checkboxfield')) { + field.mon(field.inputEl, 'mousedown', this.onCheckBoxMouseDown, this); + field.mon(field.inputEl, 'click', this.onCheckBoxClick, this); + } }, - - setFirstChild : function(node){ - this.firstChild = node; + + onCheckBoxMouseDown: function() { + this.completeEdit = Ext.emptyFn; }, - - setLastChild : function(node){ - this.lastChild = node; + + onCheckBoxClick: function() { + delete this.completeEdit; + this.field.focus(false, 10); }, + + alignment: "tl-tl", + hideEl : false, + cls: Ext.baseCSSPrefix + "small-editor " + Ext.baseCSSPrefix + "grid-editor", + shim: false, + shadow: false +}); +Ext.define('Ext.grid.ColumnLayout', { + extend: 'Ext.layout.container.HBox', + alias: 'layout.gridcolumn', + type : 'column', - isLast : function(){ - return (!this.parentNode ? true : this.parentNode.lastChild == this); - }, + clearInnerCtOnLayout: false, - - isFirst : function(){ - return (!this.parentNode ? true : this.parentNode.firstChild == this); + constructor: function() { + var me = this; + me.callParent(arguments); + if (!Ext.isDefined(me.availableSpaceOffset)) { + me.availableSpaceOffset = (Ext.getScrollBarWidth() - 2); + } }, - - hasChildNodes : function(){ - return !this.isLeaf() && this.childNodes.length > 0; - }, + beforeLayout: function() { + var me = this, + i = 0, + items = me.getLayoutItems(), + len = items.length, + item, returnValue; - - isExpandable : function(){ - return this.attributes.expandable || this.hasChildNodes(); - }, + returnValue = me.callParent(arguments); - - appendChild : function(node){ - var multi = false; - if(Ext.isArray(node)){ - multi = node; - }else if(arguments.length > 1){ - multi = arguments; - } - if(multi){ - for(var i = 0, len = multi.length; i < len; i++) { - this.appendChild(multi[i]); - } - }else{ - if(this.fireEvent("beforeappend", this.ownerTree, this, node) === false){ - return false; - } - var index = this.childNodes.length; - var oldParent = node.parentNode; - - if(oldParent){ - if(node.fireEvent("beforemove", node.getOwnerTree(), node, oldParent, this, index) === false){ - return false; + me.innerCt.setHeight(23); + + + if (me.align == 'stretchmax') { + for (; i < len; i++) { + item = items[i]; + item.el.setStyle({ + height: 'auto' + }); + item.titleContainer.setStyle({ + height: 'auto', + paddingTop: '0' + }); + if (item.componentLayout && item.componentLayout.lastComponentSize) { + item.componentLayout.lastComponentSize.height = item.el.dom.offsetHeight; } - oldParent.removeChild(node); - } - index = this.childNodes.length; - if(index === 0){ - this.setFirstChild(node); - } - this.childNodes.push(node); - node.parentNode = this; - var ps = this.childNodes[index-1]; - if(ps){ - node.previousSibling = ps; - ps.nextSibling = node; - }else{ - node.previousSibling = null; } - node.nextSibling = null; - this.setLastChild(node); - node.setOwnerTree(this.getOwnerTree()); - this.fireEvent("append", this.ownerTree, this, node, index); - if(oldParent){ - node.fireEvent("move", this.ownerTree, node, oldParent, this, index); - } - return node; } + return returnValue; }, - removeChild : function(node, destroy){ - var index = this.childNodes.indexOf(node); - if(index == -1){ - return false; - } - if(this.fireEvent("beforeremove", this.ownerTree, this, node) === false){ - return false; - } + calculateChildBoxes: function(visibleItems, targetSize) { + var me = this, + calculations = me.callParent(arguments), + boxes = calculations.boxes, + metaData = calculations.meta, + len = boxes.length, i = 0, box, item; - - this.childNodes.splice(index, 1); + if (targetSize.width && !me.isColumn) { + + if (me.owner.forceFit) { - - if(node.previousSibling){ - node.previousSibling.nextSibling = node.nextSibling; - } - if(node.nextSibling){ - node.nextSibling.previousSibling = node.previousSibling; - } + for (; i < len; i++) { + box = boxes[i]; + item = box.component; - - if(this.firstChild == node){ - this.setFirstChild(node.nextSibling); - } - if(this.lastChild == node){ - this.setLastChild(node.previousSibling); - } + + item.minWidth = Ext.grid.plugin.HeaderResizer.prototype.minColWidth; - this.fireEvent("remove", this.ownerTree, this, node); - if(destroy){ - node.destroy(true); - }else{ - node.clear(); - } - return node; - }, + + + item.flex = box.width; + } - - clear : function(destroy){ - - this.setOwnerTree(null, destroy); - this.parentNode = this.previousSibling = this.nextSibling = null; - if(destroy){ - this.firstChild = this.lastChild = null; + + calculations = me.callParent(arguments); + } + else if (metaData.tooNarrow) { + targetSize.width = metaData.desiredSize; + } } - }, - - destroy : function( silent){ - - if(silent === true){ - this.purgeListeners(); - this.clear(true); - Ext.each(this.childNodes, function(n){ - n.destroy(true); - }); - this.childNodes = null; - }else{ - this.remove(true); - } + return calculations; }, - - insertBefore : function(node, refNode){ - if(!refNode){ - return this.appendChild(node); - } - - if(node == refNode){ - return false; - } - - if(this.fireEvent("beforeinsert", this.ownerTree, this, node, refNode) === false){ - return false; - } - var index = this.childNodes.indexOf(refNode); - var oldParent = node.parentNode; - var refIndex = index; + afterLayout: function() { + var me = this, + i = 0, + items = me.getLayoutItems(), + len = items.length; - - if(oldParent == this && this.childNodes.indexOf(node) < index){ - refIndex--; - } + me.callParent(arguments); - if(oldParent){ - if(node.fireEvent("beforemove", node.getOwnerTree(), node, oldParent, this, index, refNode) === false){ - return false; + if (me.align == 'stretchmax') { + for (; i < len; i++) { + items[i].setPadding(); } - oldParent.removeChild(node); - } - if(refIndex === 0){ - this.setFirstChild(node); - } - this.childNodes.splice(refIndex, 0, node); - node.parentNode = this; - var ps = this.childNodes[refIndex-1]; - if(ps){ - node.previousSibling = ps; - ps.nextSibling = node; - }else{ - node.previousSibling = null; } - node.nextSibling = refNode; - refNode.previousSibling = node; - node.setOwnerTree(this.getOwnerTree()); - this.fireEvent("insert", this.ownerTree, this, node, refNode); - if(oldParent){ - node.fireEvent("move", this.ownerTree, node, oldParent, this, refIndex, refNode); - } - return node; }, - remove : function(destroy){ - if (this.parentNode) { - this.parentNode.removeChild(this, destroy); - } - return this; - }, - - removeAll : function(destroy){ - var cn = this.childNodes, - n; - while((n = cn[0])){ - this.removeChild(n, destroy); + updateInnerCtSize: function(tSize, calcs) { + var me = this, + extra = 0; + + + if (!me.isColumn && calcs.meta.tooNarrow) { + if ( + Ext.isWebKit || + Ext.isGecko || + (Ext.isIEQuirks && (Ext.isIE6 || Ext.isIE7 || Ext.isIE8)) + ) { + extra = 1; + + } else if (Ext.isIE6 || Ext.isIE7 || Ext.isIE8) { + extra = 2; + } + + + extra++; + tSize.width = calcs.meta.desiredSize + (me.reserveOffset ? me.availableSpaceOffset : 0) + extra; } - return this; + return me.callParent(arguments); }, - - item : function(index){ - return this.childNodes[index]; - }, + doOwnerCtLayouts: function() { + var ownerCt = this.owner.ownerCt; + if (!ownerCt.componentLayout.layoutBusy) { + ownerCt.doComponentLayout(); + } + } +}); +Ext.define('Ext.grid.LockingView', { - replaceChild : function(newChild, oldChild){ - var s = oldChild ? oldChild.nextSibling : null; - this.removeChild(oldChild); - this.insertBefore(newChild, s); - return oldChild; + mixins: { + observable: 'Ext.util.Observable' }, - - indexOf : function(child){ - return this.childNodes.indexOf(child); - }, - + eventRelayRe: /^(beforeitem|beforecontainer|item|container|cell)/, - getOwnerTree : function(){ + constructor: function(config){ + var me = this, + eventNames = [], + eventRe = me.eventRelayRe, + locked = config.locked.getView(), + normal = config.normal.getView(), + events, + event; + + Ext.apply(me, { + lockedView: locked, + normalView: normal, + lockedGrid: config.locked, + normalGrid: config.normal, + panel: config.panel + }); + me.mixins.observable.constructor.call(me, config); - if(!this.ownerTree){ - var p = this; - while(p){ - if(p.ownerTree){ - this.ownerTree = p.ownerTree; - break; - } - p = p.parentNode; + + events = locked.events; + for (event in events) { + if (events.hasOwnProperty(event) && eventRe.test(event)) { + eventNames.push(event); } } - return this.ownerTree; + me.relayEvents(locked, eventNames); + me.relayEvents(normal, eventNames); + + normal.on({ + scope: me, + itemmouseleave: me.onItemMouseLeave, + itemmouseenter: me.onItemMouseEnter + }); + + locked.on({ + scope: me, + itemmouseleave: me.onItemMouseLeave, + itemmouseenter: me.onItemMouseEnter + }); }, - - getDepth : function(){ - var depth = 0; - var p = this; - while(p.parentNode){ - ++depth; - p = p.parentNode; - } - return depth; + getGridColumns: function() { + var cols = this.lockedGrid.headerCt.getGridColumns(); + return cols.concat(this.normalGrid.headerCt.getGridColumns()); }, - - setOwnerTree : function(tree, destroy){ - - if(tree != this.ownerTree){ - if(this.ownerTree){ - this.ownerTree.unregisterNode(this); - } - this.ownerTree = tree; + onItemMouseEnter: function(view, record){ + var me = this, + locked = me.lockedView, + other = me.normalView, + item; - if(destroy !== true){ - Ext.each(this.childNodes, function(n){ - n.setOwnerTree(tree); - }); - } - if(tree){ - tree.registerNode(this); + if (view.trackOver) { + if (view !== locked) { + other = locked; } + item = other.getNode(record); + other.highlightItem(item); } }, - - setId: function(id){ - if(id !== this.id){ - var t = this.ownerTree; - if(t){ - t.unregisterNode(this); - } - this.id = this.attributes.id = id; - if(t){ - t.registerNode(this); + onItemMouseLeave: function(view, record){ + var me = this, + locked = me.lockedView, + other = me.normalView; + + if (view.trackOver) { + if (view !== locked) { + other = locked; } - this.onIdChange(id); + other.clearHighlight(); } }, - - onIdChange: Ext.emptyFn, - + relayFn: function(name, args){ + args = args || []; + + var view = this.lockedView; + view[name].apply(view, args || []); + view = this.normalView; + view[name].apply(view, args || []); + }, - getPath : function(attr){ - attr = attr || "id"; - var p = this.parentNode; - var b = [this.attributes[attr]]; - while(p){ - b.unshift(p.attributes[attr]); - p = p.parentNode; - } - var sep = this.getOwnerTree().pathSeparator; - return sep + b.join(sep); + getSelectionModel: function(){ + return this.panel.getSelectionModel(); }, - - bubble : function(fn, scope, args){ - var p = this; - while(p){ - if(fn.apply(scope || p, args || [p]) === false){ - break; - } - p = p.parentNode; - } + getStore: function(){ + return this.panel.store; }, - - cascade : function(fn, scope, args){ - if(fn.apply(scope || this, args || [this]) !== false){ - var cs = this.childNodes; - for(var i = 0, len = cs.length; i < len; i++) { - cs[i].cascade(fn, scope, args); - } + getNode: function(nodeInfo){ + + return this.normalView.getNode(nodeInfo); + }, + + getCell: function(record, column){ + var view = this.lockedView, + row; + + + if (view.getHeaderAtIndex(column) === -1) { + view = this.normalView; } + + row = view.getNode(record); + return Ext.fly(row).down(column.getCellSelector()); }, - - eachChild : function(fn, scope, args){ - var cs = this.childNodes; - for(var i = 0, len = cs.length; i < len; i++) { - if(fn.apply(scope || cs[i], args || [cs[i]]) === false){ - break; - } + getRecord: function(node){ + var result = this.lockedView.getRecord(node); + if (!node) { + result = this.normalView.getRecord(node); } + return result; }, - - findChild : function(attribute, value, deep){ - return this.findChildBy(function(){ - return this.attributes[attribute] == value; - }, null, deep); + refreshNode: function(){ + this.relayFn('refreshNode', arguments); }, - - findChildBy : function(fn, scope, deep){ - var cs = this.childNodes, - len = cs.length, - i = 0, - n, - res; - for(; i < len; i++){ - n = cs[i]; - if(fn.call(scope || n, n) === true){ - return n; - }else if (deep){ - res = n.findChildBy(fn, scope, deep); - if(res != null){ - return res; - } - } - - } - return null; + refresh: function(){ + this.relayFn('refresh', arguments); }, - - sort : function(fn, scope){ - var cs = this.childNodes; - var len = cs.length; - if(len > 0){ - var sortFn = scope ? function(){fn.apply(scope, arguments);} : fn; - cs.sort(sortFn); - for(var i = 0; i < len; i++){ - var n = cs[i]; - n.previousSibling = cs[i-1]; - n.nextSibling = cs[i+1]; - if(i === 0){ - this.setFirstChild(n); - } - if(i == len-1){ - this.setLastChild(n); - } - } - } + bindStore: function(){ + this.relayFn('bindStore', arguments); }, - - contains : function(node){ - return node.isAncestor(this); + addRowCls: function(){ + this.relayFn('addRowCls', arguments); }, + + removeRowCls: function(){ + this.relayFn('removeRowCls', arguments); + } + +}); +Ext.define('Ext.grid.Lockable', { - isAncestor : function(node){ - var p = this.parentNode; - while(p){ - if(p == node){ - return true; + requires: ['Ext.grid.LockingView'], + + + syncRowHeight: true, + + + + + + + + + spacerHidden: true, + + + unlockText: 'Unlock', + lockText: 'Lock', + + determineXTypeToCreate: function() { + var me = this, + typeToCreate; + + if (me.subGridXType) { + typeToCreate = me.subGridXType; + } else { + var xtypes = this.getXTypes().split('/'), + xtypesLn = xtypes.length, + xtype = xtypes[xtypesLn - 1], + superxtype = xtypes[xtypesLn - 2]; + + if (superxtype !== 'tablepanel') { + typeToCreate = superxtype; + } else { + typeToCreate = xtype; } - p = p.parentNode; } - return false; + + return typeToCreate; }, - - toString : function(){ - return "[Node"+(this.id?" "+this.id:"")+"]"; - } -}); -Ext.tree.TreeNode = Ext.extend(Ext.data.Node, { - constructor : function(attributes){ - attributes = attributes || {}; - if(Ext.isString(attributes)){ - attributes = {text: attributes}; - } - this.childrenRendered = false; - this.rendered = false; - Ext.tree.TreeNode.superclass.constructor.call(this, attributes); - this.expanded = attributes.expanded === true; - this.isTarget = attributes.isTarget !== false; - this.draggable = attributes.draggable !== false && attributes.allowDrag !== false; - this.allowChildren = attributes.allowChildren !== false && attributes.allowDrop !== false; - + + + injectLockable: function() { - this.text = attributes.text; + this.lockable = true; - this.disabled = attributes.disabled === true; - this.hidden = attributes.hidden === true; - - this.addEvents( - - 'textchange', - - 'beforeexpand', - - 'beforecollapse', - - 'expand', - - 'disabledchange', + this.hasView = true; + + var me = this, - 'collapse', - 'beforeclick', - 'click', + xtype = me.determineXTypeToCreate(), - 'checkchange', + selModel = me.getSelectionModel(), + lockedGrid = { + xtype: xtype, + + enableAnimations: false, + scroll: false, + scrollerOwner: false, + selModel: selModel, + border: false, + cls: Ext.baseCSSPrefix + 'grid-inner-locked' + }, + normalGrid = { + xtype: xtype, + enableAnimations: false, + scrollerOwner: false, + selModel: selModel, + border: false + }, + i = 0, + columns, + lockedHeaderCt, + normalHeaderCt; + + me.addCls(Ext.baseCSSPrefix + 'grid-locked'); + + + + + Ext.copyTo(normalGrid, me, me.normalCfgCopy); + Ext.copyTo(lockedGrid, me, me.lockedCfgCopy); + for (; i < me.normalCfgCopy.length; i++) { + delete me[me.normalCfgCopy[i]]; + } + for (i = 0; i < me.lockedCfgCopy.length; i++) { + delete me[me.lockedCfgCopy[i]]; + } + + me.lockedHeights = []; + me.normalHeights = []; + + columns = me.processColumns(me.columns); + + lockedGrid.width = columns.lockedWidth; + lockedGrid.columns = columns.locked; + normalGrid.columns = columns.normal; + + me.store = Ext.StoreManager.lookup(me.store); + lockedGrid.store = me.store; + normalGrid.store = me.store; + + + normalGrid.flex = 1; + lockedGrid.viewConfig = me.lockedViewConfig || {}; + lockedGrid.viewConfig.loadingUseMsg = false; + normalGrid.viewConfig = me.normalViewConfig || {}; + + Ext.applyIf(lockedGrid.viewConfig, me.viewConfig); + Ext.applyIf(normalGrid.viewConfig, me.viewConfig); + + me.normalGrid = Ext.ComponentManager.create(normalGrid); + me.lockedGrid = Ext.ComponentManager.create(lockedGrid); + + me.view = Ext.create('Ext.grid.LockingView', { + locked: me.lockedGrid, + normal: me.normalGrid, + panel: me + }); + + if (me.syncRowHeight) { + me.lockedGrid.getView().on({ + refresh: me.onLockedGridAfterRefresh, + itemupdate: me.onLockedGridAfterUpdate, + scope: me + }); - 'beforedblclick', + me.normalGrid.getView().on({ + refresh: me.onNormalGridAfterRefresh, + itemupdate: me.onNormalGridAfterUpdate, + scope: me + }); + } + + lockedHeaderCt = me.lockedGrid.headerCt; + normalHeaderCt = me.normalGrid.headerCt; + + lockedHeaderCt.lockedCt = true; + lockedHeaderCt.lockableInjected = true; + normalHeaderCt.lockableInjected = true; + + lockedHeaderCt.on({ + columnshow: me.onLockedHeaderShow, + columnhide: me.onLockedHeaderHide, + columnmove: me.onLockedHeaderMove, + sortchange: me.onLockedHeaderSortChange, + columnresize: me.onLockedHeaderResize, + scope: me + }); + + normalHeaderCt.on({ + columnmove: me.onNormalHeaderMove, + sortchange: me.onNormalHeaderSortChange, + scope: me + }); + + me.normalGrid.on({ + scrollershow: me.onScrollerShow, + scrollerhide: me.onScrollerHide, + scope: me + }); + + me.lockedGrid.on('afterlayout', me.onLockedGridAfterLayout, me, {single: true}); + + me.modifyHeaderCt(); + me.items = [me.lockedGrid, me.normalGrid]; + + me.layout = { + type: 'hbox', + align: 'stretch' + }; + }, + + processColumns: function(columns){ + + var i = 0, + len = columns.length, + lockedWidth = 0, + lockedHeaders = [], + normalHeaders = [], + column; - 'dblclick', + for (; i < len; ++i) { + column = columns[i]; - 'contextmenu', - 'beforechildrenrendered' - ); + column.processed = true; + if (column.locked) { + if (column.flex) { + Ext.Error.raise("Columns which are locked do NOT support a flex width. You must set a width on the " + columns[i].text + "column."); + } + lockedWidth += column.width; + lockedHeaders.push(column); + } else { + normalHeaders.push(column); + } + } + return { + lockedWidth: lockedWidth, + locked: lockedHeaders, + normal: normalHeaders + }; + }, - var uiClass = this.attributes.uiProvider || this.defaultUI || Ext.tree.TreeNodeUI; - - this.ui = new uiClass(this); + onLockedGridAfterLayout: function() { + var me = this, + lockedView = me.lockedGrid.getView(); + lockedView.on({ + refresh: me.createSpacer, + beforerefresh: me.destroySpacer, + scope: me + }); }, - preventHScroll : true, - isExpanded : function(){ - return this.expanded; + onLockedHeaderMove: function() { + if (this.syncRowHeight) { + this.onNormalGridAfterRefresh(); + } }, - - - getUI : function(){ - return this.ui; + + + onNormalHeaderMove: function() { + if (this.syncRowHeight) { + this.onLockedGridAfterRefresh(); + } }, + + + + createSpacer: function() { + var me = this, + + + w = Ext.getScrollBarWidth() + (Ext.isIE ? 2 : 0), + view = me.lockedGrid.getView(), + el = view.el; - getLoader : function(){ - var owner; - return this.loader || ((owner = this.getOwnerTree()) && owner.loader ? owner.loader : (this.loader = new Ext.tree.TreeLoader())); + me.spacerEl = Ext.core.DomHelper.append(el, { + cls: me.spacerHidden ? (Ext.baseCSSPrefix + 'hidden') : '', + style: 'height: ' + w + 'px;' + }, true); }, - - setFirstChild : function(node){ - var of = this.firstChild; - Ext.tree.TreeNode.superclass.setFirstChild.call(this, node); - if(this.childrenRendered && of && node != of){ - of.renderIndent(true, true); - } - if(this.rendered){ - this.renderIndent(true, true); + destroySpacer: function() { + var me = this; + if (me.spacerEl) { + me.spacerEl.destroy(); + delete me.spacerEl; } }, - - setLastChild : function(node){ - var ol = this.lastChild; - Ext.tree.TreeNode.superclass.setLastChild.call(this, node); - if(this.childrenRendered && ol && node != ol){ - ol.renderIndent(true, true); - } - if(this.rendered){ - this.renderIndent(true, true); + + onLockedGridAfterRefresh: function() { + var me = this, + view = me.lockedGrid.getView(), + el = view.el, + rowEls = el.query(view.getItemSelector()), + ln = rowEls.length, + i = 0; + + + me.lockedHeights = []; + + for (; i < ln; i++) { + me.lockedHeights[i] = rowEls[i].clientHeight; } + me.syncRowHeights(); }, - - appendChild : function(n){ - if(!n.render && !Ext.isArray(n)){ - n = this.getLoader().createNode(n); - } - var node = Ext.tree.TreeNode.superclass.appendChild.call(this, n); - if(node && this.childrenRendered){ - node.render(); + onNormalGridAfterRefresh: function() { + var me = this, + view = me.normalGrid.getView(), + el = view.el, + rowEls = el.query(view.getItemSelector()), + ln = rowEls.length, + i = 0; + + + me.normalHeights = []; + + for (; i < ln; i++) { + me.normalHeights[i] = rowEls[i].clientHeight; } - this.ui.updateExpandIcon(); - return node; + me.syncRowHeights(); + }, + + + onLockedGridAfterUpdate: function(record, index, node) { + this.lockedHeights[index] = node.clientHeight; + this.syncRowHeights(); + }, + + + onNormalGridAfterUpdate: function(record, index, node) { + this.normalHeights[index] = node.clientHeight; + this.syncRowHeights(); }, - - removeChild : function(node, destroy){ - this.ownerTree.getSelectionModel().unselect(node); - Ext.tree.TreeNode.superclass.removeChild.apply(this, arguments); + + + syncRowHeights: function() { + var me = this, + lockedHeights = me.lockedHeights, + normalHeights = me.normalHeights, + calcHeights = [], + ln = lockedHeights.length, + i = 0, + lockedView, normalView, + lockedRowEls, normalRowEls, + vertScroller = me.getVerticalScroller(), + scrollTop; + - if(!destroy){ - var rendered = node.ui.rendered; + + if (lockedHeights.length && normalHeights.length) { + lockedView = me.lockedGrid.getView(); + normalView = me.normalGrid.getView(); + lockedRowEls = lockedView.el.query(lockedView.getItemSelector()); + normalRowEls = normalView.el.query(normalView.getItemSelector()); + - if(rendered){ - node.ui.remove(); - } - if(rendered && this.childNodes.length < 1){ - this.collapse(false, false); - }else{ - this.ui.updateExpandIcon(); + for (; i < ln; i++) { + + if (!isNaN(lockedHeights[i]) && !isNaN(normalHeights[i])) { + if (lockedHeights[i] > normalHeights[i]) { + Ext.fly(normalRowEls[i]).setHeight(lockedHeights[i]); + } else if (lockedHeights[i] < normalHeights[i]) { + Ext.fly(lockedRowEls[i]).setHeight(normalHeights[i]); + } + } } - if(!this.firstChild && !this.isHiddenRoot()){ - this.childrenRendered = false; + + + me.normalGrid.invalidateScroller(); + + + + if (vertScroller && vertScroller.setViewScrollTop) { + vertScroller.setViewScrollTop(me.virtualScrollTop); + } else { + + + + scrollTop = normalView.el.dom.scrollTop; + normalView.el.dom.scrollTop = scrollTop; + lockedView.el.dom.scrollTop = scrollTop; } + + + me.lockedHeights = []; + me.normalHeights = []; } - return node; }, - - insertBefore : function(node, refNode){ - if(!node.render){ - node = this.getLoader().createNode(node); - } - var newNode = Ext.tree.TreeNode.superclass.insertBefore.call(this, node, refNode); - if(newNode && refNode && this.childrenRendered){ - node.render(); - } - this.ui.updateExpandIcon(); - return newNode; - }, - - setText : function(text){ - var oldText = this.text; - this.text = this.attributes.text = text; - if(this.rendered){ - this.ui.onTextChange(this, text, oldText); + onScrollerShow: function(scroller, direction) { + if (direction === 'horizontal') { + this.spacerHidden = false; + this.spacerEl.removeCls(Ext.baseCSSPrefix + 'hidden'); } - this.fireEvent('textchange', this, text, oldText); }, - setIconCls : function(cls){ - var old = this.attributes.iconCls; - this.attributes.iconCls = cls; - if(this.rendered){ - this.ui.onIconClsChange(this, cls, old); + onScrollerHide: function(scroller, direction) { + if (direction === 'horizontal') { + this.spacerHidden = true; + this.spacerEl.addCls(Ext.baseCSSPrefix + 'hidden'); } }, + - setTooltip : function(tip, title){ - this.attributes.qtip = tip; - this.attributes.qtipTitle = title; - if(this.rendered){ - this.ui.onTipChange(this, tip, title); - } + modifyHeaderCt: function() { + var me = this; + me.lockedGrid.headerCt.getMenuItems = me.getMenuItems(true); + me.normalGrid.headerCt.getMenuItems = me.getMenuItems(false); }, - - setIcon : function(icon){ - this.attributes.icon = icon; - if(this.rendered){ - this.ui.onIconChange(this, icon); - } + onUnlockMenuClick: function() { + this.unlock(); }, + onLockMenuClick: function() { + this.lock(); + }, - setHref : function(href, target){ - this.attributes.href = href; - this.attributes.hrefTarget = target; - if(this.rendered){ - this.ui.onHrefChange(this, href, target); - } + getMenuItems: function(locked) { + var me = this, + unlockText = me.unlockText, + lockText = me.lockText, + + unlockCls = 'xg-hmenu-unlock', + lockCls = 'xg-hmenu-lock', + unlockHandler = Ext.Function.bind(me.onUnlockMenuClick, me), + lockHandler = Ext.Function.bind(me.onLockMenuClick, me); + + + return function() { + var o = Ext.grid.header.Container.prototype.getMenuItems.call(this); + o.push('-',{ + cls: unlockCls, + text: unlockText, + handler: unlockHandler, + disabled: !locked + }); + o.push({ + cls: lockCls, + text: lockText, + handler: lockHandler, + disabled: locked + }); + return o; + }; }, - setCls : function(cls){ - var old = this.attributes.cls; - this.attributes.cls = cls; - if(this.rendered){ - this.ui.onClsChange(this, cls, old); - } - }, - - select : function(){ - var t = this.getOwnerTree(); - if(t){ - t.getSelectionModel().select(this); + lock: function(activeHd, toIdx) { + var me = this, + normalGrid = me.normalGrid, + lockedGrid = me.lockedGrid, + normalHCt = normalGrid.headerCt, + lockedHCt = lockedGrid.headerCt; + + activeHd = activeHd || normalHCt.getMenu().activeHeader; + + + + if (activeHd.flex) { + activeHd.width = activeHd.getWidth(); + delete activeHd.flex; + } + + normalHCt.remove(activeHd, false); + lockedHCt.suspendLayout = true; + if (Ext.isDefined(toIdx)) { + lockedHCt.insert(toIdx, activeHd); + } else { + lockedHCt.add(activeHd); } + lockedHCt.suspendLayout = false; + me.syncLockedSection(); }, - - unselect : function(silent){ - var t = this.getOwnerTree(); - if(t){ - t.getSelectionModel().unselect(this, silent); - } + syncLockedSection: function() { + var me = this; + me.syncLockedWidth(); + me.lockedGrid.getView().refresh(); + me.normalGrid.getView().refresh(); }, - - isSelected : function(){ - var t = this.getOwnerTree(); - return t ? t.getSelectionModel().isSelected(this) : false; + + + syncLockedWidth: function() { + var me = this, + width = me.lockedGrid.headerCt.getFullWidth(true); + me.lockedGrid.setWidth(width); }, - - expand : function(deep, anim, callback, scope){ - if(!this.expanded){ - if(this.fireEvent('beforeexpand', this, deep, anim) === false){ - return; - } - if(!this.childrenRendered){ - this.renderChildren(); - } - this.expanded = true; - if(!this.isHiddenRoot() && (this.getOwnerTree().animate && anim !== false) || anim){ - this.ui.animExpand(function(){ - this.fireEvent('expand', this); - this.runCallback(callback, scope || this, [this]); - if(deep === true){ - this.expandChildNodes(true, true); - } - }.createDelegate(this)); - return; - }else{ - this.ui.expand(); - this.fireEvent('expand', this); - this.runCallback(callback, scope || this, [this]); - } - }else{ - this.runCallback(callback, scope || this, [this]); - } - if(deep === true){ - this.expandChildNodes(true); - } + onLockedHeaderResize: function() { + this.syncLockedWidth(); }, - - runCallback : function(cb, scope, args){ - if(Ext.isFunction(cb)){ - cb.apply(scope, args); - } + + onLockedHeaderHide: function() { + this.syncLockedWidth(); }, - - isHiddenRoot : function(){ - return this.isRoot && !this.getOwnerTree().rootVisible; + + onLockedHeaderShow: function() { + this.syncLockedWidth(); }, - - collapse : function(deep, anim, callback, scope){ - if(this.expanded && !this.isHiddenRoot()){ - if(this.fireEvent('beforecollapse', this, deep, anim) === false){ - return; - } - this.expanded = false; - if((this.getOwnerTree().animate && anim !== false) || anim){ - this.ui.animCollapse(function(){ - this.fireEvent('collapse', this); - this.runCallback(callback, scope || this, [this]); - if(deep === true){ - this.collapseChildNodes(true); - } - }.createDelegate(this)); - return; - }else{ - this.ui.collapse(); - this.fireEvent('collapse', this); - this.runCallback(callback, scope || this, [this]); - } - }else if(!this.expanded){ - this.runCallback(callback, scope || this, [this]); - } - if(deep === true){ - var cs = this.childNodes; - for(var i = 0, len = cs.length; i < len; i++) { - cs[i].collapse(true, false); - } + onLockedHeaderSortChange: function(headerCt, header, sortState) { + if (sortState) { + + + this.normalGrid.headerCt.clearOtherSortStates(null, true); } }, - - delayedExpand : function(delay){ - if(!this.expandProcId){ - this.expandProcId = this.expand.defer(delay, this); + onNormalHeaderSortChange: function(headerCt, header, sortState) { + if (sortState) { + + + this.lockedGrid.headerCt.clearOtherSortStates(null, true); } }, - - cancelExpand : function(){ - if(this.expandProcId){ - clearTimeout(this.expandProcId); + + + unlock: function(activeHd, toIdx) { + var me = this, + normalGrid = me.normalGrid, + lockedGrid = me.lockedGrid, + normalHCt = normalGrid.headerCt, + lockedHCt = lockedGrid.headerCt; + + if (!Ext.isDefined(toIdx)) { + toIdx = 0; } - this.expandProcId = false; + activeHd = activeHd || lockedHCt.getMenu().activeHeader; + + lockedHCt.remove(activeHd, false); + me.syncLockedWidth(); + me.lockedGrid.getView().refresh(); + normalHCt.insert(toIdx, activeHd); + me.normalGrid.getView().refresh(); }, - - toggle : function(){ - if(this.expanded){ - this.collapse(); - }else{ - this.expand(); + + reconfigureLockable: function(store, columns) { + var me = this, + lockedGrid = me.lockedGrid, + normalGrid = me.normalGrid; + + if (columns) { + lockedGrid.headerCt.removeAll(); + normalGrid.headerCt.removeAll(); + + columns = me.processColumns(columns); + lockedGrid.setWidth(columns.lockedWidth); + lockedGrid.headerCt.add(columns.locked); + normalGrid.headerCt.add(columns.normal); } - }, + + if (store) { + store = Ext.data.StoreManager.lookup(store); + me.store = store; + lockedGrid.bindStore(store); + normalGrid.bindStore(store); + } else { + lockedGrid.getView().refresh(); + normalGrid.getView().refresh(); + } + } +}); - - ensureVisible : function(callback, scope){ - var tree = this.getOwnerTree(); - tree.expandPath(this.parentNode ? this.parentNode.getPath() : this.getPath(), false, function(){ - var node = tree.getNodeById(this.id); - tree.getTreeEl().scrollChildIntoView(node.ui.anchor); - this.runCallback(callback, scope || this, [this]); - }.createDelegate(this)); - }, +Ext.define('Ext.grid.Scroller', { + extend: 'Ext.Component', + alias: 'widget.gridscroller', + weight: 110, + cls: Ext.baseCSSPrefix + 'scroller', + focusable: false, - expandChildNodes : function(deep, anim) { - var cs = this.childNodes, - i, - len = cs.length; - for (i = 0; i < len; i++) { - cs[i].expand(deep, anim); + renderTpl: ['
    '], + + initComponent: function() { + var me = this, + dock = me.dock, + cls = Ext.baseCSSPrefix + 'scroller-vertical', + sizeProp = 'width', + + + + + + scrollbarWidth = Ext.getScrollBarWidth() + (Ext.isIE ? 1 : -1); + + me.offsets = {bottom: 0}; + + if (dock === 'top' || dock === 'bottom') { + cls = Ext.baseCSSPrefix + 'scroller-horizontal'; + sizeProp = 'height'; } + me[sizeProp] = scrollbarWidth; + + me.cls += (' ' + cls); + + Ext.applyIf(me.renderSelectors, { + stretchEl: '.' + Ext.baseCSSPrefix + 'stretcher' + }); + me.callParent(); }, - - collapseChildNodes : function(deep){ - var cs = this.childNodes; - for(var i = 0, len = cs.length; i < len; i++) { - cs[i].collapse(deep); - } + + afterRender: function() { + var me = this; + me.callParent(); + me.ownerCt.on('afterlayout', me.onOwnerAfterLayout, me); + me.mon(me.el, 'scroll', me.onElScroll, me); + Ext.cache[me.el.id].skipGarbageCollection = true; }, - - disable : function(){ - this.disabled = true; - this.unselect(); - if(this.rendered && this.ui.onDisableChange){ - this.ui.onDisableChange(this, true); + getSizeCalculation: function() { + var owner = this.getPanel(), + dock = this.dock, + elDom = this.el.dom, + width = 1, + height = 1, + view, tbl; + + if (dock === 'top' || dock === 'bottom') { + + + var items = owner.query('tableview'), + center = items[1] || items[0]; + + if (!center) { + return false; + } + + + + width = center.headerCt.getFullWidth(); + + if (Ext.isIEQuirks) { + width--; + } + + width--; + } else { + view = owner.down('tableview:not([lockableInjected])'); + if (!view) { + return false; + } + tbl = view.el; + if (!tbl) { + return false; + } + + + + height = tbl.dom.scrollHeight; } - this.fireEvent('disabledchange', this, true); - }, - - - enable : function(){ - this.disabled = false; - if(this.rendered && this.ui.onDisableChange){ - this.ui.onDisableChange(this, false); + if (isNaN(width)) { + width = 1; } - this.fireEvent('disabledchange', this, false); + if (isNaN(height)) { + height = 1; + } + return { + width: width, + height: height + }; }, - - renderChildren : function(suppressEvent){ - if(suppressEvent !== false){ - this.fireEvent('beforechildrenrendered', this); + invalidate: function(firstPass) { + if (!this.stretchEl || !this.ownerCt) { + return; } - var cs = this.childNodes; - for(var i = 0, len = cs.length; i < len; i++){ - cs[i].render(true); + var size = this.getSizeCalculation(), + elDom = this.el.dom; + if (size) { + this.stretchEl.setSize(size); + + + + elDom.scrollTop = elDom.scrollTop; } - this.childrenRendered = true; }, - - sort : function(fn, scope){ - Ext.tree.TreeNode.superclass.sort.apply(this, arguments); - if(this.childrenRendered){ - var cs = this.childNodes; - for(var i = 0, len = cs.length; i < len; i++){ - cs[i].render(true); - } - } + onOwnerAfterLayout: function(owner, layout) { + this.invalidate(); }, - render : function(bulkRender){ - this.ui.render(bulkRender); - if(!this.rendered){ - - this.getOwnerTree().registerNode(this); - this.rendered = true; - if(this.expanded){ - this.expanded = false; - this.expand(false, false); - } + setScrollTop: function(scrollTop) { + if (this.el) { + var elDom = this.el.dom; + return elDom.scrollTop = Ext.Number.constrain(scrollTop, 0, elDom.scrollHeight - elDom.clientHeight); } }, - renderIndent : function(deep, refresh){ - if(refresh){ - this.ui.childIndent = null; - } - this.ui.renderIndent(); - if(deep === true && this.childrenRendered){ - var cs = this.childNodes; - for(var i = 0, len = cs.length; i < len; i++){ - cs[i].renderIndent(true, refresh); - } - } - }, - - beginUpdate : function(){ - this.childrenRendered = false; - }, - - endUpdate : function(){ - if(this.expanded && this.rendered){ - this.renderChildren(); + setScrollLeft: function(scrollLeft) { + if (this.el) { + var elDom = this.el.dom; + return elDom.scrollLeft = Ext.Number.constrain(scrollLeft, 0, elDom.scrollWidth - elDom.clientWidth); } }, - destroy : function(silent){ - if(silent === true){ - this.unselect(true); + scrollByDeltaY: function(delta) { + if (this.el) { + var elDom = this.el.dom; + return this.setScrollTop(elDom.scrollTop + delta); } - Ext.tree.TreeNode.superclass.destroy.call(this, silent); - Ext.destroy(this.ui, this.loader); - this.ui = this.loader = null; }, - onIdChange : function(id){ - this.ui.onIdChange(id); - } -}); - -Ext.tree.TreePanel.nodeTypes.node = Ext.tree.TreeNode; - Ext.tree.AsyncTreeNode = function(config){ - this.loaded = config && config.loaded === true; - this.loading = false; - Ext.tree.AsyncTreeNode.superclass.constructor.apply(this, arguments); - - this.addEvents('beforeload', 'load'); - - -}; -Ext.extend(Ext.tree.AsyncTreeNode, Ext.tree.TreeNode, { - expand : function(deep, anim, callback, scope){ - if(this.loading){ - var timer; - var f = function(){ - if(!this.loading){ - clearInterval(timer); - this.expand(deep, anim, callback, scope); - } - }.createDelegate(this); - timer = setInterval(f, 200); - return; - } - if(!this.loaded){ - if(this.fireEvent("beforeload", this) === false){ - return; - } - this.loading = true; - this.ui.beforeLoad(this); - var loader = this.loader || this.attributes.loader || this.getOwnerTree().getLoader(); - if(loader){ - loader.load(this, this.loadComplete.createDelegate(this, [deep, anim, callback, scope]), this); - return; - } + scrollByDeltaX: function(delta) { + if (this.el) { + var elDom = this.el.dom; + return this.setScrollLeft(elDom.scrollLeft + delta); } - Ext.tree.AsyncTreeNode.superclass.expand.call(this, deep, anim, callback, scope); }, - isLoading : function(){ - return this.loading; - }, - loadComplete : function(deep, anim, callback, scope){ - this.loading = false; - this.loaded = true; - this.ui.afterLoad(this); - this.fireEvent("load", this); - this.expand(deep, anim, callback, scope); + scrollToTop : function(){ + this.setScrollTop(0); }, - isLoaded : function(){ - return this.loaded; - }, - - hasChildNodes : function(){ - if(!this.isLeaf() && !this.loaded){ - return true; - }else{ - return Ext.tree.AsyncTreeNode.superclass.hasChildNodes.call(this); - } + onElScroll: function(event, target) { + this.fireEvent('bodyscroll', event, target); }, - - reload : function(callback, scope){ - this.collapse(false, false); - while(this.firstChild){ - this.removeChild(this.firstChild).destroy(); - } - this.childrenRendered = false; - this.loaded = false; - if(this.isHiddenRoot()){ - this.expanded = false; + getPanel: function() { + var me = this; + if (!me.panel) { + me.panel = this.up('[scrollerOwner]'); } - this.expand(false, false, callback, scope); + return me.panel; } }); -Ext.tree.TreePanel.nodeTypes.async = Ext.tree.AsyncTreeNode; -Ext.tree.TreeNodeUI = Ext.extend(Object, { - - constructor : function(node){ - Ext.apply(this, { - node: node, - rendered: false, - animating: false, - wasLeaf: true, - ecc: 'x-tree-ec-icon x-tree-elbow', - emptyIcon: Ext.BLANK_IMAGE_URL - }); - }, - - - removeChild : function(node){ - if(this.rendered){ - this.ctNode.removeChild(node.ui.getEl()); - } - }, - - beforeLoad : function(){ - this.addClass("x-tree-node-loading"); - }, +Ext.define('Ext.grid.PagingScroller', { + extend: 'Ext.grid.Scroller', + alias: 'widget.paginggridscroller', - afterLoad : function(){ - this.removeClass("x-tree-node-loading"); - }, - - onTextChange : function(node, text, oldText){ - if(this.rendered){ - this.textNode.innerHTML = text; - } - }, - onIconClsChange : function(node, cls, oldCls){ - if(this.rendered){ - Ext.fly(this.iconNode).replaceClass(oldCls, cls); - } - }, - onIconChange : function(node, icon){ - if(this.rendered){ - - var empty = Ext.isEmpty(icon); - this.iconNode.src = empty ? this.emptyIcon : icon; - Ext.fly(this.iconNode)[empty ? 'removeClass' : 'addClass']('x-tree-node-inline-icon'); - } - }, + percentageFromEdge: 0.35, - onTipChange : function(node, tip, title){ - if(this.rendered){ - var hasTitle = Ext.isDefined(title); - if(this.textNode.setAttributeNS){ - this.textNode.setAttributeNS("ext", "qtip", tip); - if(hasTitle){ - this.textNode.setAttributeNS("ext", "qtitle", title); - } - }else{ - this.textNode.setAttribute("ext:qtip", tip); - if(hasTitle){ - this.textNode.setAttribute("ext:qtitle", title); - } - } - } - }, + scrollToLoadBuffer: 200, - onHrefChange : function(node, href, target){ - if(this.rendered){ - this.anchor.href = this.getHref(href); - if(Ext.isDefined(target)){ - this.anchor.target = target; - } - } - }, + activePrefetch: true, + chunkSize: 50, + snapIncrement: 25, - onClsChange : function(node, cls, oldCls){ - if(this.rendered){ - Ext.fly(this.elNode).replaceClass(oldCls, cls); - } - }, + syncScroll: true, + + initComponent: function() { + var me = this, + ds = me.store; + ds.on('guaranteedrange', this.onGuaranteedRange, this); + this.callParent(arguments); + }, + - onDisableChange : function(node, state){ - this.disabled = state; - if (this.checkbox) { - this.checkbox.disabled = state; + onGuaranteedRange: function(range, start, end) { + var me = this, + ds = me.store, + rs; + + if (range.length && me.visibleStart < range[0].index) { + return; } - this[state ? 'addClass' : 'removeClass']('x-tree-node-disabled'); - }, + + ds.loadRecords(range); - - onSelectedChange : function(state){ - if(state){ - this.focus(); - this.addClass("x-tree-selected"); - }else{ + if (!me.firstLoad) { + if (me.rendered) { + me.invalidate(); + } else { + me.on('afterrender', this.invalidate, this, {single: true}); + } + me.firstLoad = true; + } else { - this.removeClass("x-tree-selected"); + me.syncTo(); } }, - - onMove : function(tree, node, oldParent, newParent, index, refNode){ - this.childIndent = null; - if(this.rendered){ - var targetNode = newParent.ui.getContainer(); - if(!targetNode){ - this.holder = document.createElement("div"); - this.holder.appendChild(this.wrap); - return; - } - var insertBefore = refNode ? refNode.ui.getEl() : null; - if(insertBefore){ - targetNode.insertBefore(this.wrap, insertBefore); - }else{ - targetNode.appendChild(this.wrap); - } - this.node.renderIndent(true, oldParent != newParent); + syncTo: function() { + var me = this, + pnl = me.getPanel(), + store = pnl.store, + scrollerElDom = this.el.dom, + rowOffset = me.visibleStart - store.guaranteedStart, + scrollBy = rowOffset * me.rowHeight, + scrollHeight = scrollerElDom.scrollHeight, + clientHeight = scrollerElDom.clientHeight, + scrollTop = scrollerElDom.scrollTop, + useMaximum; + + + + if (Ext.isIE9 && Ext.isStrict) { + clientHeight = scrollerElDom.offsetHeight + 2; } - }, - - addClass : function(cls){ - if(this.elNode){ - Ext.fly(this.elNode).addClass(cls); - } + + + useMaximum = (scrollHeight - clientHeight - scrollTop <= 0); + this.setViewScrollTop(scrollBy, useMaximum); }, - - - removeClass : function(cls){ - if(this.elNode){ - Ext.fly(this.elNode).removeClass(cls); - } + + getPageData : function(){ + var panel = this.getPanel(), + store = panel.store, + totalCount = store.getTotalCount(); + + return { + total : totalCount, + currentPage : store.currentPage, + pageCount: Math.ceil(totalCount / store.pageSize), + fromRecord: ((store.currentPage - 1) * store.pageSize) + 1, + toRecord: Math.min(store.currentPage * store.pageSize, totalCount) + }; }, - - remove : function(){ - if(this.rendered){ - this.holder = document.createElement("div"); - this.holder.appendChild(this.wrap); + onElScroll: function(e, t) { + var me = this, + panel = me.getPanel(), + store = panel.store, + pageSize = store.pageSize, + guaranteedStart = store.guaranteedStart, + guaranteedEnd = store.guaranteedEnd, + totalCount = store.getTotalCount(), + numFromEdge = Math.ceil(me.percentageFromEdge * store.pageSize), + position = t.scrollTop, + visibleStart = Math.floor(position / me.rowHeight), + view = panel.down('tableview'), + viewEl = view.el, + visibleHeight = viewEl.getHeight(), + visibleAhead = Math.ceil(visibleHeight / me.rowHeight), + visibleEnd = visibleStart + visibleAhead, + prevPage = Math.floor(visibleStart / store.pageSize), + nextPage = Math.floor(visibleEnd / store.pageSize) + 2, + lastPage = Math.ceil(totalCount / store.pageSize), + + requestStart = Math.floor(visibleStart / me.snapIncrement) * me.snapIncrement, + requestEnd = requestStart + pageSize - 1, + activePrefetch = me.activePrefetch; + + me.visibleStart = visibleStart; + me.visibleEnd = visibleEnd; + + + me.syncScroll = true; + if (totalCount >= pageSize) { + + if (requestEnd > totalCount - 1) { + this.cancelLoad(); + if (store.rangeSatisfied(totalCount - pageSize, totalCount - 1)) { + me.syncScroll = true; + } + store.guaranteeRange(totalCount - pageSize, totalCount - 1); + + } else if (visibleStart < guaranteedStart || visibleEnd > guaranteedEnd) { + if (store.rangeSatisfied(requestStart, requestEnd)) { + this.cancelLoad(); + store.guaranteeRange(requestStart, requestEnd); + } else { + store.mask(); + me.attemptLoad(requestStart, requestEnd); + } + + me.syncScroll = false; + } else if (activePrefetch && visibleStart < (guaranteedStart + numFromEdge) && prevPage > 0) { + me.syncScroll = true; + store.prefetchPage(prevPage); + } else if (activePrefetch && visibleEnd > (guaranteedEnd - numFromEdge) && nextPage < lastPage) { + me.syncScroll = true; + store.prefetchPage(nextPage); + } } - }, - - fireEvent : function(){ - return this.node.fireEvent.apply(this.node, arguments); - }, - - initEvents : function(){ - this.node.on("move", this.onMove, this); - - if(this.node.disabled){ - this.onDisableChange(this.node, true); - } - if(this.node.hidden){ - this.hide(); - } - var ot = this.node.getOwnerTree(); - var dd = ot.enableDD || ot.enableDrag || ot.enableDrop; - if(dd && (!this.node.isRoot || ot.rootVisible)){ - Ext.dd.Registry.register(this.elNode, { - node: this.node, - handles: this.getDDHandles(), - isHandle: false - }); + if (me.syncScroll) { + me.syncTo(); } }, - - getDDHandles : function(){ - return [this.iconNode, this.textNode, this.elNode]; - }, - - - hide : function(){ - this.node.hidden = true; - if(this.wrap){ - this.wrap.style.display = "none"; + getSizeCalculation: function() { + + + var owner = this.ownerCt, + view = owner.getView(), + store = this.store, + dock = this.dock, + elDom = this.el.dom, + width = 1, + height = 1; + + if (!this.rowHeight) { + this.rowHeight = view.el.down(view.getItemSelector()).getHeight(false, true); } - }, + height = store.getTotalCount() * this.rowHeight; - show : function(){ - this.node.hidden = false; - if(this.wrap){ - this.wrap.style.display = ""; + if (isNaN(width)) { + width = 1; } + if (isNaN(height)) { + height = 1; + } + return { + width: width, + height: height + }; }, - - onContextMenu : function(e){ - if (this.node.hasListener("contextmenu") || this.node.getOwnerTree().hasListener("contextmenu")) { - e.preventDefault(); - this.focus(); - this.fireEvent("contextmenu", this.node, e); + attemptLoad: function(start, end) { + var me = this; + if (!me.loadTask) { + me.loadTask = Ext.create('Ext.util.DelayedTask', me.doAttemptLoad, me, []); } + me.loadTask.delay(me.scrollToLoadBuffer, me.doAttemptLoad, me, [start, end]); }, - - onClick : function(e){ - if(this.dropping){ - e.stopEvent(); - return; - } - if(this.fireEvent("beforeclick", this.node, e) !== false){ - var a = e.getTarget('a'); - if(!this.disabled && this.node.attributes.href && a){ - this.fireEvent("click", this.node, e); - return; - }else if(a && e.ctrlKey){ - e.stopEvent(); - } - e.preventDefault(); - if(this.disabled){ - return; - } - - if(this.node.attributes.singleClickExpand && !this.animating && this.node.isExpandable()){ - this.node.toggle(); - } - - this.fireEvent("click", this.node, e); - }else{ - e.stopEvent(); + cancelLoad: function() { + if (this.loadTask) { + this.loadTask.cancel(); } }, - - onDblClick : function(e){ - e.preventDefault(); - if(this.disabled){ + doAttemptLoad: function(start, end) { + var store = this.getPanel().store; + store.guaranteeRange(start, end); + }, + + setViewScrollTop: function(scrollTop, useMax) { + var owner = this.getPanel(), + items = owner.query('tableview'), + i = 0, + len = items.length, + center, + centerEl, + calcScrollTop, + maxScrollTop, + scrollerElDom = this.el.dom; + + owner.virtualScrollTop = scrollTop; + + center = items[1] || items[0]; + centerEl = center.el.dom; + + maxScrollTop = ((owner.store.pageSize * this.rowHeight) - centerEl.clientHeight); + calcScrollTop = (scrollTop % ((owner.store.pageSize * this.rowHeight) + 1)); + if (useMax) { + calcScrollTop = maxScrollTop; + } + if (calcScrollTop > maxScrollTop) { + return; + } - if(this.fireEvent("beforedblclick", this.node, e) !== false){ - if(this.checkbox){ - this.toggleCheck(); - } - if(!this.animating && this.node.isExpandable()){ - this.node.toggle(); - } - this.fireEvent("dblclick", this.node, e); + for (; i < len; i++) { + items[i].el.dom.scrollTop = calcScrollTop; } - }, + } +}); - onOver : function(e){ - this.addClass('x-tree-node-over'); - }, - onOut : function(e){ - this.removeClass('x-tree-node-over'); - }, - - onCheckChange : function(){ - var checked = this.checkbox.checked; - - this.checkbox.defaultChecked = checked; - this.node.attributes.checked = checked; - this.fireEvent('checkchange', this.node, checked); - }, +Ext.define('Ext.panel.Table', { + extend: 'Ext.panel.Panel', - - ecClick : function(e){ - if(!this.animating && this.node.isExpandable()){ - this.node.toggle(); - } - }, + alias: 'widget.tablepanel', - - startDrop : function(){ - this.dropping = true; - }, + uses: [ + 'Ext.selection.RowModel', + 'Ext.grid.Scroller', + 'Ext.grid.header.Container', + 'Ext.grid.Lockable' + ], - - endDrop : function(){ - setTimeout(function(){ - this.dropping = false; - }.createDelegate(this), 50); - }, + cls: Ext.baseCSSPrefix + 'grid', + extraBodyCls: Ext.baseCSSPrefix + 'grid-body', + layout: 'fit', - expand : function(){ - this.updateExpandIcon(); - this.ctNode.style.display = ""; - }, + hasView: false, - focus : function(){ - if(!this.node.preventHScroll){ - try{this.anchor.focus(); - }catch(e){} - }else{ - try{ - var noscroll = this.node.getOwnerTree().getTreeEl().dom; - var l = noscroll.scrollLeft; - this.anchor.focus(); - noscroll.scrollLeft = l; - }catch(e){} - } - }, - - - toggleCheck : function(value){ - var cb = this.checkbox; - if(cb){ - cb.checked = (value === undefined ? !cb.checked : value); - this.onCheckChange(); - } - }, + viewType: null, + selType: 'rowmodel', - blur : function(){ - try{ - this.anchor.blur(); - }catch(e){} - }, + scrollDelta: 40, - animExpand : function(callback){ - var ct = Ext.get(this.ctNode); - ct.stopFx(); - if(!this.node.isExpandable()){ - this.updateExpandIcon(); - this.ctNode.style.display = ""; - Ext.callback(callback); - return; - } - this.animating = true; - this.updateExpandIcon(); - - ct.slideIn('t', { - callback : function(){ - this.animating = false; - Ext.callback(callback); - }, - scope: this, - duration: this.node.ownerTree.duration || .25 - }); - }, + scroll: true, - highlight : function(){ - var tree = this.node.getOwnerTree(); - Ext.fly(this.wrap).highlight( - tree.hlColor || "C3DAF9", - {endColor: tree.hlBaseColor} - ); - }, - collapse : function(){ - this.updateExpandIcon(); - this.ctNode.style.display = "none"; - }, - animCollapse : function(callback){ - var ct = Ext.get(this.ctNode); - ct.enableDisplayMode('block'); - ct.stopFx(); - - this.animating = true; - this.updateExpandIcon(); - - ct.slideOut('t', { - callback : function(){ - this.animating = false; - Ext.callback(callback); - }, - scope: this, - duration: this.node.ownerTree.duration || .25 - }); - }, - getContainer : function(){ - return this.ctNode; - }, + sortableColumns: true, + verticalScrollDock: 'right', + verticalScrollerType: 'gridscroller', - getEl : function(){ - return this.wrap; - }, + horizontalScrollerPresentCls: Ext.baseCSSPrefix + 'horizontal-scroller-present', + verticalScrollerPresentCls: Ext.baseCSSPrefix + 'vertical-scroller-present', - appendDDGhost : function(ghostNode){ - ghostNode.appendChild(this.elNode.cloneNode(true)); - }, - - getDDRepairXY : function(){ - return Ext.lib.Dom.getXY(this.iconNode); - }, + scrollerOwner: true, + invalidateScrollerOnRefresh: true, - onRender : function(){ - this.render(); - }, + enableColumnMove: true, + enableColumnResize: true, - - render : function(bulkRender){ - var n = this.node, a = n.attributes; - var targetNode = n.parentNode ? - n.parentNode.ui.getContainer() : n.ownerTree.innerCt.dom; - if(!this.rendered){ - this.rendered = true; + initComponent: function() { + if (!this.viewType) { + Ext.Error.raise("You must specify a viewType config."); + } + if (!this.store) { + Ext.Error.raise("You must specify a store config"); + } + if (this.headers) { + Ext.Error.raise("The headers config is not supported. Please specify columns instead."); + } - this.renderElements(n, a, targetNode, bulkRender); + var me = this, + scroll = me.scroll, + vertical = false, + horizontal = false, + headerCtCfg = me.columns || me.colModel, + i = 0, + view, + border = me.border; - if(a.qtip){ - this.onTipChange(n, a.qtip, a.qtipTitle); - }else if(a.qtipCfg){ - a.qtipCfg.target = Ext.id(this.textNode); - Ext.QuickTips.register(a.qtipCfg); - } - this.initEvents(); - if(!this.node.expanded){ - this.updateExpandIcon(true); - } - }else{ - if(bulkRender === true) { - targetNode.appendChild(this.wrap); - } + + me.determineScrollbars = Ext.Function.createBuffered(me.determineScrollbars, 30); + me.injectView = Ext.Function.createBuffered(me.injectView, 30); + + if (me.hideHeaders) { + border = false; } - }, - - renderElements : function(n, a, targetNode, bulkRender){ - this.indentMarkup = n.parentNode ? n.parentNode.ui.getChildIndent() : ''; - - var cb = Ext.isBoolean(a.checked), - nel, - href = this.getHref(a.href), - buf = ['
  • ', - '',this.indentMarkup,"", - '', - '', - cb ? ('' : '/>')) : '', - '',n.text,"
    ", - '', - "
  • "].join(''); + + if (headerCtCfg instanceof Ext.grid.header.Container) { + me.headerCt = headerCtCfg; + me.headerCt.border = border; + me.columns = me.headerCt.items.items; + } else { + if (Ext.isArray(headerCtCfg)) { + headerCtCfg = { + items: headerCtCfg, + border: border + }; + } + Ext.apply(headerCtCfg, { + forceFit: me.forceFit, + sortable: me.sortableColumns, + enableColumnMove: me.enableColumnMove, + enableColumnResize: me.enableColumnResize, + border: border + }); + me.columns = headerCtCfg.items; - if(bulkRender !== true && n.nextSibling && (nel = n.nextSibling.ui.getEl())){ - this.wrap = Ext.DomHelper.insertHtml("beforeBegin", nel, buf); - }else{ - this.wrap = Ext.DomHelper.insertHtml("beforeEnd", targetNode, buf); + + + if (Ext.ComponentQuery.query('{locked !== undefined}{processed != true}', me.columns).length) { + me.self.mixin('lockable', Ext.grid.Lockable); + me.injectLockable(); + } } - this.elNode = this.wrap.childNodes[0]; - this.ctNode = this.wrap.childNodes[1]; - var cs = this.elNode.childNodes; - this.indentNode = cs[0]; - this.ecNode = cs[1]; - this.iconNode = cs[2]; - var index = 3; - if(cb){ - this.checkbox = cs[3]; + me.store = Ext.data.StoreManager.lookup(me.store); + me.addEvents( - this.checkbox.defaultChecked = this.checkbox.checked; - index++; - } - this.anchor = cs[index]; - this.textNode = cs[index].firstChild; - }, - - - getHref : function(href){ - return Ext.isEmpty(href) ? (Ext.isGecko ? '' : '#') : href; - }, - - - getAnchor : function(){ - return this.anchor; - }, - - - getTextEl : function(){ - return this.textNode; - }, - + 'scrollerhide', + + 'scrollershow' + ); - getIconEl : function(){ - return this.iconNode; - }, + me.bodyCls = me.bodyCls || ''; + me.bodyCls += (' ' + me.extraBodyCls); + + delete me.autoScroll; - isChecked : function(){ - return this.checkbox ? this.checkbox.checked : false; - }, + + + if (!me.hasView) { - - updateExpandIcon : function(){ - if(this.rendered){ - var n = this.node, - c1, - c2, - cls = n.isLast() ? "x-tree-elbow-end" : "x-tree-elbow", - hasChild = n.hasChildNodes(); - if(hasChild || n.attributes.expandable){ - if(n.expanded){ - cls += "-minus"; - c1 = "x-tree-node-collapsed"; - c2 = "x-tree-node-expanded"; - }else{ - cls += "-plus"; - c1 = "x-tree-node-expanded"; - c2 = "x-tree-node-collapsed"; - } - if(this.wasLeaf){ - this.removeClass("x-tree-node-leaf"); - this.wasLeaf = false; - } - if(this.c1 != c1 || this.c2 != c2){ - Ext.fly(this.elNode).replaceClass(c1, c2); - this.c1 = c1; this.c2 = c2; - } - }else{ - if(!this.wasLeaf){ - Ext.fly(this.elNode).replaceClass("x-tree-node-expanded", "x-tree-node-collapsed"); - delete this.c1; - delete this.c2; - this.wasLeaf = true; - } - } - var ecc = "x-tree-ec-icon "+cls; - if(this.ecc != ecc){ - this.ecNode.className = ecc; - this.ecc = ecc; + + + if (!me.headerCt) { + me.headerCt = Ext.create('Ext.grid.header.Container', headerCtCfg); } - } - }, - - onIdChange: function(id){ - if(this.rendered){ - this.elNode.setAttribute('ext:tree-node-id', id); - } - }, + + me.columns = me.headerCt.items.items; - - getChildIndent : function(){ - if(!this.childIndent){ - var buf = [], - p = this.node; - while(p){ - if(!p.isRoot || (p.isRoot && p.ownerTree.rootVisible)){ - if(!p.isLast()) { - buf.unshift(''); - } else { - buf.unshift(''); - } + if (me.hideHeaders) { + me.headerCt.height = 0; + me.headerCt.border = false; + me.headerCt.addCls(Ext.baseCSSPrefix + 'grid-header-ct-hidden'); + me.addCls(Ext.baseCSSPrefix + 'grid-header-hidden'); + + + if (Ext.isIEQuirks) { + me.headerCt.style = { + display: 'none' + }; } - p = p.parentNode; } - this.childIndent = buf.join(""); - } - return this.childIndent; - }, - - renderIndent : function(){ - if(this.rendered){ - var indent = "", - p = this.node.parentNode; - if(p){ - indent = p.ui.getChildIndent(); - } - if(this.indentMarkup != indent){ - this.indentNode.innerHTML = indent; - this.indentMarkup = indent; + + if (scroll === true || scroll === 'both') { + vertical = horizontal = true; + } else if (scroll === 'horizontal') { + horizontal = true; + } else if (scroll === 'vertical') { + vertical = true; + + } else { + me.headerCt.availableSpaceOffset = 0; } - this.updateExpandIcon(); - } - }, - destroy : function(){ - if(this.elNode){ - Ext.dd.Registry.unregister(this.elNode.id); - } - - Ext.each(['textnode', 'anchor', 'checkbox', 'indentNode', 'ecNode', 'iconNode', 'elNode', 'ctNode', 'wrap', 'holder'], function(el){ - if(this[el]){ - Ext.fly(this[el]).remove(); - delete this[el]; + if (vertical) { + me.verticalScroller = me.verticalScroller || {}; + Ext.applyIf(me.verticalScroller, { + dock: me.verticalScrollDock, + xtype: me.verticalScrollerType, + store: me.store + }); + me.verticalScroller = Ext.ComponentManager.create(me.verticalScroller); + me.mon(me.verticalScroller, { + bodyscroll: me.onVerticalScroll, + scope: me + }); } - }, this); - delete this.node; - } -}); - - -Ext.tree.RootTreeNodeUI = Ext.extend(Ext.tree.TreeNodeUI, { - - render : function(){ - if(!this.rendered){ - var targetNode = this.node.ownerTree.innerCt.dom; - this.node.expanded = true; - targetNode.innerHTML = '
    '; - this.wrap = this.ctNode = targetNode.firstChild; - } - }, - collapse : Ext.emptyFn, - expand : Ext.emptyFn -}); -Ext.tree.TreeLoader = function(config){ - this.baseParams = {}; - Ext.apply(this, config); - - this.addEvents( - - "beforeload", - - "load", - - "loadexception" - ); - Ext.tree.TreeLoader.superclass.constructor.call(this); - if(Ext.isString(this.paramOrder)){ - this.paramOrder = this.paramOrder.split(/[\s,|]/); - } -}; -Ext.extend(Ext.tree.TreeLoader, Ext.util.Observable, { - - - - - - - - uiProviders : {}, - - - clearOnLoad : true, - - - paramOrder: undefined, + if (horizontal) { + me.horizontalScroller = Ext.ComponentManager.create({ + xtype: 'gridscroller', + section: me, + dock: 'bottom', + store: me.store + }); + me.mon(me.horizontalScroller, { + bodyscroll: me.onHorizontalScroll, + scope: me + }); + } - - paramsAsHash: false, + me.headerCt.on('columnresize', me.onHeaderResize, me); + me.relayEvents(me.headerCt, ['columnresize', 'columnmove', 'columnhide', 'columnshow', 'sortchange']); + me.features = me.features || []; + me.dockedItems = me.dockedItems || []; + me.dockedItems.unshift(me.headerCt); + me.viewConfig = me.viewConfig || {}; + me.viewConfig.invalidateScrollerOnRefresh = me.invalidateScrollerOnRefresh; - - nodeParameter: 'node', + + + view = me.getView(); - - directFn : undefined, + if (view) { + me.mon(view.store, { + load: me.onStoreLoad, + scope: me + }); + me.mon(view, { + refresh: { + fn: this.onViewRefresh, + scope: me, + buffer: 50 + }, + itemupdate: me.onViewItemUpdate, + scope: me + }); + this.relayEvents(view, [ + + 'beforeitemmousedown', + + 'beforeitemmouseup', + + 'beforeitemmouseenter', + + 'beforeitemmouseleave', + + 'beforeitemclick', + + 'beforeitemdblclick', + + 'beforeitemcontextmenu', + + 'itemmousedown', + + 'itemmouseup', + + 'itemmouseenter', + + 'itemmouseleave', + + 'itemclick', + + 'itemdblclick', + + 'itemcontextmenu', + + 'beforecontainermousedown', + + 'beforecontainermouseup', + + 'beforecontainermouseover', + + 'beforecontainermouseout', + + 'beforecontainerclick', + + 'beforecontainerdblclick', + + 'beforecontainercontextmenu', + + 'containermouseup', + + 'containermouseover', + + 'containermouseout', + + 'containerclick', + + 'containerdblclick', + + 'containercontextmenu', - - load : function(node, callback, scope){ - if(this.clearOnLoad){ - while(node.firstChild){ - node.removeChild(node.firstChild); + + 'selectionchange', + + 'beforeselect' + ]); } } - if(this.doPreload(node)){ - this.runCallback(callback, scope || node, [node]); - }else if(this.directFn || this.dataUrl || this.url){ - this.requestData(node, callback, scope || node); - } + me.callParent(arguments); }, - doPreload : function(node){ - if(node.attributes.children){ - if(node.childNodes.length < 1){ - var cs = node.attributes.children; - node.beginUpdate(); - for(var i = 0, len = cs.length; i < len; i++){ - var cn = node.appendChild(this.createNode(cs[i])); - if(this.preloadChildren){ - this.doPreload(cn); - } - } - node.endUpdate(); + + initStateEvents: function(){ + var events = this.stateEvents; + + Ext.each(['columnresize', 'columnmove', 'columnhide', 'columnshow', 'sortchange'], function(event){ + if (Ext.Array.indexOf(events, event)) { + events.push(event); } - return true; - } - return false; + }); + this.callParent(); }, - getParams: function(node){ - var bp = Ext.apply({}, this.baseParams), - np = this.nodeParameter, - po = this.paramOrder; + getState: function(){ + var state = { + columns: [] + }, + sorter = this.store.sorters.first(); + + this.headerCt.items.each(function(header){ + state.columns.push({ + id: header.headerId, + width: header.flex ? undefined : header.width, + hidden: header.hidden, + sortable: header.sortable + }); + }); - np && (bp[ np ] = node.id); + if (sorter) { + state.sort = { + property: sorter.property, + direction: sorter.direction + }; + } + return state; + }, - if(this.directFn){ - var buf = [node.id]; - if(po){ - - if(np && po.indexOf(np) > -1){ - buf = []; - } + applyState: function(state) { + var headers = state.columns, + length = headers ? headers.length : 0, + headerCt = this.headerCt, + items = headerCt.items, + sorter = state.sort, + store = this.store, + i = 0, + index, + headerState, + header; - for(var i = 0, len = po.length; i < len; i++){ - buf.push(bp[ po[i] ]); + for (; i < length; ++i) { + headerState = headers[i]; + header = headerCt.down('gridcolumn[headerId=' + headerState.id + ']'); + index = items.indexOf(header); + if (i !== index) { + headerCt.moveHeader(index, i); + } + header.sortable = headerState.sortable; + if (Ext.isDefined(headerState.width)) { + delete header.flex; + if (header.rendered) { + header.setWidth(headerState.width); + } else { + header.minWidth = header.width = headerState.width; } - }else if(this.paramsAsHash){ - buf = [bp]; } - return buf; - }else{ - return bp; + header.hidden = headerState.hidden; } - }, - requestData : function(node, callback, scope){ - if(this.fireEvent("beforeload", this, node, callback) !== false){ - if(this.directFn){ - var args = this.getParams(node); - args.push(this.processDirectResponse.createDelegate(this, [{callback: callback, node: node, scope: scope}], true)); - this.directFn.apply(window, args); - }else{ - this.transId = Ext.Ajax.request({ - method:this.requestMethod, - url: this.dataUrl||this.url, - success: this.handleResponse, - failure: this.handleFailure, - scope: this, - argument: {callback: callback, node: node, scope: scope}, - params: this.getParams(node) - }); + if (sorter) { + if (store.remoteSort) { + store.sorters.add(Ext.create('Ext.util.Sorter', { + property: sorter.property, + direction: sorter.direction + })); + } + else { + store.sort(sorter.property, sorter.direction); } - }else{ - - - this.runCallback(callback, scope || node, []); } }, - processDirectResponse: function(result, response, args){ - if(response.status){ - this.handleResponse({ - responseData: Ext.isArray(result) ? result : null, - responseText: result, - argument: args - }); - }else{ - this.handleFailure({ - argument: args - }); - } + + getStore: function(){ + return this.store; }, - runCallback: function(cb, scope, args){ - if(Ext.isFunction(cb)){ - cb.apply(scope, args); + getView: function() { + var me = this, + sm; + + if (!me.view) { + sm = me.getSelectionModel(); + me.view = me.createComponent(Ext.apply({}, me.viewConfig, { + xtype: me.viewType, + store: me.store, + headerCt: me.headerCt, + selModel: sm, + features: me.features, + panel: me + })); + me.mon(me.view, { + uievent: me.processEvent, + scope: me + }); + sm.view = me.view; + me.headerCt.view = me.view; + me.relayEvents(me.view, ['cellclick', 'celldblclick']); } + return me.view; }, - isLoading : function(){ - return !!this.transId; - }, - - abort : function(){ - if(this.isLoading()){ - Ext.Ajax.abort(this.transId); - } - }, + + setAutoScroll: Ext.emptyFn, - createNode : function(attr){ - - if(this.baseAttrs){ - Ext.applyIf(attr, this.baseAttrs); - } - if(this.applyLoader !== false && !attr.loader){ - attr.loader = this; - } - if(Ext.isString(attr.uiProvider)){ - attr.uiProvider = this.uiProviders[attr.uiProvider] || eval(attr.uiProvider); - } - if(attr.nodeType){ - return new Ext.tree.TreePanel.nodeTypes[attr.nodeType](attr); - }else{ - return attr.leaf ? - new Ext.tree.TreeNode(attr) : - new Ext.tree.AsyncTreeNode(attr); - } - }, + + + elScroll: function(direction, distance, animate) { + var me = this, + scroller; - processResponse : function(response, node, callback, scope){ - var json = response.responseText; - try { - var o = response.responseData || Ext.decode(json); - node.beginUpdate(); - for(var i = 0, len = o.length; i < len; i++){ - var n = this.createNode(o[i]); - if(n){ - node.appendChild(n); - } - } - node.endUpdate(); - this.runCallback(callback, scope || node, [node]); - }catch(e){ - this.handleFailure(response); + if (direction === "up" || direction === "left") { + distance = -distance; } - }, - handleResponse : function(response){ - this.transId = false; - var a = response.argument; - this.processResponse(response, a.node, a.callback, a.scope); - this.fireEvent("load", this, a.node, response); + if (direction === "down" || direction === "up") { + scroller = me.getVerticalScroller(); + scroller.scrollByDeltaY(distance); + } else { + scroller = me.getHorizontalScroller(); + scroller.scrollByDeltaX(distance); + } }, - - handleFailure : function(response){ - this.transId = false; - var a = response.argument; - this.fireEvent("loadexception", this, a.node, response); - this.runCallback(a.callback, a.scope || a.node, [a.node]); + + afterLayout: function() { + this.callParent(arguments); + this.injectView(); }, + - destroy : function(){ - this.abort(); - this.purgeListeners(); - } -}); -Ext.tree.TreeFilter = function(tree, config){ - this.tree = tree; - this.filtered = {}; - Ext.apply(this, config); -}; + + injectView: function() { + if (!this.hasView && !this.collapsed) { + var me = this, + view = me.getView(); -Ext.tree.TreeFilter.prototype = { - clearBlank:false, - reverse:false, - autoClear:false, - remove:false, + me.hasView = true; + me.add(view); - - filter : function(value, attr, startNode){ - attr = attr || "text"; - var f; - if(typeof value == "string"){ - var vlen = value.length; - - if(vlen == 0 && this.clearBlank){ - this.clear(); - return; - } - value = value.toLowerCase(); - f = function(n){ - return n.attributes[attr].substr(0, vlen).toLowerCase() == value; - }; - }else if(value.exec){ - f = function(n){ - return value.test(n.attributes[attr]); - }; - }else{ - throw 'Illegal filter type, must be string or regex'; + + view.el.scroll = Ext.Function.bind(me.elScroll, me); + + + me.mon(view.el, { + mousewheel: me.onMouseWheel, + scope: me + }); } - this.filterBy(f, null, startNode); - }, + }, - - filterBy : function(fn, scope, startNode){ - startNode = startNode || this.tree.root; - if(this.autoClear){ - this.clear(); - } - var af = this.filtered, rv = this.reverse; - var f = function(n){ - if(n == startNode){ - return true; - } - if(af[n.id]){ - return false; - } - var m = fn.call(scope || n, n); - if(!m || rv){ - af[n.id] = n; - n.ui.hide(); - return false; - } - return true; - }; - startNode.cascade(f); - if(this.remove){ - for(var id in af){ - if(typeof id != "function"){ - var n = af[id]; - if(n && n.parentNode){ - n.parentNode.removeChild(n); - } - } - } + afterExpand: function() { + this.callParent(arguments); + if (!this.hasView) { + this.injectView(); } }, - clear : function(){ - var t = this.tree; - var af = this.filtered; - for(var id in af){ - if(typeof id != "function"){ - var n = af[id]; - if(n){ - n.ui.show(); - } - } + processEvent: function(type, view, cell, recordIndex, cellIndex, e) { + var me = this, + header; + + if (cellIndex !== -1) { + header = me.headerCt.getGridColumns()[cellIndex]; + return header.processEvent.apply(header, arguments); } - this.filtered = {}; - } -}; + }, -Ext.tree.TreeSorter = Ext.extend(Object, { - - constructor: function(tree, config){ - - - - - + determineScrollbars: function() { + var me = this, + viewElDom, + centerScrollWidth, + centerClientWidth, + scrollHeight, + clientHeight; - Ext.apply(this, config); - tree.on({ - scope: this, - beforechildrenrendered: this.doSort, - append: this.updateSort, - insert: this.updateSort, - textchange: this.updateSortParent - }); + if (!me.collapsed && me.view && me.view.el) { + viewElDom = me.view.el.dom; + + centerScrollWidth = me.headerCt.getFullWidth(); + + centerClientWidth = viewElDom.offsetWidth; + if (me.verticalScroller && me.verticalScroller.el) { + scrollHeight = me.verticalScroller.getSizeCalculation().height; + } else { + scrollHeight = viewElDom.scrollHeight; + } - var desc = this.dir && this.dir.toLowerCase() == 'desc', - prop = this.property || 'text'; - sortType = this.sortType; - folderSort = this.folderSort; - caseSensitive = this.caseSensitive === true; - leafAttr = this.leafAttr || 'leaf'; + clientHeight = viewElDom.clientHeight; - if(Ext.isString(sortType)){ - sortType = Ext.data.SortTypes[sortType]; - } - this.sortFn = function(n1, n2){ - var attr1 = n1.attributes, - attr2 = n2.attributes; - - if(folderSort){ - if(attr1[leafAttr] && !attr2[leafAttr]){ - return 1; + if (!me.collapsed && scrollHeight > clientHeight) { + me.showVerticalScroller(); + } else { + me.hideVerticalScroller(); } - if(!attr1[leafAttr] && attr2[leafAttr]){ - return -1; + + if (!me.collapsed && centerScrollWidth > (centerClientWidth + Ext.getScrollBarWidth() - 2)) { + me.showHorizontalScroller(); + } else { + me.hideHorizontalScroller(); } } - var prop1 = attr1[prop], - prop2 = attr2[prop], - v1 = sortType ? sortType(prop1) : (caseSensitive ? prop1 : prop1.toUpperCase()); - v2 = sortType ? sortType(prop2) : (caseSensitive ? prop2 : prop2.toUpperCase()); - - if(v1 < v2){ - return desc ? 1 : -1; - }else if(v1 > v2){ - return desc ? -1 : 1; - } - return 0; - }; - }, - - doSort : function(node){ - node.sort(this.sortFn); }, - updateSort : function(tree, node){ - if(node.childrenRendered){ - this.doSort.defer(1, this, [node]); + onHeaderResize: function() { + if (this.view && this.view.rendered) { + this.determineScrollbars(); + this.invalidateScroller(); } }, - updateSortParent : function(node){ - var p = node.parentNode; - if(p && p.childrenRendered){ - this.doSort.defer(1, this, [p]); - } - } -}); -if(Ext.dd.DropZone){ - -Ext.tree.TreeDropZone = function(tree, config){ - - this.allowParentInsert = config.allowParentInsert || false; - this.allowContainerDrop = config.allowContainerDrop || false; - - this.appendOnly = config.appendOnly || false; + hideHorizontalScroller: function() { + var me = this; - Ext.tree.TreeDropZone.superclass.constructor.call(this, tree.getTreeEl(), config); - - this.tree = tree; - - this.dragOverData = {}; - - this.lastInsertClass = "x-tree-no-status"; -}; + if (me.horizontalScroller && me.horizontalScroller.ownerCt === me) { + me.verticalScroller.offsets.bottom = 0; + me.removeDocked(me.horizontalScroller, false); + me.removeCls(me.horizontalScrollerPresentCls); + me.fireEvent('scrollerhide', me.horizontalScroller, 'horizontal'); + } -Ext.extend(Ext.tree.TreeDropZone, Ext.dd.DropZone, { - - ddGroup : "TreeDD", + }, - expandDelay : 1000, + showHorizontalScroller: function() { + var me = this; - - expandNode : function(node){ - if(node.hasChildNodes() && !node.isExpanded()){ - node.expand(false, null, this.triggerCacheRefresh.createDelegate(this)); + if (me.verticalScroller) { + me.verticalScroller.offsets.bottom = Ext.getScrollBarWidth() - 2; + } + if (me.horizontalScroller && me.horizontalScroller.ownerCt !== me) { + me.addDocked(me.horizontalScroller); + me.addCls(me.horizontalScrollerPresentCls); + me.fireEvent('scrollershow', me.horizontalScroller, 'horizontal'); } }, - queueExpand : function(node){ - this.expandProcId = this.expandNode.defer(this.expandDelay, this, [node]); - }, + hideVerticalScroller: function() { + var me = this, + headerCt = me.headerCt; - - cancelExpand : function(){ - if(this.expandProcId){ - clearTimeout(this.expandProcId); - this.expandProcId = false; + + if (headerCt && headerCt.layout.reserveOffset) { + headerCt.layout.reserveOffset = false; + headerCt.doLayout(); + } + if (me.verticalScroller && me.verticalScroller.ownerCt === me) { + me.removeDocked(me.verticalScroller, false); + me.removeCls(me.verticalScrollerPresentCls); + me.fireEvent('scrollerhide', me.verticalScroller, 'vertical'); } }, - isValidDropPoint : function(n, pt, dd, e, data){ - if(!n || !data){ return false; } - var targetNode = n.node; - var dropNode = data.node; + showVerticalScroller: function() { + var me = this, + headerCt = me.headerCt; + - if(!(targetNode && targetNode.isTarget && pt)){ - return false; + if (headerCt && !headerCt.layout.reserveOffset) { + headerCt.layout.reserveOffset = true; + headerCt.doLayout(); } - if(pt == "append" && targetNode.allowChildren === false){ - return false; - } - if((pt == "above" || pt == "below") && (targetNode.parentNode && targetNode.parentNode.allowChildren === false)){ - return false; + if (me.verticalScroller && me.verticalScroller.ownerCt !== me) { + me.addDocked(me.verticalScroller); + me.addCls(me.verticalScrollerPresentCls); + me.fireEvent('scrollershow', me.verticalScroller, 'vertical'); } - if(dropNode && (targetNode == dropNode || dropNode.contains(targetNode))){ - return false; + }, + + + invalidateScroller: function() { + var me = this, + vScroll = me.verticalScroller, + hScroll = me.horizontalScroller; + + if (vScroll) { + vScroll.invalidate(); } - - var overEvent = this.dragOverData; - overEvent.tree = this.tree; - overEvent.target = targetNode; - overEvent.data = data; - overEvent.point = pt; - overEvent.source = dd; - overEvent.rawEvent = e; - overEvent.dropNode = dropNode; - overEvent.cancel = false; - var result = this.tree.fireEvent("nodedragover", overEvent); - return overEvent.cancel === false && result !== false; - }, - - - getDropPoint : function(e, n, dd){ - var tn = n.node; - if(tn.isRoot){ - return tn.allowChildren !== false ? "append" : false; - } - var dragEl = n.ddel; - var t = Ext.lib.Dom.getY(dragEl), b = t + dragEl.offsetHeight; - var y = Ext.lib.Event.getPageY(e); - var noAppend = tn.allowChildren === false || tn.isLeaf(); - if(this.appendOnly || tn.parentNode.allowChildren === false){ - return noAppend ? false : "append"; - } - var noBelow = false; - if(!this.allowParentInsert){ - noBelow = tn.hasChildNodes() && tn.isExpanded(); - } - var q = (b - t) / (noAppend ? 2 : 3); - if(y >= t && y < (t + q)){ - return "above"; - }else if(!noBelow && (noAppend || y >= b-q && y <= b)){ - return "below"; - }else{ - return "append"; + if (hScroll) { + hScroll.invalidate(); } }, - onNodeEnter : function(n, dd, e, data){ - this.cancelExpand(); + onHeaderMove: function(headerCt, header, fromIdx, toIdx) { + this.view.refresh(); }, + - onContainerOver : function(dd, e, data) { - if (this.allowContainerDrop && this.isValidDropPoint({ ddel: this.tree.getRootNode().ui.elNode, node: this.tree.getRootNode() }, "append", dd, e, data)) { - return this.dropAllowed; - } - return this.dropNotAllowed; + onHeaderHide: function(headerCt, header) { + this.invalidateScroller(); }, - - onNodeOver : function(n, dd, e, data){ - var pt = this.getDropPoint(e, n, dd); - var node = n.node; - - - if(!this.expandProcId && pt == "append" && node.hasChildNodes() && !n.node.isExpanded()){ - this.queueExpand(node); - }else if(pt != "append"){ - this.cancelExpand(); - } - - - var returnCls = this.dropNotAllowed; - if(this.isValidDropPoint(n, pt, dd, e, data)){ - if(pt){ - var el = n.ddel; - var cls; - if(pt == "above"){ - returnCls = n.node.isFirst() ? "x-tree-drop-ok-above" : "x-tree-drop-ok-between"; - cls = "x-tree-drag-insert-above"; - }else if(pt == "below"){ - returnCls = n.node.isLast() ? "x-tree-drop-ok-below" : "x-tree-drop-ok-between"; - cls = "x-tree-drag-insert-below"; - }else{ - returnCls = "x-tree-drop-ok-append"; - cls = "x-tree-drag-append"; - } - if(this.lastInsertClass != cls){ - Ext.fly(el).replaceClass(this.lastInsertClass, cls); - this.lastInsertClass = cls; - } - } - } - return returnCls; + onHeaderShow: function(headerCt, header) { + this.invalidateScroller(); }, - - onNodeOut : function(n, dd, e, data){ - this.cancelExpand(); - this.removeDropIndicators(n); + getVerticalScroller: function() { + return this.getScrollerOwner().down('gridscroller[dock=' + this.verticalScrollDock + ']'); }, - - onNodeDrop : function(n, dd, e, data){ - var point = this.getDropPoint(e, n, dd); - var targetNode = n.node; - targetNode.ui.startDrop(); - if(!this.isValidDropPoint(n, point, dd, e, data)){ - targetNode.ui.endDrop(); - return false; + getHorizontalScroller: function() { + return this.getScrollerOwner().down('gridscroller[dock=bottom]'); + }, + + onMouseWheel: function(e) { + var me = this, + browserEvent = e.browserEvent, + vertScroller = me.getVerticalScroller(), + horizScroller = me.getHorizontalScroller(), + scrollDelta = me.scrollDelta, + deltaY, deltaX, + vertScrollerEl, horizScrollerEl, + origScrollLeft, origScrollTop, + newScrollLeft, newScrollTop; + + + + if (horizScroller) { + horizScrollerEl = horizScroller.el; + if (horizScrollerEl) { + origScrollLeft = horizScrollerEl.dom.scrollLeft; + } + } + if (vertScroller) { + vertScrollerEl = vertScroller.el; + if (vertScrollerEl) { + origScrollTop = vertScrollerEl.dom.scrollTop; + } + } + + + if (browserEvent.wheelDeltaX || browserEvent.wheelDeltaY) { + deltaX = -browserEvent.wheelDeltaX / 120 * scrollDelta / 3; + deltaY = -browserEvent.wheelDeltaY / 120 * scrollDelta / 3; + if (horizScroller) { + newScrollLeft = horizScroller.scrollByDeltaX(deltaX); + } + if (vertScroller) { + newScrollTop = vertScroller.scrollByDeltaY(deltaY); + } + } else { + + if (browserEvent.axis && browserEvent.axis === 1) { + if (horizScroller) { + deltaX = -(scrollDelta * e.getWheelDelta()) / 3; + newScrollLeft = horizScroller.scrollByDeltaX(deltaX); + } + } else { + if (vertScroller) { + + deltaY = -(scrollDelta * e.getWheelDelta() / 3); + newScrollTop = vertScroller.scrollByDeltaY(deltaY); + } + } } + + - var dropNode = data.node || (dd.getTreeNode ? dd.getTreeNode(data, targetNode, point, e) : null); - return this.processDrop(targetNode, data, point, dd, e, dropNode); + if ((deltaX !== 0 && newScrollLeft !== origScrollLeft) || + (deltaY !== 0 && newScrollTop !== origScrollTop)) { + e.stopEvent(); + } }, + - onContainerDrop : function(dd, e, data){ - if (this.allowContainerDrop && this.isValidDropPoint({ ddel: this.tree.getRootNode().ui.elNode, node: this.tree.getRootNode() }, "append", dd, e, data)) { - var targetNode = this.tree.getRootNode(); - targetNode.ui.startDrop(); - var dropNode = data.node || (dd.getTreeNode ? dd.getTreeNode(data, targetNode, 'append', e) : null); - return this.processDrop(targetNode, data, 'append', dd, e, dropNode); + onViewRefresh: function() { + if (Ext.isIE) { + this.syncCellHeight(); + } + this.determineScrollbars(); + if (this.invalidateScrollerOnRefresh) { + this.invalidateScroller(); + } + }, + + onViewItemUpdate: function(record, index, tr) { + if (Ext.isIE) { + this.syncCellHeight([tr]); } - return false; }, + - processDrop: function(target, data, point, dd, e, dropNode){ - var dropEvent = { - tree : this.tree, - target: target, - data: data, - point: point, - source: dd, - rawEvent: e, - dropNode: dropNode, - cancel: !dropNode, - dropStatus: false - }; - var retval = this.tree.fireEvent("beforenodedrop", dropEvent); - if(retval === false || dropEvent.cancel === true || !dropEvent.dropNode){ - target.ui.endDrop(); - return dropEvent.dropStatus; - } - target = dropEvent.target; - if(point == 'append' && !target.isExpanded()){ - target.expand(false, null, function(){ - this.completeDrop(dropEvent); - }.createDelegate(this)); - }else{ - this.completeDrop(dropEvent); + syncCellHeight: function(trs) { + var me = this, + i = 0, + tds, + j, tdsLn, + tr, td, + trsLn, + rowHeights = [], + cellHeights, + cellClsSelector = ('.' + Ext.baseCSSPrefix + 'grid-cell'); + + trs = trs || me.view.getNodes(); + + trsLn = trs.length; + + for (; i < trsLn; i++) { + tr = trs[i]; + tds = Ext.fly(tr).query(cellClsSelector); + tdsLn = tds.length; + cellHeights = []; + for (j = 0; j < tdsLn; j++) { + td = tds[j]; + cellHeights.push(td.clientHeight); + } + rowHeights.push(Ext.Array.max(cellHeights)); + } + + + for (i = 0; i < trsLn; i++) { + tr = trs[i]; + tdsLn = tr.childNodes.length; + for (j = 0; j < tdsLn; j++) { + td = Ext.fly(tr.childNodes[j]); + if (rowHeights[i]) { + if (td.is(cellClsSelector)) { + td.setHeight(rowHeights[i]); + } else { + td.down(cellClsSelector).setHeight(rowHeights[i]); + } + } + + } } - return true; }, - completeDrop : function(de){ - var ns = de.dropNode, p = de.point, t = de.target; - if(!Ext.isArray(ns)){ - ns = [ns]; - } - var n; - for(var i = 0, len = ns.length; i < len; i++){ - n = ns[i]; - if(p == "above"){ - t.parentNode.insertBefore(n, t); - }else if(p == "below"){ - t.parentNode.insertBefore(n, t.nextSibling); - }else{ - t.appendChild(n); - } + setScrollTop: function(top) { + var me = this, + rootCmp = me.getScrollerOwner(), + verticalScroller = me.getVerticalScroller(); + + rootCmp.virtualScrollTop = top; + if (verticalScroller) { + verticalScroller.setScrollTop(top); } - n.ui.focus(); - if(Ext.enableFx && this.tree.hlDrop){ - n.ui.highlight(); + + }, + + getScrollerOwner: function() { + var rootCmp = this; + if (!this.scrollerOwner) { + rootCmp = this.up('[scrollerOwner]'); } - t.ui.endDrop(); - this.tree.fireEvent("nodedrop", de); + return rootCmp; }, - afterNodeMoved : function(dd, data, e, targetNode, dropNode){ - if(Ext.enableFx && this.tree.hlDrop){ - dropNode.ui.focus(); - dropNode.ui.highlight(); + scrollByDeltaY: function(deltaY) { + var rootCmp = this.getScrollerOwner(), + scrollerRight; + scrollerRight = rootCmp.down('gridscroller[dock=' + this.verticalScrollDock + ']'); + if (scrollerRight) { + scrollerRight.scrollByDeltaY(deltaY); } - this.tree.fireEvent("nodedrop", this.tree, targetNode, data, dd, e); }, + - getTree : function(){ - return this.tree; + scrollByDeltaX: function(deltaX) { + this.horizontalScroller.scrollByDeltaX(deltaX); }, - removeDropIndicators : function(n){ - if(n && n.ddel){ - var el = n.ddel; - Ext.fly(el).removeClass([ - "x-tree-drag-insert-above", - "x-tree-drag-insert-below", - "x-tree-drag-append"]); - this.lastInsertClass = "_noclass"; + getLhsMarker: function() { + var me = this; + + if (!me.lhsMarker) { + me.lhsMarker = Ext.core.DomHelper.append(me.el, { + cls: Ext.baseCSSPrefix + 'grid-resize-marker' + }, true); } + return me.lhsMarker; }, - beforeDragDrop : function(target, e, id){ - this.cancelExpand(); - return true; + getRhsMarker: function() { + var me = this; + + if (!me.rhsMarker) { + me.rhsMarker = Ext.core.DomHelper.append(me.el, { + cls: Ext.baseCSSPrefix + 'grid-resize-marker' + }, true); + } + return me.rhsMarker; }, - afterRepair : function(data){ - if(data && Ext.enableFx){ - data.node.ui.highlight(); + getSelectionModel: function(){ + if (!this.selModel) { + this.selModel = {}; } - this.hideProxy(); - } -}); -} -if(Ext.dd.DragZone){ -Ext.tree.TreeDragZone = function(tree, config){ - Ext.tree.TreeDragZone.superclass.constructor.call(this, tree.innerCt, config); - - this.tree = tree; -}; + var mode = 'SINGLE', + type; + if (this.simpleSelect) { + mode = 'SIMPLE'; + } else if (this.multiSelect) { + mode = 'MULTI'; + } -Ext.extend(Ext.tree.TreeDragZone, Ext.dd.DragZone, { - - ddGroup : "TreeDD", + Ext.applyIf(this.selModel, { + allowDeselect: this.allowDeselect, + mode: mode + }); - - onBeforeDrag : function(data, e){ - var n = data.node; - return n && n.draggable && !n.disabled; - }, + if (!this.selModel.events) { + type = this.selModel.selType || this.selType; + this.selModel = Ext.create('selection.' + type, this.selModel); + } - - onInitDrag : function(e){ - var data = this.dragData; - this.tree.getSelectionModel().select(data.node); - this.tree.eventModel.disable(); - this.proxy.update(""); - data.node.ui.appendDDGhost(this.proxy.ghost.dom); - this.tree.fireEvent("startdrag", this.tree, data.node, e); + if (!this.selModel.hasRelaySetup) { + this.relayEvents(this.selModel, ['selectionchange', 'select', 'deselect']); + this.selModel.hasRelaySetup = true; + } + + + + if (this.disableSelection) { + this.selModel.locked = true; + } + return this.selModel; }, - - getRepairXY : function(e, data){ - return data.node.ui.getDDRepairXY(); + onVerticalScroll: function(event, target) { + var owner = this.getScrollerOwner(), + items = owner.query('tableview'), + i = 0, + len = items.length; + + for (; i < len; i++) { + items[i].el.dom.scrollTop = target.scrollTop; + } }, - - onEndDrag : function(data, e){ - this.tree.eventModel.enable.defer(100, this.tree.eventModel); - this.tree.fireEvent("enddrag", this.tree, data.node, e); + onHorizontalScroll: function(event, target) { + var owner = this.getScrollerOwner(), + items = owner.query('tableview'), + i = 0, + len = items.length, + center, + centerEl, + centerScrollWidth, + centerClientWidth, + width; + + center = items[1] || items[0]; + centerEl = center.el.dom; + centerScrollWidth = centerEl.scrollWidth; + centerClientWidth = centerEl.offsetWidth; + width = this.horizontalScroller.getWidth(); + + centerEl.scrollLeft = target.scrollLeft; + this.headerCt.el.dom.scrollLeft = target.scrollLeft; }, - onValidDrop : function(dd, e, id){ - this.tree.fireEvent("dragdrop", this.tree, this.dragData.node, dd, e); - this.hideProxy(); + onStoreLoad: Ext.emptyFn, + + getEditorParent: function() { + return this.body; }, - - beforeInvalidDrop : function(e, id){ - - var sm = this.tree.getSelectionModel(); - sm.clearSelections(); - sm.select(this.dragData.node); + bindStore: function(store) { + var me = this; + me.store = store; + me.getView().bindStore(store); }, - - - afterRepair : function(){ - if (Ext.enableFx && this.tree.hlDrop) { - Ext.Element.fly(this.dragData.ddel).highlight(this.hlColor || "c3daf9"); + + reconfigure: function(store, columns) { + var me = this; + + if (me.lockable) { + me.reconfigureLockable(store, columns); + return; } - this.dragging = false; + + if (columns) { + me.headerCt.removeAll(); + me.headerCt.add(columns); + } + if (store) { + store = Ext.StoreManager.lookup(store); + me.bindStore(store); + } else { + me.getView().refresh(); + } + }, + + afterComponentLayout: function() { + this.callParent(arguments); + this.determineScrollbars(); + this.invalidateScroller(); } }); -} -Ext.tree.TreeEditor = function(tree, fc, config){ - fc = fc || {}; - var field = fc.events ? fc : new Ext.form.TextField(fc); - - Ext.tree.TreeEditor.superclass.constructor.call(this, field, config); - this.tree = tree; +Ext.define('Ext.view.Table', { + extend: 'Ext.view.View', + alias: 'widget.tableview', + uses: [ + 'Ext.view.TableChunker', + 'Ext.util.DelayedTask', + 'Ext.util.MixedCollection' + ], - if(!tree.rendered){ - tree.on('render', this.initEditor, this); - }else{ - this.initEditor(tree); - } -}; + cls: Ext.baseCSSPrefix + 'grid-view', -Ext.extend(Ext.tree.TreeEditor, Ext.Editor, { - - alignment: "l-l", - - autoSize: false, - - hideEl : false, - - cls: "x-small-editor x-tree-editor", - shim:false, + itemSelector: '.' + Ext.baseCSSPrefix + 'grid-row', - shadow:"frame", + cellSelector: '.' + Ext.baseCSSPrefix + 'grid-cell', + + selectedItemCls: Ext.baseCSSPrefix + 'grid-row-selected', + selectedCellCls: Ext.baseCSSPrefix + 'grid-cell-selected', + focusedItemCls: Ext.baseCSSPrefix + 'grid-row-focused', + overItemCls: Ext.baseCSSPrefix + 'grid-row-over', + altRowCls: Ext.baseCSSPrefix + 'grid-row-alt', + rowClsRe: /(?:^|\s*)grid-row-(first|last|alt)(?:\s+|$)/g, + cellRe: new RegExp('x-grid-cell-([^\\s]+) ', ''), + - maxWidth: 250, + trackOver: true, + - editDelay : 350, + getRowClass: null, - initEditor : function(tree){ - tree.on({ - scope : this, - beforeclick: this.beforeNodeClick, - dblclick : this.onNodeDblClick + initComponent: function() { + this.scrollState = {}; + this.selModel.view = this; + this.headerCt.view = this; + this.initFeatures(); + this.setNewTemplate(); + this.callParent(); + this.mon(this.store, { + load: this.onStoreLoad, + scope: this }); + + + + + + + + - this.on({ - scope : this, - complete : this.updateNode, - beforestartedit: this.fitToTree, - specialkey : this.onSpecialKey - }); - this.on('startedit', this.bindScroll, this, {delay:10}); - }, - - - fitToTree : function(ed, el){ - var td = this.tree.getTreeEl().dom, nd = el.dom; - if(td.scrollLeft > nd.offsetLeft){ - td.scrollLeft = nd.offsetLeft; - } - var w = Math.min( - this.maxWidth, - (td.clientWidth > 20 ? td.clientWidth : td.offsetWidth) - Math.max(0, nd.offsetLeft-td.scrollLeft) - 5); - this.setSize(w, ''); }, - triggerEdit : function(node, defer){ - this.completeEdit(); - if(node.attributes.editable !== false){ - - this.editNode = node; - if(this.tree.autoScroll){ - Ext.fly(node.ui.getEl()).scrollIntoView(this.tree.body); - } - var value = node.text || ''; - if (!Ext.isGecko && Ext.isEmpty(node.text)){ - node.setText(' '); + onStoreLoad: function(){ + if (this.invalidateScrollerOnRefresh) { + if (Ext.isGecko) { + if (!this.scrollToTopTask) { + this.scrollToTopTask = Ext.create('Ext.util.DelayedTask', this.scrollToTop, this); + } + this.scrollToTopTask.delay(1); + } else { + this.scrollToTop(); } - this.autoEditTimer = this.startEdit.defer(this.editDelay, this, [node.ui.textNode, value]); - return false; } }, - bindScroll : function(){ - this.tree.getTreeEl().on('scroll', this.cancelEdit, this); - }, - + scrollToTop: Ext.emptyFn, - beforeNodeClick : function(node, e){ - clearTimeout(this.autoEditTimer); - if(this.tree.getSelectionModel().isSelected(node)){ - e.stopEvent(); - return this.triggerEdit(node); - } - }, - - onNodeDblClick : function(node, e){ - clearTimeout(this.autoEditTimer); + + getGridColumns: function() { + return this.headerCt.getGridColumns(); }, - - updateNode : function(ed, value){ - this.tree.getTreeEl().un('scroll', this.cancelEdit, this); - this.editNode.setText(value); + + getHeaderAtIndex: function(index) { + return this.headerCt.getHeaderAtIndex(index); }, - - onHide : function(){ - Ext.tree.TreeEditor.superclass.onHide.call(this); - if(this.editNode){ - this.editNode.ui.focus.defer(50, this.editNode.ui); - } + + getCell: function(record, column) { + var row = this.getNode(record); + return Ext.fly(row).down(column.getCellSelector()); }, - onSpecialKey : function(field, e){ - var k = e.getKey(); - if(k == e.ESC){ - e.stopEvent(); - this.cancelEdit(); - }else if(k == e.ENTER && !e.hasModifier()){ - e.stopEvent(); - this.completeEdit(); + getFeature: function(id) { + var features = this.featuresMC; + if (features) { + return features.get(id); } }, + - onDestroy : function(){ - clearTimeout(this.autoEditTimer); - Ext.tree.TreeEditor.superclass.onDestroy.call(this); - var tree = this.tree; - tree.un('beforeclick', this.beforeNodeClick, this); - tree.un('dblclick', this.onNodeDblClick, this); - } -}); - -var swfobject = function() { - - var UNDEF = "undefined", - OBJECT = "object", - SHOCKWAVE_FLASH = "Shockwave Flash", - SHOCKWAVE_FLASH_AX = "ShockwaveFlash.ShockwaveFlash", - FLASH_MIME_TYPE = "application/x-shockwave-flash", - EXPRESS_INSTALL_ID = "SWFObjectExprInst", - ON_READY_STATE_CHANGE = "onreadystatechange", - - win = window, - doc = document, - nav = navigator, - - plugin = false, - domLoadFnArr = [main], - regObjArr = [], - objIdArr = [], - listenersArr = [], - storedAltContent, - storedAltContentId, - storedCallbackFn, - storedCallbackObj, - isDomLoaded = false, - isExpressInstallActive = false, - dynamicStylesheet, - dynamicStylesheetMedia, - autoHideShow = true, - - - ua = function() { - var w3cdom = typeof doc.getElementById != UNDEF && typeof doc.getElementsByTagName != UNDEF && typeof doc.createElement != UNDEF, - u = nav.userAgent.toLowerCase(), - p = nav.platform.toLowerCase(), - windows = p ? (/win/).test(p) : /win/.test(u), - mac = p ? (/mac/).test(p) : /mac/.test(u), - webkit = /webkit/.test(u) ? parseFloat(u.replace(/^.*webkit\/(\d+(\.\d+)?).*$/, "$1")) : false, - ie = !+"\v1", - playerVersion = [0,0,0], - d = null; - if (typeof nav.plugins != UNDEF && typeof nav.plugins[SHOCKWAVE_FLASH] == OBJECT) { - d = nav.plugins[SHOCKWAVE_FLASH].description; - if (d && !(typeof nav.mimeTypes != UNDEF && nav.mimeTypes[FLASH_MIME_TYPE] && !nav.mimeTypes[FLASH_MIME_TYPE].enabledPlugin)) { - plugin = true; - ie = false; - d = d.replace(/^.*\s+(\S+\s+\S+$)/, "$1"); - playerVersion[0] = parseInt(d.replace(/^(.*)\..*$/, "$1"), 10); - playerVersion[1] = parseInt(d.replace(/^.*\.(.*)\s.*$/, "$1"), 10); - playerVersion[2] = /[a-zA-Z]/.test(d) ? parseInt(d.replace(/^.*[a-zA-Z]+(.*)$/, "$1"), 10) : 0; - } - } - else if (typeof win.ActiveXObject != UNDEF) { - try { - var a = new ActiveXObject(SHOCKWAVE_FLASH_AX); - if (a) { - d = a.GetVariable("$version"); - if (d) { - ie = true; - d = d.split(" ")[1].split(","); - playerVersion = [parseInt(d[0], 10), parseInt(d[1], 10), parseInt(d[2], 10)]; - } - } + initFeatures: function() { + this.features = this.features || []; + var features = this.features, + ln = features.length, + i = 0; + + this.featuresMC = Ext.create('Ext.util.MixedCollection'); + for (; i < ln; i++) { + + if (!features[i].isFeature) { + features[i] = Ext.create('feature.'+features[i].ftype, features[i]); } - catch(e) {} + + features[i].view = this; + this.featuresMC.add(features[i]); } - return { w3:w3cdom, pv:playerVersion, wk:webkit, ie:ie, win:windows, mac:mac }; - }(), + }, + - - onDomLoad = function() { - if (!ua.w3) { return; } - if ((typeof doc.readyState != UNDEF && doc.readyState == "complete") || (typeof doc.readyState == UNDEF && (doc.getElementsByTagName("body")[0] || doc.body))) { - callDomLoadFunctions(); - } - if (!isDomLoaded) { - if (typeof doc.addEventListener != UNDEF) { - doc.addEventListener("DOMContentLoaded", callDomLoadFunctions, false); - } - if (ua.ie && ua.win) { - doc.attachEvent(ON_READY_STATE_CHANGE, function() { - if (doc.readyState == "complete") { - doc.detachEvent(ON_READY_STATE_CHANGE, arguments.callee); - callDomLoadFunctions(); - } - }); - if (win == top) { - (function(){ - if (isDomLoaded) { return; } - try { - doc.documentElement.doScroll("left"); - } - catch(e) { - setTimeout(arguments.callee, 0); - return; - } - callDomLoadFunctions(); - })(); - } - } - if (ua.wk) { - (function(){ - if (isDomLoaded) { return; } - if (!(/loaded|complete/).test(doc.readyState)) { - setTimeout(arguments.callee, 0); - return; - } - callDomLoadFunctions(); - })(); + attachEventsForFeatures: function() { + var features = this.features, + ln = features.length, + i = 0; + + for (; i < ln; i++) { + if (features[i].isFeature) { + features[i].attachEvents(); } - addLoadEvent(callDomLoadFunctions); - } - }(); - - function callDomLoadFunctions() { - if (isDomLoaded) { return; } - try { - var t = doc.getElementsByTagName("body")[0].appendChild(createElement("span")); - t.parentNode.removeChild(t); - } - catch (e) { return; } - isDomLoaded = true; - var dl = domLoadFnArr.length; - for (var i = 0; i < dl; i++) { - domLoadFnArr[i](); - } - } - - function addDomLoadEvent(fn) { - if (isDomLoaded) { - fn(); - } - else { - domLoadFnArr[domLoadFnArr.length] = fn; - } - } - - - function addLoadEvent(fn) { - if (typeof win.addEventListener != UNDEF) { - win.addEventListener("load", fn, false); - } - else if (typeof doc.addEventListener != UNDEF) { - doc.addEventListener("load", fn, false); - } - else if (typeof win.attachEvent != UNDEF) { - addListener(win, "onload", fn); - } - else if (typeof win.onload == "function") { - var fnOld = win.onload; - win.onload = function() { - fnOld(); - fn(); - }; - } - else { - win.onload = fn; } - } + }, + + afterRender: function() { + this.callParent(); + this.mon(this.el, { + scroll: this.fireBodyScroll, + scope: this + }); + this.attachEventsForFeatures(); + }, + + fireBodyScroll: function(e, t) { + this.fireEvent('bodyscroll', e, t); + }, + - function main() { - if (plugin) { - testPlayerVersion(); - } - else { - matchVersions(); + prepareData: function(data, idx, record) { + var orig = this.headerCt.prepareData(data, idx, record, this), + features = this.features, + ln = features.length, + i = 0, + node, feature; + + for (; i < ln; i++) { + feature = features[i]; + if (feature.isFeature) { + Ext.apply(orig, feature.getAdditionalData(data, idx, record, orig, this)); + } } - } - + + return orig; + }, + - function testPlayerVersion() { - var b = doc.getElementsByTagName("body")[0]; - var o = createElement(OBJECT); - o.setAttribute("type", FLASH_MIME_TYPE); - var t = b.appendChild(o); - if (t) { - var counter = 0; - (function(){ - if (typeof t.GetVariable != UNDEF) { - var d = t.GetVariable("$version"); - if (d) { - d = d.split(" ")[1].split(","); - ua.pv = [parseInt(d[0], 10), parseInt(d[1], 10), parseInt(d[2], 10)]; - } - } - else if (counter < 10) { - counter++; - setTimeout(arguments.callee, 10); - return; + collectData: function(records, startIndex) { + var preppedRecords = this.callParent(arguments), + headerCt = this.headerCt, + fullWidth = headerCt.getFullWidth(), + features = this.features, + ln = features.length, + o = { + rows: preppedRecords, + fullWidth: fullWidth + }, + i = 0, + feature, + j = 0, + jln, + rowParams; + + jln = preppedRecords.length; + + + if (this.getRowClass) { + for (; j < jln; j++) { + rowParams = {}; + preppedRecords[j]['rowCls'] = this.getRowClass(records[j], j, rowParams, this.store); + if (rowParams.alt) { + Ext.Error.raise("The getRowClass alt property is no longer supported."); } - b.removeChild(o); - t = null; - matchVersions(); - })(); - } - else { - matchVersions(); - } - } - - - function matchVersions() { - var rl = regObjArr.length; - if (rl > 0) { - for (var i = 0; i < rl; i++) { - var id = regObjArr[i].id; - var cb = regObjArr[i].callbackFn; - var cbObj = {success:false, id:id}; - if (ua.pv[0] > 0) { - var obj = getElementById(id); - if (obj) { - if (hasPlayerVersion(regObjArr[i].swfVersion) && !(ua.wk && ua.wk < 312)) { - setVisibility(id, true); - if (cb) { - cbObj.success = true; - cbObj.ref = getObjectById(id); - cb(cbObj); - } - } - else if (regObjArr[i].expressInstall && canExpressInstall()) { - var att = {}; - att.data = regObjArr[i].expressInstall; - att.width = obj.getAttribute("width") || "0"; - att.height = obj.getAttribute("height") || "0"; - if (obj.getAttribute("class")) { att.styleclass = obj.getAttribute("class"); } - if (obj.getAttribute("align")) { att.align = obj.getAttribute("align"); } - - var par = {}; - var p = obj.getElementsByTagName("param"); - var pl = p.length; - for (var j = 0; j < pl; j++) { - if (p[j].getAttribute("name").toLowerCase() != "movie") { - par[p[j].getAttribute("name")] = p[j].getAttribute("value"); - } - } - showExpressInstall(att, par, id, cb); - } - else { - displayAltContent(obj); - if (cb) { cb(cbObj); } - } - } + if (rowParams.tstyle) { + Ext.Error.raise("The getRowClass tstyle property is no longer supported."); } - else { - setVisibility(id, true); - if (cb) { - var o = getObjectById(id); - if (o && typeof o.SetVariable != UNDEF) { - cbObj.success = true; - cbObj.ref = o; - } - cb(cbObj); - } + if (rowParams.cells) { + Ext.Error.raise("The getRowClass cells property is no longer supported."); + } + if (rowParams.body) { + Ext.Error.raise("The getRowClass body property is no longer supported. Use the getAdditionalData method of the rowbody feature."); + } + if (rowParams.bodyStyle) { + Ext.Error.raise("The getRowClass bodyStyle property is no longer supported."); + } + if (rowParams.cols) { + Ext.Error.raise("The getRowClass cols property is no longer supported."); } } } - } - - function getObjectById(objectIdStr) { - var r = null; - var o = getElementById(objectIdStr); - if (o && o.nodeName == "OBJECT") { - if (typeof o.SetVariable != UNDEF) { - r = o; - } - else { - var n = o.getElementsByTagName(OBJECT)[0]; - if (n) { - r = n; - } + + + for (; i < ln; i++) { + feature = features[i]; + if (feature.isFeature && feature.collectData && !feature.disabled) { + o = feature.collectData(records, preppedRecords, startIndex, fullWidth, o); + break; } } - return r; - } - - - function canExpressInstall() { - return !isExpressInstallActive && hasPlayerVersion("6.0.65") && (ua.win || ua.mac) && !(ua.wk && ua.wk < 312); - } + return o; + }, + - function showExpressInstall(att, par, replaceElemIdStr, callbackFn) { - isExpressInstallActive = true; - storedCallbackFn = callbackFn || null; - storedCallbackObj = {success:false, id:replaceElemIdStr}; - var obj = getElementById(replaceElemIdStr); - if (obj) { - if (obj.nodeName == "OBJECT") { - storedAltContent = abstractAltContent(obj); - storedAltContentId = null; - } - else { - storedAltContent = obj; - storedAltContentId = replaceElemIdStr; - } - att.id = EXPRESS_INSTALL_ID; - if (typeof att.width == UNDEF || (!(/%$/).test(att.width) && parseInt(att.width, 10) < 310)) { - att.width = "310"; - } + onHeaderResize: function(header, w, suppressFocus) { + var el = this.el; + if (el) { + this.saveScrollState(); - if (typeof att.height == UNDEF || (!(/%$/).test(att.height) && parseInt(att.height, 10) < 137)) { - att.height = "137"; - } - doc.title = doc.title.slice(0, 47) + " - Flash Player Installation"; - var pt = ua.ie && ua.win ? "ActiveX" : "PlugIn", - fv = "MMredirectURL=" + win.location.toString().replace(/&/g,"%26") + "&MMplayerType=" + pt + "&MMdoctitle=" + doc.title; - if (typeof par.flashvars != UNDEF) { - par.flashvars += "&" + fv; - } - else { - par.flashvars = fv; - } - if (ua.ie && ua.win && obj.readyState != 4) { - var newObj = createElement("div"); - replaceElemIdStr += "SWFObjectNew"; - newObj.setAttribute("id", replaceElemIdStr); - obj.parentNode.insertBefore(newObj, obj); - obj.style.display = "none"; - (function(){ - if (obj.readyState == 4) { - obj.parentNode.removeChild(obj); - } - else { - setTimeout(arguments.callee, 10); - } - })(); + el.select('.' + Ext.baseCSSPrefix + 'grid-col-resizer-'+header.id).setWidth(w); + el.select('.' + Ext.baseCSSPrefix + 'grid-table-resizer').setWidth(this.headerCt.getFullWidth()); + this.restoreScrollState(); + this.setNewTemplate(); + if (!suppressFocus) { + this.el.focus(); } - createSWF(att, par, replaceElemIdStr); - } - } - - - function displayAltContent(obj) { - if (ua.ie && ua.win && obj.readyState != 4) { - - - var el = createElement("div"); - obj.parentNode.insertBefore(el, obj); - el.parentNode.replaceChild(abstractAltContent(obj), el); - obj.style.display = "none"; - (function(){ - if (obj.readyState == 4) { - obj.parentNode.removeChild(obj); - } - else { - setTimeout(arguments.callee, 10); - } - })(); - } - else { - obj.parentNode.replaceChild(abstractAltContent(obj), obj); } - } + }, - function abstractAltContent(obj) { - var ac = createElement("div"); - if (ua.win && ua.ie) { - ac.innerHTML = obj.innerHTML; - } - else { - var nestedObj = obj.getElementsByTagName(OBJECT)[0]; - if (nestedObj) { - var c = nestedObj.childNodes; - if (c) { - var cl = c.length; - for (var i = 0; i < cl; i++) { - if (!(c[i].nodeType == 1 && c[i].nodeName == "PARAM") && !(c[i].nodeType == 8)) { - ac.appendChild(c[i].cloneNode(true)); - } - } - } - } - } - return ac; - } - - function createSWF(attObj, parObj, id) { - var r, el = getElementById(id); - if (ua.wk && ua.wk < 312) { return r; } - if (el) { - if (typeof attObj.id == UNDEF) { - attObj.id = id; - } - if (ua.ie && ua.win) { - var att = ""; - for (var i in attObj) { - if (attObj[i] != Object.prototype[i]) { - if (i.toLowerCase() == "data") { - parObj.movie = attObj[i]; - } - else if (i.toLowerCase() == "styleclass") { - att += ' class="' + attObj[i] + '"'; - } - else if (i.toLowerCase() != "classid") { - att += ' ' + i + '="' + attObj[i] + '"'; - } - } - } - var par = ""; - for (var j in parObj) { - if (parObj[j] != Object.prototype[j]) { - par += ''; - } - } - el.outerHTML = '' + par + ''; - objIdArr[objIdArr.length] = attObj.id; - r = getElementById(attObj.id); - } - else { - var o = createElement(OBJECT); - o.setAttribute("type", FLASH_MIME_TYPE); - for (var m in attObj) { - if (attObj[m] != Object.prototype[m]) { - if (m.toLowerCase() == "styleclass") { - o.setAttribute("class", attObj[m]); - } - else if (m.toLowerCase() != "classid") { - o.setAttribute(m, attObj[m]); - } - } - } - for (var n in parObj) { - if (parObj[n] != Object.prototype[n] && n.toLowerCase() != "movie") { - createObjParam(o, n, parObj[n]); - } - } - el.parentNode.replaceChild(o, el); - r = o; - } + onHeaderShow: function(headerCt, header, suppressFocus) { + + if (header.oldWidth) { + this.onHeaderResize(header, header.oldWidth, suppressFocus); + delete header.oldWidth; + + + + } else if (header.width && !header.flex) { + this.onHeaderResize(header, header.width, suppressFocus); } - return r; - } + this.setNewTemplate(); + }, + - function createObjParam(el, pName, pValue) { - var p = createElement("param"); - p.setAttribute("name", pName); - p.setAttribute("value", pValue); - el.appendChild(p); - } + onHeaderHide: function(headerCt, header, suppressFocus) { + this.onHeaderResize(header, 0, suppressFocus); + }, + + setNewTemplate: function() { + var columns = this.headerCt.getColumnsForTpl(true); + this.tpl = this.getTableChunker().getTableTpl({ + columns: columns, + features: this.features + }); + }, + - function removeSWF(id) { - var obj = getElementById(id); - if (obj && obj.nodeName == "OBJECT") { - if (ua.ie && ua.win) { - obj.style.display = "none"; - (function(){ - if (obj.readyState == 4) { - removeObjectInIE(id); - } - else { - setTimeout(arguments.callee, 10); - } - })(); - } - else { - obj.parentNode.removeChild(obj); - } - } - } + getTableChunker: function() { + return this.chunker || Ext.view.TableChunker; + }, + - function removeObjectInIE(id) { - var obj = getElementById(id); - if (obj) { - for (var i in obj) { - if (typeof obj[i] == "function") { - obj[i] = null; - } - } - obj.parentNode.removeChild(obj); + addRowCls: function(rowInfo, cls) { + var row = this.getNode(rowInfo); + if (row) { + Ext.fly(row).addCls(cls); } - } - + }, + - function getElementById(id) { - var el = null; - try { - el = doc.getElementById(id); + removeRowCls: function(rowInfo, cls) { + var row = this.getNode(rowInfo); + if (row) { + Ext.fly(row).removeCls(cls); } - catch (e) {} - return el; - } - - function createElement(el) { - return doc.createElement(el); - } - - - function addListener(target, eventType, fn) { - target.attachEvent(eventType, fn); - listenersArr[listenersArr.length] = [target, eventType, fn]; - } + }, + + onRowSelect : function(rowIdx) { + this.addRowCls(rowIdx, this.selectedItemCls); + }, + - function hasPlayerVersion(rv) { - var pv = ua.pv, v = rv.split("."); - v[0] = parseInt(v[0], 10); - v[1] = parseInt(v[1], 10) || 0; - v[2] = parseInt(v[2], 10) || 0; - return (pv[0] > v[0] || (pv[0] == v[0] && pv[1] > v[1]) || (pv[0] == v[0] && pv[1] == v[1] && pv[2] >= v[2])) ? true : false; - } + onRowDeselect : function(rowIdx) { + this.removeRowCls(rowIdx, this.selectedItemCls); + this.removeRowCls(rowIdx, this.focusedItemCls); + }, - - function createCSS(sel, decl, media, newStyle) { - if (ua.ie && ua.mac) { return; } - var h = doc.getElementsByTagName("head")[0]; - if (!h) { return; } - var m = (media && typeof media == "string") ? media : "screen"; - if (newStyle) { - dynamicStylesheet = null; - dynamicStylesheetMedia = null; + onCellSelect: function(position) { + var cell = this.getCellByPosition(position); + if (cell) { + cell.addCls(this.selectedCellCls); } - if (!dynamicStylesheet || dynamicStylesheetMedia != m) { - - var s = createElement("style"); - s.setAttribute("type", "text/css"); - s.setAttribute("media", m); - dynamicStylesheet = h.appendChild(s); - if (ua.ie && ua.win && typeof doc.styleSheets != UNDEF && doc.styleSheets.length > 0) { - dynamicStylesheet = doc.styleSheets[doc.styleSheets.length - 1]; - } - dynamicStylesheetMedia = m; + }, + + onCellDeselect: function(position) { + var cell = this.getCellByPosition(position); + if (cell) { + cell.removeCls(this.selectedCellCls); } - if (ua.ie && ua.win) { - if (dynamicStylesheet && typeof dynamicStylesheet.addRule == OBJECT) { - dynamicStylesheet.addRule(sel, decl); - } - } - else { - if (dynamicStylesheet && typeof doc.createTextNode != UNDEF) { - dynamicStylesheet.appendChild(doc.createTextNode(sel + " {" + decl + "}")); - } - } - } + }, - function setVisibility(id, isVisible) { - if (!autoHideShow) { return; } - var v = isVisible ? "visible" : "hidden"; - if (isDomLoaded && getElementById(id)) { - getElementById(id).style.visibility = v; - } - else { - createCSS("#" + id, "visibility:" + v); + onCellFocus: function(position) { + + this.focusCell(position); + }, + + getCellByPosition: function(position) { + var row = position.row, + column = position.column, + store = this.store, + node = this.getNode(row), + header = this.headerCt.getHeaderAtIndex(column), + cellSelector, + cell = false; + + if (header) { + cellSelector = header.getCellSelector(); + cell = Ext.fly(node).down(cellSelector); } - } + return cell; + }, - function urlEncodeIfNecessary(s) { - var regex = /[\\\"<>\.;]/; - var hasBadChars = regex.exec(s) != null; - return hasBadChars && typeof encodeURIComponent != UNDEF ? encodeURIComponent(s) : s; - } - - var cleanup = function() { - if (ua.ie && ua.win) { - window.attachEvent("onunload", function() { - - var ll = listenersArr.length; - for (var i = 0; i < ll; i++) { - listenersArr[i][0].detachEvent(listenersArr[i][1], listenersArr[i][2]); - } - - var il = objIdArr.length; - for (var j = 0; j < il; j++) { - removeSWF(objIdArr[j]); - } - - for (var k in ua) { - ua[k] = null; - } - ua = null; - for (var l in swfobject) { - swfobject[l] = null; - } - swfobject = null; - }); + onRowFocus: function(rowIdx, highlight, supressFocus) { + var row = this.getNode(rowIdx); + + if (highlight) { + this.addRowCls(rowIdx, this.focusedItemCls); + if (!supressFocus) { + this.focusRow(rowIdx); + } + + } else { + this.removeRowCls(rowIdx, this.focusedItemCls); } - }(); + }, + - return { - - registerObject: function(objectIdStr, swfVersionStr, xiSwfUrlStr, callbackFn) { - if (ua.w3 && objectIdStr && swfVersionStr) { - var regObj = {}; - regObj.id = objectIdStr; - regObj.swfVersion = swfVersionStr; - regObj.expressInstall = xiSwfUrlStr; - regObj.callbackFn = callbackFn; - regObjArr[regObjArr.length] = regObj; - setVisibility(objectIdStr, false); - } - else if (callbackFn) { - callbackFn({success:false, id:objectIdStr}); - } - }, - - getObjectById: function(objectIdStr) { - if (ua.w3) { - return getObjectById(objectIdStr); - } - }, - - embedSWF: function(swfUrlStr, replaceElemIdStr, widthStr, heightStr, swfVersionStr, xiSwfUrlStr, flashvarsObj, parObj, attObj, callbackFn) { - var callbackObj = {success:false, id:replaceElemIdStr}; - if (ua.w3 && !(ua.wk && ua.wk < 312) && swfUrlStr && replaceElemIdStr && widthStr && heightStr && swfVersionStr) { - setVisibility(replaceElemIdStr, false); - addDomLoadEvent(function() { - widthStr += ""; - heightStr += ""; - var att = {}; - if (attObj && typeof attObj === OBJECT) { - for (var i in attObj) { - att[i] = attObj[i]; - } - } - att.data = swfUrlStr; - att.width = widthStr; - att.height = heightStr; - var par = {}; - if (parObj && typeof parObj === OBJECT) { - for (var j in parObj) { - par[j] = parObj[j]; - } - } - if (flashvarsObj && typeof flashvarsObj === OBJECT) { - for (var k in flashvarsObj) { - if (typeof par.flashvars != UNDEF) { - par.flashvars += "&" + k + "=" + flashvarsObj[k]; - } - else { - par.flashvars = k + "=" + flashvarsObj[k]; - } - } - } - if (hasPlayerVersion(swfVersionStr)) { - var obj = createSWF(att, par, replaceElemIdStr); - if (att.id == replaceElemIdStr) { - setVisibility(replaceElemIdStr, true); - } - callbackObj.success = true; - callbackObj.ref = obj; - } - else if (xiSwfUrlStr && canExpressInstall()) { - att.data = xiSwfUrlStr; - showExpressInstall(att, par, replaceElemIdStr, callbackFn); - return; - } - else { - setVisibility(replaceElemIdStr, true); - } - if (callbackFn) { callbackFn(callbackObj); } - }); - } - else if (callbackFn) { callbackFn(callbackObj); } - }, - - switchOffAutoHideShow: function() { - autoHideShow = false; - }, - - ua: ua, - - getFlashPlayerVersion: function() { - return { major:ua.pv[0], minor:ua.pv[1], release:ua.pv[2] }; - }, - - hasFlashPlayerVersion: hasPlayerVersion, - - createSWF: function(attObj, parObj, replaceElemIdStr) { - if (ua.w3) { - return createSWF(attObj, parObj, replaceElemIdStr); + focusRow: function(rowIdx) { + var row = this.getNode(rowIdx), + el = this.el, + adjustment = 0, + panel = this.ownerCt, + rowRegion, + elRegion, + record; + + if (row && this.el) { + elRegion = el.getRegion(); + rowRegion = Ext.fly(row).getRegion(); + + if (rowRegion.top < elRegion.top) { + adjustment = rowRegion.top - elRegion.top; + + } else if (rowRegion.bottom > elRegion.bottom) { + adjustment = rowRegion.bottom - elRegion.bottom; } - else { - return undefined; + record = this.getRecord(row); + rowIdx = this.store.indexOf(record); + + if (adjustment) { + + panel.scrollByDeltaY(adjustment); } - }, - - showExpressInstall: function(att, par, replaceElemIdStr, callbackFn) { - if (ua.w3 && canExpressInstall()) { - showExpressInstall(att, par, replaceElemIdStr, callbackFn); + this.fireEvent('rowfocus', record, row, rowIdx); + } + }, + + focusCell: function(position) { + var cell = this.getCellByPosition(position), + el = this.el, + adjustmentY = 0, + adjustmentX = 0, + elRegion = el.getRegion(), + panel = this.ownerCt, + cellRegion, + record; + + if (cell) { + cellRegion = cell.getRegion(); + + if (cellRegion.top < elRegion.top) { + adjustmentY = cellRegion.top - elRegion.top; + + } else if (cellRegion.bottom > elRegion.bottom) { + adjustmentY = cellRegion.bottom - elRegion.bottom; } - }, - - removeSWF: function(objElemIdStr) { - if (ua.w3) { - removeSWF(objElemIdStr); + + + if (cellRegion.left < elRegion.left) { + adjustmentX = cellRegion.left - elRegion.left; + + } else if (cellRegion.right > elRegion.right) { + adjustmentX = cellRegion.right - elRegion.right; } - }, - - createCSS: function(selStr, declStr, mediaStr, newStyleBoolean) { - if (ua.w3) { - createCSS(selStr, declStr, mediaStr, newStyleBoolean); + + if (adjustmentY) { + + panel.scrollByDeltaY(adjustmentY); } - }, - - addDomLoadEvent: addDomLoadEvent, - - addLoadEvent: addLoadEvent, - - getQueryParamValue: function(param) { - var q = doc.location.search || doc.location.hash; - if (q) { - if (/\?/.test(q)) { q = q.split("?")[1]; } - if (param == null) { - return urlEncodeIfNecessary(q); - } - var pairs = q.split("&"); - for (var i = 0; i < pairs.length; i++) { - if (pairs[i].substring(0, pairs[i].indexOf("=")) == param) { - return urlEncodeIfNecessary(pairs[i].substring((pairs[i].indexOf("=") + 1))); - } - } + if (adjustmentX) { + panel.scrollByDeltaX(adjustmentX); } - return ""; - }, - - - expressInstallCallback: function() { - if (isExpressInstallActive) { - var obj = getElementById(EXPRESS_INSTALL_ID); - if (obj && storedAltContent) { - obj.parentNode.replaceChild(storedAltContent, obj); - if (storedAltContentId) { - setVisibility(storedAltContentId, true); - if (ua.ie && ua.win) { storedAltContent.style.display = "block"; } - } - if (storedCallbackFn) { storedCallbackFn(storedCallbackObj); } - } - isExpressInstallActive = false; - } + el.focus(); + this.fireEvent('cellfocus', record, cell, position); } - }; -}(); + }, -Ext.FlashComponent = Ext.extend(Ext.BoxComponent, { - flashVersion : '9.0.115', + scrollByDelta: function(delta, dir) { + dir = dir || 'scrollTop'; + var elDom = this.el.dom; + elDom[dir] = (elDom[dir] += delta); + }, - - backgroundColor: '#ffffff', + onUpdate: function(ds, index) { + this.callParent(arguments); + }, - wmode: 'opaque', + saveScrollState: function() { + var dom = this.el.dom, + state = this.scrollState; - - flashVars: undefined, + state.left = dom.scrollLeft; + state.top = dom.scrollTop; + }, - flashParams: undefined, + restoreScrollState: function() { + var dom = this.el.dom, + state = this.scrollState, + headerEl = this.headerCt.el.dom; - - url: undefined, - swfId : undefined, - swfWidth: '100%', - swfHeight: '100%', + headerEl.scrollLeft = dom.scrollLeft = state.left; + dom.scrollTop = state.top; + }, - expressInstall: false, + refresh: function(firstPass) { + var me = this, + table; - initComponent : function(){ - Ext.FlashComponent.superclass.initComponent.call(this); + + me.setNewTemplate(); + + + + + if (me.rendered) { + table = me.el.child('table'); + if (table) { + table.removeAllListeners(); + } + } + + me.callParent(arguments); - this.addEvents( + + if (me.rendered) { - 'initialize' - ); + table = me.el.child('table'); + if (table) { + table.unselectable(); + } + + if (!firstPass) { + + me.el.focus(); + } + } }, - onRender : function(){ - Ext.FlashComponent.superclass.onRender.apply(this, arguments); + processItemEvent: function(type, record, row, rowIndex, e) { + var me = this, + cell = e.getTarget(me.cellSelector, row), + cellIndex = cell ? cell.cellIndex : -1, + map = me.statics().EventMap, + selModel = me.getSelectionModel(), + result; - var params = Ext.apply({ - allowScriptAccess: 'always', - bgcolor: this.backgroundColor, - wmode: this.wmode - }, this.flashParams), vars = Ext.apply({ - allowedDomain: document.location.hostname, - YUISwfId: this.getId(), - YUIBridgeCallback: 'Ext.FlashEventProxy.onEvent' - }, this.flashVars); + if (type == 'keydown' && !cell && selModel.getCurrentPosition) { + + cell = me.getCellByPosition(selModel.getCurrentPosition()); + if (cell) { + cell = cell.dom; + cellIndex = cell.cellIndex; + } + } - new swfobject.embedSWF(this.url, this.id, this.swfWidth, this.swfHeight, this.flashVersion, - this.expressInstall ? Ext.FlashComponent.EXPRESS_INSTALL_URL : undefined, vars, params); + result = me.fireEvent('uievent', type, me, cell, rowIndex, cellIndex, e); - this.swf = Ext.getDom(this.id); - this.el = Ext.get(this.swf); - }, + if (result === false || me.callParent(arguments) === false) { + return false; + } - getSwfId : function(){ - return this.swfId || (this.swfId = "extswf" + (++Ext.Component.AUTO_ID)); - }, + + if (type == 'mouseover' || type == 'mouseout') { + return true; + } - getId : function(){ - return this.id || (this.id = "extflashcmp" + (++Ext.Component.AUTO_ID)); + return !( + + (me['onBeforeCell' + map[type]](cell, cellIndex, record, row, rowIndex, e) === false) || + (me.fireEvent('beforecell' + type, me, cell, cellIndex, record, row, rowIndex, e) === false) || + (me['onCell' + map[type]](cell, cellIndex, record, row, rowIndex, e) === false) || + (me.fireEvent('cell' + type, me, cell, cellIndex, record, row, rowIndex, e) === false) + ); }, - onFlashEvent : function(e){ - switch(e.type){ - case "swfReady": - this.initSwf(); - return; - case "log": - return; - } - e.component = this; - this.fireEvent(e.type.toLowerCase().replace(/event$/, ''), e); - }, + processSpecialEvent: function(e) { + var me = this, + map = this.statics().EventMap, + features = this.features, + ln = features.length, + type = e.type, + i, feature, prefix, featureTarget, + beforeArgs, args, + panel = me.ownerCt; - initSwf : function(){ - this.onSwfReady(!!this.isInitialized); - this.isInitialized = true; - this.fireEvent('initialize', this); - }, + this.callParent(arguments); - beforeDestroy: function(){ - if(this.rendered){ - swfobject.removeSWF(this.swf.id); + if (type == 'mouseover' || type == 'mouseout') { + return; + } + + for (i = 0; i < ln; i++) { + feature = features[i]; + if (feature.hasFeatureEvent) { + featureTarget = e.getTarget(feature.eventSelector, me.getTargetEl()); + if (featureTarget) { + prefix = feature.eventPrefix; + + + beforeArgs = feature.getFireEventArgs('before' + prefix + type, me, featureTarget); + args = feature.getFireEventArgs(prefix + type, me, featureTarget); + + if ( + + (me.fireEvent.apply(me, beforeArgs) === false) || + + (panel.fireEvent.apply(panel, beforeArgs) === false) || + + (me.fireEvent.apply(me, args) === false) || + + (panel.fireEvent.apply(panel, args) === false) + ) { + return false; + } + } + } } - Ext.FlashComponent.superclass.beforeDestroy.call(this); + return true; }, - onSwfReady : Ext.emptyFn -}); + onCellMouseDown: Ext.emptyFn, + onCellMouseUp: Ext.emptyFn, + onCellClick: Ext.emptyFn, + onCellDblClick: Ext.emptyFn, + onCellContextMenu: Ext.emptyFn, + onCellKeyDown: Ext.emptyFn, + onBeforeCellMouseDown: Ext.emptyFn, + onBeforeCellMouseUp: Ext.emptyFn, + onBeforeCellClick: Ext.emptyFn, + onBeforeCellDblClick: Ext.emptyFn, + onBeforeCellContextMenu: Ext.emptyFn, + onBeforeCellKeyDown: Ext.emptyFn, + + expandToFit: function(header) { + var maxWidth = this.getMaxContentWidth(header); + delete header.flex; + header.setWidth(maxWidth); + }, -Ext.FlashComponent.EXPRESS_INSTALL_URL = 'http:/' + '/swfobject.googlecode.com/svn/trunk/swfobject/expressInstall.swf'; + + getMaxContentWidth: function(header) { + var cellSelector = header.getCellInnerSelector(), + cells = this.el.query(cellSelector), + i = 0, + ln = cells.length, + maxWidth = header.el.dom.scrollWidth, + scrollWidth; -Ext.reg('flash', Ext.FlashComponent); -Ext.FlashEventProxy = { - onEvent : function(id, e){ - var fp = Ext.getCmp(id); - if(fp){ - fp.onFlashEvent(e); - }else{ - arguments.callee.defer(10, this, [id, e]); + for (; i < ln; i++) { + scrollWidth = cells[i].scrollWidth; + if (scrollWidth > maxWidth) { + maxWidth = scrollWidth; + } } - } -}; + return maxWidth; + }, - Ext.chart.Chart = Ext.extend(Ext.FlashComponent, { - refreshBuffer: 100, + getPositionByEvent: function(e) { + var cellNode = e.getTarget(this.cellSelector), + rowNode = e.getTarget(this.itemSelector), + record = this.getRecord(rowNode), + header = this.getHeaderByCell(cellNode); - + return this.getPosition(record, header); + }, - - chartStyle: { - padding: 10, - animationEnabled: true, - font: { - name: 'Tahoma', - color: 0x444444, - size: 11 - }, - dataTip: { - padding: 5, - border: { - color: 0x99bbe8, - size:1 - }, - background: { - color: 0xDAE7F6, - alpha: .9 - }, - font: { - name: 'Tahoma', - color: 0x15428B, - size: 10, - bold: true + getHeaderByCell: function(cell) { + if (cell) { + var m = cell.className.match(this.cellRe); + if (m && m[1]) { + return Ext.getCmp(m[1]); } } + return false; }, + walkCells: function(pos, direction, e, preventWrap, verifierFn, scope) { + var row = pos.row, + column = pos.column, + rowCount = this.store.getCount(), + firstCol = this.getFirstVisibleColumnIndex(), + lastCol = this.getLastVisibleColumnIndex(), + newPos = {row: row, column: column}, + activeHeader = this.headerCt.getHeaderAtIndex(column); - - extraStyle: null, + + if (!activeHeader || activeHeader.hidden) { + return false; + } - - seriesStyles: null, + e = e || {}; + direction = direction.toLowerCase(); + switch (direction) { + case 'right': + + if (column === lastCol) { + + if (preventWrap || row === rowCount - 1) { + return false; + } + if (!e.ctrlKey) { + + newPos.row = row + 1; + newPos.column = firstCol; + } + + } else { + if (!e.ctrlKey) { + newPos.column = column + this.getRightGap(activeHeader); + } else { + newPos.column = lastCol; + } + } + break; - - disableCaching: Ext.isIE || Ext.isOpera, - disableCacheParam: '_dc', + case 'left': + + if (column === firstCol) { + + if (preventWrap || row === 0) { + return false; + } + if (!e.ctrlKey) { + + newPos.row = row - 1; + newPos.column = lastCol; + } + + } else { + if (!e.ctrlKey) { + newPos.column = column + this.getLeftGap(activeHeader); + } else { + newPos.column = firstCol; + } + } + break; - initComponent : function(){ - Ext.chart.Chart.superclass.initComponent.call(this); - if(!this.url){ - this.url = Ext.chart.Chart.CHART_URL; + case 'up': + + if (row === 0) { + return false; + + } else { + if (!e.ctrlKey) { + newPos.row = row - 1; + } else { + newPos.row = 0; + } + } + break; + + case 'down': + + if (row === rowCount - 1) { + return false; + + } else { + if (!e.ctrlKey) { + newPos.row = row + 1; + } else { + newPos.row = rowCount - 1; + } + } + break; } - if(this.disableCaching){ - this.url = Ext.urlAppend(this.url, String.format('{0}={1}', this.disableCacheParam, new Date().getTime())); + + if (verifierFn && verifierFn.call(scope || window, newPos) !== true) { + return false; + } else { + return newPos; } - this.addEvents( - 'itemmouseover', - 'itemmouseout', - 'itemclick', - 'itemdoubleclick', - 'itemdragstart', - 'itemdrag', - 'itemdragend', - - 'beforerefresh', - - 'refresh' - ); - this.store = Ext.StoreMgr.lookup(this.store); }, + getFirstVisibleColumnIndex: function() { + var headerCt = this.getHeaderCt(), + allColumns = headerCt.getGridColumns(), + visHeaders = Ext.ComponentQuery.query(':not([hidden])', allColumns), + firstHeader = visHeaders[0]; - - setStyle: function(name, value){ - this.swf.setStyle(name, Ext.encode(value)); - }, - - - setStyles: function(styles){ - this.swf.setStyles(Ext.encode(styles)); + return headerCt.getHeaderIndex(firstHeader); }, - - setSeriesStyles: function(styles){ - this.seriesStyles = styles; - var s = []; - Ext.each(styles, function(style){ - s.push(Ext.encode(style)); - }); - this.swf.setSeriesStyles(s); - }, + getLastVisibleColumnIndex: function() { + var headerCt = this.getHeaderCt(), + allColumns = headerCt.getGridColumns(), + visHeaders = Ext.ComponentQuery.query(':not([hidden])', allColumns), + lastHeader = visHeaders[visHeaders.length - 1]; - setCategoryNames : function(names){ - this.swf.setCategoryNames(names); + return headerCt.getHeaderIndex(lastHeader); }, - setLegendRenderer : function(fn, scope){ - var chart = this; - scope = scope || chart; - chart.removeFnProxy(chart.legendFnName); - chart.legendFnName = chart.createFnProxy(function(name){ - return fn.call(scope, name); - }); - chart.swf.setLegendLabelFunction(chart.legendFnName); + getHeaderCt: function() { + return this.headerCt; }, - setTipRenderer : function(fn, scope){ - var chart = this; - scope = scope || chart; - chart.removeFnProxy(chart.tipFnName); - chart.tipFnName = chart.createFnProxy(function(item, index, series){ - var record = chart.store.getAt(index); - return fn.call(scope, chart, record, index, series); - }); - chart.swf.setDataTipFunction(chart.tipFnName); - }, + getPosition: function(record, header) { + var me = this, + store = me.store, + gridCols = me.headerCt.getGridColumns(); - setSeries : function(series){ - this.series = series; - this.refresh(); + return { + row: store.indexOf(record), + column: Ext.Array.indexOf(gridCols, header) + }; }, - bindStore : function(store, initial){ - if(!initial && this.store){ - if(store !== this.store && this.store.autoDestroy){ - this.store.destroy(); - }else{ - this.store.un("datachanged", this.refresh, this); - this.store.un("add", this.delayRefresh, this); - this.store.un("remove", this.delayRefresh, this); - this.store.un("update", this.delayRefresh, this); - this.store.un("clear", this.refresh, this); + getRightGap: function(activeHeader) { + var headerCt = this.getHeaderCt(), + headers = headerCt.getGridColumns(), + activeHeaderIdx = Ext.Array.indexOf(headers, activeHeader), + i = activeHeaderIdx + 1, + nextIdx; + + for (; i <= headers.length; i++) { + if (!headers[i].hidden) { + nextIdx = i; + break; } } - if(store){ - store = Ext.StoreMgr.lookup(store); - store.on({ - scope: this, - datachanged: this.refresh, - add: this.delayRefresh, - remove: this.delayRefresh, - update: this.delayRefresh, - clear: this.refresh - }); - } - this.store = store; - if(store && !initial){ - this.refresh(); - } - }, - onSwfReady : function(isReset){ - Ext.chart.Chart.superclass.onSwfReady.call(this, isReset); - var ref; - this.swf.setType(this.type); + return nextIdx - activeHeaderIdx; + }, - if(this.chartStyle){ - this.setStyles(Ext.apply({}, this.extraStyle, this.chartStyle)); + beforeDestroy: function() { + if (this.rendered) { + table = this.el.child('table'); + if (table) { + table.removeAllListeners(); + } } + this.callParent(arguments); + }, - if(this.categoryNames){ - this.setCategoryNames(this.categoryNames); - } + + getLeftGap: function(activeHeader) { + var headerCt = this.getHeaderCt(), + headers = headerCt.getGridColumns(), + activeHeaderIdx = Ext.Array.indexOf(headers, activeHeader), + i = activeHeaderIdx - 1, + prevIdx; - if(this.tipRenderer){ - ref = this.getFunctionRef(this.tipRenderer); - this.setTipRenderer(ref.fn, ref.scope); - } - if(this.legendRenderer){ - ref = this.getFunctionRef(this.legendRenderer); - this.setLegendRenderer(ref.fn, ref.scope); - } - if(!isReset){ - this.bindStore(this.store, true); + for (; i >= 0; i--) { + if (!headers[i].hidden) { + prevIdx = i; + break; + } } - this.refresh.defer(10, this); - }, - delayRefresh : function(){ - if(!this.refreshTask){ - this.refreshTask = new Ext.util.DelayedTask(this.refresh, this); - } - this.refreshTask.delay(this.refreshBuffer); - }, + return prevIdx - activeHeaderIdx; + } +}); - refresh : function(){ - if(this.fireEvent('beforerefresh', this) !== false){ - var styleChanged = false; - - var data = [], rs = this.store.data.items; - for(var j = 0, len = rs.length; j < len; j++){ - data[j] = rs[j].data; - } - - - var dataProvider = []; - var seriesCount = 0; - var currentSeries = null; - var i = 0; - if(this.series){ - seriesCount = this.series.length; - for(i = 0; i < seriesCount; i++){ - currentSeries = this.series[i]; - var clonedSeries = {}; - for(var prop in currentSeries){ - if(prop == "style" && currentSeries.style !== null){ - clonedSeries.style = Ext.encode(currentSeries.style); - styleChanged = true; - - - - - } else{ - clonedSeries[prop] = currentSeries[prop]; - } - } - dataProvider.push(clonedSeries); - } - } +Ext.define('Ext.grid.View', { + extend: 'Ext.view.Table', + alias: 'widget.gridview', - if(seriesCount > 0){ - for(i = 0; i < seriesCount; i++){ - currentSeries = dataProvider[i]; - if(!currentSeries.type){ - currentSeries.type = this.type; - } - currentSeries.dataProvider = data; - } - } else{ - dataProvider.push({type: this.type, dataProvider: data}); - } - this.swf.setDataProvider(dataProvider); - if(this.seriesStyles){ - this.setSeriesStyles(this.seriesStyles); + + stripeRows: true, + + invalidateScrollerOnRefresh: true, + + + scrollToTop : function(){ + if (this.rendered) { + var section = this.ownerCt, + verticalScroller = section.verticalScroller; + + if (verticalScroller) { + verticalScroller.scrollToTop(); } - this.fireEvent('refresh', this); } }, - createFnProxy : function(fn){ - var fnName = 'extFnProxy' + (++Ext.chart.Chart.PROXY_FN_ID); - Ext.chart.Chart.proxyFunction[fnName] = fn; - return 'Ext.chart.Chart.proxyFunction.' + fnName; + onAdd: function(ds, records, index) { + this.callParent(arguments); + this.doStripeRows(index); }, - - removeFnProxy : function(fn){ - if(!Ext.isEmpty(fn)){ - fn = fn.replace('Ext.chart.Chart.proxyFunction.', ''); - delete Ext.chart.Chart.proxyFunction[fn]; - } + + onRemove: function(ds, records, index) { + this.callParent(arguments); + this.doStripeRows(index); }, - - getFunctionRef : function(val){ - if(Ext.isFunction(val)){ - return { - fn: val, - scope: this - }; - }else{ - return { - fn: val.fn, - scope: val.scope || this - }; + + doStripeRows: function(startRow) { + + if (this.stripeRows) { + var rows = this.getNodes(startRow), + rowsLn = rows.length, + i = 0, + row; + + for (; i < rowsLn; i++) { + row = rows[i]; + + row.className = row.className.replace(this.rowClsRe, ' '); + + if (i % 2 === 1) { + row.className += (' ' + this.altRowCls); + } + } } }, + + refresh: function(firstPass) { + this.callParent(arguments); + this.doStripeRows(0); + + var g = this.up('gridpanel'); + if (g && this.invalidateScrollerOnRefresh) { + g.invalidateScroller(); + } + } +}); + +Ext.define('Ext.grid.Panel', { + extend: 'Ext.panel.Table', + requires: ['Ext.grid.View'], + alias: ['widget.gridpanel', 'widget.grid'], + alternateClassName: ['Ext.list.ListView', 'Ext.ListView', 'Ext.grid.GridPanel'], + viewType: 'gridview', - onDestroy: function(){ - if (this.refreshTask && this.refreshTask.cancel){ - this.refreshTask.cancel(); + lockable: false, + + + + normalCfgCopy: ['invalidateScrollerOnRefresh', 'verticalScroller', 'verticalScrollDock', 'verticalScrollerType', 'scroll'], + lockedCfgCopy: ['invalidateScrollerOnRefresh'], + + + + initComponent: function() { + var me = this; + + if (me.columnLines) { + me.setColumnLines(me.columnLines); } - Ext.chart.Chart.superclass.onDestroy.call(this); - this.bindStore(null); - this.removeFnProxy(this.tipFnName); - this.removeFnProxy(this.legendFnName); + + me.callParent(); + }, + + setColumnLines: function(show) { + var me = this, + method = (show) ? 'addClsWithUI' : 'removeClsWithUI'; + + me[method]('with-col-lines') } }); -Ext.reg('chart', Ext.chart.Chart); -Ext.chart.Chart.PROXY_FN_ID = 0; -Ext.chart.Chart.proxyFunction = {}; -Ext.chart.Chart.CHART_URL = 'http:/' + '/yui.yahooapis.com/2.8.2/build/charts/assets/charts.swf'; -Ext.chart.PieChart = Ext.extend(Ext.chart.Chart, { - type: 'pie', - onSwfReady : function(isReset){ - Ext.chart.PieChart.superclass.onSwfReady.call(this, isReset); - this.setDataField(this.dataField); - this.setCategoryField(this.categoryField); - }, - setDataField : function(field){ - this.dataField = field; - this.swf.setDataField(field); - }, - setCategoryField : function(field){ - this.categoryField = field; - this.swf.setCategoryField(field); - } -}); -Ext.reg('piechart', Ext.chart.PieChart); +Ext.define('Ext.grid.RowEditor', { + extend: 'Ext.form.Panel', + requires: [ + 'Ext.tip.ToolTip', + 'Ext.util.HashMap', + 'Ext.util.KeyNav' + ], + + saveBtnText : 'Update', + cancelBtnText: 'Cancel', + errorsText: 'Errors', + dirtyText: 'You need to commit or cancel your changes', + + lastScrollLeft: 0, + lastScrollTop: 0, + + border: false, + + initComponent: function() { + var me = this, + form; + + me.cls = Ext.baseCSSPrefix + 'grid-row-editor'; + + me.layout = { + type: 'hbox', + align: 'middle' + }; + + + + me.columns = Ext.create('Ext.util.HashMap'); + me.columns.getKey = function(columnHeader) { + var f; + if (columnHeader.getEditor) { + f = columnHeader.getEditor(); + if (f) { + return f.id; + } + } + return columnHeader.id; + }; + me.mon(me.columns, { + add: me.onFieldAdd, + remove: me.onFieldRemove, + replace: me.onFieldReplace, + scope: me + }); + + me.callParent(arguments); -Ext.chart.CartesianChart = Ext.extend(Ext.chart.Chart, { - onSwfReady : function(isReset){ - Ext.chart.CartesianChart.superclass.onSwfReady.call(this, isReset); - this.labelFn = []; - if(this.xField){ - this.setXField(this.xField); + if (me.fields) { + me.setField(me.fields); + delete me.fields; } - if(this.yField){ - this.setYField(this.yField); + + form = me.getForm(); + form.trackResetOnLoad = true; + }, + + onFieldChange: function() { + var me = this, + form = me.getForm(), + valid = form.isValid(); + if (me.errorSummary && me.isVisible()) { + me[valid ? 'hideToolTip' : 'showToolTip'](); } - if(this.xAxis){ - this.setXAxis(this.xAxis); + if (me.floatingButtons) { + me.floatingButtons.child('#update').setDisabled(!valid); } - if(this.xAxes){ - this.setXAxes(this.xAxes); + me.isValid = valid; + }, + + afterRender: function() { + var me = this, + plugin = me.editingPlugin; + + me.callParent(arguments); + me.mon(me.renderTo, 'scroll', me.onCtScroll, me, { buffer: 100 }); + + + me.mon(me.el, { + click: Ext.emptyFn, + stopPropagation: true + }); + + me.el.swallowEvent([ + 'keypress', + 'keydown' + ]); + + me.keyNav = Ext.create('Ext.util.KeyNav', me.el, { + enter: plugin.completeEdit, + esc: plugin.onEscKey, + scope: plugin + }); + + me.mon(plugin.view, { + beforerefresh: me.onBeforeViewRefresh, + refresh: me.onViewRefresh, + scope: me + }); + }, + + onBeforeViewRefresh: function(view) { + var me = this, + viewDom = view.el.dom; + + if (me.el.dom.parentNode === viewDom) { + viewDom.removeChild(me.el.dom); } - if(this.yAxis){ - this.setYAxis(this.yAxis); + }, + + onViewRefresh: function(view) { + var me = this, + viewDom = view.el.dom, + context = me.context, + idx; + + viewDom.appendChild(me.el.dom); + + + if (context && (idx = context.store.indexOf(context.record)) >= 0) { + context.row = view.getNode(idx); + me.reposition(); + if (me.tooltip && me.tooltip.isVisible()) { + me.tooltip.setTarget(context.row); + } + } else { + me.editingPlugin.cancelEdit(); } - if(this.yAxes){ - this.setYAxes(this.yAxes); + }, + + onCtScroll: function(e, target) { + var me = this, + scrollTop = target.scrollTop, + scrollLeft = target.scrollLeft; + + if (scrollTop !== me.lastScrollTop) { + me.lastScrollTop = scrollTop; + if ((me.tooltip && me.tooltip.isVisible()) || me.hiddenTip) { + me.repositionTip(); + } } - if(Ext.isDefined(this.constrainViewport)){ - this.swf.setConstrainViewport(this.constrainViewport); + if (scrollLeft !== me.lastScrollLeft) { + me.lastScrollLeft = scrollLeft; + me.reposition(); } }, - setXField : function(value){ - this.xField = value; - this.swf.setHorizontalField(value); + onColumnAdd: function(column) { + this.setField(column); }, - setYField : function(value){ - this.yField = value; - this.swf.setVerticalField(value); + onColumnRemove: function(column) { + this.columns.remove(column); }, - setXAxis : function(value){ - this.xAxis = this.createAxis('xAxis', value); - this.swf.setHorizontalAxis(this.xAxis); + onColumnResize: function(column, width) { + column.getEditor().setWidth(width - 2); + if (this.isVisible()) { + this.reposition(); + } }, - setXAxes : function(value){ - var axis; - for(var i = 0; i < value.length; i++) { - axis = this.createAxis('xAxis' + i, value[i]); - this.swf.setHorizontalAxis(axis); + onColumnHide: function(column) { + column.getEditor().hide(); + if (this.isVisible()) { + this.reposition(); } }, - setYAxis : function(value){ - this.yAxis = this.createAxis('yAxis', value); - this.swf.setVerticalAxis(this.yAxis); + onColumnShow: function(column) { + var field = column.getEditor(); + field.setWidth(column.getWidth() - 2).show(); + if (this.isVisible()) { + this.reposition(); + } }, - setYAxes : function(value){ - var axis; - for(var i = 0; i < value.length; i++) { - axis = this.createAxis('yAxis' + i, value[i]); - this.swf.setVerticalAxis(axis); + onColumnMove: function(column, fromIdx, toIdx) { + var field = column.getEditor(); + if (this.items.indexOf(field) != toIdx) { + this.move(fromIdx, toIdx); } }, - createAxis : function(axis, value){ - var o = Ext.apply({}, value), - ref, - old; + onFieldAdd: function(hm, fieldId, column) { + var me = this, + colIdx = me.editingPlugin.grid.headerCt.getHeaderIndex(column), + field = column.getEditor({ xtype: 'displayfield' }); - if(this[axis]){ - old = this[axis].labelFunction; - this.removeFnProxy(old); - this.labelFn.remove(old); - } - if(o.labelRenderer){ - ref = this.getFunctionRef(o.labelRenderer); - o.labelFunction = this.createFnProxy(function(v){ - return ref.fn.call(ref.scope, v); + me.insert(colIdx, field); + }, + + onFieldRemove: function(hm, fieldId, column) { + var me = this, + field = column.getEditor(), + fieldDom = field.el.dom; + me.remove(field, false); + fieldDom.parentNode.removeChild(fieldDom); + }, + + onFieldReplace: function(hm, fieldId, column, oldColumn) { + var me = this; + me.onFieldRemove(hm, fieldId, oldColumn); + }, + + clearFields: function() { + var me = this, + hm = me.columns; + hm.each(function(fieldId) { + hm.removeAtKey(fieldId); + }); + }, + + getFloatingButtons: function() { + var me = this, + cssPrefix = Ext.baseCSSPrefix, + btnsCss = cssPrefix + 'grid-row-editor-buttons', + plugin = me.editingPlugin, + btns; + + if (!me.floatingButtons) { + btns = me.floatingButtons = Ext.create('Ext.Container', { + renderTpl: [ + '
    ', + '
    ', + '
    ', + '
    ', + '
    ' + ], + + renderTo: me.el, + baseCls: btnsCss, + layout: { + type: 'hbox', + align: 'middle' + }, + defaults: { + margins: '0 1 0 1' + }, + items: [{ + itemId: 'update', + flex: 1, + xtype: 'button', + handler: plugin.completeEdit, + scope: plugin, + text: me.saveBtnText, + disabled: !me.isValid + }, { + flex: 1, + xtype: 'button', + handler: plugin.cancelEdit, + scope: plugin, + text: me.cancelBtnText + }] + }); + + + me.mon(btns.el, { + + + mousedown: Ext.emptyFn, + click: Ext.emptyFn, + stopEvent: true }); - delete o.labelRenderer; - this.labelFn.push(o.labelFunction); - } - if(axis.indexOf('xAxis') > -1 && o.position == 'left'){ - o.position = 'bottom'; } - return o; + return me.floatingButtons; }, - onDestroy : function(){ - Ext.chart.CartesianChart.superclass.onDestroy.call(this); - Ext.each(this.labelFn, function(fn){ - this.removeFnProxy(fn); - }, this); - } -}); -Ext.reg('cartesianchart', Ext.chart.CartesianChart); - + reposition: function(animateConfig) { + var me = this, + context = me.context, + row = context && Ext.get(context.row), + btns = me.getFloatingButtons(), + btnEl = btns.el, + grid = me.editingPlugin.grid, + viewEl = grid.view.el, + scroller = grid.verticalScroller, -Ext.chart.LineChart = Ext.extend(Ext.chart.CartesianChart, { - type: 'line' -}); -Ext.reg('linechart', Ext.chart.LineChart); + + + mainBodyWidth = grid.headerCt.getFullWidth(), + scrollerWidth = grid.getWidth(), + + + width = Math.min(mainBodyWidth, scrollerWidth), + scrollLeft = grid.view.el.dom.scrollLeft, + btnWidth = btns.getWidth(), + left = (width - btnWidth) / 2 + scrollLeft, + y, rowH, newHeight, -Ext.chart.ColumnChart = Ext.extend(Ext.chart.CartesianChart, { - type: 'column' -}); -Ext.reg('columnchart', Ext.chart.ColumnChart); + invalidateScroller = function() { + if (scroller) { + scroller.invalidate(); + btnEl.scrollIntoView(viewEl, false); + } + if (animateConfig && animateConfig.callback) { + animateConfig.callback.call(animateConfig.scope || me); + } + }; + + if (row && Ext.isElement(row.dom)) { + + + row.scrollIntoView(viewEl, false); -Ext.chart.StackedColumnChart = Ext.extend(Ext.chart.CartesianChart, { - type: 'stackcolumn' -}); -Ext.reg('stackedcolumnchart', Ext.chart.StackedColumnChart); + + + + y = row.getXY()[1] - 5; + rowH = row.getHeight(); + newHeight = rowH + 10; + + + + + if (Ext.isIE) { + newHeight += 2; + } -Ext.chart.BarChart = Ext.extend(Ext.chart.CartesianChart, { - type: 'bar' -}); -Ext.reg('barchart', Ext.chart.BarChart); + + if (me.getHeight() != newHeight) { + me.setHeight(newHeight); + me.el.setLeft(0); + } + if (animateConfig) { + var animObj = { + to: { + y: y + }, + duration: animateConfig.duration || 125, + listeners: { + afteranimate: function() { + invalidateScroller(); + y = row.getXY()[1] - 5; + me.el.setY(y); + } + } + }; + me.animate(animObj); + } else { + me.el.setY(y); + invalidateScroller(); + } + } + if (me.getWidth() != mainBodyWidth) { + me.setWidth(mainBodyWidth); + } + btnEl.setLeft(left); + }, -Ext.chart.StackedBarChart = Ext.extend(Ext.chart.CartesianChart, { - type: 'stackbar' -}); -Ext.reg('stackedbarchart', Ext.chart.StackedBarChart); + getEditor: function(fieldInfo) { + var me = this; + if (Ext.isNumber(fieldInfo)) { + + + + return me.query('>[isFormField]')[fieldInfo]; + } else if (fieldInfo instanceof Ext.grid.column.Column) { + return fieldInfo.getEditor(); + } + }, + removeField: function(field) { + var me = this; + + field = me.getEditor(field); + me.mun(field, 'validitychange', me.onValidityChange, me); -Ext.chart.Axis = function(config){ - Ext.apply(this, config); -}; + + + me.columns.removeKey(field.id); + }, -Ext.chart.Axis.prototype = -{ - - type: null, + setField: function(column) { + var me = this, + field; - - orientation: "horizontal", + if (Ext.isArray(column)) { + Ext.Array.forEach(column, me.setField, me); + return; + } - - reverse: false, + + field = column.getEditor(null, { xtype: 'displayfield' }); + field.margins = '0 0 0 2'; + field.setWidth(column.getWidth() - 2); + me.mon(field, 'change', me.onFieldChange, me); - - labelFunction: null, + + + me.columns.add(field.id, column); + }, - - hideOverlappingLabels: true, + loadRecord: function(record) { + var me = this, + form = me.getForm(); + form.loadRecord(record); + if (form.isValid()) { + me.hideToolTip(); + } else { + me.showToolTip(); + } - - labelSpacing: 2 -}; + + Ext.Array.forEach(me.query('>displayfield'), function(field) { + me.renderColumnData(field, record); + }, me); + }, + renderColumnData: function(field, record) { + var me = this, + grid = me.editingPlugin.grid, + headerCt = grid.headerCt, + view = grid.view, + store = view.store, + column = me.columns.get(field.id), + value = field.getRawValue(); + + + if (column.renderer) { + var metaData = { tdCls: '', style: '' }, + rowIdx = store.indexOf(record), + colIdx = headerCt.getHeaderIndex(column); + + value = column.renderer.call( + column.scope || headerCt.ownerCt, + value, + metaData, + record, + rowIdx, + colIdx, + store, + view + ); + } -Ext.chart.NumericAxis = Ext.extend(Ext.chart.Axis, { - type: "numeric", + field.setRawValue(value); + field.resetOriginalValue(); + }, - - minimum: NaN, + beforeEdit: function() { + var me = this; - - maximum: NaN, + if (me.isVisible() && !me.autoCancel && me.isDirty()) { + me.showToolTip(); + return false; + } + }, - majorUnit: NaN, + startEdit: function(record, columnHeader) { + var me = this, + grid = me.editingPlugin.grid, + view = grid.getView(), + store = grid.store, + context = me.context = Ext.apply(me.editingPlugin.context, { + view: grid.getView(), + store: store + }); - - minorUnit: NaN, + + context.grid.getSelectionModel().select(record); - - snapToUnits: true, + + me.loadRecord(record); - - alwaysShowZero: true, + if (!me.isVisible()) { + me.show(); + me.focusContextCell(); + } else { + me.reposition({ + callback: this.focusContextCell + }); + } + }, - scale: "linear", + focusContextCell: function() { + var field = this.getEditor(this.context.colIdx); + if (field && field.focus) { + field.focus(); + } + }, - - roundMajorUnit: true, + cancelEdit: function() { + var me = this, + form = me.getForm(); - - calculateByLabelSize: true, + me.hide(); + form.clearInvalid(); + form.reset(); + }, - - position: 'left', + completeEdit: function() { + var me = this, + form = me.getForm(); - - adjustMaximumByMajorUnit: true, + if (!form.isValid()) { + return; + } - - adjustMinimumByMajorUnit: true + form.updateRecord(me.context.record); + me.hide(); + return true; + }, -}); + onShow: function() { + var me = this; + me.callParent(arguments); + me.reposition(); + }, + onHide: function() { + var me = this; + me.callParent(arguments); + me.hideToolTip(); + me.invalidateScroller(); + if (me.context) { + me.context.view.focus(); + me.context = null; + } + }, -Ext.chart.TimeAxis = Ext.extend(Ext.chart.Axis, { - type: "time", + isDirty: function() { + var me = this, + form = me.getForm(); + return form.isDirty(); + }, - - minimum: null, + getToolTip: function() { + var me = this, + tip; + + if (!me.tooltip) { + tip = me.tooltip = Ext.createWidget('tooltip', { + cls: Ext.baseCSSPrefix + 'grid-row-editor-errors', + title: me.errorsText, + autoHide: false, + closable: true, + closeAction: 'disable', + anchor: 'left' + }); + } + return me.tooltip; + }, - - maximum: null, + hideToolTip: function() { + var me = this, + tip = me.getToolTip(); + if (tip.rendered) { + tip.disable(); + } + me.hiddenTip = false; + }, - - majorUnit: NaN, + showToolTip: function() { + var me = this, + tip = me.getToolTip(), + context = me.context, + row = Ext.get(context.row), + viewEl = context.grid.view.el; - - majorTimeUnit: null, + tip.setTarget(row); + tip.showAt([-10000, -10000]); + tip.body.update(me.getErrors()); + tip.mouseOffset = [viewEl.getWidth() - row.getWidth() + me.lastScrollLeft + 15, 0]; + me.repositionTip(); + tip.doLayout(); + tip.enable(); + }, - - minorUnit: NaN, + repositionTip: function() { + var me = this, + tip = me.getToolTip(), + context = me.context, + row = Ext.get(context.row), + viewEl = context.grid.view.el, + viewHeight = viewEl.getHeight(), + viewTop = me.lastScrollTop, + viewBottom = viewTop + viewHeight, + rowHeight = row.getHeight(), + rowTop = row.dom.offsetTop, + rowBottom = rowTop + rowHeight; + + if (rowBottom > viewTop && rowTop < viewBottom) { + tip.show(); + me.hiddenTip = false; + } else { + tip.hide(); + me.hiddenTip = true; + } + }, - - minorTimeUnit: null, + getErrors: function() { + var me = this, + dirtyText = !me.autoCancel && me.isDirty() ? me.dirtyText + '
    ' : '', + errors = []; - - snapToUnits: true, + Ext.Array.forEach(me.query('>[isFormField]'), function(field) { + errors = errors.concat( + Ext.Array.map(field.getErrors(), function(e) { + return '
  • ' + e + '
  • '; + }) + ); + }, me); - - stackingEnabled: false, + return dirtyText + '
      ' + errors.join('') + '
    '; + }, - - calculateByLabelSize: true + invalidateScroller: function() { + var me = this, + context = me.context, + scroller = context.grid.verticalScroller; + if (scroller) { + scroller.invalidate(); + } + } }); +Ext.define('Ext.grid.header.Container', { + extend: 'Ext.container.Container', + uses: [ + 'Ext.grid.ColumnLayout', + 'Ext.grid.column.Column', + 'Ext.menu.Menu', + 'Ext.menu.CheckItem', + 'Ext.menu.Separator', + 'Ext.grid.plugin.HeaderResizer', + 'Ext.grid.plugin.HeaderReorderer' + ], + border: true, -Ext.chart.CategoryAxis = Ext.extend(Ext.chart.Axis, { - type: "category", + alias: 'widget.headercontainer', - - categoryNames: null, + baseCls: Ext.baseCSSPrefix + 'grid-header-ct', + dock: 'top', - calculateCategoryCount: false - -}); + weight: 100, + defaultType: 'gridcolumn', + + defaultWidth: 100, -Ext.chart.Series = function(config) { Ext.apply(this, config); }; + sortAscText: 'Sort Ascending', + sortDescText: 'Sort Descending', + sortClearText: 'Clear Sort', + columnsText: 'Columns', -Ext.chart.Series.prototype = -{ - - type: null, + lastHeaderCls: Ext.baseCSSPrefix + 'column-header-last', + firstHeaderCls: Ext.baseCSSPrefix + 'column-header-first', + headerOpenCls: Ext.baseCSSPrefix + 'column-header-open', - displayName: null -}; + triStateSort: false, + ddLock: false, -Ext.chart.CartesianSeries = Ext.extend(Ext.chart.Series, { - - xField: null, + dragging: false, - yField: null, - showInLegend: true, - + sortable: true, - axis: 'primary' -}); - + initComponent: function() { + var me = this; + + me.headerCounter = 0; + me.plugins = me.plugins || []; -Ext.chart.ColumnSeries = Ext.extend(Ext.chart.CartesianSeries, { - type: "column" -}); + + + + + if (!me.isHeader) { + me.resizer = Ext.create('Ext.grid.plugin.HeaderResizer'); + me.reorderer = Ext.create('Ext.grid.plugin.HeaderReorderer'); + if (!me.enableColumnResize) { + me.resizer.disable(); + } + if (!me.enableColumnMove) { + me.reorderer.disable(); + } + me.plugins.push(me.reorderer, me.resizer); + } -Ext.chart.LineSeries = Ext.extend(Ext.chart.CartesianSeries, { - type: "line" -}); + + if (me.isHeader && !me.items) { + me.layout = 'auto'; + } + + else { + me.layout = { + type: 'gridcolumn', + availableSpaceOffset: me.availableSpaceOffset, + align: 'stretchmax', + resetStretch: true + }; + } + me.defaults = me.defaults || {}; + Ext.applyIf(me.defaults, { + width: me.defaultWidth, + triStateSort: me.triStateSort, + sortable: me.sortable + }); + me.callParent(); + me.addEvents( + + 'columnresize', + + 'headerclick', -Ext.chart.BarSeries = Ext.extend(Ext.chart.CartesianSeries, { - type: "bar" -}); + + 'headertriggerclick', + + 'columnmove', + + 'columnhide', + + 'columnshow', + + 'sortchange', + + 'menucreate' + ); + }, + onDestroy: function() { + Ext.destroy(this.resizer, this.reorderer); + this.callParent(); + }, -Ext.chart.PieSeries = Ext.extend(Ext.chart.Series, { - type: "pie", - dataField: null, - categoryField: null -}); -Ext.menu.Menu = Ext.extend(Ext.Container, { - - - - minWidth : 120, - - shadow : 'sides', - - subMenuAlign : 'tl-tr?', - - defaultAlign : 'tl-bl?', - - allowOtherMenus : false, - ignoreParentClicks : false, - enableScrolling : true, - maxHeight : null, + onAdd: function(c) { + var me = this; + if (!c.headerId) { + c.headerId = 'h' + (++me.headerCounter); + } + me.callParent(arguments); + me.purgeCache(); + }, + - scrollIncrement : 24, - showSeparator : true, - defaultOffsets : [0, 0], + onRemove: function(c) { + var me = this; + me.callParent(arguments); + me.purgeCache(); + }, - - plain : false, + afterRender: function() { + this.callParent(); + var store = this.up('[store]').store, + sorters = store.sorters, + first = sorters.first(), + hd; - - floating : true, + if (first) { + hd = this.down('gridcolumn[dataIndex=' + first.property +']'); + if (hd) { + hd.setSortState(first.direction, false, true); + } + } + }, + afterLayout: function() { + if (!this.isHeader) { + var me = this, + topHeaders = me.query('>gridcolumn:not([hidden])'), + viewEl; - - zIndex: 15000, + me.callParent(arguments); - - hidden : true, + if (topHeaders.length) { + topHeaders[0].el.radioCls(me.firstHeaderCls); + topHeaders[topHeaders.length - 1].el.radioCls(me.lastHeaderCls); + } + } + }, - - layout : 'menu', - hideMode : 'offsets', - scrollerHeight : 8, - autoLayout : true, - defaultType : 'menuitem', - bufferResize : false, + onHeaderShow: function(header) { + + var me = this, + gridSection = me.ownerCt, + menu = me.getMenu(), + topItems, topItemsVisible, + colCheckItem, + itemToEnable, + len, i; + + if (menu) { + + colCheckItem = menu.down('menucheckitem[headerId=' + header.id + ']'); + if (colCheckItem) { + colCheckItem.setChecked(true, true); + } - initComponent : function(){ - if(Ext.isArray(this.initialConfig)){ - Ext.apply(this, {items:this.initialConfig}); - } - this.addEvents( - - 'click', - - 'mouseover', - - 'mouseout', - 'itemclick' - ); - Ext.menu.MenuMgr.register(this); - if(this.floating){ - Ext.EventManager.onWindowResize(this.hide, this); - }else{ - if(this.initialConfig.hidden !== false){ - this.hidden = false; + topItems = menu.query('#columnItem>menucheckitem[checked]'); + topItemsVisible = topItems.length; + if ((me.getVisibleGridColumns().length > 1) && me.disabledMenuItems && me.disabledMenuItems.length) { + if (topItemsVisible == 1) { + Ext.Array.remove(me.disabledMenuItems, topItems[0]); + } + for (i = 0, len = me.disabledMenuItems.length; i < len; i++) { + itemToEnable = me.disabledMenuItems[i]; + if (!itemToEnable.isDestroyed) { + itemToEnable[itemToEnable.menu ? 'enableCheckChange' : 'enable'](); + } + } + if (topItemsVisible == 1) { + me.disabledMenuItems = topItems; + } else { + me.disabledMenuItems = []; + } } - this.internalDefaults = {hideOnClick: false}; } - Ext.menu.Menu.superclass.initComponent.call(this); - if(this.autoLayout){ - var fn = this.doLayout.createDelegate(this, []); - this.on({ - add: fn, - remove: fn - }); + + + + if (!header.isGroupHeader) { + if (me.view) { + me.view.onHeaderShow(me, header, true); + } + if (gridSection) { + gridSection.onHeaderShow(me, header); + } } - }, + me.fireEvent('columnshow', me, header); - - getLayoutTarget : function() { - return this.ul; + + me.doLayout(); }, - - onRender : function(ct, position){ - if(!ct){ - ct = Ext.getBody(); - } + onHeaderHide: function(header, suppressLayout) { + + var me = this, + gridSection = me.ownerCt, + menu = me.getMenu(), + colCheckItem; - var dh = { - id: this.getId(), - cls: 'x-menu ' + ((this.floating) ? 'x-menu-floating x-layer ' : '') + (this.cls || '') + (this.plain ? ' x-menu-plain' : '') + (this.showSeparator ? '' : ' x-menu-nosep'), - style: this.style, - cn: [ - {tag: 'a', cls: 'x-menu-focus', href: '#', onclick: 'return false;', tabIndex: '-1'}, - {tag: 'ul', cls: 'x-menu-list'} - ] - }; - if(this.floating){ - this.el = new Ext.Layer({ - shadow: this.shadow, - dh: dh, - constrain: false, - parentEl: ct, - zindex: this.zIndex - }); - }else{ - this.el = ct.createChild(dh); - } - Ext.menu.Menu.superclass.onRender.call(this, ct, position); + if (menu) { - if(!this.keyNav){ - this.keyNav = new Ext.menu.MenuNav(this); + + colCheckItem = menu.down('menucheckitem[headerId=' + header.id + ']'); + if (colCheckItem) { + colCheckItem.setChecked(false, true); + } + me.setDisabledItems(); } + - this.focusEl = this.el.child('a.x-menu-focus'); - this.ul = this.el.child('ul.x-menu-list'); - this.mon(this.ul, { - scope: this, - click: this.onClick, - mouseover: this.onMouseOver, - mouseout: this.onMouseOut - }); - if(this.enableScrolling){ - this.mon(this.el, { - scope: this, - delegate: '.x-menu-scroller', - click: this.onScroll, - mouseover: this.deactivateActive - }); - } - }, + if (!header.isGroupHeader) { + if (me.view) { + me.view.onHeaderHide(me, header, true); + } + if (gridSection) { + gridSection.onHeaderHide(me, header); + } - - findTargetItem : function(e){ - var t = e.getTarget('.x-menu-list-item', this.ul, true); - if(t && t.menuItemId){ - return this.items.get(t.menuItemId); + + if (!suppressLayout) { + me.doLayout(); + } } + me.fireEvent('columnhide', me, header); }, - - onClick : function(e){ - var t = this.findTargetItem(e); - if(t){ - if(t.isFormField){ - this.setActiveItem(t); - }else if(t instanceof Ext.menu.BaseItem){ - if(t.menu && this.ignoreParentClicks){ - t.expandMenu(); - e.preventDefault(); - }else if(t.onClick){ - t.onClick(e); - this.fireEvent('click', this, t, e); - } + setDisabledItems: function(){ + var me = this, + menu = me.getMenu(), + i = 0, + len, + itemsToDisable, + itemToDisable; + + + itemsToDisable = menu.query('#columnItem>menucheckitem[checked]'); + if ((itemsToDisable.length === 1)) { + if (!me.disabledMenuItems) { + me.disabledMenuItems = []; } - } - }, - - setActiveItem : function(item, autoExpand){ - if(item != this.activeItem){ - this.deactivateActive(); - if((this.activeItem = item).isFormField){ - item.focus(); - }else{ - item.activate(autoExpand); + + if ((me.getVisibleGridColumns().length === 1) && itemsToDisable[0].menu) { + itemsToDisable = itemsToDisable.concat(itemsToDisable[0].menu.query('menucheckitem[checked]')); } - }else if(autoExpand){ - item.expandMenu(); - } - }, - deactivateActive : function(){ - var a = this.activeItem; - if(a){ - if(a.isFormField){ - - if(a.collapse){ - a.collapse(); + len = itemsToDisable.length; + + for (i = 0; i < len; i++) { + itemToDisable = itemsToDisable[i]; + if (!Ext.Array.contains(me.disabledMenuItems, itemToDisable)) { + itemToDisable[itemToDisable.menu ? 'disableCheckChange' : 'disable'](); + me.disabledMenuItems.push(itemToDisable); } - }else{ - a.deactivate(); } - delete this.activeItem; } }, - tryActivate : function(start, step){ - var items = this.items; - for(var i = start, len = items.length; i >= 0 && i < len; i+= step){ - var item = items.get(i); - if(item.isVisible() && !item.disabled && (item.canActivate || item.isFormField)){ - this.setActiveItem(item, false); - return item; - } - } - return false; + tempLock: function() { + this.ddLock = true; + Ext.Function.defer(function() { + this.ddLock = false; + }, 200, this); }, - - onMouseOver : function(e){ - var t = this.findTargetItem(e); - if(t){ - if(t.canActivate && !t.disabled){ - this.setActiveItem(t, true); - } + onHeaderResize: function(header, w, suppressFocus) { + this.tempLock(); + if (this.view && this.view.rendered) { + this.view.onHeaderResize(header, w, suppressFocus); } - this.over = true; - this.fireEvent('mouseover', this, e, t); + this.fireEvent('columnresize', this, header, w); }, - - onMouseOut : function(e){ - var t = this.findTargetItem(e); - if(t){ - if(t == this.activeItem && t.shouldDeactivate && t.shouldDeactivate(e)){ - this.activeItem.deactivate(); - delete this.activeItem; - } - } - this.over = false; - this.fireEvent('mouseout', this, e, t); + onHeaderClick: function(header, e, t) { + this.fireEvent("headerclick", this, header, e, t); }, - - onScroll : function(e, t){ - if(e){ - e.stopEvent(); - } - var ul = this.ul.dom, top = Ext.fly(t).is('.x-menu-scroller-top'); - ul.scrollTop += this.scrollIncrement * (top ? -1 : 1); - if(top ? ul.scrollTop <= 0 : ul.scrollTop + this.activeMax >= ul.scrollHeight){ - this.onScrollerOut(null, t); + onHeaderTriggerClick: function(header, e, t) { + + if (this.fireEvent("headertriggerclick", this, header, e, t) !== false) { + this.showMenuBy(t, header); } }, - - onScrollerIn : function(e, t){ - var ul = this.ul.dom, top = Ext.fly(t).is('.x-menu-scroller-top'); - if(top ? ul.scrollTop > 0 : ul.scrollTop + this.activeMax < ul.scrollHeight){ - Ext.fly(t).addClass(['x-menu-item-active', 'x-menu-scroller-active']); + showMenuBy: function(t, header) { + var menu = this.getMenu(), + ascItem = menu.down('#ascItem'), + descItem = menu.down('#descItem'), + sortableMth; + + menu.activeHeader = menu.ownerCt = header; + menu.setFloatParent(header); + + header.titleContainer.addCls(this.headerOpenCls); + + + sortableMth = header.sortable ? 'enable' : 'disable'; + if (ascItem) { + ascItem[sortableMth](); } + if (descItem) { + descItem[sortableMth](); + } + menu.showBy(t); }, - onScrollerOut : function(e, t){ - Ext.fly(t).removeClass(['x-menu-item-active', 'x-menu-scroller-active']); + onMenuDeactivate: function() { + var menu = this.getMenu(); + + menu.activeHeader.titleContainer.removeCls(this.headerOpenCls); }, - - show : function(el, pos, parentMenu){ - if(this.floating){ - this.parentMenu = parentMenu; - if(!this.el){ - this.render(); - this.doLayout(false, true); - } - this.showAt(this.el.getAlignToXY(el, pos || this.defaultAlign, this.defaultOffsets), parentMenu); - }else{ - Ext.menu.Menu.superclass.show.call(this); - } - }, + moveHeader: function(fromIdx, toIdx) { - - showAt : function(xy, parentMenu){ - if(this.fireEvent('beforeshow', this) !== false){ - this.parentMenu = parentMenu; - if(!this.el){ - this.render(); - } - if(this.enableScrolling){ - - this.el.setXY(xy); - - xy[1] = this.constrainScroll(xy[1]); - xy = [this.el.adjustForConstraints(xy)[0], xy[1]]; - }else{ - - xy = this.el.adjustForConstraints(xy); - } - this.el.setXY(xy); - this.el.show(); - Ext.menu.Menu.superclass.onShow.call(this); - if(Ext.isIE){ - - this.fireEvent('autosize', this); - if(!Ext.isIE8){ - this.el.repaint(); - } - } - this.hidden = false; - this.focus(); - this.fireEvent('show', this); - } + + this.tempLock(); + this.onHeaderMoved(this.move(fromIdx, toIdx), fromIdx, toIdx); }, - constrainScroll : function(y){ - var max, full = this.ul.setHeight('auto').getHeight(), - returnY = y, normalY, parentEl, scrollTop, viewHeight; - if(this.floating){ - parentEl = Ext.fly(this.el.dom.parentNode); - scrollTop = parentEl.getScroll().top; - viewHeight = parentEl.getViewSize().height; - - - normalY = y - scrollTop; - max = this.maxHeight ? this.maxHeight : viewHeight - normalY; - if(full > viewHeight) { - max = viewHeight; - - returnY = y - normalY; - } else if(max < full) { - returnY = y - (full - max); - max = full; - } - }else{ - max = this.getHeight(); - } + purgeCache: function() { + var me = this; + + delete me.gridDataColumns; + - if (this.maxHeight){ - max = Math.min(this.maxHeight, max); + if (me.menu) { + me.menu.destroy(); + delete me.menu; } - if(full > max && max > 0){ - this.activeMax = max - this.scrollerHeight * 2 - this.el.getFrameWidth('tb') - Ext.num(this.el.shadowOffset, 0); - this.ul.setHeight(this.activeMax); - this.createScrollers(); - this.el.select('.x-menu-scroller').setDisplayed(''); - }else{ - this.ul.setHeight(full); - this.el.select('.x-menu-scroller').setDisplayed('none'); + }, + + onHeaderMoved: function(header, fromIdx, toIdx) { + var me = this, + gridSection = me.ownerCt; + + if (gridSection) { + gridSection.onHeaderMove(me, header, fromIdx, toIdx); } - this.ul.dom.scrollTop = 0; - return returnY; + me.fireEvent("columnmove", me, header, fromIdx, toIdx); }, - createScrollers : function(){ - if(!this.scroller){ - this.scroller = { - pos: 0, - top: this.el.insertFirst({ - tag: 'div', - cls: 'x-menu-scroller x-menu-scroller-top', - html: ' ' - }), - bottom: this.el.createChild({ - tag: 'div', - cls: 'x-menu-scroller x-menu-scroller-bottom', - html: ' ' - }) - }; - this.scroller.top.hover(this.onScrollerIn, this.onScrollerOut, this); - this.scroller.topRepeater = new Ext.util.ClickRepeater(this.scroller.top, { - listeners: { - click: this.onScroll.createDelegate(this, [null, this.scroller.top], false) - } - }); - this.scroller.bottom.hover(this.onScrollerIn, this.onScrollerOut, this); - this.scroller.bottomRepeater = new Ext.util.ClickRepeater(this.scroller.bottom, { + + getMenu: function() { + var me = this; + + if (!me.menu) { + me.menu = Ext.create('Ext.menu.Menu', { + items: me.getMenuItems(), listeners: { - click: this.onScroll.createDelegate(this, [null, this.scroller.bottom], false) + deactivate: me.onMenuDeactivate, + scope: me } }); + me.setDisabledItems(); + me.fireEvent('menucreate', me, me.menu); } + return me.menu; }, - onLayout : function(){ - if(this.isVisible()){ - if(this.enableScrolling){ - this.constrainScroll(this.el.getTop()); - } - if(this.floating){ - this.el.sync(); - } + + getMenuItems: function() { + var me = this, + menuItems = [{ + itemId: 'columnItem', + text: me.columnsText, + cls: Ext.baseCSSPrefix + 'cols-icon', + menu: me.getColumnMenu(me) + }]; + + if (me.sortable) { + menuItems.unshift({ + itemId: 'ascItem', + text: me.sortAscText, + cls: 'xg-hmenu-sort-asc', + handler: me.onSortAscClick, + scope: me + },{ + itemId: 'descItem', + text: me.sortDescText, + cls: 'xg-hmenu-sort-desc', + handler: me.onSortDescClick, + scope: me + },'-'); } + return menuItems; }, - focus : function(){ - if(!this.hidden){ - this.doFocus.defer(50, this); - } + + onSortAscClick: function() { + var menu = this.getMenu(), + activeHeader = menu.activeHeader; + + activeHeader.setSortState('ASC'); }, - doFocus : function(){ - if(!this.hidden){ - this.focusEl.focus(); - } + + onSortDescClick: function() { + var menu = this.getMenu(), + activeHeader = menu.activeHeader; + + activeHeader.setSortState('DESC'); }, - hide : function(deep){ - if (!this.isDestroyed) { - this.deepHide = deep; - Ext.menu.Menu.superclass.hide.call(this); - delete this.deepHide; + getColumnMenu: function(headerContainer) { + var menuItems = [], + i = 0, + item, + items = headerContainer.query('>gridcolumn[hideable]'), + itemsLn = items.length, + menuItem; + + for (; i < itemsLn; i++) { + item = items[i]; + menuItem = Ext.create('Ext.menu.CheckItem', { + text: item.text, + checked: !item.hidden, + hideOnClick: false, + headerId: item.id, + menu: item.isGroupHeader ? this.getColumnMenu(item) : undefined, + checkHandler: this.onColumnCheckChange, + scope: this + }); + if (itemsLn === 1) { + menuItem.disabled = true; + } + menuItems.push(menuItem); + + + + item.on({ + destroy: Ext.Function.bind(menuItem.destroy, menuItem) + }); } + return menuItems; + }, + + onColumnCheckChange: function(checkItem, checked) { + var header = Ext.getCmp(checkItem.headerId); + header[checked ? 'show' : 'hide'](); }, - onHide : function(){ - Ext.menu.Menu.superclass.onHide.call(this); - this.deactivateActive(); - if(this.el && this.floating){ - this.el.hide(); - } - var pm = this.parentMenu; - if(this.deepHide === true && pm){ - if(pm.floating){ - pm.hide(true); - }else{ - pm.deactivateActive(); - } + getColumnsForTpl: function(flushCache) { + var cols = [], + headers = this.getGridColumns(flushCache), + headersLn = headers.length, + i = 0, + header; + + for (; i < headersLn; i++) { + header = headers[i]; + cols.push({ + dataIndex: header.dataIndex, + align: header.align, + width: header.hidden ? 0 : header.getDesiredWidth(), + id: header.id, + cls: header.tdCls, + columnId: header.getItemId() + }); } + return cols; }, - lookupComponent : function(c){ - if(Ext.isString(c)){ - c = (c == 'separator' || c == '-') ? new Ext.menu.Separator() : new Ext.menu.TextItem(c); - this.applyDefaults(c); - }else{ - if(Ext.isObject(c)){ - c = this.getMenuItem(c); - }else if(c.tagName || c.el){ - c = new Ext.BoxComponent({ - el: c - }); - } - } - return c; + getColumnCount: function() { + return this.getGridColumns().length; }, - applyDefaults : function(c) { - if (!Ext.isString(c)) { - c = Ext.menu.Menu.superclass.applyDefaults.call(this, c); - var d = this.internalDefaults; - if(d){ - if(c.events){ - Ext.applyIf(c.initialConfig, d); - Ext.apply(c, d); - }else{ - Ext.applyIf(c, d); + + getFullWidth: function(flushCache) { + var fullWidth = 0, + headers = this.getVisibleGridColumns(flushCache), + headersLn = headers.length, + i = 0; + + for (; i < headersLn; i++) { + if (!isNaN(headers[i].width)) { + + if (headers[i].getDesiredWidth) { + fullWidth += headers[i].getDesiredWidth(); + + } else { + fullWidth += headers[i].getWidth(); } } } - return c; + return fullWidth; }, - getMenuItem : function(config) { - if (!config.isXType) { - if (!config.xtype && Ext.isBoolean(config.checked)) { - return new Ext.menu.CheckItem(config); + clearOtherSortStates: function(activeHeader) { + var headers = this.getGridColumns(), + headersLn = headers.length, + i = 0, + oldSortState; + + for (; i < headersLn; i++) { + if (headers[i] !== activeHeader) { + oldSortState = headers[i].sortState; + + headers[i].setSortState(null, true); + + + } - return Ext.create(config, this.defaultType); } - return config; }, - addSeparator : function() { - return this.add(new Ext.menu.Separator()); + getVisibleGridColumns: function(refreshCache) { + return Ext.ComponentQuery.query(':not([hidden])', this.getGridColumns(refreshCache)); }, - addElement : function(el) { - return this.add(new Ext.menu.BaseItem({ - el: el - })); - }, + getGridColumns: function(refreshCache) { + var me = this, + result = refreshCache ? null : me.gridDataColumns; - - addItem : function(item) { - return this.add(item); + + if (!result) { + me.gridDataColumns = result = []; + me.cascade(function(c) { + if ((c !== me) && !c.isGroupHeader) { + result.push(c); + } + }); + } + + return result; }, - addMenuItem : function(config) { - return this.add(this.getMenuItem(config)); + getHeaderIndex: function(header) { + var columns = this.getGridColumns(); + return Ext.Array.indexOf(columns, header); }, - addText : function(text){ - return this.add(new Ext.menu.TextItem(text)); + getHeaderAtIndex: function(index) { + var columns = this.getGridColumns(); + return columns[index]; }, - onDestroy : function(){ - Ext.EventManager.removeResizeListener(this.hide, this); - var pm = this.parentMenu; - if(pm && pm.activeChild == this){ - delete pm.activeChild; - } - delete this.parentMenu; - Ext.menu.Menu.superclass.onDestroy.call(this); - Ext.menu.MenuMgr.unregister(this); - if(this.keyNav) { - this.keyNav.disable(); - } - var s = this.scroller; - if(s){ - Ext.destroy(s.topRepeater, s.bottomRepeater, s.top, s.bottom); - } - Ext.destroy( - this.el, - this.focusEl, - this.ul - ); - } -}); - -Ext.reg('menu', Ext.menu.Menu); - - -Ext.menu.MenuNav = Ext.extend(Ext.KeyNav, function(){ - function up(e, m){ - if(!m.tryActivate(m.items.indexOf(m.activeItem)-1, -1)){ - m.tryActivate(m.items.length-1, -1); - } - } - function down(e, m){ - if(!m.tryActivate(m.items.indexOf(m.activeItem)+1, 1)){ - m.tryActivate(0, 1); - } - } - return { - constructor : function(menu){ - Ext.menu.MenuNav.superclass.constructor.call(this, menu.el); - this.scope = this.menu = menu; - }, - - doRelay : function(e, h){ - var k = e.getKey(); + prepareData: function(data, rowIdx, record, view) { + var obj = {}, + headers = this.getGridColumns(), + headersLn = headers.length, + colIdx = 0, + header, value, + metaData, + g = this.up('tablepanel'), + store = g.store; - if (this.menu.activeItem && this.menu.activeItem.isFormField && k != e.TAB) { - return false; - } - if(!this.menu.activeItem && e.isNavKeyPress() && k != e.SPACE && k != e.RETURN){ - this.menu.tryActivate(0, 1); - return false; - } - return h.call(this.scope || this, e, this.menu); - }, + for (; colIdx < headersLn; colIdx++) { + metaData = { + tdCls: '', + style: '' + }; + header = headers[colIdx]; + value = data[header.dataIndex]; - tab: function(e, m) { - e.stopEvent(); - if (e.shiftKey) { - up(e, m); - } else { - down(e, m); + + + if (Ext.isString(header.renderer)) { + header.renderer = Ext.util.Format[header.renderer]; } - }, - up : up, - - down : down, - - right : function(e, m){ - if(m.activeItem){ - m.activeItem.expandMenu(true); + if (Ext.isFunction(header.renderer)) { + value = header.renderer.call( + header.scope || this.ownerCt, + value, + + + metaData, + record, + rowIdx, + colIdx, + store, + view + ); } - }, - left : function(e, m){ - m.hide(); - if(m.parentMenu && m.parentMenu.activeItem){ - m.parentMenu.activeItem.activate(); + if (metaData.css) { + + obj.cssWarning = true; + metaData.tdCls = metaData.css; + delete metaData.css; } - }, - - enter : function(e, m){ - if(m.activeItem){ - e.stopPropagation(); - m.activeItem.onClick(e); - m.fireEvent('click', this, m.activeItem); - return true; + obj[header.id+'-modified'] = record.isModified(header.dataIndex) ? Ext.baseCSSPrefix + 'grid-dirty-cell' : Ext.baseCSSPrefix + 'grid-clean-cell'; + obj[header.id+'-tdCls'] = metaData.tdCls; + obj[header.id+'-tdAttr'] = metaData.tdAttr; + obj[header.id+'-style'] = metaData.style; + if (value === undefined || value === null || value === '') { + value = ' '; } + obj[header.id] = value; } - }; -}()); + return obj; + }, -Ext.menu.MenuMgr = function(){ - var menus, active, groups = {}, attached = false, lastShow = new Date(); + expandToFit: function(header) { + if (this.view) { + this.view.expandToFit(header); + } + } +}); - - function init(){ - menus = {}; - active = new Ext.util.MixedCollection(); - Ext.getDoc().addKeyListener(27, function(){ - if(active.length > 0){ - hideAll(); - } - }); - } - - function hideAll(){ - if(active && active.length > 0){ - var c = active.clone(); - c.each(function(m){ - m.hide(); - }); - return true; - } - return false; - } +Ext.define('Ext.grid.column.Column', { + extend: 'Ext.grid.header.Container', + alias: 'widget.gridcolumn', + requires: ['Ext.util.KeyNav'], + alternateClassName: 'Ext.grid.Column', - - function onHide(m){ - active.remove(m); - if(active.length < 1){ - Ext.getDoc().un("mousedown", onMouseDown); - attached = false; - } - } + baseCls: Ext.baseCSSPrefix + 'column-header ' + Ext.baseCSSPrefix + 'unselectable', - - function onShow(m){ - var last = active.last(); - lastShow = new Date(); - active.add(m); - if(!attached){ - Ext.getDoc().on("mousedown", onMouseDown); - attached = true; - } - if(m.parentMenu){ - m.getEl().setZIndex(parseInt(m.parentMenu.getEl().getStyle("z-index"), 10) + 3); - m.parentMenu.activeChild = m; - }else if(last && !last.isDestroyed && last.isVisible()){ - m.getEl().setZIndex(parseInt(last.getEl().getStyle("z-index"), 10) + 3); - } - } + + hoverCls: Ext.baseCSSPrefix + 'column-header-over', - - function onBeforeHide(m){ - if(m.activeChild){ - m.activeChild.hide(); - } - if(m.autoHideTimer){ - clearTimeout(m.autoHideTimer); - delete m.autoHideTimer; - } - } + handleWidth: 5, - - function onBeforeShow(m){ - var pm = m.parentMenu; - if(!pm && !m.allowOtherMenus){ - hideAll(); - }else if(pm && pm.activeChild){ - pm.activeChild.hide(); - } - } + sortState: null, - - function onMouseDown(e){ - if(lastShow.getElapsed() > 50 && active.length > 0 && !e.getTarget(".x-menu")){ - hideAll(); - } - } + possibleSortStates: ['ASC', 'DESC'], - return { + renderTpl: + '
    ' + + '' + + '{text}' + + '' + + '
    ' + + '
    ', - - hideAll : function(){ - return hideAll(); - }, + - - register : function(menu){ - if(!menus){ - init(); - } - menus[menu.id] = menu; - menu.on({ - beforehide: onBeforeHide, - hide: onHide, - beforeshow: onBeforeShow, - show: onShow - }); - }, - - - get : function(menu){ - if(typeof menu == "string"){ - if(!menus){ - return null; - } - return menus[menu]; - }else if(menu.events){ - return menu; - }else if(typeof menu.length == 'number'){ - return new Ext.menu.Menu({items:menu}); - }else{ - return Ext.create(menu, 'menu'); - } - }, + + dataIndex: null, - - unregister : function(menu){ - delete menus[menu.id]; - menu.un("beforehide", onBeforeHide); - menu.un("hide", onHide); - menu.un("beforeshow", onBeforeShow); - menu.un("show", onShow); - }, + + text: ' ', - - registerCheckable : function(menuItem){ - var g = menuItem.group; - if(g){ - if(!groups[g]){ - groups[g] = []; - } - groups[g].push(menuItem); - } - }, + + sortable: true, + + + + + hideable: true, - - unregisterCheckable : function(menuItem){ - var g = menuItem.group; - if(g){ - groups[g].remove(menuItem); - } - }, - - - onCheckChange: function(item, state){ - if(item.group && state){ - var group = groups[item.group], - i = 0, - len = group.length, - current; - - for(; i < len; i++){ - current = group[i]; - if(current != item){ - current.setChecked(false); - } - } - } - }, - - getCheckedItem : function(groupId){ - var g = groups[groupId]; - if(g){ - for(var i = 0, l = g.length; i < l; i++){ - if(g[i].checked){ - return g[i]; - } - } - } - return null; - }, - - setCheckedItem : function(groupId, itemId){ - var g = groups[groupId]; - if(g){ - for(var i = 0, l = g.length; i < l; i++){ - if(g[i].id == itemId){ - g[i].setChecked(true); - } - } - } - return null; - } - }; -}(); + + menuDisabled: false, -Ext.menu.BaseItem = Ext.extend(Ext.Component, { + renderer: false, + + align: 'left', + + draggable: true, + - canActivate : false, - activeClass : "x-menu-item-active", + initDraggable: Ext.emptyFn, + - hideOnClick : true, + - clickHideDelay : 1, - ctype : "Ext.menu.BaseItem", - actionMode : "container", + isHeader: true, + + initComponent: function() { + var me = this, + i, + len; + + if (Ext.isDefined(me.header)) { + me.text = me.header; + delete me.header; + } + + + + + if (me.flex) { + me.minWidth = me.minWidth || Ext.grid.plugin.HeaderResizer.prototype.minColWidth; + } + + + else { + me.minWidth = me.width; + } + + if (!me.triStateSort) { + me.possibleSortStates.length = 2; + } + + + if (Ext.isDefined(me.columns)) { + me.isGroupHeader = true; + + if (me.dataIndex) { + Ext.Error.raise('Ext.grid.column.Column: Group header may not accept a dataIndex'); + } + if ((me.width && me.width !== Ext.grid.header.Container.prototype.defaultWidth) || me.flex) { + Ext.Error.raise('Ext.grid.column.Column: Group header does not support setting explicit widths or flexs. The group header width is calculated by the sum of its children.'); + } - initComponent : function(){ - Ext.menu.BaseItem.superclass.initComponent.call(this); - this.addEvents( - - 'click', - 'activate', + me.items = me.columns; + delete me.columns; + delete me.flex; + me.width = 0; + - 'deactivate' - ); - if(this.handler){ - this.on("click", this.handler, this.scope); - } - }, + for (i = 0, len = me.items.length; i < len; i++) { + me.width += me.items[i].width || Ext.grid.header.Container.prototype.defaultWidth; + if (me.items[i].flex) { + Ext.Error.raise('Ext.grid.column.Column: items of a grouped header do not support flexed values. Each item must explicitly define its width.'); + } + } + me.minWidth = me.width; - - onRender : function(container, position){ - Ext.menu.BaseItem.superclass.onRender.apply(this, arguments); - if(this.ownerCt && this.ownerCt instanceof Ext.menu.Menu){ - this.parentMenu = this.ownerCt; - }else{ - this.container.addClass('x-menu-list-item'); - this.mon(this.el, { - scope: this, - click: this.onClick, - mouseenter: this.activate, - mouseleave: this.deactivate - }); + me.cls = (me.cls||'') + ' ' + Ext.baseCSSPrefix + 'group-header'; + me.sortable = false; + me.fixed = true; + me.align = 'center'; } + + Ext.applyIf(me.renderSelectors, { + titleContainer: '.' + Ext.baseCSSPrefix + 'column-header-inner', + triggerEl: '.' + Ext.baseCSSPrefix + 'column-header-trigger', + textEl: '.' + Ext.baseCSSPrefix + 'column-header-text' + }); + + + me.callParent(arguments); }, - - setHandler : function(handler, scope){ - if(this.handler){ - this.un("click", this.handler, this.scope); - } - this.on("click", this.handler = handler, this.scope = scope); + onAdd: function(childHeader) { + childHeader.isSubHeader = true; + childHeader.addCls(Ext.baseCSSPrefix + 'group-sub-header'); }, - - onClick : function(e){ - if(!this.disabled && this.fireEvent("click", this, e) !== false - && (this.parentMenu && this.parentMenu.fireEvent("itemclick", this, e) !== false)){ - this.handleClick(e); - }else{ - e.stopEvent(); - } + onRemove: function(childHeader) { + childHeader.isSubHeader = false; + childHeader.removeCls(Ext.baseCSSPrefix + 'group-sub-header'); }, - - activate : function(){ - if(this.disabled){ - return false; - } - var li = this.container; - li.addClass(this.activeClass); - this.region = li.getRegion().adjust(2, 2, -2, -2); - this.fireEvent("activate", this); - return true; + initRenderData: function() { + var me = this; + + Ext.applyIf(me.renderData, { + text: me.text, + menuDisabled: me.menuDisabled + }); + return me.callParent(arguments); }, - deactivate : function(){ - this.container.removeClass(this.activeClass); - this.fireEvent("deactivate", this); + setText: function(text) { + this.text = text; + if (this.rendered) { + this.textEl.update(text); + } }, - shouldDeactivate : function(e){ - return !this.region || !this.region.contains(e.getPoint()); + + getOwnerHeaderCt: function() { + return this.up(':not([isHeader])'); }, - handleClick : function(e){ - var pm = this.parentMenu; - if(this.hideOnClick){ - if(pm.floating){ - pm.hide.defer(this.clickHideDelay, pm, [true]); - }else{ - pm.deactivateActive(); - } - } + getIndex: function() { + return this.isGroupColumn ? false : this.getOwnerHeaderCt().getHeaderIndex(this); }, - - expandMenu : Ext.emptyFn, + afterRender: function() { + var me = this, + el = me.el; - - hideMenu : Ext.emptyFn -}); -Ext.reg('menubaseitem', Ext.menu.BaseItem); -Ext.menu.TextItem = Ext.extend(Ext.menu.BaseItem, { - - - hideOnClick : false, - - itemCls : "x-menu-text", - - constructor : function(config) { - if (typeof config == 'string') { - config = { - text: config - }; + me.callParent(arguments); + + el.addCls(Ext.baseCSSPrefix + 'column-header-align-' + me.align).addClsOnOver(me.overCls); + + me.mon(el, { + click: me.onElClick, + dblclick: me.onElDblClick, + scope: me + }); + + + + if (!Ext.isIE8 || !Ext.isStrict) { + me.mon(me.getFocusEl(), { + focus: me.onTitleMouseOver, + blur: me.onTitleMouseOut, + scope: me + }); } - Ext.menu.TextItem.superclass.constructor.call(this, config); + + me.mon(me.titleContainer, { + mouseenter: me.onTitleMouseOver, + mouseleave: me.onTitleMouseOut, + scope: me + }); + + me.keyNav = Ext.create('Ext.util.KeyNav', el, { + enter: me.onEnterKey, + down: me.onDownKey, + scope: me + }); }, - - onRender : function() { - var s = document.createElement("span"); - s.className = this.itemCls; - s.innerHTML = this.text; - this.el = s; - Ext.menu.TextItem.superclass.onRender.apply(this, arguments); - } -}); -Ext.reg('menutextitem', Ext.menu.TextItem); -Ext.menu.Separator = Ext.extend(Ext.menu.BaseItem, { - - itemCls : "x-menu-sep", - - hideOnClick : false, - - - activeClass: '', + setSize: function(width, height) { + var me = this, + headerCt = me.ownerCt, + ownerHeaderCt = me.getOwnerHeaderCt(), + siblings, + len, i, + oldWidth = me.getWidth(), + newWidth = 0; - - onRender : function(li){ - var s = document.createElement("span"); - s.className = this.itemCls; - s.innerHTML = " "; - this.el = s; - li.addClass("x-menu-sep-li"); - Ext.menu.Separator.superclass.onRender.apply(this, arguments); - } -}); -Ext.reg('menuseparator', Ext.menu.Separator); -Ext.menu.Item = Ext.extend(Ext.menu.BaseItem, { - - - - - - - - - itemCls : 'x-menu-item', - - canActivate : true, - - showDelay: 200, - - - altText: '', - - - hideDelay: 200, + if (width !== oldWidth) { + + + if (headerCt.isGroupHeader) { + + siblings = headerCt.items.items; + len = siblings.length; + + + if (siblings[len - 1].rendered) { + + for (i = 0; i < len; i++) { + newWidth += (siblings[i] === me) ? width : siblings[i].getWidth(); + } + headerCt.minWidth = newWidth; + headerCt.setWidth(newWidth); + } + } + me.callParent(arguments); + } + }, - - ctype: 'Ext.menu.Item', + afterComponentLayout: function(width, height) { + var me = this, + ownerHeaderCt = this.getOwnerHeaderCt(); - initComponent : function(){ - Ext.menu.Item.superclass.initComponent.call(this); - if(this.menu){ - this.menu = Ext.menu.MenuMgr.get(this.menu); - this.menu.ownerCt = this; + me.callParent(arguments); + + + + + if (width && !me.isGroupHeader && ownerHeaderCt) { + ownerHeaderCt.onHeaderResize(me, width, true); } }, - onRender : function(container, position){ - if (!this.itemTpl) { - this.itemTpl = Ext.menu.Item.prototype.itemTpl = new Ext.XTemplate( - '', - ' target="{hrefTarget}"', - '', - '>', - '{altText}', - '{text}', - '' - ); + + setPadding: function() { + var me = this, + headerHeight, + lineHeight = parseInt(me.textEl.getStyle('line-height'), 10); + + + if (!me.isGroupHeader) { + headerHeight = me.el.getViewSize().height; + if (me.titleContainer.getHeight() < headerHeight) { + me.titleContainer.dom.style.height = headerHeight + 'px'; + } + } + headerHeight = me.titleContainer.getViewSize().height; + + + if (lineHeight) { + me.titleContainer.setStyle({ + paddingTop: Math.max(((headerHeight - lineHeight) / 2), 0) + 'px' + }); } - var a = this.getTemplateArgs(); - this.el = position ? this.itemTpl.insertBefore(position, a, true) : this.itemTpl.append(container, a, true); - this.iconEl = this.el.child('img.x-menu-item-icon'); - this.textEl = this.el.child('.x-menu-item-text'); - if(!this.href) { - this.mon(this.el, 'click', Ext.emptyFn, null, { preventDefault: true }); + + + if (Ext.isIE && me.triggerEl) { + me.triggerEl.setHeight(headerHeight); } - Ext.menu.Item.superclass.onRender.call(this, container, position); }, - getTemplateArgs: function() { - return { - id: this.id, - cls: this.itemCls + (this.menu ? ' x-menu-item-arrow' : '') + (this.cls ? ' ' + this.cls : ''), - href: this.href || '#', - hrefTarget: this.hrefTarget, - icon: this.icon || Ext.BLANK_IMAGE_URL, - iconCls: this.iconCls || '', - text: this.itemText||this.text||' ', - altText: this.altText || '' - }; + onDestroy: function() { + var me = this; + Ext.destroy(me.keyNav); + delete me.keyNav; + me.callParent(arguments); }, - - setText : function(text){ - this.text = text||' '; - if(this.rendered){ - this.textEl.update(this.text); - this.parentMenu.layout.doAutoSize(); - } + onTitleMouseOver: function() { + this.titleContainer.addCls(this.hoverCls); }, - - setIconClass : function(cls){ - var oldCls = this.iconCls; - this.iconCls = cls; - if(this.rendered){ - this.iconEl.replaceClass(oldCls, this.iconCls); - } + onTitleMouseOut: function() { + this.titleContainer.removeCls(this.hoverCls); }, - - beforeDestroy: function(){ - if (this.menu){ - delete this.menu.ownerCt; - this.menu.destroy(); + onDownKey: function(e) { + if (this.triggerEl) { + this.onElClick(e, this.triggerEl.dom || this.el.dom); } - Ext.menu.Item.superclass.beforeDestroy.call(this); }, - - handleClick : function(e){ - if(!this.href){ - e.stopEvent(); - } - Ext.menu.Item.superclass.handleClick.apply(this, arguments); + onEnterKey: function(e) { + this.onElClick(e, this.el.dom); }, - activate : function(autoExpand){ - if(Ext.menu.Item.superclass.activate.apply(this, arguments)){ - this.focus(); - if(autoExpand){ - this.expandMenu(); - } + onElDblClick: function(e, t) { + var me = this, + ownerCt = me.ownerCt; + if (ownerCt && Ext.Array.indexOf(ownerCt.items, me) !== 0 && me.isOnLeftEdge(e) ) { + ownerCt.expandToFit(me.previousSibling('gridcolumn')); } - return true; }, - - shouldDeactivate : function(e){ - if(Ext.menu.Item.superclass.shouldDeactivate.call(this, e)){ - if(this.menu && this.menu.isVisible()){ - return !this.menu.getEl().getRegion().contains(e.getPoint()); + onElClick: function(e, t) { + + + var me = this, + ownerHeaderCt = me.getOwnerHeaderCt(); + + if (ownerHeaderCt && !ownerHeaderCt.ddLock) { + + + if (me.triggerEl && (e.target === me.triggerEl.dom || t === me.triggerEl.dom || e.within(me.triggerEl))) { + ownerHeaderCt.onHeaderTriggerClick(me, e, t); + + } else if (e.getKey() || (!me.isOnLeftEdge(e) && !me.isOnRightEdge(e))) { + me.toggleSortState(); + ownerHeaderCt.onHeaderClick(me, e, t); } - return true; } - return false; }, - deactivate : function(){ - Ext.menu.Item.superclass.deactivate.apply(this, arguments); - this.hideMenu(); + processEvent: function(type, view, cell, recordIndex, cellIndex, e) { + return this.fireEvent.apply(this, arguments); }, - - expandMenu : function(autoActivate){ - if(!this.disabled && this.menu){ - clearTimeout(this.hideTimer); - delete this.hideTimer; - if(!this.menu.isVisible() && !this.showTimer){ - this.showTimer = this.deferExpand.defer(this.showDelay, this, [autoActivate]); - }else if (this.menu.isVisible() && autoActivate){ - this.menu.tryActivate(0, 1); - } + toggleSortState: function() { + var me = this, + idx, + nextIdx; + + if (me.sortable) { + idx = Ext.Array.indexOf(me.possibleSortStates, me.sortState); + + nextIdx = (idx + 1) % me.possibleSortStates.length; + me.setSortState(me.possibleSortStates[nextIdx]); } }, - - deferExpand : function(autoActivate){ - delete this.showTimer; - this.menu.show(this.container, this.parentMenu.subMenuAlign || 'tl-tr?', this.parentMenu); - if(autoActivate){ - this.menu.tryActivate(0, 1); - } + doSort: function(state) { + var ds = this.up('tablepanel').store; + ds.sort({ + property: this.getSortParam(), + direction: state + }); }, - hideMenu : function(){ - clearTimeout(this.showTimer); - delete this.showTimer; - if(!this.hideTimer && this.menu && this.menu.isVisible()){ - this.hideTimer = this.deferHide.defer(this.hideDelay, this); - } + getSortParam: function() { + return this.dataIndex; }, - deferHide : function(){ - delete this.hideTimer; - if(this.menu.over){ - this.parentMenu.setActiveItem(this, false); - }else{ - this.menu.hide(); - } - } -}); -Ext.reg('menuitem', Ext.menu.Item); -Ext.menu.CheckItem = Ext.extend(Ext.menu.Item, { - - itemCls : "x-menu-item x-menu-check-item", - - groupClass : "x-menu-group-item", + setSortState: function(state, skipClear, initial) { + var me = this, + colSortClsPrefix = Ext.baseCSSPrefix + 'column-header-sort-', + ascCls = colSortClsPrefix + 'ASC', + descCls = colSortClsPrefix + 'DESC', + nullCls = colSortClsPrefix + 'null', + ownerHeaderCt = me.getOwnerHeaderCt(), + oldSortState = me.sortState; + + if (oldSortState !== state && me.getSortParam()) { + me.addCls(colSortClsPrefix + state); + + if (state && !initial) { + me.doSort(state); + } + switch (state) { + case 'DESC': + me.removeCls([ascCls, nullCls]); + break; + case 'ASC': + me.removeCls([descCls, nullCls]); + break; + case null: + me.removeCls([ascCls, descCls]); + break; + } + if (ownerHeaderCt && !me.triStateSort && !skipClear) { + ownerHeaderCt.clearOtherSortStates(me); + } + me.sortState = state; + ownerHeaderCt.fireEvent('sortchange', ownerHeaderCt, me, state); + } + }, - - checked: false, + hide: function() { + var me = this, + items, + len, i, + lb, + newWidth = 0, + ownerHeaderCt = me.getOwnerHeaderCt(); - - ctype: "Ext.menu.CheckItem", - - initComponent : function(){ - Ext.menu.CheckItem.superclass.initComponent.call(this); - this.addEvents( - - "beforecheckchange" , - - "checkchange" - ); - - if(this.checkHandler){ - this.on('checkchange', this.checkHandler, this.scope); - } - Ext.menu.MenuMgr.registerCheckable(this); - }, + + me.oldWidth = me.getWidth(); - - onRender : function(c){ - Ext.menu.CheckItem.superclass.onRender.apply(this, arguments); - if(this.group){ - this.el.addClass(this.groupClass); - } - if(this.checked){ - this.checked = false; - this.setChecked(true, true); + + if (me.isGroupHeader) { + items = me.items.items; + me.callParent(arguments); + ownerHeaderCt.onHeaderHide(me); + for (i = 0, len = items.length; i < len; i++) { + items[i].hidden = true; + ownerHeaderCt.onHeaderHide(items[i], true); + } + return; } - }, - - destroy : function(){ - Ext.menu.MenuMgr.unregisterCheckable(this); - Ext.menu.CheckItem.superclass.destroy.apply(this, arguments); - }, + + lb = me.ownerCt.componentLayout.layoutBusy; + me.ownerCt.componentLayout.layoutBusy = true; + me.callParent(arguments); + me.ownerCt.componentLayout.layoutBusy = lb; - - setChecked : function(state, suppressEvent){ - var suppress = suppressEvent === true; - if(this.checked != state && (suppress || this.fireEvent("beforecheckchange", this, state) !== false)){ - Ext.menu.MenuMgr.onCheckChange(this, state); - if(this.container){ - this.container[state ? "addClass" : "removeClass"]("x-menu-item-checked"); + + ownerHeaderCt.onHeaderHide(me); + + if (me.ownerCt.isGroupHeader) { + + items = me.ownerCt.query('>:not([hidden])'); + if (!items.length) { + me.ownerCt.hide(); } - this.checked = state; - if(!suppress){ - this.fireEvent("checkchange", this, state); + + else { + for (i = 0, len = items.length; i < len; i++) { + newWidth += items[i].getWidth(); + } + me.ownerCt.minWidth = newWidth; + me.ownerCt.setWidth(newWidth); } } }, - - handleClick : function(e){ - if(!this.disabled && !(this.checked && this.group)){ - this.setChecked(!this.checked); - } - Ext.menu.CheckItem.superclass.handleClick.apply(this, arguments); - } -}); -Ext.reg('menucheckitem', Ext.menu.CheckItem); - Ext.menu.DateMenu = Ext.extend(Ext.menu.Menu, { - - enableScrolling : false, - + show: function() { + var me = this, + ownerCt = me.getOwnerHeaderCt(), + lb, + items, + len, i, + newWidth = 0; + - - hideOnClick : true, - - - pickerId : null, - - - - - cls : 'x-date-menu', - - - - + lb = me.ownerCt.componentLayout.layoutBusy; + me.ownerCt.componentLayout.layoutBusy = true; + me.callParent(arguments); + me.ownerCt.componentLayout.layoutBusy = lb; - initComponent : function(){ - this.on('beforeshow', this.onBeforeShow, this); - if(this.strict = (Ext.isIE7 && Ext.isStrict)){ - this.on('show', this.onShow, this, {single: true, delay: 20}); + + if (me.isSubHeader) { + if (!me.ownerCt.isVisible()) { + me.ownerCt.show(); + } } - Ext.apply(this, { - plain: true, - showSeparator: false, - items: this.picker = new Ext.DatePicker(Ext.applyIf({ - internalRender: this.strict || !Ext.isIE, - ctCls: 'x-menu-date-item', - id: this.pickerId - }, this.initialConfig)) - }); - this.picker.purgeListeners(); - Ext.menu.DateMenu.superclass.initComponent.call(this); - - this.relayEvents(this.picker, ['select']); - this.on('show', this.picker.focus, this.picker); - this.on('select', this.menuHide, this); - if(this.handler){ - this.on('select', this.handler, this.scope || this); + + + if (me.isGroupHeader && !me.query(':not([hidden])').length) { + items = me.query('>*'); + for (i = 0, len = items.length; i < len; i++) { + items[i].show(); + } + } + + + if (me.ownerCt.isGroupHeader) { + items = me.ownerCt.query('>:not([hidden])'); + for (i = 0, len = items.length; i < len; i++) { + newWidth += items[i].getWidth(); + } + me.ownerCt.minWidth = newWidth; + me.ownerCt.setWidth(newWidth); } - }, - menuHide : function() { - if(this.hideOnClick){ - this.hide(true); + + if (ownerCt) { + ownerCt.onHeaderShow(me); } }, - onBeforeShow : function(){ - if(this.picker){ - this.picker.hideMonthPicker(true); + getDesiredWidth: function() { + var me = this; + if (me.rendered && me.componentLayout && me.componentLayout.lastComponentSize) { + + + + + + + return me.componentLayout.lastComponentSize.width; + + + + } + else if (me.flex) { + + return me.width; + } + else { + return me.width; } }, - onShow : function(){ - var el = this.picker.getEl(); - el.setWidth(el.getWidth()); + getCellSelector: function() { + return '.' + Ext.baseCSSPrefix + 'grid-cell-' + this.getItemId(); + }, + + getCellInnerSelector: function() { + return this.getCellSelector() + ' .' + Ext.baseCSSPrefix + 'grid-cell-inner'; + }, + + isOnLeftEdge: function(e) { + return (e.getXY()[0] - this.el.getLeft() <= this.handleWidth); + }, + + isOnRightEdge: function(e) { + return (this.el.getRight() - e.getXY()[0] <= this.handleWidth); } - }); - Ext.reg('datemenu', Ext.menu.DateMenu); - - Ext.menu.ColorMenu = Ext.extend(Ext.menu.Menu, { - - enableScrolling : false, - - - - - hideOnClick : true, - - cls : 'x-color-menu', - - - paletteId : null, @@ -39269,11988 +76980,11394 @@ Ext.reg('menucheckitem', Ext.menu.CheckItem); +}); + +Ext.define('Ext.grid.RowNumberer', { + extend: 'Ext.grid.column.Column', + alias: 'widget.rownumberer', + text: " ", + + width: 23, + - initComponent : function(){ - Ext.apply(this, { - plain: true, - showSeparator: false, - items: this.palette = new Ext.ColorPalette(Ext.applyIf({ - id: this.paletteId - }, this.initialConfig)) - }); - this.palette.purgeListeners(); - Ext.menu.ColorMenu.superclass.initComponent.call(this); - - this.relayEvents(this.palette, ['select']); - this.on('select', this.menuHide, this); - if(this.handler){ - this.on('select', this.handler, this.scope || this); + sortable: false, + + align: 'right', + + constructor : function(config){ + this.callParent(arguments); + if (this.rowspan) { + this.renderer = Ext.Function.bind(this.renderer, this); } }, - menuHide : function(){ - if(this.hideOnClick){ - this.hide(true); + + fixed: true, + hideable: false, + menuDisabled: true, + dataIndex: '', + cls: Ext.baseCSSPrefix + 'row-numberer', + rowspan: undefined, + + + renderer: function(value, metaData, record, rowIdx, colIdx, store) { + if (this.rowspan){ + metaData.cellAttr = 'rowspan="'+this.rowspan+'"'; } + + metaData.tdCls = Ext.baseCSSPrefix + 'grid-cell-special'; + return store.indexOfTotal(record) + 1; } }); -Ext.reg('colormenu', Ext.menu.ColorMenu); -Ext.form.Field = Ext.extend(Ext.BoxComponent, { - - - - - - - - invalidClass : 'x-form-invalid', - - invalidText : 'The value in this field is invalid', - - focusClass : 'x-form-focus', - - - validationEvent : 'keyup', - - validateOnBlur : true, - - validationDelay : 250, - - defaultAutoCreate : {tag: 'input', type: 'text', size: '20', autocomplete: 'off'}, - - fieldClass : 'x-form-field', - - msgTarget : 'qtip', - - msgFx : 'normal', - - readOnly : false, - - disabled : false, - - submitValue: true, +Ext.define('Ext.view.DropZone', { + extend: 'Ext.dd.DropZone', - - isFormField : true, + indicatorHtml: '
    ', + indicatorCls: 'x-grid-drop-indicator', - - msgDisplay: '', + constructor: function(config) { + var me = this; + Ext.apply(me, config); - - hasFocus : false, + + + + + + if (!me.ddGroup) { + me.ddGroup = 'view-dd-zone-' + me.view.id; + } - - initComponent : function(){ - Ext.form.Field.superclass.initComponent.call(this); - this.addEvents( - - 'focus', - - 'blur', - - 'specialkey', - - 'change', - - 'invalid', - - 'valid' - ); + + + + me.callParent([me.view.el]); }, - - getName : function(){ - return this.rendered && this.el.dom.name ? this.el.dom.name : this.name || this.id || ''; + + + fireViewEvent: function() { + this.lock(); + var result = this.view.fireEvent.apply(this.view, arguments); + this.unlock(); + return result; }, - - onRender : function(ct, position){ - if(!this.el){ - var cfg = this.getAutoCreate(); + getTargetFromEvent : function(e) { + var node = e.getTarget(this.view.getItemSelector()), + mouseY, nodeList, testNode, i, len, box; - if(!cfg.name){ - cfg.name = this.name || this.id; - } - if(this.inputType){ - cfg.type = this.inputType; - } - this.autoEl = cfg; - } - Ext.form.Field.superclass.onRender.call(this, ct, position); - if(this.submitValue === false){ - this.el.dom.removeAttribute('name'); - } - var type = this.el.dom.type; - if(type){ - if(type == 'password'){ - type = 'text'; + + + if (!node) { + mouseY = e.getPageY(); + for (i = 0, nodeList = this.view.getNodes(), len = nodeList.length; i < len; i++) { + testNode = nodeList[i]; + box = Ext.fly(testNode).getBox(); + if (mouseY <= box.bottom) { + return testNode; + } } - this.el.addClass('x-form-'+type); - } - if(this.readOnly){ - this.setReadOnly(true); - } - if(this.tabIndex !== undefined){ - this.el.dom.setAttribute('tabIndex', this.tabIndex); } - - this.el.addClass([this.fieldClass, this.cls]); + return node; }, - - getItemCt : function(){ - return this.itemCt; + getIndicator: function() { + var me = this; + + if (!me.indicator) { + me.indicator = Ext.createWidget('component', { + html: me.indicatorHtml, + cls: me.indicatorCls, + ownerCt: me.view, + floating: true, + shadow: false + }); + } + return me.indicator; }, - - initValue : function(){ - if(this.value !== undefined){ - this.setValue(this.value); - }else if(!Ext.isEmpty(this.el.dom.value) && this.el.dom.value != this.emptyText){ - this.setValue(this.el.dom.value); + getPosition: function(e, node) { + var y = e.getXY()[1], + region = Ext.fly(node).getRegion(), + pos; + + if ((region.bottom - y) >= (region.bottom - region.top) / 2) { + pos = "before"; + } else { + pos = "after"; } - - this.originalValue = this.getValue(); + return pos; }, - isDirty : function() { - if(this.disabled || !this.rendered) { + containsRecordAtOffset: function(records, record, offset) { + if (!record) { return false; } - return String(this.getValue()) !== String(this.originalValue); + var view = this.view, + recordIndex = view.indexOf(record), + nodeBefore = view.getNode(recordIndex + offset), + recordBefore = nodeBefore ? view.getRecord(nodeBefore) : null; + + return recordBefore && Ext.Array.contains(records, recordBefore); }, - - setReadOnly : function(readOnly){ - if(this.rendered){ - this.el.dom.readOnly = readOnly; + positionIndicator: function(node, data, e) { + var me = this, + view = me.view, + pos = me.getPosition(e, node), + overRecord = view.getRecord(node), + draggingRecords = data.records, + indicator, indicatorY; + + if (!Ext.Array.contains(draggingRecords, overRecord) && ( + pos == 'before' && !me.containsRecordAtOffset(draggingRecords, overRecord, -1) || + pos == 'after' && !me.containsRecordAtOffset(draggingRecords, overRecord, 1) + )) { + me.valid = true; + + if (me.overRecord != overRecord || me.currentPosition != pos) { + + indicatorY = Ext.fly(node).getY() - view.el.getY() - 1; + if (pos == 'after') { + indicatorY += Ext.fly(node).getHeight(); + } + me.getIndicator().setWidth(Ext.fly(view.el).getWidth()).showAt(0, indicatorY); + + + me.overRecord = overRecord; + me.currentPosition = pos; + } + } else { + me.invalidateDrop(); } - this.readOnly = readOnly; }, - - afterRender : function(){ - Ext.form.Field.superclass.afterRender.call(this); - this.initEvents(); - this.initValue(); + invalidateDrop: function() { + if (this.valid) { + this.valid = false; + this.getIndicator().hide(); + } }, - fireKey : function(e){ - if(e.isSpecialKey()){ - this.fireEvent('specialkey', this, e); + onNodeOver: function(node, dragZone, e, data) { + if (!Ext.Array.contains(data.records, this.view.getRecord(node))) { + this.positionIndicator(node, data, e); } + return this.valid ? this.dropAllowed : this.dropNotAllowed; }, - reset : function(){ - this.setValue(this.originalValue); - this.clearInvalid(); + + notifyOut: function(node, dragZone, e, data) { + this.callParent(arguments); + delete this.overRecord; + delete this.currentPosition; + if (this.indicator) { + this.indicator.hide(); + } }, - initEvents : function(){ - this.mon(this.el, Ext.EventManager.getKeyEvent(), this.fireKey, this); - this.mon(this.el, 'focus', this.onFocus, this); + onContainerOver : function(dd, e, data) { + var v = this.view, + c = v.store.getCount(); + if (c) { + this.positionIndicator(v.getNode(c - 1), data, e); + } + - this.mon(this.el, 'blur', this.onBlur, this, this.inEditor ? {buffer:10} : null); + else { + delete this.overRecord; + delete this.currentPosition; + this.getIndicator().setWidth(Ext.fly(v.el).getWidth()).showAt(0, 0); + this.valid = true; + } + return this.dropAllowed; }, - - preFocus: Ext.emptyFn, + onContainerDrop : function(dd, e, data) { + return this.onNodeDrop(dd, null, e, data); + }, - - onFocus : function(){ - this.preFocus(); - if(this.focusClass){ - this.el.addClass(this.focusClass); - } - if(!this.hasFocus){ - this.hasFocus = true; + onNodeDrop: function(node, dragZone, e, data) { + var me = this, + dropped = false, + + + + - this.startValue = this.getValue(); - this.fireEvent('focus', this); + processDrop = function () { + me.invalidateDrop(); + me.handleNodeDrop(data, me.overRecord, me.currentPosition); + dropped = true; + me.fireViewEvent('drop', node, data, me.overRecord, me.currentPosition); + }, + performOperation; + + if (me.valid) { + performOperation = me.fireViewEvent('beforedrop', node, data, me.overRecord, me.currentPosition, processDrop); + if (performOperation === 0) { + return; + } else if (performOperation !== false) { + + if (!dropped) { + processDrop(); + } + } else { + return false; + } + } else { + return false; } - }, + } +}); - - beforeBlur : Ext.emptyFn, +Ext.define('Ext.grid.ViewDropZone', { + extend: 'Ext.view.DropZone', - - onBlur : function(){ - this.beforeBlur(); - if(this.focusClass){ - this.el.removeClass(this.focusClass); - } - this.hasFocus = false; - if(this.validationEvent !== false && (this.validateOnBlur || this.validationEvent == 'blur')){ - this.validate(); - } - var v = this.getValue(); - if(String(v) !== String(this.startValue)){ - this.fireEvent('change', this, v, this.startValue); - } - this.fireEvent('blur', this); - this.postBlur(); - }, + indicatorHtml: '
    ', + indicatorCls: 'x-grid-drop-indicator', - - postBlur : Ext.emptyFn, + handleNodeDrop : function(data, record, position) { + var view = this.view, + store = view.getStore(), + index, records, i, len; - - isValid : function(preventMark){ - if(this.disabled){ - return true; + + if (data.copy) { + records = data.records; + data.records = []; + for (i = 0, len = records.length; i < len; i++) { + data.records.push(records[i].copy(records[i].getId())); + } + } else { + + data.view.store.remove(data.records, data.view === view); } - var restore = this.preventMark; - this.preventMark = preventMark === true; - var v = this.validateValue(this.processValue(this.getRawValue())); - this.preventMark = restore; - return v; - }, - - validate : function(){ - if(this.disabled || this.validateValue(this.processValue(this.getRawValue()))){ - this.clearInvalid(); - return true; + index = store.indexOf(record); + if (position == 'after') { + index++; } - return false; - }, + store.insert(index, data.records); + view.getSelectionModel().select(data.records); + } +}); - - processValue : function(value){ - return value; - }, +Ext.define('Ext.grid.column.Action', { + extend: 'Ext.grid.column.Column', + alias: ['widget.actioncolumn'], + alternateClassName: 'Ext.grid.ActionColumn', - validateValue : function(value) { - - var error = this.getErrors(value)[0]; - - if (error == undefined) { - return true; - } else { - this.markInvalid(error); - return false; - } - }, - getErrors: function() { - return []; - }, - - getActiveError : function(){ - return this.activeError || ''; - }, - - markInvalid : function(msg){ - - if (this.rendered && !this.preventMark) { - msg = msg || this.invalidText; + + + + header: ' ', + + actionIdRe: /x-action-col-(\d+)/, - var mt = this.getMessageHandler(); - if(mt){ - mt.mark(this, msg); - }else if(this.msgTarget){ - this.el.addClass(this.invalidClass); - var t = Ext.getDom(this.msgTarget); - if(t){ - t.innerHTML = msg; - t.style.display = this.msgDisplay; - } - } - } - - this.setActiveError(msg); - }, + altText: '', - clearInvalid : function(){ + sortable: false, + + constructor: function(config) { + var me = this, + cfg = Ext.apply({}, config), + items = cfg.items || [me], + l = items.length, + i, + item; + - if (this.rendered && !this.preventMark) { - this.el.removeClass(this.invalidClass); - var mt = this.getMessageHandler(); - if(mt){ - mt.clear(this); - }else if(this.msgTarget){ - this.el.removeClass(this.invalidClass); - var t = Ext.getDom(this.msgTarget); - if(t){ - t.innerHTML = ''; - t.style.display = 'none'; - } - } - } + delete cfg.items; + this.callParent([cfg]); + - this.unsetActiveError(); - }, + me.items = items; - - setActiveError: function(msg, suppressEvent) { - this.activeError = msg; - if (suppressEvent !== true) this.fireEvent('invalid', this, msg); - }, - - - unsetActiveError: function(suppressEvent) { - delete this.activeError; - if (suppressEvent !== true) this.fireEvent('valid', this); - }, - - getMessageHandler : function(){ - return Ext.form.MessageTargets[this.msgTarget]; - }, - - getErrorCt : function(){ - return this.el.findParent('.x-form-element', 5, true) || - this.el.findParent('.x-form-field-wrap', 5, true); - }, + me.renderer = function(v, meta) { - - alignErrorEl : function(){ - this.errorEl.setWidth(this.getErrorCt().getWidth(true) - 20); - }, + v = Ext.isFunction(cfg.renderer) ? cfg.renderer.apply(this, arguments)||'' : ''; - - alignErrorIcon : function(){ - this.errorIcon.alignTo(this.el, 'tl-tr', [2, 0]); + meta.tdCls += ' ' + Ext.baseCSSPrefix + 'action-col-cell'; + for (i = 0; i < l; i++) { + item = items[i]; + v += '' + me.altText + ''; + } + return v; + }; }, - - getRawValue : function(){ - var v = this.rendered ? this.el.getValue() : Ext.value(this.value, ''); - if(v === this.emptyText){ - v = ''; - } - return v; + destroy: function() { + delete this.items; + delete this.renderer; + return this.callParent(arguments); }, - getValue : function(){ - if(!this.rendered) { - return this.value; - } - var v = this.el.getValue(); - if(v === this.emptyText || v === undefined){ - v = ''; + processEvent : function(type, view, cell, recordIndex, cellIndex, e){ + var m = e.getTarget().className.match(this.actionIdRe), + item, fn; + if (m && (item = this.items[parseInt(m[1], 10)])) { + if (type == 'click') { + fn = item.handler; + if (fn || this.handler) { + fn.call(item.scope||this.scope||this, view, recordIndex, cellIndex, item, e); + } + } else if ((type == 'mousedown') && (item.stopSelection !== false)) { + return false; + } } - return v; - }, - - - setRawValue : function(v){ - return this.rendered ? (this.el.dom.value = (Ext.isEmpty(v) ? '' : v)) : ''; + return this.callParent(arguments); }, - - setValue : function(v){ - this.value = v; - if(this.rendered){ - this.el.dom.value = (Ext.isEmpty(v) ? '' : v); - this.validate(); - } - return this; + cascade: function(fn, scope) { + fn.call(scope||this, this); }, - append : function(v){ - this.setValue([this.getValue(), v].join('')); + getRefItems: function() { + return []; } +}); + +Ext.define('Ext.grid.column.Boolean', { + extend: 'Ext.grid.column.Column', + alias: ['widget.booleancolumn'], + alternateClassName: 'Ext.grid.BooleanColumn', + trueText: 'true', + + falseText: 'false', -}); + undefinedText: ' ', + constructor: function(cfg){ + this.callParent(arguments); + var trueText = this.trueText, + falseText = this.falseText, + undefinedText = this.undefinedText; -Ext.form.MessageTargets = { - 'qtip' : { - mark: function(field, msg){ - field.el.addClass(field.invalidClass); - field.el.dom.qtip = msg; - field.el.dom.qclass = 'x-form-invalid-tip'; - if(Ext.QuickTips){ - Ext.QuickTips.enable(); - } - }, - clear: function(field){ - field.el.removeClass(field.invalidClass); - field.el.dom.qtip = ''; - } - }, - 'title' : { - mark: function(field, msg){ - field.el.addClass(field.invalidClass); - field.el.dom.title = msg; - }, - clear: function(field){ - field.el.dom.title = ''; - } - }, - 'under' : { - mark: function(field, msg){ - field.el.addClass(field.invalidClass); - if(!field.errorEl){ - var elp = field.getErrorCt(); - if(!elp){ - field.el.dom.title = msg; - return; - } - field.errorEl = elp.createChild({cls:'x-form-invalid-msg'}); - field.on('resize', field.alignErrorEl, field); - field.on('destroy', function(){ - Ext.destroy(this.errorEl); - }, field); - } - field.alignErrorEl(); - field.errorEl.update(msg); - Ext.form.Field.msgFx[field.msgFx].show(field.errorEl, field); - }, - clear: function(field){ - field.el.removeClass(field.invalidClass); - if(field.errorEl){ - Ext.form.Field.msgFx[field.msgFx].hide(field.errorEl, field); - }else{ - field.el.dom.title = ''; + this.renderer = function(value){ + if(value === undefined){ + return undefinedText; } - } - }, - 'side' : { - mark: function(field, msg){ - field.el.addClass(field.invalidClass); - if(!field.errorIcon){ - var elp = field.getErrorCt(); - - if(!elp){ - field.el.dom.title = msg; - return; - } - field.errorIcon = elp.createChild({cls:'x-form-invalid-icon'}); - if (field.ownerCt) { - field.ownerCt.on('afterlayout', field.alignErrorIcon, field); - field.ownerCt.on('expand', field.alignErrorIcon, field); - } - field.on('resize', field.alignErrorIcon, field); - field.on('destroy', function(){ - Ext.destroy(this.errorIcon); - }, field); - } - field.alignErrorIcon(); - field.errorIcon.dom.qtip = msg; - field.errorIcon.dom.qclass = 'x-form-invalid-tip'; - field.errorIcon.show(); - }, - clear: function(field){ - field.el.removeClass(field.invalidClass); - if(field.errorIcon){ - field.errorIcon.dom.qtip = ''; - field.errorIcon.hide(); - }else{ - field.el.dom.title = ''; + if(!value || value === 'false'){ + return falseText; } - } + return trueText; + }; } -}; +}); +Ext.define('Ext.grid.column.Date', { + extend: 'Ext.grid.column.Column', + alias: ['widget.datecolumn'], + requires: ['Ext.Date'], + alternateClassName: 'Ext.grid.DateColumn', -Ext.form.Field.msgFx = { - normal : { - show: function(msgEl, f){ - msgEl.setDisplayed('block'); - }, + + format : Ext.Date.defaultFormat, - hide : function(msgEl, f){ - msgEl.setDisplayed(false).update(''); - } - }, + constructor: function(cfg){ + this.callParent(arguments); + this.renderer = Ext.util.Format.dateRenderer(this.format); + } +}); - slide : { - show: function(msgEl, f){ - msgEl.slideIn('t', {stopFx:true}); - }, +Ext.define('Ext.grid.column.Number', { + extend: 'Ext.grid.column.Column', + alias: ['widget.numbercolumn'], + requires: ['Ext.util.Format'], + alternateClassName: 'Ext.grid.NumberColumn', - hide : function(msgEl, f){ - msgEl.slideOut('t', {stopFx:true,useDisplay:true}); - } - }, + + format : '0,000.00', + constructor: function(cfg) { + this.callParent(arguments); + this.renderer = Ext.util.Format.numberRenderer(this.format); + } +}); - slideRight : { - show: function(msgEl, f){ - msgEl.fixDisplay(); - msgEl.alignTo(f.el, 'tl-tr'); - msgEl.slideIn('l', {stopFx:true}); - }, +Ext.define('Ext.grid.column.Template', { + extend: 'Ext.grid.column.Column', + alias: ['widget.templatecolumn'], + requires: ['Ext.XTemplate'], + alternateClassName: 'Ext.grid.TemplateColumn', - hide : function(msgEl, f){ - msgEl.slideOut('l', {stopFx:true,useDisplay:true}); - } + + constructor: function(cfg){ + var me = this, + tpl; + + me.callParent(arguments); + tpl = me.tpl = (!Ext.isPrimitive(me.tpl) && me.tpl.compile) ? me.tpl : Ext.create('Ext.XTemplate', me.tpl); + + me.renderer = function(value, p, record) { + var data = Ext.apply({}, record.data, record.getAssociatedData()); + return tpl.apply(data); + }; } -}; -Ext.reg('field', Ext.form.Field); +}); -Ext.form.TextField = Ext.extend(Ext.form.Field, { - + +Ext.define('Ext.grid.feature.Feature', { + extend: 'Ext.util.Observable', + alias: 'feature.feature', + isFeature: true, + disabled: false, - grow : false, - growMin : 30, + hasFeatureEvent: true, - growMax : 800, - vtype : null, + eventPrefix: null, - maskRe : null, - disableKeyFilter : false, + eventSelector: null, - allowBlank : true, - minLength : 0, + view: null, - maxLength : Number.MAX_VALUE, - minLengthText : 'The minimum length for this field is {0}', + grid: null, - maxLengthText : 'The maximum length for this field is {0}', - selectOnFocus : false, + collectData: false, + + getFeatureTpl: function() { + return ''; + }, - blankText : 'This field is required', - validator : null, + getFireEventArgs: function(eventName, view, featureTarget) { + return [eventName, view, featureTarget]; + }, - regex : null, - regexText : '', + attachEvents: function() { + + }, - emptyText : null, + getFragmentTpl: function() { + return; + }, - emptyClass : 'x-form-empty-field', - - - initComponent : function(){ - Ext.form.TextField.superclass.initComponent.call(this); - this.addEvents( - - 'autosize', - - - 'keydown', - - 'keyup', - - 'keypress' - ); + mutateMetaRowTpl: function(metaRowTplArray) { + }, - - initEvents : function(){ - Ext.form.TextField.superclass.initEvents.call(this); - if(this.validationEvent == 'keyup'){ - this.validationTask = new Ext.util.DelayedTask(this.validate, this); - this.mon(this.el, 'keyup', this.filterValidation, this); - } - else if(this.validationEvent !== false && this.validationEvent != 'blur'){ - this.mon(this.el, this.validationEvent, this.validate, this, {buffer: this.validationDelay}); - } - if(this.selectOnFocus || this.emptyText){ - this.mon(this.el, 'mousedown', this.onMouseDown, this); - - if(this.emptyText){ - this.applyEmptyText(); - } - } - if(this.maskRe || (this.vtype && this.disableKeyFilter !== true && (this.maskRe = Ext.form.VTypes[this.vtype+'Mask']))){ - this.mon(this.el, 'keypress', this.filterKeys, this); - } - if(this.grow){ - this.mon(this.el, 'keyup', this.onKeyUpBuffered, this, {buffer: 50}); - this.mon(this.el, 'click', this.autoSize, this); - } - if(this.enableKeyEvents){ - this.mon(this.el, { - scope: this, - keyup: this.onKeyUp, - keydown: this.onKeyDown, - keypress: this.onKeyPress - }); - } - }, - onMouseDown: function(e){ - if(!this.hasFocus){ - this.mon(this.el, 'mouseup', Ext.emptyFn, this, { single: true, preventDefault: true }); - } - }, - - processValue : function(value){ - if(this.stripCharsRe){ - var newValue = value.replace(this.stripCharsRe, ''); - if(newValue !== value){ - this.setRawValue(newValue); - return newValue; - } - } - return value; + getMetaRowTplFragments: function() { + return {}; }, - filterValidation : function(e){ - if(!e.isNavKeyPress()){ - this.validationTask.delay(this.validationDelay); - } + getTableFragments: function() { + return {}; }, - onDisable: function(){ - Ext.form.TextField.superclass.onDisable.call(this); - if(Ext.isIE){ - this.el.dom.unselectable = 'on'; - } + getAdditionalData: function(data, idx, record, orig) { + return {}; }, - onEnable: function(){ - Ext.form.TextField.superclass.onEnable.call(this); - if(Ext.isIE){ - this.el.dom.unselectable = ''; - } + enable: function() { + this.disabled = false; }, - - onKeyUpBuffered : function(e){ - if(this.doAutoSize(e)){ - this.autoSize(); - } - }, + disable: function() { + this.disabled = true; + } - doAutoSize : function(e){ - return !e.isNavKeyPress(); - }, +}); +Ext.define('Ext.grid.feature.AbstractSummary', { - onKeyUp : function(e){ - this.fireEvent('keyup', this, e); - }, - - onKeyDown : function(e){ - this.fireEvent('keydown', this, e); + + extend: 'Ext.grid.feature.Feature', + + alias: 'feature.abstractsummary', + + + + + showSummaryRow: true, + + + nestedIdRe: /\{\{id\}([\w\-]*)\}/g, + + + toggleSummaryRow: function(visible){ + this.showSummaryRow = !!visible; }, - - onKeyPress : function(e){ - this.fireEvent('keypress', this, e); + + getSummaryFragments: function(){ + var fragments = {}; + if (this.showSummaryRow) { + Ext.apply(fragments, { + printSummaryRow: Ext.bind(this.printSummaryRow, this) + }); + } + return fragments; }, - - reset : function(){ - Ext.form.TextField.superclass.reset.call(this); - this.applyEmptyText(); + + printSummaryRow: function(index){ + var inner = this.view.getTableChunker().metaRowTpl.join(''); + + inner = inner.replace('x-grid-row', 'x-grid-row-summary'); + inner = inner.replace('{{id}}', '{gridSummaryValue}'); + inner = inner.replace(this.nestedIdRe, '{id$1}'); + inner = inner.replace('{[this.embedRowCls()]}', '{rowCls}'); + inner = inner.replace('{[this.embedRowAttr()]}', '{rowAttr}'); + inner = Ext.create('Ext.XTemplate', inner, { + firstOrLastCls: Ext.view.TableChunker.firstOrLastCls + }); + + return inner.applyTemplate({ + columns: this.getPrintData(index) + }); }, - - applyEmptyText : function(){ - if(this.rendered && this.emptyText && this.getRawValue().length < 1 && !this.hasFocus){ - this.setRawValue(this.emptyText); - this.el.addClass(this.emptyClass); + + + getColumnValue: function(column, data){ + var comp = Ext.getCmp(column.id), + value = data[column.dataIndex], + renderer = comp.summaryRenderer || comp.renderer; + + if (renderer) { + value = renderer.call(comp.scope || this, value, data, column.dataIndex); } + return value; }, - - preFocus : function(){ - var el = this.el, - isEmpty; - if(this.emptyText){ - if(el.dom.value == this.emptyText){ - this.setRawValue(''); - isEmpty = true; + + getSummary: function(store, type, field, group){ + if (type) { + if (Ext.isFunction(type)) { + return store.aggregate(type, null, group); + } + + switch (type) { + case 'count': + return store.count(group); + case 'min': + return store.min(field, group); + case 'max': + return store.max(field, group); + case 'sum': + return store.sum(field, group); + case 'average': + return store.average(field, group); + default: + return group ? {} : ''; + } - el.removeClass(this.emptyClass); - } - if(this.selectOnFocus || isEmpty){ - el.dom.select(); } - }, - + } - postBlur : function(){ - this.applyEmptyText(); - }, +}); + +Ext.define('Ext.grid.feature.Chunking', { + extend: 'Ext.grid.feature.Feature', + alias: 'feature.chunking', - filterKeys : function(e){ - if(e.ctrlKey){ - return; - } - var k = e.getKey(); - if(Ext.isGecko && (e.isNavKeyPress() || k == e.BACKSPACE || (k == e.DELETE && e.button == -1))){ - return; - } - var cc = String.fromCharCode(e.getCharCode()); - if(!Ext.isGecko && e.isSpecialKey() && !cc){ - return; - } - if(!this.maskRe.test(cc)){ - e.stopEvent(); - } + chunkSize: 20, + rowHeight: Ext.isIE ? 27 : 26, + visibleChunk: 0, + hasFeatureEvent: false, + attachEvents: function() { + var grid = this.view.up('gridpanel'), + scroller = grid.down('gridscroller[dock=right]'); + scroller.el.on('scroll', this.onBodyScroll, this, {buffer: 300}); + }, - - setValue : function(v){ - if(this.emptyText && this.el && !Ext.isEmpty(v)){ - this.el.removeClass(this.emptyClass); + + onBodyScroll: function(e, t) { + var view = this.view, + top = t.scrollTop, + nextChunk = Math.floor(top / this.rowHeight / this.chunkSize); + if (nextChunk !== this.visibleChunk) { + + this.visibleChunk = nextChunk; + view.refresh(); + view.el.dom.scrollTop = top; + + view.el.dom.scrollTop = top; } - Ext.form.TextField.superclass.setValue.apply(this, arguments); - this.applyEmptyText(); - this.autoSize(); - return this; }, - - getErrors: function(value) { - var errors = Ext.form.TextField.superclass.getErrors.apply(this, arguments); - - value = Ext.isDefined(value) ? value : this.processValue(this.getRawValue()); + collectData: function(records, preppedRecords, startIndex, fullWidth, orig) { + var o = { + fullWidth: orig.fullWidth, + chunks: [] + }, - if (Ext.isFunction(this.validator)) { - var msg = this.validator(value); - if (msg !== true) { - errors.push(msg); - } - } - if (value.length < 1 || value === this.emptyText) { - if (this.allowBlank) { - - return errors; + recordCount = orig.rows.length, + start = 0, + i = 0, + visibleChunk = this.visibleChunk, + chunk, + rows, + chunkLength; + + for (; start < recordCount; start+=this.chunkSize, i++) { + if (start+this.chunkSize > recordCount) { + chunkLength = recordCount - start; } else { - errors.push(this.blankText); + chunkLength = this.chunkSize; } - } - - if (!this.allowBlank && (value.length < 1 || value === this.emptyText)) { - errors.push(this.blankText); - } - - if (value.length < this.minLength) { - errors.push(String.format(this.minLengthText, this.minLength)); - } - - if (value.length > this.maxLength) { - errors.push(String.format(this.maxLengthText, this.maxLength)); - } - - if (this.vtype) { - var vt = Ext.form.VTypes; - if(!vt[this.vtype](value, this)){ - errors.push(this.vtypeText || vt[this.vtype +'Text']); + + if (i >= visibleChunk - 1 && i <= visibleChunk + 1) { + rows = orig.rows.slice(start, start+this.chunkSize); + } else { + rows = []; } + o.chunks.push({ + rows: rows, + fullWidth: fullWidth, + chunkHeight: chunkLength * this.rowHeight + }); } - if (this.regex && !this.regex.test(value)) { - errors.push(this.regexText); - } - return errors; + return o; }, - - selectText : function(start, end){ - var v = this.getRawValue(); - var doFocus = false; - if(v.length > 0){ - start = start === undefined ? 0 : start; - end = end === undefined ? v.length : end; - var d = this.el.dom; - if(d.setSelectionRange){ - d.setSelectionRange(start, end); - }else if(d.createTextRange){ - var range = d.createTextRange(); - range.moveStart('character', start); - range.moveEnd('character', end-v.length); - range.select(); + getTableFragments: function() { + return { + openTableWrap: function() { + return '
    '; + }, + closeTableWrap: function() { + return '
    '; } - doFocus = Ext.isGecko || Ext.isOpera; - }else{ - doFocus = true; - } - if(doFocus){ - this.focus(); - } - }, - - - autoSize : function(){ - if(!this.grow || !this.rendered){ - return; - } - if(!this.metrics){ - this.metrics = Ext.util.TextMetrics.createInstance(this.el); - } - var el = this.el; - var v = el.dom.value; - var d = document.createElement('div'); - d.appendChild(document.createTextNode(v)); - v = d.innerHTML; - Ext.removeNode(d); - d = null; - v += ' '; - var w = Math.min(this.growMax, Math.max(this.metrics.getWidth(v) + 10, this.growMin)); - this.el.setWidth(w); - this.fireEvent('autosize', this, w); - }, - - onDestroy: function(){ - if(this.validationTask){ - this.validationTask.cancel(); - this.validationTask = null; - } - Ext.form.TextField.superclass.onDestroy.call(this); - } + }; + } }); -Ext.reg('textfield', Ext.form.TextField); -Ext.form.TriggerField = Ext.extend(Ext.form.TextField, { + +Ext.define('Ext.grid.feature.Grouping', { + extend: 'Ext.grid.feature.Feature', + alias: 'feature.grouping', + + eventPrefix: 'group', + eventSelector: '.' + Ext.baseCSSPrefix + 'grid-group-hd', + + constructor: function() { + this.collapsedState = {}; + this.callParent(arguments); + }, + - defaultAutoCreate : {tag: "input", type: "text", size: "16", autocomplete: "off"}, + - hideTrigger:false, + - editable: true, + - readOnly: false, + - wrapFocusClass: 'x-trigger-wrap-focus', + groupHeaderTpl: 'Group: {name}', + - autoSize: Ext.emptyFn, + depthToIndent: 17, + + collapsedCls: Ext.baseCSSPrefix + 'grid-group-collapsed', + hdCollapsedCls: Ext.baseCSSPrefix + 'grid-group-hd-collapsed', + - monitorTab : true, + groupByText : 'Group By This Field', - deferHeight : true, + showGroupsText : 'Show in Groups', + - mimicing : false, + hideGroupedHeader : false, - actionMode: 'wrap', + + startCollapsed : false, - defaultTriggerWidth: 17, + + enableGroupingMenu : true, - onResize : function(w, h){ - Ext.form.TriggerField.superclass.onResize.call(this, w, h); - var tw = this.getTriggerWidth(); - if(Ext.isNumber(w)){ - this.el.setWidth(w - tw); + enableNoGroups : true, + + enable: function() { + var me = this, + view = me.view, + store = view.store, + groupToggleMenuItem; + + if (me.lastGroupIndex) { + store.group(me.lastGroupIndex); } - this.wrap.setWidth(this.el.getWidth() + tw); + me.callParent(); + groupToggleMenuItem = me.view.headerCt.getMenu().down('#groupToggleMenuItem'); + groupToggleMenuItem.setChecked(true, true); + view.refresh(); }, - getTriggerWidth: function(){ - var tw = this.trigger.getWidth(); - if(!this.hideTrigger && !this.readOnly && tw === 0){ - tw = this.defaultTriggerWidth; - } - return tw; + disable: function() { + var me = this, + view = me.view, + store = view.store, + groupToggleMenuItem, + lastGroup; + + lastGroup = store.groupers.first(); + if (lastGroup) { + me.lastGroupIndex = lastGroup.property; + store.groupers.clear(); + } + + me.callParent(); + groupToggleMenuItem = me.view.headerCt.getMenu().down('#groupToggleMenuItem'); + groupToggleMenuItem.setChecked(true, true); + groupToggleMenuItem.setChecked(false, true); + view.refresh(); }, - - alignErrorIcon : function(){ - if(this.wrap){ - this.errorIcon.alignTo(this.wrap, 'tl-tr', [2, 0]); - } + getFeatureTpl: function(values, parent, x, xcount) { + var me = this; + + return [ + '', + + '
    {collapsed}' + me.groupHeaderTpl + '
    ', + + '{[this.recurse(values)]}', + '
    ' + ].join(''); }, - - onRender : function(ct, position){ - this.doc = Ext.isIE ? Ext.getBody() : Ext.getDoc(); - Ext.form.TriggerField.superclass.onRender.call(this, ct, position); + getFragmentTpl: function() { + return { + indentByDepth: this.indentByDepth, + depthToIndent: this.depthToIndent + }; + }, - this.wrap = this.el.wrap({cls: 'x-form-field-wrap x-form-field-trigger-wrap'}); - this.trigger = this.wrap.createChild(this.triggerConfig || - {tag: "img", src: Ext.BLANK_IMAGE_URL, alt: "", cls: "x-form-trigger " + this.triggerClass}); - this.initTrigger(); - if(!this.width){ - this.wrap.setWidth(this.el.getWidth()+this.trigger.getWidth()); - } - this.resizeEl = this.positionEl = this.wrap; + indentByDepth: function(values) { + var depth = values.depth || 0; + return 'style="padding-left:'+ depth * this.depthToIndent + 'px;"'; }, - getWidth: function() { - return(this.el.getWidth() + this.trigger.getWidth()); + + + destroy: function() { + var me = this; + + delete me.view; + delete me.prunedHeader; }, - updateEditState: function(){ - if(this.rendered){ - if (this.readOnly) { - this.el.dom.readOnly = true; - this.el.addClass('x-trigger-noedit'); - this.mun(this.el, 'click', this.onTriggerClick, this); - this.trigger.setDisplayed(false); - } else { - if (!this.editable) { - this.el.dom.readOnly = true; - this.el.addClass('x-trigger-noedit'); - this.mon(this.el, 'click', this.onTriggerClick, this); - } else { - this.el.dom.readOnly = false; - this.el.removeClass('x-trigger-noedit'); - this.mun(this.el, 'click', this.onTriggerClick, this); - } - this.trigger.setDisplayed(!this.hideTrigger); + + attachEvents: function() { + var me = this, + view = me.view, + header, headerId, menu, menuItem; + + view.on({ + scope: me, + groupclick: me.onGroupClick, + rowfocus: me.onRowFocus + }); + view.store.on('groupchange', me.onGroupChange, me); + + me.pruneGroupedHeader(); + + if (me.enableGroupingMenu) { + me.injectGroupingMenu(); + } + + if (me.hideGroupedHeader) { + header = view.headerCt.down('gridcolumn[dataIndex=' + me.getGroupField() + ']'); + headerId = header.id; + menu = view.headerCt.getMenu(); + menuItem = menu.down('menuitem[headerId='+ headerId +']'); + if (menuItem) { + menuItem.setChecked(false); } - this.onResize(this.width || this.wrap.getWidth()); } }, - - setHideTrigger: function(hideTrigger){ - if(hideTrigger != this.hideTrigger){ - this.hideTrigger = hideTrigger; - this.updateEditState(); - } + injectGroupingMenu: function() { + var me = this, + view = me.view, + headerCt = view.headerCt; + headerCt.showMenuBy = me.showMenuBy; + headerCt.getMenuItems = me.getMenuItems(); }, - - setEditable: function(editable){ - if(editable != this.editable){ - this.editable = editable; - this.updateEditState(); - } + showMenuBy: function(t, header) { + var menu = this.getMenu(), + groupMenuItem = menu.down('#groupMenuItem'), + groupableMth = header.groupable === false ? 'disable' : 'enable'; + + groupMenuItem[groupableMth](); + Ext.grid.header.Container.prototype.showMenuBy.apply(this, arguments); }, - - setReadOnly: function(readOnly){ - if(readOnly != this.readOnly){ - this.readOnly = readOnly; - this.updateEditState(); - } + getMenuItems: function() { + var me = this, + groupByText = me.groupByText, + disabled = me.disabled, + showGroupsText = me.showGroupsText, + enableNoGroups = me.enableNoGroups, + groupMenuItemClick = Ext.Function.bind(me.onGroupMenuItemClick, me), + groupToggleMenuItemClick = Ext.Function.bind(me.onGroupToggleMenuItemClick, me) + + + return function() { + var o = Ext.grid.header.Container.prototype.getMenuItems.call(this); + o.push('-', { + itemId: 'groupMenuItem', + text: groupByText, + handler: groupMenuItemClick + }); + if (enableNoGroups) { + o.push({ + itemId: 'groupToggleMenuItem', + text: showGroupsText, + checked: !disabled, + checkHandler: groupToggleMenuItemClick + }); + } + return o; + }; }, - afterRender : function(){ - Ext.form.TriggerField.superclass.afterRender.call(this); - this.updateEditState(); - }, - initTrigger : function(){ - this.mon(this.trigger, 'click', this.onTriggerClick, this, {preventDefault:true}); - this.trigger.addClassOnOver('x-form-trigger-over'); - this.trigger.addClassOnClick('x-form-trigger-click'); + onGroupMenuItemClick: function(menuItem, e) { + var menu = menuItem.parentMenu, + hdr = menu.activeHeader, + view = this.view; + + delete this.lastGroupIndex; + this.enable(); + view.store.group(hdr.dataIndex); + this.pruneGroupedHeader(); + }, - onDestroy : function(){ - Ext.destroy(this.trigger, this.wrap); - if (this.mimicing){ - this.doc.un('mousedown', this.mimicBlur, this); - } - delete this.doc; - Ext.form.TriggerField.superclass.onDestroy.call(this); + onGroupToggleMenuItemClick: function(menuItem, checked) { + this[checked ? 'enable' : 'disable'](); }, - onFocus : function(){ - Ext.form.TriggerField.superclass.onFocus.call(this); - if(!this.mimicing){ - this.wrap.addClass(this.wrapFocusClass); - this.mimicing = true; - this.doc.on('mousedown', this.mimicBlur, this, {delay: 10}); - if(this.monitorTab){ - this.on('specialkey', this.checkTab, this); + pruneGroupedHeader: function() { + var me = this, + view = me.view, + store = view.store, + groupField = me.getGroupField(), + headerCt = view.headerCt, + header = headerCt.down('header[dataIndex=' + groupField + ']'); + + if (header) { + if (me.prunedHeader) { + me.prunedHeader.show(); } + me.prunedHeader = header; + header.hide(); } }, - - checkTab : function(me, e){ - if(e.getKey() == e.TAB){ - this.triggerBlur(); + getGroupField: function(){ + var group = this.view.store.groupers.first(); + if (group) { + return group.property; } + return ''; }, - onBlur : Ext.emptyFn, + onRowFocus: function(rowIdx) { + var node = this.view.getNode(rowIdx), + groupBd = Ext.fly(node).up('.' + this.collapsedCls); - - mimicBlur : function(e){ - if(!this.isDestroyed && !this.wrap.contains(e.target) && this.validateBlur(e)){ - this.triggerBlur(); + if (groupBd) { + + + this.expand(groupBd); } }, - triggerBlur : function(){ - this.mimicing = false; - this.doc.un('mousedown', this.mimicBlur, this); - if(this.monitorTab && this.el){ - this.un('specialkey', this.checkTab, this); - } - Ext.form.TriggerField.superclass.onBlur.call(this); - if(this.wrap){ - this.wrap.removeClass(this.wrapFocusClass); - } - }, + expand: function(groupBd) { + var me = this, + view = me.view, + grid = view.up('gridpanel'), + groupBdDom = Ext.getDom(groupBd); + + me.collapsedState[groupBdDom.id] = false; - beforeBlur : Ext.emptyFn, + groupBd.removeCls(me.collapsedCls); + groupBd.prev().removeCls(me.hdCollapsedCls); - - - validateBlur : function(e){ - return true; + grid.determineScrollbars(); + grid.invalidateScroller(); + view.fireEvent('groupexpand'); }, - onTriggerClick : Ext.emptyFn - - - - -}); - - -Ext.form.TwinTriggerField = Ext.extend(Ext.form.TriggerField, { - - - - - initComponent : function(){ - Ext.form.TwinTriggerField.superclass.initComponent.call(this); + collapse: function(groupBd) { + var me = this, + view = me.view, + grid = view.up('gridpanel'), + groupBdDom = Ext.getDom(groupBd); + + me.collapsedState[groupBdDom.id] = true; - this.triggerConfig = { - tag:'span', cls:'x-form-twin-triggers', cn:[ - {tag: "img", src: Ext.BLANK_IMAGE_URL, alt: "", cls: "x-form-trigger " + this.trigger1Class}, - {tag: "img", src: Ext.BLANK_IMAGE_URL, alt: "", cls: "x-form-trigger " + this.trigger2Class} - ]}; - }, + groupBd.addCls(me.collapsedCls); + groupBd.prev().addCls(me.hdCollapsedCls); - getTrigger : function(index){ - return this.triggers[index]; + grid.determineScrollbars(); + grid.invalidateScroller(); + view.fireEvent('groupcollapse'); }, - afterRender: function(){ - Ext.form.TwinTriggerField.superclass.afterRender.call(this); - var triggers = this.triggers, - i = 0, - len = triggers.length; - - for(; i < len; ++i){ - if(this['hideTrigger' + (i + 1)]){ - triggers[i].hide(); - } - - } + onGroupChange: function(){ + this.view.refresh(); }, - initTrigger : function(){ - var ts = this.trigger.select('.x-form-trigger', true), - triggerField = this; - - ts.each(function(t, all, index){ - var triggerIndex = 'Trigger'+(index+1); - t.hide = function(){ - var w = triggerField.wrap.getWidth(); - this.dom.style.display = 'none'; - triggerField.el.setWidth(w-triggerField.trigger.getWidth()); - triggerField['hidden' + triggerIndex] = true; - }; - t.show = function(){ - var w = triggerField.wrap.getWidth(); - this.dom.style.display = ''; - triggerField.el.setWidth(w-triggerField.trigger.getWidth()); - triggerField['hidden' + triggerIndex] = false; - }; - this.mon(t, 'click', this['on'+triggerIndex+'Click'], this, {preventDefault:true}); - t.addClassOnOver('x-form-trigger-over'); - t.addClassOnClick('x-form-trigger-click'); - }, this); - this.triggers = ts.elements; - }, + + onGroupClick: function(view, group, idx, foo, e) { + var me = this, + toggleCls = me.toggleCls, + groupBd = Ext.fly(group.nextSibling, '_grouping'); - getTriggerWidth: function(){ - var tw = 0; - Ext.each(this.triggers, function(t, index){ - var triggerIndex = 'Trigger' + (index + 1), - w = t.getWidth(); - if(w === 0 && !this['hidden' + triggerIndex]){ - tw += this.defaultTriggerWidth; - }else{ - tw += w; - } - }, this); - return tw; + if (groupBd.hasCls(me.collapsedCls)) { + me.expand(groupBd); + } else { + me.collapse(groupBd); + } }, - onDestroy : function() { - Ext.destroy(this.triggers); - Ext.form.TwinTriggerField.superclass.onDestroy.call(this); + getMetaRowTplFragments: function() { + return { + isRow: this.isRow, + closeRow: this.closeRow + }; }, - onTrigger1Click : Ext.emptyFn, - onTrigger2Click : Ext.emptyFn -}); -Ext.reg('trigger', Ext.form.TriggerField); + isRow: function() { + return ''; + }, -Ext.form.TextArea = Ext.extend(Ext.form.TextField, { - growMin : 60, - growMax: 1000, - growAppend : ' \n ', + closeRow: function() { + return ''; + }, - enterIsSpecial : false, + + mutateMetaRowTpl: function(metaRowTpl) { + metaRowTpl.unshift('{[this.isRow()]}'); + metaRowTpl.push('{[this.closeRow()]}'); + }, - preventScrollbars: false, + getAdditionalData: function(data, idx, record, orig) { + var view = this.view, + hCt = view.headerCt, + col = hCt.items.getAt(0), + o = {}, + tdAttrKey = col.id + '-tdAttr'; + + + o[tdAttrKey] = this.indentByDepth(data) + " " + (orig[tdAttrKey] ? orig[tdAttrKey] : ''); + o.collapsed = 'true'; + return o; + }, - onRender : function(ct, position){ - if(!this.el){ - this.defaultAutoCreate = { - tag: "textarea", - style:"width:100px;height:60px;", - autocomplete: "off" - }; - } - Ext.form.TextArea.superclass.onRender.call(this, ct, position); - if(this.grow){ - this.textSizeEl = Ext.DomHelper.append(document.body, { - tag: "pre", cls: "x-form-grow-sizer" - }); - if(this.preventScrollbars){ - this.el.setStyle("overflow", "hidden"); + getGroupRows: function(group, records, preppedRecords, fullWidth) { + var me = this, + children = group.children, + rows = group.rows = [], + view = me.view; + group.viewId = view.id; + + Ext.Array.each(records, function(record, idx) { + if (Ext.Array.indexOf(children, record) != -1) { + rows.push(Ext.apply(preppedRecords[idx], { + depth: 1 + })); } - this.el.setHeight(this.growMin); + }); + delete group.children; + group.fullWidth = fullWidth; + if (me.collapsedState[view.id + '-gp-' + group.name]) { + group.collapsedCls = me.collapsedCls; + group.hdCollapsedCls = me.hdCollapsedCls; } - }, - onDestroy : function(){ - Ext.removeNode(this.textSizeEl); - Ext.form.TextArea.superclass.onDestroy.call(this); + return group; }, - fireKey : function(e){ - if(e.isSpecialKey() && (this.enterIsSpecial || (e.getKey() != e.ENTER || e.hasModifier()))){ - this.fireEvent("specialkey", this, e); + + collectData: function(records, preppedRecords, startIndex, fullWidth, o) { + var me = this, + store = me.view.store, + groups; + + if (!me.disabled && store.isGrouped()) { + groups = store.getGroups(); + Ext.Array.each(groups, function(group, idx){ + me.getGroupRows(group, records, preppedRecords, fullWidth); + }, me); + return { + rows: groups, + fullWidth: fullWidth + }; } + return o; }, - doAutoSize : function(e){ - return !e.isNavKeyPress() || e.getKey() == e.ENTER; - }, - filterValidation: function(e) { - if(!e.isNavKeyPress() || (!this.enterIsSpecial && e.keyCode == e.ENTER)){ - this.validationTask.delay(this.validationDelay); - } - }, - - autoSize: function(){ - if(!this.grow || !this.textSizeEl){ - return; - } - var el = this.el, - v = Ext.util.Format.htmlEncode(el.dom.value), - ts = this.textSizeEl, - h; - - Ext.fly(ts).setWidth(this.el.getWidth()); - if(v.length < 1){ - v = "  "; - }else{ - v += this.growAppend; - if(Ext.isIE){ - v = v.replace(/\n/g, ' 
    '); - } - } - ts.innerHTML = v; - h = Math.min(this.growMax, Math.max(ts.offsetHeight, this.growMin)); - if(h != this.lastHeight){ - this.lastHeight = h; - this.el.setHeight(h); - this.fireEvent("autosize", this, h); - } + getFireEventArgs: function(type, view, featureTarget) { + var returnArray = [type, view, featureTarget], + groupBd = Ext.fly(featureTarget.nextSibling, '_grouping'), + groupBdId = Ext.getDom(groupBd).id, + prefix = view.id + '-gp-', + groupName = groupBdId.substr(prefix.length); + + returnArray.push(groupName); + + return returnArray; } }); -Ext.reg('textarea', Ext.form.TextArea); -Ext.form.NumberField = Ext.extend(Ext.form.TextField, { - - - - fieldClass: "x-form-field x-form-num-field", - - - allowDecimals : true, - - - decimalSeparator : ".", - + + +Ext.define('Ext.grid.feature.GroupingSummary', { - decimalPrecision : 2, - allowNegative : true, + extend: 'Ext.grid.feature.Grouping', + alias: 'feature.groupingsummary', - minValue : Number.NEGATIVE_INFINITY, + mixins: { + summary: 'Ext.grid.feature.AbstractSummary' + }, - maxValue : Number.MAX_VALUE, + + + + getFeatureTpl: function() { + var tpl = this.callParent(arguments); + + if (this.showSummaryRow) { + + tpl = tpl.replace('', ''); + tpl += '{[this.printSummaryRow(xindex)]}'; + } + return tpl; + }, - minText : "The minimum value for this field is {0}", + getFragmentTpl: function() { + var me = this, + fragments = me.callParent(); + + Ext.apply(fragments, me.getSummaryFragments()); + if (me.showSummaryRow) { + + me.summaryGroups = me.view.store.getGroups(); + me.summaryData = me.generateSummaryData(); + } + return fragments; + }, - maxText : "The maximum value for this field is {0}", + getPrintData: function(index){ + var me = this, + columns = me.view.headerCt.getColumnsForTpl(), + i = 0, + length = columns.length, + data = [], + name = me.summaryGroups[index - 1].name, + active = me.summaryData[name], + column; + + for (; i < length; ++i) { + column = columns[i]; + column.gridSummaryValue = this.getColumnValue(column, active); + data.push(column); + } + return data; + }, - nanText : "{0} is not a valid number", + generateSummaryData: function(){ + var me = this, + data = {}, + remoteData = {}, + store = me.view.store, + groupField = this.getGroupField(), + reader = store.proxy.reader, + groups = me.summaryGroups, + columns = me.view.headerCt.getColumnsForTpl(), + i, + length, + fieldData, + root, + key, + comp; + + for (i = 0, length = groups.length; i < length; ++i) { + data[groups[i].name] = {}; + } + + if (me.remoteRoot && reader.rawData) { + + root = reader.root; + reader.root = me.remoteRoot; + reader.buildExtractors(true); + Ext.Array.each(reader.getRoot(reader.rawData), function(value) { + data[value[groupField]] = value; + data[value[groupField]]._remote = true; + }); + + reader.root = root; + reader.buildExtractors(true); + } + + for (i = 0, length = columns.length; i < length; ++i) { + comp = Ext.getCmp(columns[i].id); + fieldData = me.getSummary(store, comp.summaryType, comp.dataIndex, true); + + for (key in fieldData) { + if (fieldData.hasOwnProperty(key)) { + if (!data[key]._remote) { + data[key][comp.dataIndex] = fieldData[key]; + } + } + } + } + return data; + } +}); + + +Ext.define('Ext.grid.feature.RowBody', { + extend: 'Ext.grid.feature.Feature', + alias: 'feature.rowbody', + rowBodyHiddenCls: Ext.baseCSSPrefix + 'grid-row-body-hidden', + rowBodyTrCls: Ext.baseCSSPrefix + 'grid-rowbody-tr', + rowBodyTdCls: Ext.baseCSSPrefix + 'grid-cell-rowbody', + rowBodyDivCls: Ext.baseCSSPrefix + 'grid-rowbody', + + eventPrefix: 'rowbody', + eventSelector: '.' + Ext.baseCSSPrefix + 'grid-rowbody-tr', - baseChars : "0123456789", + getRowBody: function(values) { + return [ + '', + '', + '
    {rowBody}
    ', + '', + '' + ].join(''); + }, - autoStripChars: false, + getMetaRowTplFragments: function() { + return { + getRowBody: this.getRowBody, + rowBodyTrCls: this.rowBodyTrCls, + rowBodyTdCls: this.rowBodyTdCls, + rowBodyDivCls: this.rowBodyDivCls + }; + }, - - initEvents : function() { - var allowed = this.baseChars + ''; - if (this.allowDecimals) { - allowed += this.decimalSeparator; - } - if (this.allowNegative) { - allowed += '-'; - } - allowed = Ext.escapeRe(allowed); - this.maskRe = new RegExp('[' + allowed + ']'); - if (this.autoStripChars) { - this.stripCharsRe = new RegExp('[^' + allowed + ']', 'gi'); - } - - Ext.form.NumberField.superclass.initEvents.call(this); + mutateMetaRowTpl: function(metaRowTpl) { + metaRowTpl.push('{[this.getRowBody(values)]}'); }, + + getAdditionalData: function(data, idx, record, orig) { + var headerCt = this.view.headerCt, + colspan = headerCt.getColumnCount(); + + return { + rowBody: "", + rowBodyCls: this.rowBodyCls, + rowBodyColspan: colspan + }; + } +}); + +Ext.define('Ext.grid.feature.RowWrap', { + extend: 'Ext.grid.feature.Feature', + alias: 'feature.rowwrap', + - getErrors: function(value) { - var errors = Ext.form.NumberField.superclass.getErrors.apply(this, arguments); - - value = Ext.isDefined(value) ? value : this.processValue(this.getRawValue()); + hasFeatureEvent: false, + + mutateMetaRowTpl: function(metaRowTpl) { - if (value.length < 1) { - return errors; - } - value = String(value).replace(this.decimalSeparator, "."); + metaRowTpl[0] = metaRowTpl[0].replace(Ext.baseCSSPrefix + 'grid-row', ''); + metaRowTpl[0] = metaRowTpl[0].replace("{[this.embedRowCls()]}", ""); - if(isNaN(value)){ - errors.push(String.format(this.nanText, value)); - } + metaRowTpl.unshift(''); - var num = this.parseValue(value); + metaRowTpl.unshift('
    '); - if (num < this.minValue) { - errors.push(String.format(this.minText, this.minValue)); - } - if (num > this.maxValue) { - errors.push(String.format(this.maxText, this.maxValue)); - } + metaRowTpl.push('
    '); - return errors; - }, - - getValue : function() { - return this.fixPrecision(this.parseValue(Ext.form.NumberField.superclass.getValue.call(this))); - }, - - setValue : function(v) { - v = this.fixPrecision(v); - v = Ext.isNumber(v) ? v : parseFloat(String(v).replace(this.decimalSeparator, ".")); - v = isNaN(v) ? '' : String(v).replace(".", this.decimalSeparator); - return Ext.form.NumberField.superclass.setValue.call(this, v); + metaRowTpl.push('
    '); }, - - setMinValue : function(value) { - this.minValue = Ext.num(value, Number.NEGATIVE_INFINITY); + embedColSpan: function() { + return '{colspan}'; }, - - setMaxValue : function(value) { - this.maxValue = Ext.num(value, Number.MAX_VALUE); + embedFullWidth: function() { + return '{fullWidth}'; }, - - parseValue : function(value) { - value = parseFloat(String(value).replace(this.decimalSeparator, ".")); - return isNaN(value) ? '' : value; - }, + getAdditionalData: function(data, idx, record, orig) { + var headerCt = this.view.headerCt, + colspan = headerCt.getColumnCount(), + fullWidth = headerCt.getFullWidth(), + items = headerCt.query('gridcolumn'), + itemsLn = items.length, + i = 0, + o = { + colspan: colspan, + fullWidth: fullWidth + }, + id, + tdClsKey, + colResizerCls; - - fixPrecision : function(value) { - var nan = isNaN(value); - - if (!this.allowDecimals || this.decimalPrecision == -1 || nan || !value) { - return nan ? '' : value; + for (; i < itemsLn; i++) { + id = items[i].id; + tdClsKey = id + '-tdCls'; + colResizerCls = Ext.baseCSSPrefix + 'grid-col-resizer-'+id; + + + + o[tdClsKey] = colResizerCls + " " + (orig[tdClsKey] ? orig[tdClsKey] : ''); + + o[id+'-tdAttr'] = " style=\"width: " + (items[i].hidden ? 0 : items[i].getDesiredWidth()) + "px;\" "; + if (orig[id+'-tdAttr']) { + o[id+'-tdAttr'] += orig[id+'-tdAttr']; + } + } - - return parseFloat(parseFloat(value).toFixed(this.decimalPrecision)); - }, - beforeBlur : function() { - var v = this.parseValue(this.getRawValue()); - - if (!Ext.isEmpty(v)) { - this.setValue(v); - } + return o; + }, + + getMetaRowTplFragments: function() { + return { + embedFullWidth: this.embedFullWidth, + embedColSpan: this.embedColSpan + }; } + }); -Ext.reg('numberfield', Ext.form.NumberField); - -Ext.form.DateField = Ext.extend(Ext.form.TriggerField, { - - format : "m/d/Y", +Ext.define('Ext.grid.feature.Summary', { - altFormats : "m/d/Y|n/j/Y|n/j/y|m/j/y|n/d/y|m/j/Y|n/d/Y|m-d-y|m-d-Y|m/d|m-d|md|mdy|mdY|d|Y-m-d|n-j|n/j", - disabledDaysText : "Disabled", - disabledDatesText : "Disabled", + extend: 'Ext.grid.feature.AbstractSummary', - minText : "The date in this field must be equal to or after {0}", + alias: 'feature.summary', - maxText : "The date in this field must be equal to or before {0}", - invalidText : "{0} is not a valid date - it must be in the format {1}", - triggerClass : 'x-form-date-trigger', - showToday : true, + getFragmentTpl: function() { + + this.summaryData = this.generateSummaryData(); + return this.getSummaryFragments(); + }, - startDay : 0, + getTableFragments: function(){ + if (this.showSummaryRow) { + return { + closeRows: this.closeRows + }; + } + }, + closeRows: function() { + return '{[this.printSummaryRow()]}'; + }, + getPrintData: function(index){ + var me = this, + columns = me.view.headerCt.getColumnsForTpl(), + i = 0, + length = columns.length, + data = [], + active = me.summaryData, + column; + + for (; i < length; ++i) { + column = columns[i]; + column.gridSummaryValue = this.getColumnValue(column, active); + data.push(column); + } + return data; + }, + generateSummaryData: function(){ + var me = this, + data = {}, + store = me.view.store, + columns = me.view.headerCt.getColumnsForTpl(), + i = 0, + length = columns.length, + fieldData, + key, + comp; + + for (i = 0, length = columns.length; i < length; ++i) { + comp = Ext.getCmp(columns[i].id); + data[comp.dataIndex] = me.getSummary(store, comp.summaryType, comp.dataIndex, false); + } + return data; + } +}); + +Ext.define('Ext.grid.header.DragZone', { + extend: 'Ext.dd.DragZone', + colHeaderCls: Ext.baseCSSPrefix + 'column-header', + maxProxyWidth: 120, - - defaultAutoCreate : {tag: "input", type: "text", size: "10", autocomplete: "off"}, + constructor: function(headerCt) { + this.headerCt = headerCt; + this.ddGroup = this.getDDGroup(); + this.callParent([headerCt.el]); + this.proxy.el.addCls(Ext.baseCSSPrefix + 'grid-col-dd'); + }, + + getDDGroup: function() { + return 'header-dd-zone-' + this.headerCt.up('[scrollerOwner]').id; + }, + + getDragData: function(e) { + var header = e.getTarget('.'+this.colHeaderCls), + headerCmp; + + if (header) { + headerCmp = Ext.getCmp(header.id); + if (!this.headerCt.dragging && headerCmp.draggable && !(headerCmp.isOnLeftEdge(e) || headerCmp.isOnRightEdge(e))) { + var ddel = document.createElement('div'); + ddel.innerHTML = Ext.getCmp(header.id).text; + return { + ddel: ddel, + header: headerCmp + }; + } + } + return false; + }, + + onBeforeDrag: function() { + return !(this.headerCt.dragging || this.disabled); + }, + + onInitDrag: function() { + this.headerCt.dragging = true; + this.callParent(arguments); + }, + onDragDrop: function() { + this.headerCt.dragging = false; + this.callParent(arguments); + }, + + afterRepair: function() { + this.callParent(); + this.headerCt.dragging = false; + }, + + getRepairXY: function() { + return this.dragData.header.el.getXY(); + }, + disable: function() { + this.disabled = true; + }, - initTime: '12', + enable: function() { + this.disabled = false; + } +}); - initTimeFormat: 'H', - - safeParse : function(value, format) { - if (/[gGhH]/.test(format.replace(/(\\.)/g, ''))) { - - return Date.parseDate(value, format); - } else { - - var parsedDate = Date.parseDate(value + ' ' + this.initTime, format + ' ' + this.initTimeFormat); +Ext.define('Ext.grid.header.DropZone', { + extend: 'Ext.dd.DropZone', + colHeaderCls: Ext.baseCSSPrefix + 'column-header', + proxyOffsets: [-4, -9], - if (parsedDate) { - return parsedDate.clearTime(); - } - } + constructor: function(headerCt){ + this.headerCt = headerCt; + this.ddGroup = this.getDDGroup(); + this.callParent([headerCt.el]); }, - initComponent : function(){ - Ext.form.DateField.superclass.initComponent.call(this); + getDDGroup: function() { + return 'header-dd-zone-' + this.headerCt.up('[scrollerOwner]').id; + }, - this.addEvents( - - 'select' - ); + getTargetFromEvent : function(e){ + return e.getTarget('.' + this.colHeaderCls); + }, - if(Ext.isString(this.minValue)){ - this.minValue = this.parseDate(this.minValue); + getTopIndicator: function() { + if (!this.topIndicator) { + this.topIndicator = Ext.core.DomHelper.append(Ext.getBody(), { + cls: "col-move-top", + html: " " + }, true); } - if(Ext.isString(this.maxValue)){ - this.maxValue = this.parseDate(this.maxValue); + return this.topIndicator; + }, + + getBottomIndicator: function() { + if (!this.bottomIndicator) { + this.bottomIndicator = Ext.core.DomHelper.append(Ext.getBody(), { + cls: "col-move-bottom", + html: " " + }, true); } - this.disabledDatesRE = null; - this.initDisabledDays(); + return this.bottomIndicator; }, - initEvents: function() { - Ext.form.DateField.superclass.initEvents.call(this); - this.keyNav = new Ext.KeyNav(this.el, { - "down": function(e) { - this.onTriggerClick(); - }, - scope: this, - forceKeyDown: true - }); + getLocation: function(e, t) { + var x = e.getXY()[0], + region = Ext.fly(t).getRegion(), + pos, header; + + if ((region.right - x) <= (region.right - region.left) / 2) { + pos = "after"; + } else { + pos = "before"; + } + return { + pos: pos, + header: Ext.getCmp(t.id), + node: t + }; }, + positionIndicator: function(draggedHeader, node, e){ + var location = this.getLocation(e, node), + header = location.header, + pos = location.pos, + nextHd = draggedHeader.nextSibling('gridcolumn:not([hidden])'), + prevHd = draggedHeader.previousSibling('gridcolumn:not([hidden])'), + region, topIndicator, bottomIndicator, topAnchor, bottomAnchor, + topXY, bottomXY, headerCtEl, minX, maxX; - - initDisabledDays : function(){ - if(this.disabledDates){ - var dd = this.disabledDates, - len = dd.length - 1, - re = "(?:"; + + if (!header.draggable && header.getIndex() == 0) { + return false; + } - Ext.each(dd, function(d, i){ - re += Ext.isDate(d) ? '^' + Ext.escapeRe(d.dateFormat(this.format)) + '$' : dd[i]; - if(i != len){ - re += '|'; + this.lastLocation = location; + + if ((draggedHeader !== header) && + ((pos === "before" && nextHd !== header) || + (pos === "after" && prevHd !== header)) && + !header.isDescendantOf(draggedHeader)) { + + + + + var allDropZones = Ext.dd.DragDropManager.getRelated(this), + ln = allDropZones.length, + i = 0, + dropZone; + + for (; i < ln; i++) { + dropZone = allDropZones[i]; + if (dropZone !== this && dropZone.invalidateDrop) { + dropZone.invalidateDrop(); } - }, this); - this.disabledDatesRE = new RegExp(re + ')'); + } + + + this.valid = true; + topIndicator = this.getTopIndicator(); + bottomIndicator = this.getBottomIndicator(); + if (pos === 'before') { + topAnchor = 'tl'; + bottomAnchor = 'bl'; + } else { + topAnchor = 'tr'; + bottomAnchor = 'br'; + } + topXY = header.el.getAnchorXY(topAnchor); + bottomXY = header.el.getAnchorXY(bottomAnchor); + + + headerCtEl = this.headerCt.el; + minX = headerCtEl.getLeft(); + maxX = headerCtEl.getRight(); + + topXY[0] = Ext.Number.constrain(topXY[0], minX, maxX); + bottomXY[0] = Ext.Number.constrain(bottomXY[0], minX, maxX); + + + + topXY[0] -= 4; + topXY[1] -= 9; + bottomXY[0] -= 4; + + + topIndicator.setXY(topXY); + bottomIndicator.setXY(bottomXY); + topIndicator.show(); + bottomIndicator.show(); + + } else { + this.invalidateDrop(); } }, - - setDisabledDates : function(dd){ - this.disabledDates = dd; - this.initDisabledDays(); - if(this.menu){ - this.menu.picker.setDisabledDates(this.disabledDatesRE); - } + invalidateDrop: function() { + this.valid = false; + this.hideIndicators(); }, - - setDisabledDays : function(dd){ - this.disabledDays = dd; - if(this.menu){ - this.menu.picker.setDisabledDays(dd); + onNodeOver: function(node, dragZone, e, data) { + if (data.header.el.dom !== node) { + this.positionIndicator(data.header, node, e); } + return this.valid ? this.dropAllowed : this.dropNotAllowed; }, - - setMinValue : function(dt){ - this.minValue = (Ext.isString(dt) ? this.parseDate(dt) : dt); - if(this.menu){ - this.menu.picker.setMinDate(this.minValue); - } + hideIndicators: function() { + this.getTopIndicator().hide(); + this.getBottomIndicator().hide(); }, - - setMaxValue : function(dt){ - this.maxValue = (Ext.isString(dt) ? this.parseDate(dt) : dt); - if(this.menu){ - this.menu.picker.setMaxDate(this.maxValue); - } + onNodeOut: function() { + this.hideIndicators(); }, - - getErrors: function(value) { - var errors = Ext.form.DateField.superclass.getErrors.apply(this, arguments); + onNodeDrop: function(node, dragZone, e, data) { + if (this.valid) { + this.invalidateDrop(); + var hd = data.header, + lastLocation = this.lastLocation, + fromCt = hd.ownerCt, + fromIdx = fromCt.items.indexOf(hd), + toCt = lastLocation.header.ownerCt, + toIdx = toCt.items.indexOf(lastLocation.header), + headerCt = this.headerCt, + groupCt, + scrollerOwner; - value = this.formatDate(value || this.processValue(this.getRawValue())); + if (lastLocation.pos === 'after') { + toIdx++; + } - if (value.length < 1) { - return errors; - } + + + + if (fromCt !== toCt && fromCt.lockableInjected && toCt.lockableInjected && toCt.lockedCt) { + scrollerOwner = fromCt.up('[scrollerOwner]'); + scrollerOwner.lock(hd, toIdx); + } else if (fromCt !== toCt && fromCt.lockableInjected && toCt.lockableInjected && fromCt.lockedCt) { + scrollerOwner = fromCt.up('[scrollerOwner]'); + scrollerOwner.unlock(hd, toIdx); + } else { + + + if ((fromCt === toCt) && (toIdx > fromCt.items.indexOf(hd))) { + toIdx--; + } - var svalue = value; - value = this.parseDate(value); - if (!value) { - errors.push(String.format(this.invalidText, svalue, this.format)); - return errors; - } + + if (fromCt !== toCt) { + fromCt.suspendLayout = true; + fromCt.remove(hd, false); + fromCt.suspendLayout = false; + } - var time = value.getTime(); - if (this.minValue && time < this.minValue.clearTime().getTime()) { - errors.push(String.format(this.minText, this.formatDate(this.minValue))); - } + + if (fromCt.isGroupHeader) { + if (!fromCt.items.getCount()) { + groupCt = fromCt.ownerCt; + groupCt.suspendLayout = true; + groupCt.remove(fromCt, false); + fromCt.el.dom.parentNode.removeChild(fromCt.el.dom); + groupCt.suspendLayout = false; + } else { + fromCt.minWidth = fromCt.getWidth() - hd.getWidth(); + fromCt.setWidth(fromCt.minWidth); + } + } - if (this.maxValue && time > this.maxValue.clearTime().getTime()) { - errors.push(String.format(this.maxText, this.formatDate(this.maxValue))); - } + + toCt.suspendLayout = true; + if (fromCt === toCt) { + toCt.move(fromIdx, toIdx); + } else { + toCt.insert(toIdx, hd); + } + toCt.suspendLayout = false; + + + + + if (toCt.isGroupHeader) { + hd.savedFlex = hd.flex; + delete hd.flex; + hd.width = hd.getWidth(); + + + toCt.minWidth = toCt.getWidth() + hd.getWidth() - (hd.savedFlex ? 1 : 0); + toCt.setWidth(toCt.minWidth); + } else { + if (hd.savedFlex) { + hd.flex = hd.savedFlex; + delete hd.width; + } + } - if (this.disabledDays) { - var day = value.getDay(); - for(var i = 0; i < this.disabledDays.length; i++) { - if (day === this.disabledDays[i]) { - errors.push(this.disabledDaysText); - break; + + headerCt.purgeCache(); + headerCt.doLayout(); + headerCt.onHeaderMoved(hd, fromIdx, toIdx); + + if (!fromCt.items.getCount()) { + fromCt.destroy(); } } } + } +}); - var fvalue = this.formatDate(value); - if (this.disabledDatesRE && this.disabledDatesRE.test(fvalue)) { - errors.push(String.format(this.disabledDatesText, fvalue)); - } - return errors; + +Ext.define('Ext.grid.plugin.Editing', { + alias: 'editing.editing', + + requires: [ + 'Ext.grid.column.Column', + 'Ext.util.KeyNav' + ], + + mixins: { + observable: 'Ext.util.Observable' }, + clicksToEdit: 2, + - validateBlur : function(){ - return !this.menu || !this.menu.isVisible(); - }, + defaultFieldXType: 'textfield', - getValue : function(){ - return this.parseDate(Ext.form.DateField.superclass.getValue.call(this)) || ""; + editStyle: '', + + constructor: function(config) { + var me = this; + Ext.apply(me, config); + + me.addEvents( + + 'beforeedit', + + + 'edit', + + + 'validateedit' + ); + me.mixins.observable.constructor.call(me); + + me.relayEvents(me, ['afteredit'], 'after'); }, - setValue : function(date){ - return Ext.form.DateField.superclass.setValue.call(this, this.formatDate(this.parseDate(date))); + init: function(grid) { + var me = this; + + me.grid = grid; + me.view = grid.view; + me.initEvents(); + me.initFieldAccessors(me.view.getGridColumns()); + + grid.relayEvents(me, ['beforeedit', 'edit', 'validateedit']); + + + grid.isEditable = true; + grid.editingPlugin = grid.view.editingPlugin = me; }, - parseDate : function(value) { - if(!value || Ext.isDate(value)){ - return value; - } + destroy: function() { + var me = this, + grid = me.grid, + headerCt = grid.headerCt, + events = grid.events; - var v = this.safeParse(value, this.format), - af = this.altFormats, - afa = this.altFormatsArray; + Ext.destroy(me.keyNav); + me.removeFieldAccessors(grid.getView().getGridColumns()); - if (!v && af) { - afa = afa || af.split("|"); + + me.clearListeners(); - for (var i = 0, len = afa.length; i < len && !v; i++) { - v = this.safeParse(value, afa[i]); - } - } - return v; + delete me.grid.editingPlugin; + delete me.grid.view.editingPlugin; + delete me.grid; + delete me.view; + delete me.editor; + delete me.keyNav; }, - onDestroy : function(){ - Ext.destroy(this.menu, this.keyNav); - Ext.form.DateField.superclass.onDestroy.call(this); + getEditStyle: function() { + return this.editStyle; }, - formatDate : function(date){ - return Ext.isDate(date) ? date.dateFormat(this.format) : date; + initFieldAccessors: function(column) { + var me = this; + + if (Ext.isArray(column)) { + Ext.Array.forEach(column, me.initFieldAccessors, me); + return; + } + + + + Ext.applyIf(column, { + getEditor: function(record, defaultField) { + return me.getColumnField(this, defaultField); + }, + + setEditor: function(field) { + me.setColumnField(this, field); + } + }); }, + removeFieldAccessors: function(column) { + var me = this; + + if (Ext.isArray(column)) { + Ext.Array.forEach(column, me.removeFieldAccessors, me); + return; + } + + delete column.getEditor; + delete column.setEditor; + }, + - onTriggerClick : function(){ - if(this.disabled){ - return; + getColumnField: function(columnHeader, defaultField) { + var field = columnHeader.field; + + if (!field && columnHeader.editor) { + field = columnHeader.editor; + delete columnHeader.editor; } - if(this.menu == null){ - this.menu = new Ext.menu.DateMenu({ - hideOnClick: false, - focusOnSelect: false + + if (!field && defaultField) { + field = defaultField; + } + + if (field) { + if (Ext.isString(field)) { + field = { xtype: field }; + } + if (Ext.isObject(field) && !field.isFormField) { + field = Ext.ComponentManager.create(field, this.defaultFieldXType); + columnHeader.field = field; + } + + Ext.apply(field, { + name: columnHeader.dataIndex }); + + return field; } - this.onFocus(); - Ext.apply(this.menu.picker, { - minDate : this.minValue, - maxDate : this.maxValue, - disabledDatesRE : this.disabledDatesRE, - disabledDatesText : this.disabledDatesText, - disabledDays : this.disabledDays, - disabledDaysText : this.disabledDaysText, - format : this.format, - showToday : this.showToday, - startDay: this.startDay, - minText : String.format(this.minText, this.formatDate(this.minValue)), - maxText : String.format(this.maxText, this.formatDate(this.maxValue)) - }); - this.menu.picker.setValue(this.getValue() || new Date()); - this.menu.show(this.el, "tl-bl?"); - this.menuEvents('on'); }, - menuEvents: function(method){ - this.menu[method]('select', this.onSelect, this); - this.menu[method]('hide', this.onMenuHide, this); - this.menu[method]('show', this.onFocus, this); + + setColumnField: function(column, field) { + if (Ext.isObject(field) && !field.isFormField) { + field = Ext.ComponentManager.create(field, this.defaultFieldXType); + } + column.field = field; }, - onSelect: function(m, d){ - this.setValue(d); - this.fireEvent('select', this, d); - this.menu.hide(); + + initEvents: function() { + var me = this; + me.initEditTriggers(); + me.initCancelTriggers(); }, - onMenuHide: function(){ - this.focus(false, 60); - this.menuEvents('un'); + + initCancelTriggers: Ext.emptyFn, + + + initEditTriggers: function() { + var me = this, + view = me.view, + clickEvent = me.clicksToEdit === 1 ? 'click' : 'dblclick'; + + + me.mon(view, 'cell' + clickEvent, me.startEditByClick, me); + view.on('render', function() { + me.keyNav = Ext.create('Ext.util.KeyNav', view.el, { + enter: me.onEnterKey, + esc: me.onEscKey, + scope: me + }); + }, me, { single: true }); }, - beforeBlur : function(){ - var v = this.parseDate(this.getRawValue()); - if(v){ - this.setValue(v); + onEnterKey: function(e) { + var me = this, + grid = me.grid, + selModel = grid.getSelectionModel(), + record, + columnHeader = grid.headerCt.getHeaderAtIndex(0); + + + + if (selModel.getCurrentPosition) { + pos = selModel.getCurrentPosition(); + record = grid.store.getAt(pos.row); + columnHeader = grid.headerCt.getHeaderAtIndex(pos.column); } - } + + else { + record = selModel.getLastSelected(); + } + me.startEdit(record, columnHeader); + }, - - - -}); -Ext.reg('datefield', Ext.form.DateField); + onEscKey: function(e) { + this.cancelEdit(); + }, -Ext.form.DisplayField = Ext.extend(Ext.form.Field, { - validationEvent : false, - validateOnBlur : false, - defaultAutoCreate : {tag: "div"}, - fieldClass : "x-form-display-field", + startEditByClick: function(view, cell, colIdx, record, row, rowIdx, e) { + this.startEdit(record, view.getHeaderAtIndex(colIdx)); + }, + - htmlEncode: false, + beforeEdit: Ext.emptyFn, - initEvents : Ext.emptyFn, + startEdit: function(record, columnHeader) { + var me = this, + context = me.getEditingContext(record, columnHeader); - isValid : function(){ - return true; - }, + if (me.beforeEdit(context) === false || me.fireEvent('beforeedit', context) === false || context.cancel) { + return false; + } - validate : function(){ - return true; + me.context = context; + me.editing = true; }, - getRawValue : function(){ - var v = this.rendered ? this.el.dom.innerHTML : Ext.value(this.value, ''); - if(v === this.emptyText){ - v = ''; + + getEditingContext: function(record, columnHeader) { + var me = this, + grid = me.grid, + store = grid.store, + rowIdx, + colIdx, + view = grid.getView(), + value; + + + if (Ext.isNumber(record)) { + rowIdx = record; + record = store.getAt(rowIdx); + } else { + rowIdx = store.indexOf(record); } - if(this.htmlEncode){ - v = Ext.util.Format.htmlDecode(v); + if (Ext.isNumber(columnHeader)) { + colIdx = columnHeader; + columnHeader = grid.headerCt.getHeaderAtIndex(colIdx); + } else { + colIdx = columnHeader.getIndex(); } - return v; - }, - getValue : function(){ - return this.getRawValue(); + value = record.get(columnHeader.dataIndex); + return { + grid: grid, + record: record, + field: columnHeader.dataIndex, + value: value, + row: view.getNode(rowIdx), + column: columnHeader, + rowIdx: rowIdx, + colIdx: colIdx + }; }, + - getName: function() { - return this.name; + cancelEdit: function() { + this.editing = false; }, - setRawValue : function(v){ - if(this.htmlEncode){ - v = Ext.util.Format.htmlEncode(v); + + completeEdit: function() { + var me = this; + + if (me.editing && me.validateEdit()) { + me.fireEvent('edit', me.context); } - return this.rendered ? (this.el.dom.innerHTML = (Ext.isEmpty(v) ? '' : v)) : (this.value = v); + + delete me.context; + me.editing = false; }, - setValue : function(v){ - this.setRawValue(v); - return this; - } - - - - - + validateEdit: function() { + var me = this, + context = me.context; + + return me.fireEvent('validateedit', me, context) !== false && !context.cancel; + } }); -Ext.reg('displayfield', Ext.form.DisplayField); +Ext.define('Ext.grid.plugin.CellEditing', { + alias: 'plugin.cellediting', + extend: 'Ext.grid.plugin.Editing', + requires: ['Ext.grid.CellEditor'], -Ext.form.ComboBox = Ext.extend(Ext.form.TriggerField, { - - - - - + constructor: function() { + + + + this.callParent(arguments); + this.editors = Ext.create('Ext.util.MixedCollection', false, function(editor) { + return editor.editorId; + }); + }, - defaultAutoCreate : {tag: "input", type: "text", size: "24", autocomplete: "off"}, - - - - - - - - listClass : '', - - selectedClass : 'x-combo-selected', - - listEmptyText: '', - - triggerClass : 'x-form-arrow-trigger', - - shadow : 'sides', - - listAlign : 'tl-bl?', - - maxHeight : 300, - - minHeight : 90, - - triggerAction : 'query', - - minChars : 4, - - autoSelect : true, - - typeAhead : false, - - queryDelay : 500, - - pageSize : 0, - - selectOnFocus : false, - - queryParam : 'query', - - loadingText : 'Loading...', - - resizable : false, - - handleHeight : 8, - - allQuery: '', - - mode: 'remote', - - minListWidth : 70, - - forceSelection : false, + destroy: function() { + var me = this; + me.editors.each(Ext.destroy, Ext); + me.editors.clear(); + me.callParent(arguments); + }, + - typeAheadDelay : 250, + initCancelTriggers: function() { + var me = this; + grid = me.grid, + view = grid.view; - - lazyInit : true, + me.mon(view, { + mousewheel: { + element: 'el', + fn: me.cancelEdit, + scope: me + } + }); + me.mon(grid, { + columnresize: me.cancelEdit, + columnmove: me.cancelEdit, + scope: me + }); + }, - clearFilterOnReset : true, + startEdit: function(record, columnHeader) { + var me = this, + ed = me.getEditor(record, columnHeader), + value = record.get(columnHeader.dataIndex), + context = me.getEditingContext(record, columnHeader); - - submitValue: undefined, + record = context.record; + columnHeader = context.column; - + + + me.completeEdit(); + + + if (columnHeader && !columnHeader.getEditor(record)) { + return false; + } + + if (ed) { + context.originalValue = context.value = value; + if (me.beforeEdit(context) === false || me.fireEvent('beforeedit', context) === false || context.cancel) { + return false; + } + + me.context = context; + me.setActiveEditor(ed); + me.setActiveRecord(record); + me.setActiveColumn(columnHeader); - - initComponent : function(){ - Ext.form.ComboBox.superclass.initComponent.call(this); - this.addEvents( - 'expand', + Ext.defer(ed.startEdit, 15, ed, [me.getCell(record, columnHeader), value]); + } else { - 'collapse', - - 'beforeselect', - 'select', - 'beforequery' - ); - if(this.transform){ - var s = Ext.getDom(this.transform); - if(!this.hiddenName){ - this.hiddenName = s.name; - } - if(!this.store){ - this.mode = 'local'; - var d = [], opts = s.options; - for(var i = 0, len = opts.length;i < len; i++){ - var o = opts[i], - value = (o.hasAttribute ? o.hasAttribute('value') : o.getAttributeNode('value').specified) ? o.value : o.text; - if(o.selected && Ext.isEmpty(this.value, true)) { - this.value = value; - } - d.push([value, o.text]); - } - this.store = new Ext.data.ArrayStore({ - idIndex: 0, - fields: ['value', 'text'], - data : d, - autoDestroy: true - }); - this.valueField = 'value'; - this.displayField = 'text'; - } - s.name = Ext.id(); - if(!this.lazyRender){ - this.target = true; - this.el = Ext.DomHelper.insertBefore(s, this.autoCreate || this.defaultAutoCreate); - this.render(this.el.parentNode, s); - } - Ext.removeNode(s); - } - - else if(this.store){ - this.store = Ext.StoreMgr.lookup(this.store); - if(this.store.autoCreated){ - this.displayField = this.valueField = 'field1'; - if(!this.store.expandData){ - this.displayField = 'field2'; - } - this.mode = 'local'; - } + me.grid.getView().el.focus((Ext.isWebKit || Ext.isIE) ? 10 : false); } + }, - this.selectedIndex = -1; - if(this.mode == 'local'){ - if(!Ext.isDefined(this.initialConfig.queryDelay)){ - this.queryDelay = 10; - } - if(!Ext.isDefined(this.initialConfig.minChars)){ - this.minChars = 0; - } + completeEdit: function() { + var activeEd = this.getActiveEditor(); + if (activeEd) { + activeEd.completeEdit(); } }, - onRender : function(ct, position){ - if(this.hiddenName && !Ext.isDefined(this.submitValue)){ - this.submitValue = false; - } - Ext.form.ComboBox.superclass.onRender.call(this, ct, position); - if(this.hiddenName){ - this.hiddenField = this.el.insertSibling({tag:'input', type:'hidden', name: this.hiddenName, - id: (this.hiddenId || Ext.id())}, 'before', true); - - } - if(Ext.isGecko){ - this.el.dom.setAttribute('autocomplete', 'off'); - } + setActiveEditor: function(ed) { + this.activeEditor = ed; + }, - if(!this.lazyInit){ - this.initList(); - }else{ - this.on('focus', this.initList, this, {single: true}); - } + getActiveEditor: function() { + return this.activeEditor; }, - - initValue : function(){ - Ext.form.ComboBox.superclass.initValue.call(this); - if(this.hiddenField){ - this.hiddenField.value = - Ext.value(Ext.isDefined(this.hiddenValue) ? this.hiddenValue : this.value, ''); - } + setActiveColumn: function(column) { + this.activeColumn = column; }, - getParentZIndex : function(){ - var zindex; - if (this.ownerCt){ - this.findParentBy(function(ct){ - zindex = parseInt(ct.getPositionEl().getStyle('z-index'), 10); - return !!zindex; - }); - } - return zindex; + getActiveColumn: function() { + return this.activeColumn; }, - - getZIndex : function(listParent){ - listParent = listParent || Ext.getDom(this.getListParent() || Ext.getBody()); - var zindex = parseInt(Ext.fly(listParent).getStyle('z-index'), 10); - if(!zindex){ - zindex = this.getParentZIndex(); - } - return (zindex || 12000) + 5; + + setActiveRecord: function(record) { + this.activeRecord = record; }, - - initList : function(){ - if(!this.list){ - var cls = 'x-combo-list', - listParent = Ext.getDom(this.getListParent() || Ext.getBody()); + getActiveRecord: function() { + return this.activeRecord; + }, - this.list = new Ext.Layer({ - parentEl: listParent, - shadow: this.shadow, - cls: [cls, this.listClass].join(' '), - constrain:false, - zindex: this.getZIndex(listParent) - }); + getEditor: function(record, column) { + var editors = this.editors, + editorId = column.itemId || column.id, + editor = editors.getByKey(editorId); - var lw = this.listWidth || Math.max(this.wrap.getWidth(), this.minListWidth); - this.list.setSize(lw, 0); - this.list.swallowEvent('mousewheel'); - this.assetHeight = 0; - if(this.syncFont !== false){ - this.list.setStyle('font-size', this.el.getStyle('font-size')); - } - if(this.title){ - this.header = this.list.createChild({cls:cls+'-hd', html: this.title}); - this.assetHeight += this.header.getHeight(); + if (editor) { + return editor; + } else { + editor = column.getEditor(record); + if (!editor) { + return false; } - this.innerList = this.list.createChild({cls:cls+'-inner'}); - this.mon(this.innerList, 'mouseover', this.onViewOver, this); - this.mon(this.innerList, 'mousemove', this.onViewMove, this); - this.innerList.setWidth(lw - this.list.getFrameWidth('lr')); - - if(this.pageSize){ - this.footer = this.list.createChild({cls:cls+'-ft'}); - this.pageTb = new Ext.PagingToolbar({ - store: this.store, - pageSize: this.pageSize, - renderTo:this.footer + + if (!(editor instanceof Ext.grid.CellEditor)) { + editor = Ext.create('Ext.grid.CellEditor', { + editorId: editorId, + field: editor }); - this.assetHeight += this.footer.getHeight(); - } - - if(!this.tpl){ - - this.tpl = '
    {' + this.displayField + '}
    '; - } - + editor.parentEl = this.grid.getEditorParent(); - this.view = new Ext.DataView({ - applyTo: this.innerList, - tpl: this.tpl, - singleSelect: true, - selectedClass: this.selectedClass, - itemSelector: this.itemSelector || '.' + cls + '-item', - emptyText: this.listEmptyText, - deferEmptyText: false - }); - - this.mon(this.view, { - containerclick : this.onViewClick, - click : this.onViewClick, - scope :this + editor.on({ + scope: this, + specialkey: this.onSpecialKey, + complete: this.onEditComplete, + canceledit: this.cancelEdit }); + editors.add(editor); + return editor; + } + }, - this.bindStore(this.store, true); - - if(this.resizable){ - this.resizer = new Ext.Resizable(this.list, { - pinned:true, handles:'se' - }); - this.mon(this.resizer, 'resize', function(r, w, h){ - this.maxHeight = h-this.handleHeight-this.list.getFrameWidth('tb')-this.assetHeight; - this.listWidth = w; - this.innerList.setWidth(w - this.list.getFrameWidth('lr')); - this.restrictHeight(); - }, this); + + getCell: function(record, column) { + return this.grid.getView().getCell(record, column); + }, - this[this.pageSize?'footer':'innerList'].setStyle('margin-bottom', this.handleHeight+'px'); + onSpecialKey: function(ed, field, e) { + var grid = this.grid, + sm; + if (e.getKey() === e.TAB) { + e.stopEvent(); + sm = grid.getSelectionModel(); + if (sm.onEditorTab) { + sm.onEditorTab(this, e); } } }, - - getListParent : function() { - return document.body; + onEditComplete : function(ed, value, startValue) { + var me = this, + grid = me.grid, + sm = grid.getSelectionModel(), + dataIndex = me.getActiveColumn().dataIndex; + + me.setActiveEditor(null); + me.setActiveColumn(null); + me.setActiveRecord(null); + delete sm.wasEditing; + + if (!me.validateEdit()) { + return; + } + me.context.record.set(dataIndex, value); + me.fireEvent('edit', me, me.context); }, - getStore : function(){ - return this.store; + cancelEdit: function() { + var me = this, + activeEd = me.getActiveEditor(), + viewEl = me.grid.getView().el; + + me.setActiveEditor(null); + me.setActiveColumn(null); + me.setActiveRecord(null); + if (activeEd) { + activeEd.cancelEdit(); + viewEl.focus(); + } }, - bindStore : function(store, initial){ - if(this.store && !initial){ - if(this.store !== store && this.store.autoDestroy){ - this.store.destroy(); - }else{ - this.store.un('beforeload', this.onBeforeLoad, this); - this.store.un('load', this.onLoad, this); - this.store.un('exception', this.collapse, this); - } - if(!store){ - this.store = null; - if(this.view){ - this.view.bindStore(null); - } - if(this.pageTb){ - this.pageTb.bindStore(null); - } - } + startEditByPosition: function(position) { + var me = this, + grid = me.grid, + sm = grid.getSelectionModel(), + editRecord = grid.store.getAt(position.row), + editColumnHeader = grid.headerCt.getHeaderAtIndex(position.column); + + if (sm.selectByPosition) { + sm.selectByPosition(position); } - if(store){ - if(!initial) { - this.lastQuery = null; - if(this.pageTb) { - this.pageTb.bindStore(store); - } - } + me.startEdit(editRecord, editColumnHeader); + } +}); - this.store = Ext.StoreMgr.lookup(store); - this.store.on({ - scope: this, - beforeload: this.onBeforeLoad, - load: this.onLoad, - exception: this.collapse - }); +Ext.define('Ext.grid.plugin.DragDrop', { + extend: 'Ext.AbstractPlugin', + alias: 'plugin.gridviewdragdrop', - if(this.view){ - this.view.bindStore(store); - } - } - }, + uses: [ + 'Ext.view.DragZone', + 'Ext.grid.ViewDropZone' + ], - reset : function(){ - if(this.clearFilterOnReset && this.mode == 'local'){ - this.store.clearFilter(); - } - Ext.form.ComboBox.superclass.reset.call(this); - }, + - initEvents : function(){ - Ext.form.ComboBox.superclass.initEvents.call(this); - - this.keyNav = new Ext.KeyNav(this.el, { - "up" : function(e){ - this.inKeyMode = true; - this.selectPrev(); - }, + dragText : '{0} selected row{1}', - "down" : function(e){ - if(!this.isExpanded()){ - this.onTriggerClick(); - }else{ - this.inKeyMode = true; - this.selectNext(); - } - }, + + ddGroup : "GridDD", - "enter" : function(e){ - this.onViewClick(); - }, + - "esc" : function(e){ - this.collapse(); - }, + - "tab" : function(e){ - if (this.forceSelection === true) { - this.collapse(); - } else { - this.onViewClick(false); - } - return true; - }, + + enableDrop: true, - scope : this, + + enableDrag: true, - doRelay : function(e, h, hname){ - if(hname == 'down' || this.scope.isExpanded()){ - - var relay = Ext.KeyNav.prototype.doRelay.apply(this, arguments); - if(!Ext.isIE && Ext.EventManager.useKeydown){ - - this.scope.fireKey(e); - } - return relay; - } - return true; - }, + init : function(view) { + view.on('render', this.onViewRender, this, {single: true}); + }, - forceKeyDown : true, - defaultEventAction: 'stopEvent' - }); - this.queryDelay = Math.max(this.queryDelay || 10, - this.mode == 'local' ? 10 : 250); - this.dqTask = new Ext.util.DelayedTask(this.initQuery, this); - if(this.typeAhead){ - this.taTask = new Ext.util.DelayedTask(this.onTypeAhead, this); - } - if(!this.enableKeyEvents){ - this.mon(this.el, 'keyup', this.onKeyUp, this); - } + + destroy: function() { + Ext.destroy(this.dragZone, this.dropZone); }, + onViewRender : function(view) { + var me = this; - - onDestroy : function(){ - if (this.dqTask){ - this.dqTask.cancel(); - this.dqTask = null; + if (me.enableDrag) { + me.dragZone = Ext.create('Ext.view.DragZone', { + view: view, + ddGroup: me.dragGroup || me.ddGroup, + dragText: me.dragText + }); } - this.bindStore(null); - Ext.destroy( - this.resizer, - this.view, - this.pageTb, - this.list - ); - Ext.destroyMembers(this, 'hiddenField'); - Ext.form.ComboBox.superclass.onDestroy.call(this); + + if (me.enableDrop) { + me.dropZone = Ext.create('Ext.grid.ViewDropZone', { + view: view, + ddGroup: me.dropGroup || me.ddGroup + }); + } + } +}); + +Ext.define('Ext.grid.plugin.HeaderReorderer', { + extend: 'Ext.util.Observable', + requires: ['Ext.grid.header.DragZone', 'Ext.grid.header.DropZone'], + alias: 'plugin.gridheaderreorderer', + + init: function(headerCt) { + this.headerCt = headerCt; + headerCt.on('render', this.onHeaderCtRender, this); }, - fireKey : function(e){ - if (!this.isExpanded()) { - Ext.form.ComboBox.superclass.fireKey.call(this, e); - } + destroy: function() { + Ext.destroy(this.dragZone, this.dropZone); }, + onHeaderCtRender: function() { + this.dragZone = Ext.create('Ext.grid.header.DragZone', this.headerCt); + this.dropZone = Ext.create('Ext.grid.header.DropZone', this.headerCt); + if (this.disabled) { + this.dragZone.disable(); + } + }, - onResize : function(w, h){ - Ext.form.ComboBox.superclass.onResize.apply(this, arguments); - if(!isNaN(w) && this.isVisible() && this.list){ - this.doResize(w); - }else{ - this.bufferSize = w; + enable: function() { + this.disabled = false; + if (this.dragZone) { + this.dragZone.enable(); } }, - - doResize: function(w){ - if(!Ext.isDefined(this.listWidth)){ - var lw = Math.max(w, this.minListWidth); - this.list.setWidth(lw); - this.innerList.setWidth(lw - this.list.getFrameWidth('lr')); + + disable: function() { + this.disabled = true; + if (this.dragZone) { + this.dragZone.disable(); } + } +}); + +Ext.define('Ext.grid.plugin.HeaderResizer', { + extend: 'Ext.util.Observable', + requires: ['Ext.dd.DragTracker', 'Ext.util.Region'], + alias: 'plugin.gridheaderresizer', + + disabled: false, + + + configs: { + dynamic: true }, + colHeaderCls: Ext.baseCSSPrefix + 'column-header', + + minColWidth: 40, + maxColWidth: 1000, + wResizeCursor: 'col-resize', + eResizeCursor: 'col-resize', + + + - onEnable : function(){ - Ext.form.ComboBox.superclass.onEnable.apply(this, arguments); - if(this.hiddenField){ - this.hiddenField.disabled = false; - } - }, - - onDisable : function(){ - Ext.form.ComboBox.superclass.onDisable.apply(this, arguments); - if(this.hiddenField){ - this.hiddenField.disabled = true; - } + init: function(headerCt) { + this.headerCt = headerCt; + headerCt.on('render', this.afterHeaderRender, this, {single: true}); }, - onBeforeLoad : function(){ - if(!this.hasFocus){ - return; + destroy: function() { + if (this.tracker) { + this.tracker.destroy(); } - this.innerList.update(this.loadingText ? - '
    '+this.loadingText+'
    ' : ''); - this.restrictHeight(); - this.selectedIndex = -1; }, - - onLoad : function(){ - if(!this.hasFocus){ - return; - } - if(this.store.getCount() > 0 || this.listEmptyText){ - this.expand(); - this.restrictHeight(); - if(this.lastQuery == this.allQuery){ - if(this.editable){ - this.el.dom.select(); - } + afterHeaderRender: function() { + var headerCt = this.headerCt, + el = headerCt.el; - if(this.autoSelect !== false && !this.selectByValue(this.value, true)){ - this.select(0, true); - } - }else{ - if(this.autoSelect !== false){ - this.selectNext(); - } - if(this.typeAhead && this.lastKey != Ext.EventObject.BACKSPACE && this.lastKey != Ext.EventObject.DELETE){ - this.taTask.delay(this.typeAheadDelay); - } - } - }else{ - this.collapse(); - } + headerCt.mon(el, 'mousemove', this.onHeaderCtMouseMove, this); + this.tracker = Ext.create('Ext.dd.DragTracker', { + disabled: this.disabled, + onBeforeStart: Ext.Function.bind(this.onBeforeStart, this), + onStart: Ext.Function.bind(this.onStart, this), + onDrag: Ext.Function.bind(this.onDrag, this), + onEnd: Ext.Function.bind(this.onEnd, this), + tolerance: 3, + autoStart: 300, + el: el + }); }, - onTypeAhead : function(){ - if(this.store.getCount() > 0){ - var r = this.store.getAt(0); - var newValue = r.data[this.displayField]; - var len = newValue.length; - var selStart = this.getRawValue().length; - if(selStart != len){ - this.setRawValue(newValue); - this.selectText(selStart, newValue.length); + + + onHeaderCtMouseMove: function(e, t) { + if (this.headerCt.dragging) { + if (this.activeHd) { + this.activeHd.el.dom.style.cursor = ''; + delete this.activeHd; } - } - }, + } else { + var headerEl = e.getTarget('.' + this.colHeaderCls, 3, true), + overHeader, resizeHeader; - - assertValue : function(){ - var val = this.getRawValue(), - rec; + if (headerEl){ + overHeader = Ext.getCmp(headerEl.id); - if(this.valueField && Ext.isDefined(this.value)){ - rec = this.findRecord(this.valueField, this.value); - } - if(!rec || rec.get(this.displayField) != val){ - rec = this.findRecord(this.displayField, val); - } - if(!rec && this.forceSelection){ - if(val.length > 0 && val != this.emptyText){ - this.el.dom.value = Ext.value(this.lastSelectionText, ''); - this.applyEmptyText(); - }else{ - this.clearValue(); - } - }else{ - if(rec && this.valueField){ + if (overHeader.isOnLeftEdge(e)) { + resizeHeader = overHeader.previousNode('gridcolumn:not([hidden]):not([isGroupHeader])'); + } + else if (overHeader.isOnRightEdge(e)) { + resizeHeader = overHeader; + } - if (this.value == val){ - return; + else { + resizeHeader = null; + } + + + if (resizeHeader) { + + + + if (resizeHeader.isGroupHeader) { + resizeHeader = resizeHeader.getVisibleGridColumns(); + resizeHeader = resizeHeader[resizeHeader.length - 1]; + } + + if (resizeHeader && !resizeHeader.fixed) { + this.activeHd = resizeHeader; + overHeader.el.dom.style.cursor = this.eResizeCursor; + } + + } else { + overHeader.el.dom.style.cursor = ''; + delete this.activeHd; } - val = rec.get(this.valueField || this.displayField); } - this.setValue(val); } }, - onSelect : function(record, index){ - if(this.fireEvent('beforeselect', this, record, index) !== false){ - this.setValue(record.data[this.valueField || this.displayField]); - this.collapse(); - this.fireEvent('select', this, record, index); + onBeforeStart : function(e){ + var t = e.getTarget(); + + this.dragHd = this.activeHd; + + if (!!this.dragHd && !Ext.fly(t).hasCls('x-column-header-trigger') && !this.headerCt.dragging) { + + this.tracker.constrainTo = this.getConstrainRegion(); + return true; + } else { + this.headerCt.dragging = false; + return false; } }, - getName: function(){ - var hf = this.hiddenField; - return hf && hf.name ? hf.name : this.hiddenName || Ext.form.ComboBox.superclass.getName.call(this); - }, + getConstrainRegion: function() { + var dragHdEl = this.dragHd.el, + region = Ext.util.Region.getRegion(dragHdEl); - - getValue : function(){ - if(this.valueField){ - return Ext.isDefined(this.value) ? this.value : ''; - }else{ - return Ext.form.ComboBox.superclass.getValue.call(this); - } + return region.adjust( + 0, + this.maxColWidth - dragHdEl.getWidth(), + 0, + this.minColWidth + ); }, - clearValue : function(){ - if(this.hiddenField){ - this.hiddenField.value = ''; - } - this.setRawValue(''); - this.lastSelectionText = ''; - this.applyEmptyText(); - this.value = ''; - }, - - setValue : function(v){ - var text = v; - if(this.valueField){ - var r = this.findRecord(this.valueField, v); - if(r){ - text = r.data[this.displayField]; - }else if(Ext.isDefined(this.valueNotFoundText)){ - text = this.valueNotFoundText; - } - } - this.lastSelectionText = text; - if(this.hiddenField){ - this.hiddenField.value = Ext.value(v, ''); - } - Ext.form.ComboBox.superclass.setValue.call(this, text); - this.value = v; - return this; - }, + onStart: function(e){ + var me = this, + dragHd = me.dragHd, + dragHdEl = dragHd.el, + width = dragHdEl.getWidth(), + headerCt = me.headerCt, + t = e.getTarget(); - - findRecord : function(prop, value){ - var record; - if(this.store.getCount() > 0){ - this.store.each(function(r){ - if(r.data[prop] == value){ - record = r; - return false; - } - }); + if (me.dragHd && !Ext.fly(t).hasCls('x-column-header-trigger')) { + headerCt.dragging = true; } - return record; - }, - - onViewMove : function(e, t){ - this.inKeyMode = false; - }, + me.origWidth = width; - - onViewOver : function(e, t){ - if(this.inKeyMode){ - return; - } - var item = this.view.findItemFromChild(t); - if(item){ - var index = this.view.indexOf(item); - this.select(index, false); - } - }, + + if (!me.dynamic) { + var xy = dragHdEl.getXY(), + gridSection = headerCt.up('[scrollerOwner]'), + dragHct = me.dragHd.up(':not([isGroupHeader])'), + firstSection = dragHct.up(), + lhsMarker = gridSection.getLhsMarker(), + rhsMarker = gridSection.getRhsMarker(), + el = rhsMarker.parent(), + offsetLeft = el.getLeft(true), + offsetTop = el.getTop(true), + topLeft = el.translatePoints(xy), + markerHeight = firstSection.body.getHeight() + headerCt.getHeight(), + top = topLeft.top - offsetTop; - - onViewClick : function(doFocus){ - var index = this.view.getSelectedIndexes()[0], - s = this.store, - r = s.getAt(index); - if(r){ - this.onSelect(r, index); - }else { - this.collapse(); - } - if(doFocus !== false){ - this.el.focus(); + lhsMarker.setTop(top); + rhsMarker.setTop(top); + lhsMarker.setHeight(markerHeight); + rhsMarker.setHeight(markerHeight); + lhsMarker.setLeft(topLeft.left - offsetLeft); + rhsMarker.setLeft(topLeft.left + width - offsetLeft); } }, - - restrictHeight : function(){ - this.innerList.dom.style.height = ''; - var inner = this.innerList.dom, - pad = this.list.getFrameWidth('tb') + (this.resizable ? this.handleHeight : 0) + this.assetHeight, - h = Math.max(inner.clientHeight, inner.offsetHeight, inner.scrollHeight), - ha = this.getPosition()[1]-Ext.getBody().getScroll().top, - hb = Ext.lib.Dom.getViewHeight()-ha-this.getSize().height, - space = Math.max(ha, hb, this.minHeight || 0)-this.list.shadowOffset-pad-5; - - h = Math.min(h, space, this.maxHeight); + onDrag: function(e){ + if (!this.dynamic) { + var xy = this.tracker.getXY('point'), + gridSection = this.headerCt.up('[scrollerOwner]'), + rhsMarker = gridSection.getRhsMarker(), + el = rhsMarker.parent(), + topLeft = el.translatePoints(xy), + offsetLeft = el.getLeft(true); - this.innerList.setHeight(h); - this.list.beginUpdate(); - this.list.setHeight(h+pad); - this.list.alignTo.apply(this.list, [this.el].concat(this.listAlign)); - this.list.endUpdate(); + rhsMarker.setLeft(topLeft.left - offsetLeft); + + } else { + this.doResize(); + } }, - - isExpanded : function(){ - return this.list && this.list.isVisible(); - }, + onEnd: function(e){ + this.headerCt.dragging = false; + if (this.dragHd) { + if (!this.dynamic) { + var dragHd = this.dragHd, + gridSection = this.headerCt.up('[scrollerOwner]'), + lhsMarker = gridSection.getLhsMarker(), + rhsMarker = gridSection.getRhsMarker(), + currWidth = dragHd.getWidth(), + offset = this.tracker.getOffset('point'), + offscreen = -9999; - - selectByValue : function(v, scrollIntoView){ - if(!Ext.isEmpty(v, true)){ - var r = this.findRecord(this.valueField || this.displayField, v); - if(r){ - this.select(this.store.indexOf(r), scrollIntoView); - return true; + + lhsMarker.setLeft(offscreen); + rhsMarker.setLeft(offscreen); } + this.doResize(); } - return false; }, - - select : function(index, scrollIntoView){ - this.selectedIndex = index; - this.view.select(index); - if(scrollIntoView !== false){ - var el = this.view.getNode(index); - if(el){ - this.innerList.scrollChildIntoView(el, false); + doResize: function() { + if (this.dragHd) { + var dragHd = this.dragHd, + nextHd, + offset = this.tracker.getOffset('point'); + + + if (dragHd.flex) { + delete dragHd.flex; } - } - }, + + + if (this.headerCt.forceFit) { + nextHd = dragHd.nextNode('gridcolumn:not([hidden]):not([isGroupHeader])'); + if (nextHd) { + this.headerCt.componentLayout.layoutBusy = true; + } + } - - selectNext : function(){ - var ct = this.store.getCount(); - if(ct > 0){ - if(this.selectedIndex == -1){ - this.select(0); - }else if(this.selectedIndex < ct-1){ - this.select(this.selectedIndex+1); + + + dragHd.minWidth = this.origWidth + offset[0]; + dragHd.setWidth(dragHd.minWidth); + + + + if (nextHd) { + delete nextHd.flex; + nextHd.setWidth(nextHd.getWidth() - offset[0]); + this.headerCt.componentLayout.layoutBusy = false; + this.headerCt.doComponentLayout(); } } }, - - selectPrev : function(){ - var ct = this.store.getCount(); - if(ct > 0){ - if(this.selectedIndex == -1){ - this.select(0); - }else if(this.selectedIndex !== 0){ - this.select(this.selectedIndex-1); - } + disable: function() { + this.disabled = true; + if (this.tracker) { + this.tracker.disable(); } }, - - onKeyUp : function(e){ - var k = e.getKey(); - if(this.editable !== false && this.readOnly !== true && (k == e.BACKSPACE || !e.isSpecialKey())){ - - this.lastKey = k; - this.dqTask.delay(this.queryDelay); + enable: function() { + this.disabled = false; + if (this.tracker) { + this.tracker.enable(); } - Ext.form.ComboBox.superclass.onKeyUp.call(this, e); - }, + } +}); + +Ext.define('Ext.grid.plugin.RowEditing', { + extend: 'Ext.grid.plugin.Editing', + alias: 'plugin.rowediting', + + requires: [ + 'Ext.grid.RowEditor' + ], + + editStyle: 'row', - validateBlur : function(){ - return !this.list || !this.list.isVisible(); - }, + autoCancel: true, - initQuery : function(){ - this.doQuery(this.getRawValue()); - }, - beforeBlur : function(){ - this.assertValue(); + errorSummary: true, + + + + + + constructor: function() { + var me = this; + me.callParent(arguments); + + if (!me.clicksToMoveEditor) { + me.clicksToMoveEditor = me.clicksToEdit; + } + + me.autoCancel = !!me.autoCancel; }, - postBlur : function(){ - Ext.form.ComboBox.superclass.postBlur.call(this); - this.collapse(); - this.inKeyMode = false; + destroy: function() { + var me = this; + Ext.destroy(me.editor); + me.callParent(arguments); }, - doQuery : function(q, forceAll){ - q = Ext.isEmpty(q) ? '' : q; - var qe = { - query: q, - forceAll: forceAll, - combo: this, - cancel:false - }; - if(this.fireEvent('beforequery', qe)===false || qe.cancel){ + startEdit: function(record, columnHeader) { + var me = this, + editor = me.getEditor(); + + if (me.callParent(arguments) === false) { return false; } - q = qe.query; - forceAll = qe.forceAll; - if(forceAll === true || (q.length >= this.minChars)){ - if(this.lastQuery !== q){ - this.lastQuery = q; - if(this.mode == 'local'){ - this.selectedIndex = -1; - if(forceAll){ - this.store.clearFilter(); - }else{ - this.store.filter(this.displayField, q); - } - this.onLoad(); - }else{ - this.store.baseParams[this.queryParam] = q; - this.store.load({ - params: this.getParams(q) - }); - this.expand(); - } - }else{ - this.selectedIndex = -1; - this.onLoad(); - } + + + if (editor.beforeEdit() !== false) { + editor.startEdit(me.context.record, me.context.column); } }, - getParams : function(q){ - var params = {}, - paramNames = this.store.paramNames; - if(this.pageSize){ - params[paramNames.start] = 0; - params[paramNames.limit] = this.pageSize; + cancelEdit: function() { + var me = this; + + if (me.editing) { + me.getEditor().cancelEdit(); + me.callParent(arguments); } - return params; }, - collapse : function(){ - if(!this.isExpanded()){ - return; + completeEdit: function() { + var me = this; + + if (me.editing && me.validateEdit()) { + me.editing = false; + me.fireEvent('edit', me.context); } - this.list.hide(); - Ext.getDoc().un('mousewheel', this.collapseIf, this); - Ext.getDoc().un('mousedown', this.collapseIf, this); - this.fireEvent('collapse', this); }, - collapseIf : function(e){ - if(!this.isDestroyed && !e.within(this.wrap) && !e.within(this.list)){ - this.collapse(); - } + validateEdit: function() { + var me = this; + return me.callParent(arguments) && me.getEditor().completeEdit(); }, - expand : function(){ - if(this.isExpanded() || !this.hasFocus){ - return; - } - - if(this.title || this.pageSize){ - this.assetHeight = 0; - if(this.title){ - this.assetHeight += this.header.getHeight(); - } - if(this.pageSize){ - this.assetHeight += this.footer.getHeight(); - } - } - - if(this.bufferSize){ - this.doResize(this.bufferSize); - delete this.bufferSize; - } - this.list.alignTo.apply(this.list, [this.el].concat(this.listAlign)); + getEditor: function() { + var me = this; - - this.list.setZIndex(this.getZIndex()); - this.list.show(); - if(Ext.isGecko2){ - this.innerList.setOverflow('auto'); + if (!me.editor) { + me.editor = me.initEditor(); } - this.mon(Ext.getDoc(), { - scope: this, - mousewheel: this.collapseIf, - mousedown: this.collapseIf - }); - this.fireEvent('expand', this); + return me.editor; }, - - - onTriggerClick : function(){ - if(this.readOnly || this.disabled){ - return; - } - if(this.isExpanded()){ - this.collapse(); - this.el.focus(); - }else { - this.onFocus({}); - if(this.triggerAction == 'all') { - this.doQuery(this.allQuery, true); - } else { - this.doQuery(this.getRawValue()); - } - this.el.focus(); - } - } + initEditor: function() { + var me = this, + grid = me.grid, + view = me.view, + headerCt = grid.headerCt; - - - - + return Ext.create('Ext.grid.RowEditor', { + autoCancel: me.autoCancel, + errorSummary: me.errorSummary, + fields: headerCt.getGridColumns(), + hidden: true, -}); -Ext.reg('combo', Ext.form.ComboBox); + + editingPlugin: me, + renderTo: view.el + }); + }, -Ext.form.Checkbox = Ext.extend(Ext.form.Field, { - - focusClass : undefined, - - fieldClass : 'x-form-field', - - checked : false, - - boxLabel: ' ', - - defaultAutoCreate : { tag: 'input', type: 'checkbox', autocomplete: 'off'}, - - + initEditTriggers: function() { + var me = this, + grid = me.grid, + view = me.view, + headerCt = grid.headerCt, + moveEditorEvent = me.clicksToMoveEditor === 1 ? 'click' : 'dblclick'; - - actionMode : 'wrap', + me.callParent(arguments); - - initComponent : function(){ - Ext.form.Checkbox.superclass.initComponent.call(this); - this.addEvents( + if (me.clicksToMoveEditor !== me.clicksToEdit) { + me.mon(view, 'cell' + moveEditorEvent, me.moveEditorByClick, me); + } + + view.on('render', function() { - 'check' - ); + me.mon(headerCt, { + add: me.onColumnAdd, + remove: me.onColumnRemove, + columnresize: me.onColumnResize, + columnhide: me.onColumnHide, + columnshow: me.onColumnShow, + columnmove: me.onColumnMove, + scope: me + }); + }, me, { single: true }); }, - - onResize : function(){ - Ext.form.Checkbox.superclass.onResize.apply(this, arguments); - if(!this.boxLabel && !this.fieldLabel){ - this.el.alignTo(this.wrap, 'c-c'); + startEditByClick: function() { + var me = this; + if (!me.editing || me.clicksToMoveEditor === me.clicksToEdit) { + me.callParent(arguments); } }, - - initEvents : function(){ - Ext.form.Checkbox.superclass.initEvents.call(this); - this.mon(this.el, { - scope: this, - click: this.onClick, - change: this.onClick - }); + moveEditorByClick: function() { + var me = this; + if (me.editing) { + me.superclass.startEditByClick.apply(me, arguments); + } }, - markInvalid : Ext.emptyFn, - - clearInvalid : Ext.emptyFn, + onColumnAdd: function(ct, column) { + var me = this, + editor = me.getEditor(); - - onRender : function(ct, position){ - Ext.form.Checkbox.superclass.onRender.call(this, ct, position); - if(this.inputValue !== undefined){ - this.el.dom.value = this.inputValue; + me.initFieldAccessors(column); + if (editor && editor.onColumnAdd) { + editor.onColumnAdd(column); } - this.wrap = this.el.wrap({cls: 'x-form-check-wrap'}); - if(this.boxLabel){ - this.wrap.createChild({tag: 'label', htmlFor: this.el.id, cls: 'x-form-cb-label', html: this.boxLabel}); - } - if(this.checked){ - this.setValue(true); - }else{ - this.checked = this.el.dom.checked; - } - - if (Ext.isIE && !Ext.isStrict) { - this.wrap.repaint(); - } - this.resizeEl = this.positionEl = this.wrap; }, - onDestroy : function(){ - Ext.destroy(this.wrap); - Ext.form.Checkbox.superclass.onDestroy.call(this); + onColumnRemove: function(ct, column) { + var me = this, + editor = me.getEditor(); + + if (editor && editor.onColumnRemove) { + editor.onColumnRemove(column); + } + me.removeFieldAccessors(column); }, - initValue : function() { - this.originalValue = this.getValue(); + onColumnResize: function(ct, column, width) { + var me = this, + editor = me.getEditor(); + + if (editor && editor.onColumnResize) { + editor.onColumnResize(column, width); + } }, - getValue : function(){ - if(this.rendered){ - return this.el.dom.checked; + onColumnHide: function(ct, column) { + var me = this, + editor = me.getEditor(); + + if (editor && editor.onColumnHide) { + editor.onColumnHide(column); } - return this.checked; }, - - onClick : function(){ - if(this.el.dom.checked != this.checked){ - this.setValue(this.el.dom.checked); + + onColumnShow: function(ct, column) { + var me = this, + editor = me.getEditor(); + + if (editor && editor.onColumnShow) { + editor.onColumnShow(column); } }, - setValue : function(v){ - var checked = this.checked, - inputVal = this.inputValue; - - this.checked = (v === true || v === 'true' || v == '1' || (inputVal ? v == inputVal : String(v).toLowerCase() == 'on')); - if(this.rendered){ - this.el.dom.checked = this.checked; - this.el.dom.defaultChecked = this.checked; - } - if(checked != this.checked){ - this.fireEvent('check', this, this.checked); - if(this.handler){ - this.handler.call(this.scope || this, this, this.checked); - } + onColumnMove: function(ct, column, fromIdx, toIdx) { + var me = this, + editor = me.getEditor(); + + if (editor && editor.onColumnMove) { + editor.onColumnMove(column, fromIdx, toIdx); } - return this; + }, + + + setColumnField: function(column, field) { + var me = this; + me.callParent(arguments); + me.getEditor().setField(column.field, column); } }); -Ext.reg('checkbox', Ext.form.Checkbox); -Ext.form.CheckboxGroup = Ext.extend(Ext.form.Field, { - - - columns : 'auto', - - vertical : false, - - allowBlank : true, - - blankText : "You must select at least one item in this group", +Ext.define('Ext.grid.property.Grid', { - - defaultType : 'checkbox', + extend: 'Ext.grid.Panel', - - groupCls : 'x-form-check-group', + alternateClassName: 'Ext.grid.PropertyGrid', - - initComponent: function(){ - this.addEvents( - - 'change' - ); - this.on('change', this.validate, this); - Ext.form.CheckboxGroup.superclass.initComponent.call(this); - }, + uses: [ + 'Ext.grid.plugin.CellEditing', + 'Ext.grid.property.Store', + 'Ext.grid.property.HeaderContainer', + 'Ext.XTemplate', + 'Ext.grid.CellEditor', + 'Ext.form.field.Date', + 'Ext.form.field.Text', + 'Ext.form.field.Number' + ], + + - onRender : function(ct, position){ - if(!this.el){ - var panelCfg = { - autoEl: { - id: this.id - }, - cls: this.groupCls, - layout: 'column', - renderTo: ct, - bufferResize: false - }; - var colCfg = { - xtype: 'container', - defaultType: this.defaultType, - layout: 'form', - defaults: { - hideLabel: true, - anchor: '100%' - } - }; - if(this.items[0].items){ + - + - Ext.apply(panelCfg, { - layoutConfig: {columns: this.items.length}, - defaults: this.defaults, - items: this.items - }); - for(var i=0, len=this.items.length; i0 && i%rows==0){ - ri++; - } - if(this.items[i].fieldLabel){ - this.items[i].hideLabel = false; - } - cols[ri].items.push(this.items[i]); - }; - }else{ - for(var i=0, len=this.items.length; i -1){ - item.setValue(true); - } - }); + setSource: function(source) { + this.source = source; + this.propStore.setSource(source); }, - getBox : function(id){ - var box = null; - this.eachItem(function(f){ - if(id == f || f.dataIndex == id || f.id == id || f.getName() == id){ - box = f; - return false; - } - }); - return box; + getSource: function() { + return this.propStore.getSource(); }, - getValue : function(){ - var out = []; - this.eachItem(function(item){ - if(item.checked){ - out.push(item); - } - }); - return out; + setProperty: function(prop, value, create) { + this.propStore.setValue(prop, value, create); }, - eachItem: function(fn, scope) { - if(this.items && this.items.each){ - this.items.each(fn, scope || this); - } - }, + removeProperty: function(prop) { + this.propStore.remove(prop); + } - - getRawValue : Ext.emptyFn, - - setRawValue : Ext.emptyFn - + }); -Ext.reg('checkboxgroup', Ext.form.CheckboxGroup); - -Ext.form.CompositeField = Ext.extend(Ext.form.Field, { +Ext.define('Ext.grid.property.HeaderContainer', { - - defaultMargins: '0 5 0 0', + extend: 'Ext.grid.header.Container', - - skipLastItemMargin: true, + alternateClassName: 'Ext.grid.PropertyColumnModel', - isComposite: true, + nameText : 'Name', + valueText : 'Value', + dateFormat : 'm/j/Y', + trueText: 'true', + falseText: 'false', - combineErrors: true, + nameColumnCls: Ext.baseCSSPrefix + 'grid-property-name', - - labelConnector: ', ', + constructor : function(grid, store) { + + this.grid = grid; + this.store = store; + this.callParent([{ + items: [{ + header: this.nameText, + width: 115, + sortable: true, + dataIndex: grid.nameField, + renderer: Ext.Function.bind(this.renderProp, this), + itemId: grid.nameField, + menuDisabled :true, + tdCls: this.nameColumnCls + }, { + header: this.valueText, + renderer: Ext.Function.bind(this.renderCell, this), + getEditor: function(record) { + return grid.getCellEditor(record, this); + }, + flex: 1, + fixed: true, + dataIndex: grid.valueField, + itemId: grid.valueField, + menuDisabled: true + }] + }]); + }, + + renderProp : function(v) { + return this.getPropertyName(v); + }, - initComponent: function() { - var labels = [], - items = this.items, - item; - - for (var i=0, j = items.length; i < j; i++) { - item = items[i]; - - if (!Ext.isEmpty(item.ref)){ - item.ref = '../' + item.ref; - } - - labels.push(item.fieldLabel); - - - Ext.applyIf(item, this.defaults); + renderCell : function(val, meta, rec) { + var me = this, + renderer = this.grid.customRenderers[rec.get(me.grid.nameField)], + result = val; - - if (!(i == j - 1 && this.skipLastItemMargin)) { - Ext.applyIf(item, {margins: this.defaultMargins}); - } + if (renderer) { + return renderer.apply(this, arguments); } + if (Ext.isDate(val)) { + result = this.renderDate(val); + } else if (Ext.isBoolean(val)) { + result = this.renderBool(val); + } + return Ext.util.Format.htmlEncode(result); + }, - this.fieldLabel = this.fieldLabel || this.buildLabel(labels); - - - this.fieldErrors = new Ext.util.MixedCollection(true, function(item) { - return item.field; - }); - - this.fieldErrors.on({ - scope : this, - add : this.updateInvalidMark, - remove : this.updateInvalidMark, - replace: this.updateInvalidMark - }); - - Ext.form.CompositeField.superclass.initComponent.apply(this, arguments); - - this.innerCt = new Ext.Container({ - layout : 'hbox', - items : this.items, - cls : 'x-form-composite', - defaultMargins: '0 3 0 0', - ownerCt: this - }); - this.innerCt.ownerCt = undefined; - - var fields = this.innerCt.findBy(function(c) { - return c.isFormField; - }, this); + + renderDate : Ext.util.Format.date, - - this.items = new Ext.util.MixedCollection(); - this.items.addAll(fields); - + + renderBool : function(bVal) { + return this[bVal ? 'trueText' : 'falseText']; }, - onRender: function(ct, position) { - if (!this.el) { - - var innerCt = this.innerCt; - innerCt.render(ct); + + getPropertyName : function(name) { + var pn = this.grid.propertyNames; + return pn && pn[name] ? pn[name] : name; + } +}); - this.el = innerCt.getEl(); +Ext.define('Ext.grid.property.Property', { + extend: 'Ext.data.Model', - - - if (this.combineErrors) { - this.eachItem(function(field) { - Ext.apply(field, { - markInvalid : this.onFieldMarkInvalid.createDelegate(this, [field], 0), - clearInvalid: this.onFieldClearInvalid.createDelegate(this, [field], 0) - }); - }); - } + alternateClassName: 'Ext.PropGridProperty', - - var l = this.el.parent().parent().child('label', true); - if (l) { - l.setAttribute('for', this.items.items[0].id); - } - } + fields: [{ + name: 'name', + type: 'string' + }, { + name: 'value' + }], + idProperty: 'name' +}); - Ext.form.CompositeField.superclass.onRender.apply(this, arguments); - }, +Ext.define('Ext.grid.property.Store', { - - onFieldMarkInvalid: function(field, message) { - var name = field.getName(), - error = { - field: name, - errorName: field.fieldLabel || name, - error: message - }; + extend: 'Ext.data.Store', - this.fieldErrors.replace(name, error); + alternateClassName: 'Ext.grid.PropertyStore', - field.el.addClass(field.invalidClass); + uses: ['Ext.data.reader.Reader', 'Ext.data.proxy.Proxy', 'Ext.data.ResultSet', 'Ext.grid.property.Property'], + + constructor : function(grid, source){ + this.grid = grid; + this.source = source; + this.callParent([{ + data: source, + model: Ext.grid.property.Property, + proxy: this.getProxy() + }]); }, - onFieldClearInvalid: function(field) { - this.fieldErrors.removeKey(field.getName()); - - field.el.removeClass(field.invalidClass); + getProxy: function() { + if (!this.proxy) { + Ext.grid.property.Store.prototype.proxy = Ext.create('Ext.data.proxy.Memory', { + model: Ext.grid.property.Property, + reader: this.getReader() + }); + } + return this.proxy; }, - updateInvalidMark: function() { - var ieStrict = Ext.isIE6 && Ext.isStrict; + getReader: function() { + if (!this.reader) { + Ext.grid.property.Store.prototype.reader = Ext.create('Ext.data.reader.Reader', { + model: Ext.grid.property.Property, - if (this.fieldErrors.length == 0) { - this.clearInvalid(); + buildExtractors: Ext.emptyFn, - - if (ieStrict) { - this.clearInvalid.defer(50, this); - } - } else { - var message = this.buildCombinedErrorMessage(this.fieldErrors.items); + read: function(dataObject) { + return this.readRecords(dataObject); + }, - this.sortErrors(); - this.markInvalid(message); + readRecords: function(dataObject) { + var val, + result = { + records: [], + success: true + }; - - if (ieStrict) { - this.markInvalid(message); - } + for (var propName in dataObject) { + val = dataObject[propName]; + if (dataObject.hasOwnProperty(propName) && this.isEditableValue(val)) { + result.records.push(new Ext.grid.property.Property({ + name: propName, + value: val + }, propName)); + } + } + result.total = result.count = result.records.length; + return Ext.create('Ext.data.ResultSet', result); + }, + + + isEditableValue: function(val){ + return Ext.isPrimitive(val) || Ext.isDate(val); + } + }); } + return this.reader; }, - validateValue: function() { - var valid = true; - - this.eachItem(function(field) { - if (!field.isValid()) valid = false; - }); + setSource : function(dataObject) { + var me = this; - return valid; + me.source = dataObject; + me.suspendEvents(); + me.removeAll(); + me.proxy.data = dataObject; + me.load(); + me.resumeEvents(); + me.fireEvent('datachanged', me); }, - buildCombinedErrorMessage: function(errors) { - var combined = [], - error; - - for (var i = 0, j = errors.length; i < j; i++) { - error = errors[i]; + getProperty : function(row) { + return Ext.isNumber(row) ? this.store.getAt(row) : this.store.getById(row); + }, - combined.push(String.format("{0}: {1}", error.errorName, error.error)); + + setValue : function(prop, value, create){ + var r = this.getRec(prop); + if (r) { + r.set('value', value); + this.source[prop] = value; + } else if (create) { + + this.source[prop] = value; + r = new Ext.grid.property.Property({name: prop, value: value}, prop); + this.store.add(r); } + }, - return combined.join("
    "); + + remove : function(prop) { + var r = this.getRec(prop); + if(r) { + this.store.remove(r); + delete this.source[prop]; + } }, - sortErrors: function() { - var fields = this.items; + getRec : function(prop) { + return this.store.getById(prop); + }, - this.fieldErrors.sort("ASC", function(a, b) { - var findByName = function(key) { - return function(field) { - return field.getName() == key; - }; - }; + + getSource : function() { + return this.source; + } +}); - var aIndex = fields.findIndexBy(findByName(a.field)), - bIndex = fields.findIndexBy(findByName(b.field)); - return aIndex < bIndex ? -1 : 1; - }); - }, +Ext.define('Ext.layout.component.Body', { - reset: function() { - this.eachItem(function(item) { - item.reset(); - }); - - - (function() { - this.clearInvalid(); - }).defer(50, this); - }, - - - clearInvalidChildren: function() { - this.eachItem(function(item) { - item.clearInvalid(); - }); - }, + alias: ['layout.body'], + + extend: 'Ext.layout.component.Component', + + uses: ['Ext.layout.container.Container'], - buildLabel: function(segments) { - return Ext.clean(segments).join(this.labelConnector); - }, + type: 'body', - isDirty: function(){ + onLayout: function(width, height) { + var me = this, + owner = me.owner; + - if (this.disabled || !this.rendered) { - return false; - } + me.setTargetSize(width, height); - var dirty = false; - this.eachItem(function(item){ - if(item.isDirty()){ - dirty = true; - return false; + + me.setBodySize.apply(me, arguments); + + + if (owner && owner.layout && owner.layout.isLayout) { + if (!Ext.isNumber(owner.height) || !Ext.isNumber(owner.width)) { + owner.layout.bindToOwnerCtComponent = true; } - }); - return dirty; + else { + owner.layout.bindToOwnerCtComponent = false; + } + } + + me.callParent(arguments); }, - eachItem: function(fn, scope) { - if(this.items && this.items.each){ - this.items.each(fn, scope || this); + setBodySize: function(width, height) { + var me = this, + owner = me.owner, + frameSize = owner.frameSize, + isNumber = Ext.isNumber; + + if (isNumber(width)) { + width -= owner.el.getFrameWidth('lr') - frameSize.left - frameSize.right; + } + if (isNumber(height)) { + height -= owner.el.getFrameWidth('tb') - frameSize.top - frameSize.bottom; } - }, - - onResize: function(adjWidth, adjHeight, rawWidth, rawHeight) { - var innerCt = this.innerCt; + me.setElementSize(owner.body, width, height); + } +}); + +Ext.define('Ext.layout.component.FieldSet', { + extend: 'Ext.layout.component.Body', + alias: ['layout.fieldset'], + + type: 'fieldset', - if (this.rendered && innerCt.rendered) { - innerCt.setSize(adjWidth, adjHeight); + doContainerLayout: function() { + + if (!this.owner.collapsed) { + this.callParent(); } + } +}); - Ext.form.CompositeField.superclass.onResize.apply(this, arguments); - }, +Ext.define('Ext.layout.component.Tab', { + + alias: ['layout.tab'], + + extend: 'Ext.layout.component.Button', - doLayout: function(shallow, force) { - if (this.rendered) { - var innerCt = this.innerCt; - innerCt.forceLayout = this.ownerCt.forceLayout; - innerCt.doLayout(shallow, force); + beforeLayout: function() { + var me = this, dirty = me.lastClosable !== me.owner.closable; + + if (dirty) { + delete me.adjWidth; } + + return this.callParent(arguments) || dirty; }, - - beforeDestroy: function(){ - Ext.destroy(this.innerCt); + onLayout: function () { + var me = this; - Ext.form.CompositeField.superclass.beforeDestroy.call(this); - }, + me.callParent(arguments); - - setReadOnly : function(readOnly) { - if (readOnly == undefined) { - readOnly = true; - } - readOnly = !!readOnly; + me.lastClosable = me.owner.closable; + } +}); - if(this.rendered){ - this.eachItem(function(item){ - item.setReadOnly(readOnly); - }); + +Ext.define('Ext.layout.component.field.File', { + alias: ['layout.filefield'], + extend: 'Ext.layout.component.field.Field', + + type: 'filefield', + + sizeBodyContents: function(width, height) { + var me = this, + owner = me.owner; + + if (!owner.buttonOnly) { + + + me.setElementSize(owner.inputEl, Ext.isNumber(width) ? width - owner.button.getWidth() - owner.buttonMargin : width); } - this.readOnly = readOnly; - }, + } +}); - onShow : function() { - Ext.form.CompositeField.superclass.onShow.call(this); - this.doLayout(); - }, + +Ext.define('Ext.layout.component.field.Slider', { - onDisable : function(){ - this.eachItem(function(item){ - item.disable(); - }); - }, + + alias: ['layout.sliderfield'], + + extend: 'Ext.layout.component.field.Field', - onEnable : function(){ - this.eachItem(function(item){ - item.enable(); - }); + + type: 'sliderfield', + + sizeBodyContents: function(width, height) { + var owner = this.owner, + thumbs = owner.thumbs, + length = thumbs.length, + inputEl = owner.inputEl, + innerEl = owner.innerEl, + endEl = owner.endEl, + i = 0; + + + for(; i < length; ++i) { + thumbs[i].el.stopAnimation(); + } + + if (owner.vertical) { + inputEl.setHeight(height); + innerEl.setHeight(Ext.isNumber(height) ? height - inputEl.getPadding('t') - endEl.getPadding('b') : height); + } + else { + inputEl.setWidth(width); + innerEl.setWidth(Ext.isNumber(width) ? width - inputEl.getPadding('l') - endEl.getPadding('r') : width); + } + owner.syncThumbs(); } }); -Ext.reg('compositefield', Ext.form.CompositeField); -Ext.form.Radio = Ext.extend(Ext.form.Checkbox, { - inputType: 'radio', + + +Ext.define('Ext.layout.container.Absolute', { - markInvalid : Ext.emptyFn, - - clearInvalid : Ext.emptyFn, + + alias: 'layout.absolute', + extend: 'Ext.layout.container.Anchor', + requires: ['Ext.chart.axis.Axis', 'Ext.fx.Anim'], + alternateClassName: 'Ext.layout.AbsoluteLayout', - getGroupValue : function(){ - var p = this.el.up('form') || Ext.getBody(); - var c = p.child('input[name='+this.el.dom.name+']:checked', true); - return c ? c.value : null; + + itemCls: Ext.baseCSSPrefix + 'abs-layout-item', + + type: 'absolute', + + onLayout: function() { + var me = this, + target = me.getTarget(), + targetIsBody = target.dom === document.body; + + + if (!targetIsBody) { + target.position(); + } + me.paddingLeft = target.getPadding('l'); + me.paddingTop = target.getPadding('t'); + me.callParent(arguments); }, - setValue : function(v){ - var checkEl, - els, - radio; - if (typeof v == 'boolean') { - Ext.form.Radio.superclass.setValue.call(this, v); - } else if (this.rendered) { - checkEl = this.getCheckEl(); - radio = checkEl.child('input[name=' + this.el.dom.name + '][value=' + v + ']', true); - if(radio){ - Ext.getCmp(radio.id).setValue(true); - } - } - if(this.rendered && this.checked){ - checkEl = checkEl || this.getCheckEl(); - els = this.getCheckEl().select('input[name=' + this.el.dom.name + ']'); - els.each(function(el){ - if(el.dom.id != this.id){ - Ext.getCmp(el.dom.id).setValue(false); - } - }, this); - } - return this; + adjustWidthAnchor: function(value, comp) { + + return value ? value - comp.getPosition(true)[0] : value; }, - getCheckEl: function(){ - if(this.inGroup){ - return this.el.up('.x-form-radio-group'); - } - return this.el.up('form') || Ext.getBody(); + adjustHeightAnchor: function(value, comp) { + + return value ? value - comp.getPosition(true)[1] : value; } }); -Ext.reg('radio', Ext.form.Radio); -Ext.form.RadioGroup = Ext.extend(Ext.form.CheckboxGroup, { +Ext.define('Ext.layout.container.Accordion', { + extend: 'Ext.layout.container.VBox', + alias: ['layout.accordion'], + alternateClassName: 'Ext.layout.AccordionLayout', + align: 'stretch', + - allowBlank : true, + fill : true, - blankText : 'You must select one item in this group', + autoWidth : true, + titleCollapse : true, - defaultType : 'radio', + hideCollapseTool : false, + collapseFirst : false, - groupCls : 'x-form-radio-group', + animate : true, + activeOnTop : false, + multi: false, + + constructor: function() { + var me = this; + + me.callParent(arguments); + + + me.initialAnimate = me.animate; + me.animate = false; + + + if (me.fill === false) { + me.itemCls = Ext.baseCSSPrefix + 'accordion-item'; + } + }, + - getValue : function(){ - var out = null; - this.eachItem(function(item){ - if(item.checked){ - out = item; + beforeLayout: function() { + var me = this; + + me.callParent(arguments); + if (me.fill) { + if (!me.owner.el.dom.style.height) { return false; } - }); - return out; + } else { + me.owner.componentLayout.monitorChildren = false; + me.autoSize = true; + me.owner.setAutoScroll(true); + } }, - - - onSetValue : function(id, value){ - if(arguments.length > 1){ - var f = this.getBox(id); - if(f){ - f.setValue(value); - if(f.checked){ - this.eachItem(function(item){ - if (item !== f){ - item.setValue(false); - } - }); + + renderItems : function(items, target) { + var me = this, + ln = items.length, + i = 0, + comp, + targetSize = me.getLayoutTargetSize(), + renderedPanels = [], + border; + + for (; i < ln; i++) { + comp = items[i]; + if (!comp.rendered) { + renderedPanels.push(comp); + + + if (me.collapseFirst) { + comp.collapseFirst = me.collapseFirst; + } + if (me.hideCollapseTool) { + comp.hideCollapseTool = me.hideCollapseTool; + comp.titleCollapse = true; + } + else if (me.titleCollapse) { + comp.titleCollapse = me.titleCollapse; + } + + delete comp.hideHeader; + comp.collapsible = true; + comp.title = comp.title || ' '; + comp.setBorder(false); + + + comp.width = targetSize.width; + if (me.fill) { + delete comp.height; + delete comp.flex; + + + if (me.expandedItem !== undefined) { + comp.collapsed = true; + } + + else if (comp.collapsed === false) { + comp.flex = 1; + me.expandedItem = i; + } else { + comp.collapsed = true; + } + } else { + delete comp.flex; + comp.animCollapse = me.initialAnimate; + comp.autoHeight = true; + comp.autoScroll = false; } } - }else{ - this.setValueForItem(id); } - }, - - setValueForItem : function(val){ - val = String(val).split(',')[0]; - this.eachItem(function(item){ - item.setValue(val == item.inputValue); - }); - }, - - - fireChecked : function(){ - if(!this.checkTask){ - this.checkTask = new Ext.util.DelayedTask(this.bufferChecked, this); + + + if (ln && me.expandedItem === undefined) { + me.expandedItem = 0; + comp = items[0]; + comp.collapsed = false; + if (me.fill) { + comp.flex = 1; + } + } + + + me.callParent(arguments); + + + ln = renderedPanels.length; + for (i = 0; i < ln; i++) { + comp = renderedPanels[i]; + + + delete comp.width; + + comp.header.addCls(Ext.baseCSSPrefix + 'accordion-hd'); + comp.body.addCls(Ext.baseCSSPrefix + 'accordion-body'); + + + if (me.fill) { + me.owner.mon(comp, { + show: me.onComponentShow, + beforeexpand: me.onComponentExpand, + beforecollapse: me.onComponentCollapse, + scope: me + }); + } } - this.checkTask.delay(10); }, - - - bufferChecked : function(){ - var out = null; - this.eachItem(function(item){ - if(item.checked){ - out = item; - return false; + + onLayout: function() { + var me = this; + + me.updatePanelClasses(); + + if (me.fill) { + me.callParent(arguments); + } else { + var targetSize = me.getLayoutTargetSize(), + items = me.getVisibleItems(), + len = items.length, + i = 0, comp; + + for (; i < len; i++) { + comp = items[i]; + if (comp.collapsed) { + items[i].setWidth(targetSize.width); + } else { + items[i].setSize(null, null); + } } - }); - this.fireEvent('change', this, out); + } + + return me; }, - onDestroy : function(){ - if(this.checkTask){ - this.checkTask.cancel(); - this.checkTask = null; + updatePanelClasses: function() { + var children = this.getLayoutItems(), + ln = children.length, + siblingCollapsed = true, + i, child; + + for (i = 0; i < ln; i++) { + child = children[i]; + if (!siblingCollapsed) { + child.header.addCls(Ext.baseCSSPrefix + 'accordion-hd-sibling-expanded'); + } + else { + child.header.removeCls(Ext.baseCSSPrefix + 'accordion-hd-sibling-expanded'); + } + if (i + 1 == ln && child.collapsed) { + child.header.addCls(Ext.baseCSSPrefix + 'accordion-hd-last-collapsed'); + } + else { + child.header.removeCls(Ext.baseCSSPrefix + 'accordion-hd-last-collapsed'); + } + siblingCollapsed = child.collapsed; } - Ext.form.RadioGroup.superclass.onDestroy.call(this); - } - -}); - -Ext.reg('radiogroup', Ext.form.RadioGroup); + }, -Ext.form.Hidden = Ext.extend(Ext.form.Field, { - inputType : 'hidden', - shouldLayout: false, - - onRender : function(){ - Ext.form.Hidden.superclass.onRender.apply(this, arguments); - }, + onComponentExpand: function(toExpand) { + var me = this, + it = me.owner.items.items, + len = it.length, + i = 0, + comp; - - initEvents : function(){ - this.originalValue = this.getValue(); + for (; i < len; i++) { + comp = it[i]; + if (comp === toExpand && comp.collapsed) { + me.setExpanded(comp); + } else if (!me.multi && (comp.rendered && comp.header.rendered && comp !== toExpand && !comp.collapsed)) { + me.setCollapsed(comp); + } + } + + me.animate = me.initialAnimate; + me.layout(); + me.animate = false; + return false; }, - - setSize : Ext.emptyFn, - setWidth : Ext.emptyFn, - setHeight : Ext.emptyFn, - setPosition : Ext.emptyFn, - setPagePosition : Ext.emptyFn, - markInvalid : Ext.emptyFn, - clearInvalid : Ext.emptyFn -}); -Ext.reg('hidden', Ext.form.Hidden); -Ext.form.BasicForm = Ext.extend(Ext.util.Observable, { + onComponentCollapse: function(comp) { + var me = this, + toExpand = comp.next() || comp.prev(), + expanded = me.multi ? me.owner.query('>panel:not([collapsed])') : []; - constructor: function(el, config){ - Ext.apply(this, config); - if(Ext.isString(this.paramOrder)){ - this.paramOrder = this.paramOrder.split(/[\s,|]/); - } - this.items = new Ext.util.MixedCollection(false, function(o){ - return o.getItemId(); - }); - this.addEvents( + + if (me.multi) { + me.setCollapsed(comp); + - 'beforeaction', - 'actionfailed', + if (expanded.length === 1 && expanded[0] === comp) { + me.setExpanded(toExpand); + } - 'actioncomplete' - ); + me.animate = me.initialAnimate; + me.layout(); + me.animate = false; + } + + else if (toExpand) { + me.onComponentExpand(toExpand); + } + return false; + }, - if(el){ - this.initEl(el); + onComponentShow: function(comp) { + + this.onComponentExpand(comp); + }, + + setCollapsed: function(comp) { + var otherDocks = comp.getDockedItems(), + dockItem, + len = otherDocks.length, + i = 0; + + + comp.hiddenDocked = []; + for (; i < len; i++) { + dockItem = otherDocks[i]; + if ((dockItem !== comp.header) && !dockItem.hidden) { + dockItem.hidden = true; + comp.hiddenDocked.push(dockItem); + } + } + comp.addCls(comp.collapsedCls); + comp.header.addCls(comp.collapsedHeaderCls); + comp.height = comp.header.getHeight(); + comp.el.setHeight(comp.height); + comp.collapsed = true; + delete comp.flex; + comp.fireEvent('collapse', comp); + if (comp.collapseTool) { + comp.collapseTool.setType('expand-' + comp.getOppositeDirection(comp.collapseDirection)); } - Ext.form.BasicForm.superclass.constructor.call(this); }, - - - - - - - - timeout: 30, + setExpanded: function(comp) { + var otherDocks = comp.hiddenDocked, + len = otherDocks ? otherDocks.length : 0, + i = 0; - + + for (; i < len; i++) { + otherDocks[i].hidden = false; + } - - paramOrder: undefined, + + if (!comp.body.isVisible()) { + comp.body.show(); + } + delete comp.collapsed; + delete comp.height; + delete comp.componentLayout.lastComponentSize; + comp.suspendLayout = false; + comp.flex = 1; + comp.removeCls(comp.collapsedCls); + comp.header.removeCls(comp.collapsedHeaderCls); + comp.fireEvent('expand', comp); + if (comp.collapseTool) { + comp.collapseTool.setType('collapse-' + comp.collapseDirection); + } + comp.setAutoScroll(comp.initialConfig.autoScroll); + } +}); - - paramsAsHash: false, +Ext.define('Ext.resizer.Splitter', { + extend: 'Ext.Component', + requires: ['Ext.XTemplate'], + uses: ['Ext.resizer.SplitterTracker'], + alias: 'widget.splitter', - - waitTitle: 'Please Wait...', + renderTpl: [ + '
     
    ' + ], - - activeAction : null, + baseCls: Ext.baseCSSPrefix + 'splitter', + collapsedCls: Ext.baseCSSPrefix + 'splitter-collapsed', - trackResetOnLoad : false, + collapsible: false, - - initEl : function(el){ - this.el = Ext.get(el); - this.id = this.el.id || Ext.id(); - if(!this.standardSubmit){ - this.el.on('submit', this.onSubmit, this); - } - this.el.addClass('x-form'); - }, + collapseOnDblClick: true, - getEl: function(){ - return this.el; - }, + defaultSplitMin: 40, - onSubmit : function(e){ - e.stopEvent(); - }, + defaultSplitMax: 1000, - - destroy: function(bound){ - if(bound !== true){ - this.items.each(function(f){ - Ext.destroy(f); - }); - Ext.destroy(this.el); - } - this.items.clear(); - this.purgeListeners(); - }, + width: 5, + height: 5, - isValid : function(){ - var valid = true; - this.items.each(function(f){ - if(!f.validate()){ - valid = false; - } - }); - return valid; - }, + collapseTarget: 'next', - isDirty : function(){ - var dirty = false; - this.items.each(function(f){ - if(f.isDirty()){ - dirty = true; - return false; - } + + onRender: function() { + var me = this, + target = me.getCollapseTarget(), + collapseDir = me.getCollapseDirection(); + + Ext.applyIf(me.renderData, { + collapseDir: collapseDir, + collapsible: me.collapsible || target.collapsible + }); + Ext.applyIf(me.renderSelectors, { + collapseEl: '.' + Ext.baseCSSPrefix + 'collapse-el' }); - return dirty; - }, - - doAction : function(action, options){ - if(Ext.isString(action)){ - action = new Ext.form.Action.ACTION_TYPES[action](this, options); - } - if(this.fireEvent('beforeaction', this, action) !== false){ - this.beforeAction(action); - action.run.defer(100, action); + this.callParent(arguments); + + + if (me.performCollapse !== false) { + if (me.renderData.collapsible) { + me.mon(me.collapseEl, 'click', me.toggleTargetCmp, me); + } + if (me.collapseOnDblClick) { + me.mon(me.el, 'dblclick', me.toggleTargetCmp, me); + } } - return this; + + + me.mon(target, 'collapse', me.onTargetCollapse, me); + me.mon(target, 'expand', me.onTargetExpand, me); + + me.el.addCls(me.baseCls + '-' + me.orientation); + me.el.unselectable(); + + me.tracker = Ext.create('Ext.resizer.SplitterTracker', { + el: me.el + }); }, - - submit : function(options){ - options = options || {}; - if(this.standardSubmit){ - var v = options.clientValidation === false || this.isValid(); - if(v){ - var el = this.el.dom; - if(this.url && Ext.isEmpty(el.action)){ - el.action = this.url; - } - el.submit(); - } - return v; + getCollapseDirection: function() { + var me = this, + idx, + type = me.ownerCt.layout.type; + + + + + + + + + if (me.collapseTarget.isComponent) { + idx = Number(me.ownerCt.items.indexOf(me.collapseTarget) == me.ownerCt.items.indexOf(me) - 1) << 1 | Number(type == 'hbox'); + } else { + idx = Number(me.collapseTarget == 'prev') << 1 | Number(type == 'hbox'); } - var submitAction = String.format('{0}submit', this.api ? 'direct' : ''); - this.doAction(submitAction, options); - return this; + + + me.orientation = ['horizontal', 'vertical'][idx & 1]; + return ['bottom', 'right', 'top', 'left'][idx]; }, - - load : function(options){ - var loadAction = String.format('{0}load', this.api ? 'direct' : ''); - this.doAction(loadAction, options); - return this; + getCollapseTarget: function() { + return this.collapseTarget.isComponent ? this.collapseTarget : this.collapseTarget == 'prev' ? this.previousSibling() : this.nextSibling(); }, - - updateRecord : function(record){ - record.beginEdit(); - var fs = record.fields, - field, - value; - fs.each(function(f){ - field = this.findField(f.name); - if(field){ - value = field.getValue(); - if (typeof value != undefined && value.getGroupValue) { - value = value.getGroupValue(); - } else if ( field.eachItem ) { - value = []; - field.eachItem(function(item){ - value.push(item.getValue()); - }); - } - record.set(f.name, value); - } - }, this); - record.endEdit(); - return this; + onTargetCollapse: function(target) { + this.el.addCls(this.collapsedCls); }, - - loadRecord : function(record){ - this.setValues(record.data); - return this; + onTargetExpand: function(target) { + this.el.removeCls(this.collapsedCls); }, - - beforeAction : function(action){ - - this.items.each(function(f){ - if(f.isFormField && f.syncValue){ - f.syncValue(); - } - }); - var o = action.options; - if(o.waitMsg){ - if(this.waitMsgTarget === true){ - this.el.mask(o.waitMsg, 'x-mask-loading'); - }else if(this.waitMsgTarget){ - this.waitMsgTarget = Ext.get(this.waitMsgTarget); - this.waitMsgTarget.mask(o.waitMsg, 'x-mask-loading'); - }else{ - Ext.MessageBox.wait(o.waitMsg, o.waitTitle || this.waitTitle); + toggleTargetCmp: function(e, t) { + var cmp = this.getCollapseTarget(); + + if (cmp.isVisible()) { + + if (cmp.collapsed) { + cmp.expand(cmp.animCollapse); + + } else { + cmp.collapse(this.renderData.collapseDir, cmp.animCollapse); } } }, - afterAction : function(action, success){ - this.activeAction = null; - var o = action.options; - if(o.waitMsg){ - if(this.waitMsgTarget === true){ - this.el.unmask(); - }else if(this.waitMsgTarget){ - this.waitMsgTarget.unmask(); - }else{ - Ext.MessageBox.updateProgress(1); - Ext.MessageBox.hide(); - } - } - if(success){ - if(o.reset){ - this.reset(); - } - Ext.callback(o.success, o.scope, [this, action]); - this.fireEvent('actioncomplete', this, action); - }else{ - Ext.callback(o.failure, o.scope, [this, action]); - this.fireEvent('actionfailed', this, action); + setSize: function() { + var me = this; + me.callParent(arguments); + if (Ext.isIE) { + me.el.repaint(); } - }, + } +}); - - findField : function(id) { - var field = this.items.get(id); - if (!Ext.isObject(field)) { - - var findMatchingField = function(f) { - if (f.isFormField) { - if (f.dataIndex == id || f.id == id || f.getName() == id) { - field = f; - return false; - } else if (f.isComposite) { - return f.items.each(findMatchingField); - } else if (f instanceof Ext.form.CheckboxGroup && f.rendered) { - return f.eachItem(findMatchingField); - } - } - }; +Ext.define('Ext.layout.container.Border', { - this.items.each(findMatchingField); - } - return field || null; - }, + alias: ['layout.border'], + extend: 'Ext.layout.container.Container', + requires: ['Ext.resizer.Splitter', 'Ext.container.Container', 'Ext.fx.Anim'], + alternateClassName: 'Ext.layout.BorderLayout', + targetCls: Ext.baseCSSPrefix + 'border-layout-ct', - - markInvalid : function(errors){ - if (Ext.isArray(errors)) { - for(var i = 0, len = errors.length; i < len; i++){ - var fieldError = errors[i]; - var f = this.findField(fieldError.id); - if(f){ - f.markInvalid(fieldError.msg); - } - } - } else { - var field, id; - for(id in errors){ - if(!Ext.isFunction(errors[id]) && (field = this.findField(id))){ - field.markInvalid(errors[id]); - } - } - } + itemCls: Ext.baseCSSPrefix + 'border-item', - return this; - }, + bindToOwnerCtContainer: true, - - setValues : function(values){ - if(Ext.isArray(values)){ - for(var i = 0, len = values.length; i < len; i++){ - var v = values[i]; - var f = this.findField(v.id); - if(f){ - f.setValue(v.value); - if(this.trackResetOnLoad){ - f.originalValue = f.getValue(); - } - } - } - }else{ - var field, id; - for(id in values){ - if(!Ext.isFunction(values[id]) && (field = this.findField(id))){ - field.setValue(values[id]); - if(this.trackResetOnLoad){ - field.originalValue = field.getValue(); - } - } - } - } - return this; - }, + fixedLayout: false, - - getValues : function(asString){ - var fs = Ext.lib.Ajax.serializeForm(this.el.dom); - if(asString === true){ - return fs; - } - return Ext.urlDecode(fs); - }, + percentageRe: /(\d+)%/, - - getFieldValues : function(dirtyOnly){ - var o = {}, - n, - key, - val; - this.items.each(function(f) { - if (!f.disabled && (dirtyOnly !== true || f.isDirty())) { - n = f.getName(); - key = o[n]; - val = f.getValue(); - - if(Ext.isDefined(key)){ - if(Ext.isArray(key)){ - o[n].push(val); - }else{ - o[n] = [key, val]; - } - }else{ - o[n] = val; - } - } - }); - return o; + slideDirection: { + north: 't', + south: 'b', + west: 'l', + east: 'r' }, - - clearInvalid : function(){ - this.items.each(function(f){ - f.clearInvalid(); - }); - return this; + constructor: function(config) { + this.initialConfig = config; + this.callParent(arguments); }, - - reset : function(){ - this.items.each(function(f){ - f.reset(); - }); - return this; - }, + onLayout: function() { + var me = this; + if (!me.borderLayoutInitialized) { + me.initializeBorderLayout(); + } - - add : function(){ - this.items.addAll(Array.prototype.slice.call(arguments, 0)); - return this; - }, + + me.shadowLayout.onLayout(); + if (me.embeddedContainer) { + me.embeddedContainer.layout.onLayout(); + } - - remove : function(field){ - this.items.remove(field); - return this; + + + if (!me.initialCollapsedComplete) { + Ext.iterate(me.regions, function(name, region){ + if (region.borderCollapse) { + me.onBeforeRegionCollapse(region, region.collapseDirection, false, 0); + } + }); + me.initialCollapsedComplete = true; + } }, - - cleanDestroyed : function() { - this.items.filterBy(function(o) { return !!o.isDestroyed; }).each(this.remove, this); - }, + isValidParent : function(item, target, position) { + if (!this.borderLayoutInitialized) { + this.initializeBorderLayout(); + } - - render : function(){ - this.items.each(function(f){ - if(f.isFormField && !f.rendered && document.getElementById(f.id)){ - f.applyToMarkup(f.id); - } - }); - return this; + + return this.shadowLayout.isValidParent(item, target, position); }, - - applyToFields : function(o){ - this.items.each(function(f){ - Ext.apply(f, o); - }); - return this; + beforeLayout: function() { + if (!this.borderLayoutInitialized) { + this.initializeBorderLayout(); + } + + + this.shadowLayout.beforeLayout(); }, - - applyIfToFields : function(o){ - this.items.each(function(f){ - Ext.applyIf(f, o); - }); - return this; + renderItems: function(items, target) { + Ext.Error.raise('This should not be called'); }, - callFieldMethod : function(fnName, args){ - args = args || []; - this.items.each(function(f){ - if(Ext.isFunction(f[fnName])){ - f[fnName].apply(f, args); - } - }); - return this; - } -}); + renderItem: function(item) { + Ext.Error.raise('This should not be called'); + }, + initializeBorderLayout: function() { + var me = this, + i = 0, + items = me.getLayoutItems(), + ln = items.length, + regions = (me.regions = {}), + vBoxItems = [], + hBoxItems = [], + horizontalFlex = 0, + verticalFlex = 0, + comp, percentage; -Ext.BasicForm = Ext.form.BasicForm; + + me.splitters = {}; -Ext.FormPanel = Ext.extend(Ext.Panel, { - - - - - - - + + for (; i < ln; i++) { + comp = items[i]; + regions[comp.region] = comp; + + if (comp.region != 'center' && comp.collapsible && comp.collapseMode != 'header') { - - minButtonWidth : 75, + + comp.borderCollapse = comp.collapsed; + delete comp.collapsed; + + comp.on({ + beforecollapse: me.onBeforeRegionCollapse, + beforeexpand: me.onBeforeRegionExpand, + destroy: me.onRegionDestroy, + scope: me + }); + me.setupState(comp); + } + } + if (!regions.center) { + Ext.Error.raise("You must specify a center region when defining a BorderLayout."); + } + comp = regions.center; + if (!comp.flex) { + comp.flex = 1; + } + delete comp.width; + comp.maintainFlex = true; - - labelAlign : 'left', + + comp = regions.west; + if (comp) { + comp.collapseDirection = Ext.Component.DIRECTION_LEFT; + hBoxItems.push(comp); + if (comp.split) { + hBoxItems.push(me.splitters.west = me.createSplitter(comp)); + } + percentage = Ext.isString(comp.width) && comp.width.match(me.percentageRe); + if (percentage) { + horizontalFlex += (comp.flex = parseInt(percentage[1], 10) / 100); + delete comp.width; + } + } + comp = regions.north; + if (comp) { + comp.collapseDirection = Ext.Component.DIRECTION_TOP; + vBoxItems.push(comp); + if (comp.split) { + vBoxItems.push(me.splitters.north = me.createSplitter(comp)); + } + percentage = Ext.isString(comp.height) && comp.height.match(me.percentageRe); + if (percentage) { + verticalFlex += (comp.flex = parseInt(percentage[1], 10) / 100); + delete comp.height; + } + } - - monitorValid : false, + + if (regions.north || regions.south) { + if (regions.east || regions.west) { - - monitorPoll : 200, + + vBoxItems.push(me.embeddedContainer = Ext.create('Ext.container.Container', { + xtype: 'container', + region: 'center', + id: me.owner.id + '-embedded-center', + cls: Ext.baseCSSPrefix + 'border-item', + flex: regions.center.flex, + maintainFlex: true, + layout: { + type: 'hbox', + align: 'stretch' + } + })); + hBoxItems.push(regions.center); + } + + else { + vBoxItems.push(regions.center); + } + } + + else { + hBoxItems.push(regions.center); + } - - layout : 'form', + + comp = regions.south; + if (comp) { + comp.collapseDirection = Ext.Component.DIRECTION_BOTTOM; + if (comp.split) { + vBoxItems.push(me.splitters.south = me.createSplitter(comp)); + } + percentage = Ext.isString(comp.height) && comp.height.match(me.percentageRe); + if (percentage) { + verticalFlex += (comp.flex = parseInt(percentage[1], 10) / 100); + delete comp.height; + } + vBoxItems.push(comp); + } + comp = regions.east; + if (comp) { + comp.collapseDirection = Ext.Component.DIRECTION_RIGHT; + if (comp.split) { + hBoxItems.push(me.splitters.east = me.createSplitter(comp)); + } + percentage = Ext.isString(comp.width) && comp.width.match(me.percentageRe); + if (percentage) { + horizontalFlex += (comp.flex = parseInt(percentage[1], 10) / 100); + delete comp.width; + } + hBoxItems.push(comp); + } - - initComponent : function(){ - this.form = this.createForm(); - Ext.FormPanel.superclass.initComponent.call(this); + + + + + if (regions.north || regions.south) { - this.bodyCfg = { - tag: 'form', - cls: this.baseCls + '-body', - method : this.method || 'POST', - id : this.formId || Ext.id() - }; - if(this.fileUpload) { - this.bodyCfg.enctype = 'multipart/form-data'; - } - this.initItems(); + me.shadowContainer = Ext.create('Ext.container.Container', { + ownerCt: me.owner, + el: me.getTarget(), + layout: Ext.applyIf({ + type: 'vbox', + align: 'stretch' + }, me.initialConfig) + }); + me.createItems(me.shadowContainer, vBoxItems); - this.addEvents( - 'clientvalidation' - ); + if (me.splitters.north) { + me.splitters.north.ownerCt = me.shadowContainer; + } + if (me.splitters.south) { + me.splitters.south.ownerCt = me.shadowContainer; + } - this.relayEvents(this.form, ['beforeaction', 'actionfailed', 'actioncomplete']); - }, + + if (me.embeddedContainer) { + me.embeddedContainer.ownerCt = me.shadowContainer; + me.createItems(me.embeddedContainer, hBoxItems); - - createForm : function(){ - var config = Ext.applyIf({listeners: {}}, this.initialConfig); - return new Ext.form.BasicForm(null, config); - }, + + if (me.splitters.east) { + me.splitters.east.ownerCt = me.embeddedContainer; + } + if (me.splitters.west) { + me.splitters.west.ownerCt = me.embeddedContainer; + } - - initFields : function(){ - var f = this.form; - var formPanel = this; - var fn = function(c){ - if(formPanel.isField(c)){ - f.add(c); - }else if(c.findBy && c != formPanel){ - formPanel.applySettings(c); - if(c.items && c.items.each){ - c.items.each(fn, this); + if (horizontalFlex) { + regions.center.flex -= horizontalFlex; + } + + if (verticalFlex) { + me.embeddedContainer.flex -= verticalFlex; + } + } else { + + if (verticalFlex) { + regions.center.flex -= verticalFlex; } } - }; - this.items.each(fn, this); - }, + } + + + else { + me.shadowContainer = Ext.create('Ext.container.Container', { + ownerCt: me.owner, + el: me.getTarget(), + layout: Ext.applyIf({ + type: (hBoxItems.length == 1) ? 'fit' : 'hbox', + align: 'stretch' + }, me.initialConfig) + }); + me.createItems(me.shadowContainer, hBoxItems); - - applySettings: function(c){ - var ct = c.ownerCt; - Ext.applyIf(c, { - labelAlign: ct.labelAlign, - labelWidth: ct.labelWidth, - itemCls: ct.itemCls - }); - }, + + if (me.splitters.east) { + me.splitters.east.ownerCt = me.shadowContainer; + } + if (me.splitters.west) { + me.splitters.west.ownerCt = me.shadowContainer; + } - - getLayoutTarget : function(){ - return this.form.el; - }, + + if (horizontalFlex) { + regions.center.flex -= verticalFlex; + } + } - - getForm : function(){ - return this.form; - }, + + for (i = 0, items = me.shadowContainer.items.items, ln = items.length; i < ln; i++) { + items[i].shadowOwnerCt = me.shadowContainer; + } + if (me.embeddedContainer) { + for (i = 0, items = me.embeddedContainer.items.items, ln = items.length; i < ln; i++) { + items[i].shadowOwnerCt = me.embeddedContainer; + } + } - - onRender : function(ct, position){ - this.initFields(); - Ext.FormPanel.superclass.onRender.call(this, ct, position); - this.form.initEl(this.body); + + me.shadowLayout = me.shadowContainer.getLayout(); + + me.borderLayoutInitialized = true; }, - - beforeDestroy : function(){ - this.stopMonitoring(); - this.form.destroy(true); - Ext.FormPanel.superclass.beforeDestroy.call(this); + + setupState: function(comp){ + var getState = comp.getState; + comp.getState = function(){ + + var state = getState.call(comp) || {}, + region = comp.region; + + state.collapsed = !!comp.collapsed; + if (region == 'west' || region == 'east') { + state.width = comp.getWidth(); + } else { + state.height = comp.getHeight(); + } + return state; + }; + comp.addStateEvents(['collapse', 'expand', 'resize']); }, - isField : function(c) { - return !!c.setValue && !!c.getValue && !!c.markInvalid && !!c.clearInvalid; + createItems: function(container, items){ + + + delete container.items; + container.initItems(); + container.items.addAll(items); }, - initEvents : function(){ - Ext.FormPanel.superclass.initEvents.call(this); - - this.on({ - scope: this, - add: this.onAddEvent, - remove: this.onRemoveEvent + + createSplitter: function(comp) { + var me = this, + interceptCollapse = (comp.collapseMode != 'header'), + resizer; + + resizer = Ext.create('Ext.resizer.Splitter', { + hidden: !!comp.hidden, + collapseTarget: comp, + performCollapse: !interceptCollapse, + listeners: interceptCollapse ? { + click: { + fn: Ext.Function.bind(me.onSplitterCollapseClick, me, [comp]), + element: 'collapseEl' + } + } : null }); - if(this.monitorValid){ - this.startMonitoring(); + + + if (comp.collapseMode == 'mini') { + comp.placeholder = resizer; } - }, - - onAdd: function(c){ - Ext.FormPanel.superclass.onAdd.call(this, c); - this.processAdd(c); + + comp.on({ + hide: me.onRegionVisibilityChange, + show: me.onRegionVisibilityChange, + scope: me + }); + return resizer; }, - onAddEvent: function(ct, c){ - if(ct !== this){ - this.processAdd(c); - } + onRegionVisibilityChange: function(comp){ + this.splitters[comp.region][comp.hidden ? 'hide' : 'show'](); + this.layout(); }, - processAdd : function(c){ - - if(this.isField(c)){ - this.form.add(c); - - }else if(c.findBy){ - this.applySettings(c); - this.form.add.apply(this.form, c.findBy(this.isField)); + + + onSplitterCollapseClick: function(comp) { + if (comp.collapsed) { + this.onPlaceHolderToolClick(null, null, null, {client: comp}); + } else { + comp.collapse(); } }, - onRemove: function(c){ - Ext.FormPanel.superclass.onRemove.call(this, c); - this.processRemove(c); - }, + getPlaceholder: function(comp) { + var me = this, + placeholder = comp.placeholder, + shadowContainer = comp.shadowOwnerCt, + shadowLayout = shadowContainer.layout, + oppositeDirection = Ext.panel.Panel.prototype.getOppositeDirection(comp.collapseDirection), + horiz = (comp.region == 'north' || comp.region == 'south'); - onRemoveEvent: function(ct, c){ - if(ct !== this){ - this.processRemove(c); + + if (comp.collapseMode == 'header') { + return; } - }, - - processRemove: function(c){ - if(!this.destroying){ - - if(this.isField(c)){ - this.form.remove(c); - - }else if (c.findBy){ - Ext.each(c.findBy(this.isField), this.form.remove, this.form); + + if (!placeholder) { + if (comp.collapseMode == 'mini') { + placeholder = Ext.create('Ext.resizer.Splitter', { + id: 'collapse-placeholder-' + comp.id, + collapseTarget: comp, + performCollapse: false, + listeners: { + click: { + fn: Ext.Function.bind(me.onSplitterCollapseClick, me, [comp]), + element: 'collapseEl' + } + } + }); + placeholder.addCls(placeholder.collapsedCls); + } else { + placeholder = { + id: 'collapse-placeholder-' + comp.id, + margins: comp.initialConfig.margins || Ext.getClass(comp).prototype.margins, + xtype: 'header', + orientation: horiz ? 'horizontal' : 'vertical', + title: comp.title, + textCls: comp.headerTextCls, + iconCls: comp.iconCls, + baseCls: comp.baseCls + '-header', + ui: comp.ui, + indicateDrag: comp.draggable, + cls: Ext.baseCSSPrefix + 'region-collapsed-placeholder ' + Ext.baseCSSPrefix + 'region-collapsed-' + comp.collapseDirection + '-placeholder', + listeners: comp.floatable ? { + click: { + fn: function(e) { + me.floatCollapsedPanel(e, comp); + }, + element: 'el' + } + } : null + }; - this.form.cleanDestroyed(); + if ((Ext.isIE6 || Ext.isIE7 || (Ext.isIEQuirks)) && !horiz) { + placeholder.width = 25; + } + placeholder[horiz ? 'tools' : 'items'] = [{ + xtype: 'tool', + client: comp, + type: 'expand-' + oppositeDirection, + handler: me.onPlaceHolderToolClick, + scope: me + }]; + } + placeholder = me.owner.createComponent(placeholder); + if (comp.isXType('panel')) { + comp.on({ + titlechange: me.onRegionTitleChange, + iconchange: me.onRegionIconChange, + scope: me + }); } } - }, - - startMonitoring : function(){ - if(!this.validTask){ - this.validTask = new Ext.util.TaskRunner(); - this.validTask.start({ - run : this.bindHandler, - interval : this.monitorPoll || 200, - scope: this - }); - } - }, + + comp.placeholder = placeholder; + placeholder.comp = comp; - - stopMonitoring : function(){ - if(this.validTask){ - this.validTask.stopAll(); - this.validTask = null; - } + return placeholder; }, - load : function(){ - this.form.load.apply(this.form, arguments); + onRegionTitleChange: function(comp, newTitle) { + comp.placeholder.setTitle(newTitle); }, - onDisable : function(){ - Ext.FormPanel.superclass.onDisable.call(this); - if(this.form){ - this.form.items.each(function(){ - this.disable(); - }); - } + onRegionIconChange: function(comp, newIconCls) { + comp.placeholder.setIconCls(newIconCls); }, - onEnable : function(){ - Ext.FormPanel.superclass.onEnable.call(this); - if(this.form){ - this.form.items.each(function(){ - this.enable(); - }); + calculateChildBox: function(comp) { + var me = this; + if (me.shadowContainer.items.contains(comp)) { + return me.shadowContainer.layout.calculateChildBox(comp); + } + else if (me.embeddedContainer && me.embeddedContainer.items.contains(comp)) { + return me.embeddedContainer.layout.calculateChildBox(comp); } }, - bindHandler : function(){ - var valid = true; - this.form.items.each(function(f){ - if(!f.isValid(true)){ - valid = false; - return false; - } - }); - if(this.fbar){ - var fitems = this.fbar.items.items; - for(var i = 0, len = fitems.length; i < len; i++){ - var btn = fitems[i]; - if(btn.formBind === true && btn.disabled === valid){ - btn.setDisabled(!valid); - } - } - } - this.fireEvent('clientvalidation', this, valid); - } -}); -Ext.reg('form', Ext.FormPanel); - -Ext.form.FormPanel = Ext.FormPanel; + onBeforeRegionCollapse: function(comp, direction, animate) { + var me = this, + compEl = comp.el, + miniCollapse = comp.collapseMode == 'mini', + shadowContainer = comp.shadowOwnerCt, + shadowLayout = shadowContainer.layout, + placeholder = comp.placeholder, + placeholderBox, + targetSize = shadowLayout.getLayoutTargetSize(), + sl = me.owner.suspendLayout, + scsl = shadowContainer.suspendLayout, + isNorthOrWest = (comp.region == 'north' || comp.region == 'west'); -Ext.form.FieldSet = Ext.extend(Ext.Panel, { - - - - - - - baseCls : 'x-fieldset', - - layout : 'form', - - animCollapse : false, + + me.owner.suspendLayout = true; + shadowContainer.suspendLayout = true; - - onRender : function(ct, position){ - if(!this.el){ - this.el = document.createElement('fieldset'); - this.el.id = this.id; - if (this.title || this.header || this.checkboxToggle) { - this.el.appendChild(document.createElement('legend')).className = this.baseCls + '-header'; - } + + shadowLayout.layoutBusy = true; + if (shadowContainer.componentLayout) { + shadowContainer.componentLayout.layoutBusy = true; } + me.shadowContainer.layout.layoutBusy = true; + me.layoutBusy = true; + me.owner.componentLayout.layoutBusy = true; - Ext.form.FieldSet.superclass.onRender.call(this, ct, position); - - if(this.checkboxToggle){ - var o = typeof this.checkboxToggle == 'object' ? - this.checkboxToggle : - {tag: 'input', type: 'checkbox', name: this.checkboxName || this.id+'-checkbox'}; - this.checkbox = this.header.insertFirst(o); - this.checkbox.dom.checked = !this.collapsed; - this.mon(this.checkbox, 'click', this.onCheckClick, this); + + if (!placeholder) { + placeholder = me.getPlaceholder(comp); } - }, - - onCollapse : function(doAnim, animArg){ - if(this.checkbox){ - this.checkbox.dom.checked = false; + + if (placeholder.shadowOwnerCt === shadowContainer) { + placeholder.show(); + } + + + + else { + shadowContainer.insert(shadowContainer.items.indexOf(comp) + (isNorthOrWest ? 0 : 1), placeholder); + placeholder.shadowOwnerCt = shadowContainer; + placeholder.ownerCt = me.owner; } - Ext.form.FieldSet.superclass.onCollapse.call(this, doAnim, animArg); - }, + + + + comp.hidden = true; - - onExpand : function(doAnim, animArg){ - if(this.checkbox){ - this.checkbox.dom.checked = true; + if (!placeholder.rendered) { + shadowLayout.renderItem(placeholder, shadowLayout.innerCt); } - Ext.form.FieldSet.superclass.onExpand.call(this, doAnim, animArg); - }, - - onCheckClick : function(){ - this[this.checkbox.dom.checked ? 'expand' : 'collapse'](); - } + + function afterCollapse() { - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -}); -Ext.reg('fieldset', Ext.form.FieldSet); + + me.owner.suspendLayout = sl; + shadowContainer.suspendLayout = scsl; + delete shadowLayout.layoutBusy; + if (shadowContainer.componentLayout) { + delete shadowContainer.componentLayout.layoutBusy; + } + delete me.shadowContainer.layout.layoutBusy; + delete me.layoutBusy; + delete me.owner.componentLayout.layoutBusy; -Ext.form.HtmlEditor = Ext.extend(Ext.form.Field, { - - enableFormat : true, - - enableFontSize : true, - - enableColors : true, - - enableAlignments : true, - - enableLists : true, - - enableSourceEdit : true, - - enableLinks : true, - - enableFont : true, - - createLinkText : 'Please enter the URL for the link:', - - defaultLinkValue : 'http:/'+'/', - - fontFamilies : [ - 'Arial', - 'Courier New', - 'Tahoma', - 'Times New Roman', - 'Verdana' - ], - defaultFont: 'tahoma', - - defaultValue: (Ext.isOpera || Ext.isIE6) ? ' ' : '​', + + comp.collapsed = true; + comp.fireEvent('collapse', comp); + } - - actionMode: 'wrap', - validationEvent : false, - deferHeight: true, - initialized : false, - activated : false, - sourceEditMode : false, - onFocus : Ext.emptyFn, - iframePad:3, - hideMode:'offsets', - defaultAutoCreate : { - tag: "textarea", - style:"width:500px;height:300px;", - autocomplete: "off" - }, + + if (comp.animCollapse && me.initialCollapsedComplete) { + shadowLayout.layout(); + compEl.dom.style.zIndex = 100; - - initComponent : function(){ - this.addEvents( - 'initialize', + if (!miniCollapse) { + placeholder.el.hide(); + } + compEl.slideOut(me.slideDirection[comp.region], { + duration: Ext.Number.from(comp.animCollapse, Ext.fx.Anim.prototype.duration), + listeners: { + afteranimate: function() { + compEl.show().setLeftTop(-10000, -10000); + compEl.dom.style.zIndex = ''; + + + if (!miniCollapse) { + placeholder.el.slideIn(me.slideDirection[comp.region], { + easing: 'linear', + duration: 100 + }); + } + afterCollapse(); + } + } + }); + } else { + compEl.setLeftTop(-10000, -10000); + shadowLayout.layout(); + afterCollapse(); + - 'activate', - - 'beforesync', - - 'beforepush', - - 'sync', - - 'push', - - 'editmodechange' - ); - Ext.form.HtmlEditor.superclass.initComponent.call(this); + if (Ext.isIE) { + placeholder.setCalculatedSize(placeholder.el.getWidth()); + } + } + + return false; }, - createFontOptions : function(){ - var buf = [], fs = this.fontFamilies, ff, lc; - for(var i = 0, len = fs.length; i< len; i++){ - ff = fs[i]; - lc = ff.toLowerCase(); - buf.push( - '' - ); - } - return buf.join(''); + onBeforeRegionExpand: function(comp, animate) { + this.onPlaceHolderToolClick(null, null, null, {client: comp}); + return false; }, - createToolbar : function(editor){ - var items = []; - var tipsEnabled = Ext.QuickTips && Ext.QuickTips.isEnabled(); + onPlaceHolderToolClick: function(e, target, owner, tool) { + var me = this, + comp = tool.client, + + hidePlaceholder = (comp.collapseMode != 'mini') || !comp.split, + compEl = comp.el, + toCompBox, + placeholder = comp.placeholder, + placeholderEl = placeholder.el, + shadowContainer = comp.shadowOwnerCt, + shadowLayout = shadowContainer.layout, + curSize, + sl = me.owner.suspendLayout, + scsl = shadowContainer.suspendLayout, + isFloating; - function btn(id, toggle, handler){ - return { - itemId : id, - cls : 'x-btn-icon', - iconCls: 'x-edit-'+id, - enableToggle:toggle !== false, - scope: editor, - handler:handler||editor.relayBtnCmd, - clickEvent:'mousedown', - tooltip: tipsEnabled ? editor.buttonTips[id] || undefined : undefined, - overflowText: editor.buttonTips[id].title || undefined, - tabIndex:-1 - }; + + + + if (comp.getActiveAnimation()) { + comp.stopAnimation(); } + + + + if (comp.slideOutAnim) { + + compEl.un(comp.panelMouseMon); + placeholderEl.un(comp.placeholderMouseMon); - if(this.enableFont && !Ext.isSafari2){ - var fontSelectItem = new Ext.Toolbar.Item({ - autoEl: { - tag:'select', - cls:'x-font-select', - html: this.createFontOptions() - } - }); + delete comp.slideOutAnim; + delete comp.panelMouseMon; + delete comp.placeholderMouseMon; - items.push( - fontSelectItem, - '-' - ); + + isFloating = true; } - if(this.enableFormat){ - items.push( - btn('bold'), - btn('italic'), - btn('underline') - ); - } + + me.owner.suspendLayout = true; + shadowContainer.suspendLayout = true; - if(this.enableFontSize){ - items.push( - '-', - btn('increasefontsize', false, this.adjustFont), - btn('decreasefontsize', false, this.adjustFont) - ); + + shadowLayout.layoutBusy = true; + if (shadowContainer.componentLayout) { + shadowContainer.componentLayout.layoutBusy = true; } + me.shadowContainer.layout.layoutBusy = true; + me.layoutBusy = true; + me.owner.componentLayout.layoutBusy = true; - if(this.enableColors){ - items.push( - '-', { - itemId:'forecolor', - cls:'x-btn-icon', - iconCls: 'x-edit-forecolor', - clickEvent:'mousedown', - tooltip: tipsEnabled ? editor.buttonTips.forecolor || undefined : undefined, - tabIndex:-1, - menu : new Ext.menu.ColorMenu({ - allowReselect: true, - focus: Ext.emptyFn, - value:'000000', - plain:true, - listeners: { - scope: this, - select: function(cp, color){ - this.execCmd('forecolor', Ext.isWebKit || Ext.isIE ? '#'+color : color); - this.deferFocus(); - } - }, - clickEvent:'mousedown' - }) - }, { - itemId:'backcolor', - cls:'x-btn-icon', - iconCls: 'x-edit-backcolor', - clickEvent:'mousedown', - tooltip: tipsEnabled ? editor.buttonTips.backcolor || undefined : undefined, - tabIndex:-1, - menu : new Ext.menu.ColorMenu({ - focus: Ext.emptyFn, - value:'FFFFFF', - plain:true, - allowReselect: true, - listeners: { - scope: this, - select: function(cp, color){ - if(Ext.isGecko){ - this.execCmd('useCSS', false); - this.execCmd('hilitecolor', color); - this.execCmd('useCSS', true); - this.deferFocus(); - }else{ - this.execCmd(Ext.isOpera ? 'hilitecolor' : 'backcolor', Ext.isWebKit || Ext.isIE ? '#'+color : color); - this.deferFocus(); - } - } - }, - clickEvent:'mousedown' - }) - } - ); + + + comp.hidden = false; + comp.collapsed = false; + if (hidePlaceholder) { + placeholder.hidden = true; } + toCompBox = shadowLayout.calculateChildBox(comp); - if(this.enableAlignments){ - items.push( - '-', - btn('justifyleft'), - btn('justifycenter'), - btn('justifyright') - ); + + if (comp.collapseTool) { + comp.collapseTool.show(); } - if(!Ext.isSafari2){ - if(this.enableLinks){ - items.push( - '-', - btn('createlink', false, this.createLink) - ); - } + + if (comp.animCollapse && !isFloating) { + compEl.setStyle('visibility', 'hidden'); + } + compEl.setLeftTop(toCompBox.left, toCompBox.top); - if(this.enableLists){ - items.push( - '-', - btn('insertorderedlist'), - btn('insertunorderedlist') - ); - } - if(this.enableSourceEdit){ - items.push( - '-', - btn('sourceedit', true, function(btn){ - this.toggleSourceEdit(!this.sourceEditMode); - }) - ); - } + + + curSize = comp.getSize(); + if (curSize.height != toCompBox.height || curSize.width != toCompBox.width) { + me.setItemSize(comp, toCompBox.width, toCompBox.height); } - var tb = new Ext.Toolbar({ - renderTo: this.wrap.dom.firstChild, - items: items - }); + function afterExpand() { + + me.owner.suspendLayout = sl; + shadowContainer.suspendLayout = scsl; + delete shadowLayout.layoutBusy; + if (shadowContainer.componentLayout) { + delete shadowContainer.componentLayout.layoutBusy; + } + delete me.shadowContainer.layout.layoutBusy; + delete me.layoutBusy; + delete me.owner.componentLayout.layoutBusy; - if (fontSelectItem) { - this.fontSelect = fontSelectItem.el; + + comp.removeCls(Ext.baseCSSPrefix + 'border-region-slide-in'); - this.mon(this.fontSelect, 'change', function(){ - var font = this.fontSelect.dom.value; - this.relayCmd('fontname', font); - this.deferFocus(); - }, this); + + comp.fireEvent('expand', comp); } - this.mon(tb.el, 'click', function(e){ - e.preventDefault(); - }); + if (hidePlaceholder) { + placeholder.el.hide(); + } - this.tb = tb; - this.tb.doLayout(); + + + if (comp.animCollapse && !isFloating) { + compEl.dom.style.zIndex = 100; + compEl.slideIn(me.slideDirection[comp.region], { + duration: Ext.Number.from(comp.animCollapse, Ext.fx.Anim.prototype.duration), + listeners: { + afteranimate: function() { + compEl.dom.style.zIndex = ''; + comp.hidden = false; + shadowLayout.onLayout(); + afterExpand(); + } + } + }); + } else { + shadowLayout.onLayout(); + afterExpand(); + } }, - onDisable: function(){ - this.wrap.mask(); - Ext.form.HtmlEditor.superclass.onDisable.call(this); - }, + floatCollapsedPanel: function(e, comp) { - onEnable: function(){ - this.wrap.unmask(); - Ext.form.HtmlEditor.superclass.onEnable.call(this); - }, + if (comp.floatable === false) { + return; + } - setReadOnly: function(readOnly){ + var me = this, + compEl = comp.el, + placeholder = comp.placeholder, + placeholderEl = placeholder.el, + shadowContainer = comp.shadowOwnerCt, + shadowLayout = shadowContainer.layout, + placeholderBox = shadowLayout.getChildBox(placeholder), + scsl = shadowContainer.suspendLayout, + curSize, toCompBox, compAnim; - Ext.form.HtmlEditor.superclass.setReadOnly.call(this, readOnly); - if(this.initialized){ - if(Ext.isIE){ - this.getEditorBody().contentEditable = !readOnly; - }else{ - this.setDesignMode(!readOnly); - } - var bd = this.getEditorBody(); - if(bd){ - bd.style.cursor = this.readOnly ? 'default' : 'text'; - } - this.disableItems(readOnly); + + if (e.getTarget('.' + Ext.baseCSSPrefix + 'tool')) { + return; } - }, - - - getDocMarkup : function(){ - var h = Ext.fly(this.iframe).getHeight() - this.iframePad * 2; - return String.format('', this.iframePad, h); - }, - - getEditorBody : function(){ - var doc = this.getDoc(); - return doc.body || doc.documentElement; - }, + + + if (compEl.getActiveAnimation()) { + return; + } - - getDoc : function(){ - return Ext.isIE ? this.getWin().document : (this.iframe.contentDocument || this.getWin().document); - }, + + + if (comp.slideOutAnim) { + me.slideOutFloatedComponent(comp); + return; + } - - getWin : function(){ - return Ext.isIE ? this.iframe.contentWindow : window.frames[this.iframe.name]; - }, + + + function onMouseLeaveFloated(e) { + var slideRegion = compEl.getRegion().union(placeholderEl.getRegion()).adjust(1, -1, -1, 1); - - onRender : function(ct, position){ - Ext.form.HtmlEditor.superclass.onRender.call(this, ct, position); - this.el.dom.style.border = '0 none'; - this.el.dom.setAttribute('tabIndex', -1); - this.el.addClass('x-hidden'); - if(Ext.isIE){ - this.el.applyStyles('margin-top:-1px;margin-bottom:-1px;'); + + if (!slideRegion.contains(e.getPoint())) { + me.slideOutFloatedComponent(comp); + } } - this.wrap = this.el.wrap({ - cls:'x-html-editor-wrap', cn:{cls:'x-html-editor-tb'} - }); - this.createToolbar(this); - - this.disableItems(true); + + comp.placeholderMouseMon = placeholderEl.monitorMouseLeave(500, onMouseLeaveFloated); - this.tb.doLayout(); + + shadowContainer.suspendLayout = true; - this.createIFrame(); + + me.layoutBusy = true; + me.owner.componentLayout.layoutBusy = true; - if(!this.width){ - var sz = this.el.getSize(); - this.setSize(sz.width, this.height || sz.height); + + + if (comp.collapseTool) { + comp.collapseTool.hide(); } - this.resizeEl = this.positionEl = this.wrap; - }, - createIFrame: function(){ - var iframe = document.createElement('iframe'); - iframe.name = Ext.id(); - iframe.frameBorder = '0'; - iframe.style.overflow = 'auto'; - iframe.src = Ext.SSL_SECURE_URL; + + comp.hidden = false; + comp.collapsed = false; + placeholder.hidden = true; - this.wrap.dom.appendChild(iframe); - this.iframe = iframe; + + toCompBox = shadowLayout.calculateChildBox(comp); + placeholder.hidden = false; - this.monitorTask = Ext.TaskMgr.start({ - run: this.checkDesignMode, - scope: this, - interval:100 - }); - }, + + if (comp.region == 'north' || comp.region == 'west') { + toCompBox[shadowLayout.parallelBefore] += placeholderBox[shadowLayout.parallelPrefix] - 1; + } else { + toCompBox[shadowLayout.parallelBefore] -= (placeholderBox[shadowLayout.parallelPrefix] - 1); + } + compEl.setStyle('visibility', 'hidden'); + compEl.setLeftTop(toCompBox.left, toCompBox.top); - initFrame : function(){ - Ext.TaskMgr.stop(this.monitorTask); - var doc = this.getDoc(); - this.win = this.getWin(); + + + curSize = comp.getSize(); + if (curSize.height != toCompBox.height || curSize.width != toCompBox.width) { + me.setItemSize(comp, toCompBox.width, toCompBox.height); + } - doc.open(); - doc.write(this.getDocMarkup()); - doc.close(); + + compAnim = { + listeners: { + afteranimate: function() { + shadowContainer.suspendLayout = scsl; + delete me.layoutBusy; + delete me.owner.componentLayout.layoutBusy; + + + compAnim.listeners = { + afterAnimate: function() { + compEl.show().removeCls(Ext.baseCSSPrefix + 'border-region-slide-in').setLeftTop(-10000, -10000); - var task = { - run : function(){ - var doc = this.getDoc(); - if(doc.body || doc.readyState == 'complete'){ - Ext.TaskMgr.stop(task); - this.setDesignMode(true); - this.initEditor.defer(10, this); + + comp.hidden = true; + comp.collapsed = true; + delete comp.slideOutAnim; + delete comp.panelMouseMon; + delete comp.placeholderMouseMon; + } + }; + comp.slideOutAnim = compAnim; } }, - interval : 10, - duration:10000, - scope: this + duration: 500 }; - Ext.TaskMgr.start(task); - }, + + compEl.addCls(Ext.baseCSSPrefix + 'border-region-slide-in'); - checkDesignMode : function(){ - if(this.wrap && this.wrap.dom.offsetWidth){ - var doc = this.getDoc(); - if(!doc){ - return; - } - if(!doc.editorInitialized || this.getDesignMode() != 'on'){ - this.initFrame(); - } - } - }, + + compEl.slideIn(me.slideDirection[comp.region], compAnim); - - setDesignMode : function(mode){ - var doc = this.getDoc(); - if (doc) { - if(this.readOnly){ - mode = false; - } - doc.designMode = (/on|true/i).test(String(mode).toLowerCase()) ?'on':'off'; - } + + comp.panelMouseMon = compEl.monitorMouseLeave(500, onMouseLeaveFloated); }, - - getDesignMode : function(){ - var doc = this.getDoc(); - if(!doc){ return ''; } - return String(doc.designMode).toLowerCase(); + slideOutFloatedComponent: function(comp) { + var compEl = comp.el, + slideOutAnim; - }, + + compEl.un(comp.panelMouseMon); + comp.placeholder.el.un(comp.placeholderMouseMon); - disableItems: function(disabled){ - if(this.fontSelect){ - this.fontSelect.dom.disabled = disabled; - } - this.tb.items.each(function(item){ - if(item.getItemId() != 'sourceedit'){ - item.setDisabled(disabled); - } - }); + + compEl.slideOut(this.slideDirection[comp.region], comp.slideOutAnim); + + delete comp.slideOutAnim; + delete comp.panelMouseMon; + delete comp.placeholderMouseMon; }, - onResize : function(w, h){ - Ext.form.HtmlEditor.superclass.onResize.apply(this, arguments); - if(this.el && this.iframe){ - if(Ext.isNumber(w)){ - var aw = w - this.wrap.getFrameWidth('lr'); - this.el.setWidth(aw); - this.tb.setWidth(aw); - this.iframe.style.width = Math.max(aw, 0) + 'px'; - } - if(Ext.isNumber(h)){ - var ah = h - this.wrap.getFrameWidth('tb') - this.tb.el.getHeight(); - this.el.setHeight(ah); - this.iframe.style.height = Math.max(ah, 0) + 'px'; - var bd = this.getEditorBody(); - if(bd){ - bd.style.height = Math.max((ah - (this.iframePad*2)), 0) + 'px'; - } - } + onRegionDestroy: function(comp) { + var placeholder = comp.placeholder; + if (placeholder) { + delete placeholder.ownerCt; + placeholder.destroy(); } }, - toggleSourceEdit : function(sourceEditMode){ - var iframeHeight, - elHeight; + onDestroy: function() { + var me = this, + shadowContainer = me.shadowContainer, + embeddedContainer = me.embeddedContainer; - if (sourceEditMode === undefined) { - sourceEditMode = !this.sourceEditMode; + if (shadowContainer) { + delete shadowContainer.ownerCt; + Ext.destroy(shadowContainer); } - this.sourceEditMode = sourceEditMode === true; - var btn = this.tb.getComponent('sourceedit'); - if (btn.pressed !== this.sourceEditMode) { - btn.toggle(this.sourceEditMode); - if (!btn.xtbHidden) { - return; - } + if (embeddedContainer) { + delete embeddedContainer.ownerCt; + Ext.destroy(embeddedContainer); } - if (this.sourceEditMode) { - - this.previousSize = this.getSize(); - - iframeHeight = Ext.get(this.iframe).getHeight(); + delete me.regions; + delete me.splitters; + delete me.shadowContainer; + delete me.embeddedContainer; + me.callParent(arguments); + } +}); - this.disableItems(true); - this.syncValue(); - this.iframe.className = 'x-hidden'; - this.el.removeClass('x-hidden'); - this.el.dom.removeAttribute('tabIndex'); - this.el.focus(); - this.el.dom.style.height = iframeHeight + 'px'; - } - else { - elHeight = parseInt(this.el.dom.style.height, 10); - if (this.initialized) { - this.disableItems(this.readOnly); - } - this.pushValue(); - this.iframe.className = ''; - this.el.addClass('x-hidden'); - this.el.dom.setAttribute('tabIndex', -1); - this.deferFocus(); - this.setSize(this.previousSize); - delete this.previousSize; - this.iframe.style.height = elHeight + 'px'; - } - this.fireEvent('editmodechange', this, this.sourceEditMode); - }, +Ext.define('Ext.layout.container.Card', { - createLink : function() { - var url = prompt(this.createLinkText, this.defaultLinkValue); - if(url && url != 'http:/'+'/'){ - this.relayCmd('createlink', url); - } - }, - - initEvents : function(){ - this.originalValue = this.getValue(); - }, + alias: ['layout.card'], + alternateClassName: 'Ext.layout.CardLayout', - - markInvalid : Ext.emptyFn, + extend: 'Ext.layout.container.AbstractCard', - clearInvalid : Ext.emptyFn, - - setValue : function(v){ - Ext.form.HtmlEditor.superclass.setValue.call(this, v); - this.pushValue(); - return this; - }, + setActiveItem: function(newCard) { + var me = this, + owner = me.owner, + oldCard = me.activeItem, + newIndex; - - cleanHtml: function(html) { - html = String(html); - if(Ext.isWebKit){ - html = html.replace(/\sclass="(?:Apple-style-span|khtml-block-placeholder)"/gi, ''); - } + + me.layoutBusy = true; + + newCard = me.parseActiveItem(newCard); + newIndex = owner.items.indexOf(newCard); - if(html.charCodeAt(0) == this.defaultValue.replace(/\D/g, '')){ - html = html.substring(1); + if (newIndex == -1) { + newIndex = owner.items.items.length; + owner.add(newCard); } - return html; - }, - - syncValue : function(){ - if(this.initialized){ - var bd = this.getEditorBody(); - var html = bd.innerHTML; - if(Ext.isWebKit){ - var bs = bd.getAttribute('style'); - var m = bs.match(/text-align:(.*?);/i); - if(m && m[1]){ - html = '
    ' + html + '
    '; - } - } - html = this.cleanHtml(html); - if(this.fireEvent('beforesync', this, html) !== false){ - this.el.dom.value = html; - this.fireEvent('sync', this, html); + + if (newCard && oldCard != newCard) { + + if (!newCard.rendered) { + me.renderItem(newCard, me.getRenderTarget(), owner.items.length); + me.configureItem(newCard, 0); } - } - }, - - getValue : function() { - this[this.sourceEditMode ? 'pushValue' : 'syncValue'](); - return Ext.form.HtmlEditor.superclass.getValue.call(this); - }, + me.activeItem = newCard; - - pushValue : function(){ - if(this.initialized){ - var v = this.el.dom.value; - if(!this.activated && v.length < 1){ - v = this.defaultValue; + + if (newCard.fireEvent('beforeactivate', newCard, oldCard) === false) { + me.layoutBusy = false; + return false; } - if(this.fireEvent('beforepush', this, v) !== false){ - this.getEditorBody().innerHTML = v; - if(Ext.isGecko){ - - this.setDesignMode(false); - this.setDesignMode(true); + if (oldCard && oldCard.fireEvent('beforedeactivate', oldCard, newCard) === false) { + me.layoutBusy = false; + return false; + } + + + if (!me.sizeAllCards) { + me.setItemBox(newCard, me.getTargetBox()); + } + else { + + me.onLayout(); + } + + if (oldCard) { + if (me.hideInactive) { + oldCard.hide(); } - this.fireEvent('push', this, v); + oldCard.fireEvent('deactivate', oldCard, newCard); } - } - }, + + if (newCard.hidden) { + newCard.show(); + } - - deferFocus : function(){ - this.focus.defer(10, this); - }, + newCard.fireEvent('activate', newCard, oldCard); - - focus : function(){ - if(this.win && !this.sourceEditMode){ - this.win.focus(); - }else{ - this.el.focus(); + me.layoutBusy = false; + + if (!me.sizeAllCards) { + if (!owner.componentLayout.layoutBusy) { + me.onLayout(); + } + } + return newCard; } - }, - - initEditor : function(){ - - try{ - var dbody = this.getEditorBody(), - ss = this.el.getStyles('font-size', 'font-family', 'background-image', 'background-repeat', 'background-color', 'color'), - doc, - fn; + me.layoutBusy = false; + return false; + } +}); - ss['background-attachment'] = 'fixed'; - dbody.bgProperties = 'fixed'; +Ext.define('Ext.layout.container.Column', { - Ext.DomHelper.applyStyles(dbody, ss); + extend: 'Ext.layout.container.Auto', + alias: ['layout.column'], + alternateClassName: 'Ext.layout.ColumnLayout', - doc = this.getDoc(); + type: 'column', - if(doc){ - try{ - Ext.EventManager.removeAll(doc); - }catch(e){} - } + itemCls: Ext.baseCSSPrefix + 'column', + + targetCls: Ext.baseCSSPrefix + 'column-layout-ct', + + scrollOffset: 0, + + bindToOwnerCtComponent: false, + + getRenderTarget : function() { + if (!this.innerCt) { - fn = this.onEditorEvent.createDelegate(this); - Ext.EventManager.on(doc, { - mousedown: fn, - dblclick: fn, - click: fn, - keyup: fn, - buffer:100 + + this.innerCt = this.getTarget().createChild({ + cls: Ext.baseCSSPrefix + 'column-inner' }); - if(Ext.isGecko){ - Ext.EventManager.on(doc, 'keypress', this.applyCommand, this); - } - if(Ext.isIE || Ext.isWebKit || Ext.isOpera){ - Ext.EventManager.on(doc, 'keydown', this.fixKeys, this); - } - doc.editorInitialized = true; - this.initialized = true; - this.pushValue(); - this.setReadOnly(this.readOnly); - this.fireEvent('initialize', this); - }catch(e){} + + + + this.clearEl = this.innerCt.createChild({ + cls: Ext.baseCSSPrefix + 'clear', + role: 'presentation' + }); + } + return this.innerCt; }, - beforeDestroy : function(){ - if(this.monitorTask){ - Ext.TaskMgr.stop(this.monitorTask); + onLayout : function() { + var me = this, + target = me.getTarget(), + items = me.getLayoutItems(), + len = items.length, + item, + i, + parallelMargins = [], + itemParallelMargins, + size, + availableWidth, + columnWidth; + + size = me.getLayoutTargetSize(); + if (size.width < len * 10) { + return; } - if(this.rendered){ - Ext.destroy(this.tb); - var doc = this.getDoc(); - if(doc){ - try{ - Ext.EventManager.removeAll(doc); - for (var prop in doc){ - delete doc[prop]; - } - }catch(e){} + + + + + if (me.adjustmentPass) { + if (Ext.isIE6 || Ext.isIE7 || Ext.isIEQuirks) { + size.width = me.adjustedWidth; } - if(this.wrap){ - this.wrap.dom.innerHTML = ''; - this.wrap.remove(); + } else { + i = target.getStyle('overflow'); + if (i && i != 'hidden') { + me.autoScroll = true; + if (!(Ext.isIE6 || Ext.isIE7 || Ext.isIEQuirks)) { + target.setStyle('overflow', 'hidden'); + size = me.getLayoutTargetSize(); + } } } - Ext.form.HtmlEditor.superclass.beforeDestroy.call(this); - }, - - onFirstFocus : function(){ - this.activated = true; - this.disableItems(this.readOnly); - if(Ext.isGecko){ - this.win.focus(); - var s = this.win.getSelection(); - if(!s.focusNode || s.focusNode.nodeType != 3){ - var r = s.getRangeAt(0); - r.selectNodeContents(this.getEditorBody()); - r.collapse(true); - this.deferFocus(); + availableWidth = size.width - me.scrollOffset; + me.innerCt.setWidth(availableWidth); + + + + for (i = 0; i < len; i++) { + item = items[i]; + itemParallelMargins = parallelMargins[i] = item.getEl().getMargin('lr'); + if (!item.columnWidth) { + availableWidth -= (item.getWidth() + itemParallelMargins); } - try{ - this.execCmd('useCSS', true); - this.execCmd('styleWithCSS', false); - }catch(e){} } - this.fireEvent('activate', this); - }, - - adjustFont: function(btn){ - var adjust = btn.getItemId() == 'increasefontsize' ? 1 : -1, - doc = this.getDoc(), - v = parseInt(doc.queryCommandValue('FontSize') || 2, 10); - if((Ext.isSafari && !Ext.isSafari2) || Ext.isChrome || Ext.isAir){ - + availableWidth = availableWidth < 0 ? 0 : availableWidth; + for (i = 0; i < len; i++) { + item = items[i]; + if (item.columnWidth) { + columnWidth = Math.floor(item.columnWidth * availableWidth) - parallelMargins[i]; + if (item.getWidth() != columnWidth) { + me.setItemSize(item, columnWidth, item.height); + } + } + } + + + if (!me.adjustmentPass && me.autoScroll) { + - if(v <= 10){ - v = 1 + adjust; - }else if(v <= 13){ - v = 2 + adjust; - }else if(v <= 16){ - v = 3 + adjust; - }else if(v <= 18){ - v = 4 + adjust; - }else if(v <= 24){ - v = 5 + adjust; - }else { - v = 6 + adjust; + target.setStyle('overflow', 'auto'); + me.adjustmentPass = (target.dom.scrollHeight > size.height); + if (Ext.isIE6 || Ext.isIE7 || Ext.isIEQuirks) { + me.adjustedWidth = size.width - Ext.getScrollBarWidth(); + } else { + target.setStyle('overflow', 'auto'); } - v = v.constrain(1, 6); - }else{ - if(Ext.isSafari){ - adjust *= 2; + + + if (me.adjustmentPass) { + me.onLayout(); } - v = Math.max(1, v+adjust) + (Ext.isSafari ? 'px' : 0); } - this.execCmd('FontSize', v); - }, + delete me.adjustmentPass; + } +}); + + +Ext.define('Ext.layout.container.Table', { - onEditorEvent : function(e){ - this.updateToolbar(); - }, + alias: ['layout.table'], + extend: 'Ext.layout.container.Auto', + alternateClassName: 'Ext.layout.TableLayout', - updateToolbar: function(){ - if(this.readOnly){ - return; - } + - if(!this.activated){ - this.onFirstFocus(); - return; - } + + monitorResize:false, - var btns = this.tb.items.map, - doc = this.getDoc(); + type: 'table', - if(this.enableFont && !Ext.isSafari2){ - var name = (doc.queryCommandValue('FontName')||this.defaultFont).toLowerCase(); - if(name != this.fontSelect.dom.value){ - this.fontSelect.dom.value = name; - } - } - if(this.enableFormat){ - btns.bold.toggle(doc.queryCommandState('bold')); - btns.italic.toggle(doc.queryCommandState('italic')); - btns.underline.toggle(doc.queryCommandState('underline')); - } - if(this.enableAlignments){ - btns.justifyleft.toggle(doc.queryCommandState('justifyleft')); - btns.justifycenter.toggle(doc.queryCommandState('justifycenter')); - btns.justifyright.toggle(doc.queryCommandState('justifyright')); - } - if(!Ext.isSafari2 && this.enableLists){ - btns.insertorderedlist.toggle(doc.queryCommandState('insertorderedlist')); - btns.insertunorderedlist.toggle(doc.queryCommandState('insertunorderedlist')); - } + + + autoSize: true, - Ext.menu.MenuMgr.hideAll(); + clearEl: true, - this.syncValue(); - }, + targetCls: Ext.baseCSSPrefix + 'table-layout-ct', + tableCls: Ext.baseCSSPrefix + 'table-layout', + cellCls: Ext.baseCSSPrefix + 'table-layout-cell', - relayBtnCmd : function(btn){ - this.relayCmd(btn.getItemId()); - }, + tableAttrs:null, - relayCmd : function(cmd, value){ - (function(){ - this.focus(); - this.execCmd(cmd, value); - this.updateToolbar(); - }).defer(10, this); - }, + renderItems: function(items) { + var tbody = this.getTable().tBodies[0], + rows = tbody.rows, + i = 0, + len = items.length, + cells, curCell, rowIdx, cellIdx, item, trEl, tdEl, itemCt; - - execCmd : function(cmd, value){ - var doc = this.getDoc(); - doc.execCommand(cmd, false, value === undefined ? null : value); - this.syncValue(); - }, + + cells = this.calculateCells(items); - - applyCommand : function(e){ - if(e.ctrlKey){ - var c = e.getCharCode(), cmd; - if(c > 0){ - c = String.fromCharCode(c); - switch(c){ - case 'b': - cmd = 'bold'; - break; - case 'i': - cmd = 'italic'; - break; - case 'u': - cmd = 'underline'; - break; - } - if(cmd){ - this.win.focus(); - this.execCmd(cmd); - this.deferFocus(); - e.preventDefault(); + + + + for (; i < len; i++) { + curCell = cells[i]; + rowIdx = curCell.rowIdx; + cellIdx = curCell.cellIdx; + item = items[i]; + + + trEl = rows[rowIdx]; + if (!trEl) { + trEl = tbody.insertRow(rowIdx); + } + + + itemCt = tdEl = Ext.get(trEl.cells[cellIdx] || trEl.insertCell(cellIdx)); + if (this.needsDivWrap()) { + itemCt = tdEl.first() || tdEl.createChild({tag: 'div'}); + itemCt.setWidth(null); + } + + + if (!item.rendered) { + this.renderItem(item, itemCt, 0); + } + else if (!this.isValidParent(item, itemCt, 0)) { + this.moveItem(item, itemCt, 0); + } + + + tdEl.set({ + colSpan: item.colspan || 1, + rowSpan: item.rowspan || 1, + id: item.cellId || '', + cls: this.cellCls + ' ' + (item.cellCls || '') + }); + + + if (!cells[i + 1] || cells[i + 1].rowIdx !== rowIdx) { + cellIdx++; + while (trEl.cells[cellIdx]) { + trEl.deleteCell(cellIdx); } } } - }, - - insertAtCursor : function(text){ - if(!this.activated){ - return; + + rowIdx++; + while (tbody.rows[rowIdx]) { + tbody.deleteRow(rowIdx); } - if(Ext.isIE){ - this.win.focus(); - var doc = this.getDoc(), - r = doc.selection.createRange(); - if(r){ - r.pasteHTML(text); - this.syncValue(); - this.deferFocus(); - } - }else{ - this.win.focus(); - this.execCmd('InsertHTML', text); - this.deferFocus(); + }, + + afterLayout: function() { + this.callParent(); + + if (this.needsDivWrap()) { + + Ext.Array.forEach(this.getLayoutItems(), function(item) { + Ext.fly(item.el.dom.parentNode).setWidth(item.getWidth()); + }); } }, - fixKeys : function(){ - if(Ext.isIE){ - return function(e){ - var k = e.getKey(), - doc = this.getDoc(), - r; - if(k == e.TAB){ - e.stopEvent(); - r = doc.selection.createRange(); - if(r){ - r.collapse(true); - r.pasteHTML('    '); - this.deferFocus(); - } - }else if(k == e.ENTER){ - r = doc.selection.createRange(); - if(r){ - var target = r.parentElement(); - if(!target || target.tagName.toLowerCase() != 'li'){ - e.stopEvent(); - r.pasteHTML('
    '); - r.collapse(false); - r.select(); + calculateCells: function(items) { + var cells = [], + rowIdx = 0, + colIdx = 0, + cellIdx = 0, + totalCols = this.columns || Infinity, + rowspans = [], + i = 0, j, + len = items.length, + item; + + for (; i < len; i++) { + item = items[i]; + + + while (colIdx >= totalCols || rowspans[colIdx] > 0) { + if (colIdx >= totalCols) { + + colIdx = 0; + cellIdx = 0; + rowIdx++; + + + for (j = 0; j < totalCols; j++) { + if (rowspans[j] > 0) { + rowspans[j]--; } } + } else { + colIdx++; } - }; - }else if(Ext.isOpera){ - return function(e){ - var k = e.getKey(); - if(k == e.TAB){ - e.stopEvent(); - this.win.focus(); - this.execCmd('InsertHTML','    '); - this.deferFocus(); - } - }; - }else if(Ext.isWebKit){ - return function(e){ - var k = e.getKey(); - if(k == e.TAB){ - e.stopEvent(); - this.execCmd('InsertText','\t'); - this.deferFocus(); - }else if(k == e.ENTER){ - e.stopEvent(); - this.execCmd('InsertHtml','

    '); - this.deferFocus(); - } - }; + } + + + cells.push({ + rowIdx: rowIdx, + cellIdx: cellIdx + }); + + + rowspans[colIdx] = item.rowspan || 1; + colIdx += item.colspan || 1; + cellIdx++; } - }(), - - getToolbar : function(){ - return this.tb; + return cells; }, - buttonTips : { - bold : { - title: 'Bold (Ctrl+B)', - text: 'Make the selected text bold.', - cls: 'x-html-editor-tip' - }, - italic : { - title: 'Italic (Ctrl+I)', - text: 'Make the selected text italic.', - cls: 'x-html-editor-tip' - }, - underline : { - title: 'Underline (Ctrl+U)', - text: 'Underline the selected text.', - cls: 'x-html-editor-tip' - }, - increasefontsize : { - title: 'Grow Text', - text: 'Increase the font size.', - cls: 'x-html-editor-tip' - }, - decreasefontsize : { - title: 'Shrink Text', - text: 'Decrease the font size.', - cls: 'x-html-editor-tip' - }, - backcolor : { - title: 'Text Highlight Color', - text: 'Change the background color of the selected text.', - cls: 'x-html-editor-tip' - }, - forecolor : { - title: 'Font Color', - text: 'Change the color of the selected text.', - cls: 'x-html-editor-tip' - }, - justifyleft : { - title: 'Align Text Left', - text: 'Align text to the left.', - cls: 'x-html-editor-tip' - }, - justifycenter : { - title: 'Center Text', - text: 'Center text in the editor.', - cls: 'x-html-editor-tip' - }, - justifyright : { - title: 'Align Text Right', - text: 'Align text to the right.', - cls: 'x-html-editor-tip' - }, - insertunorderedlist : { - title: 'Bullet List', - text: 'Start a bulleted list.', - cls: 'x-html-editor-tip' - }, - insertorderedlist : { - title: 'Numbered List', - text: 'Start a numbered list.', - cls: 'x-html-editor-tip' - }, - createlink : { - title: 'Hyperlink', - text: 'Make the selected text a hyperlink.', - cls: 'x-html-editor-tip' - }, - sourceedit : { - title: 'Source Edit', - text: 'Switch to source editing mode.', - cls: 'x-html-editor-tip' + getTable: function() { + var table = this.table; + if (!table) { + table = this.table = this.getTarget().createChild( + Ext.apply({ + tag: 'table', + role: 'presentation', + cls: this.tableCls, + cellspacing: 0, + cn: {tag: 'tbody'} + }, this.tableAttrs), + null, true + ); } - } + return table; + }, + needsDivWrap: function() { + return Ext.isOpera10_5; + } +}); + +Ext.define('Ext.menu.Item', { + extend: 'Ext.Component', + alias: 'widget.menuitem', + alternateClassName: 'Ext.menu.TextItem', + + activeCls: Ext.baseCSSPrefix + 'menu-item-active', + ariaRole: 'menuitem', + canActivate: true, + clickHideDelay: 1, + destroyMenu: true, + disabledCls: Ext.baseCSSPrefix + 'menu-item-disabled', + + + hideOnClick: true, + + isMenuItem: true, + menuAlign: 'tl-tr?', + menuExpandDelay: 200, + menuHideDelay: 200, + renderTpl: [ + '', + '{text}', + '', + '', + 'target="{hrefTarget}" hidefocus="true" unselectable="on">', + '', + 'style="margin-right: 17px;" >{text}', + '', + '', + '', + '', + '' + ], -}); -Ext.reg('htmleditor', Ext.form.HtmlEditor); - -Ext.form.TimeField = Ext.extend(Ext.form.ComboBox, { - - minValue : undefined, - - maxValue : undefined, - - minText : "The time in this field must be equal to or after {0}", - - maxText : "The time in this field must be equal to or before {0}", - - invalidText : "{0} is not a valid time", - - format : "g:i A", - - altFormats : "g:ia|g:iA|g:i a|g:i A|h:i|g:i|H:i|ga|ha|gA|h a|g a|g A|gi|hi|gia|hia|g|H|gi a|hi a|giA|hiA|gi A|hi A", - - increment: 15, - - - mode: 'local', - - triggerAction: 'all', - - typeAhead: false, - - + maskOnDisable: false, - initDate: '1/1/2008', - - initDateFormat: 'j/n/Y', - - initComponent : function(){ - if(Ext.isDefined(this.minValue)){ - this.setMinValue(this.minValue, true); - } - if(Ext.isDefined(this.maxValue)){ - this.setMaxValue(this.maxValue, true); - } - if(!this.store){ - this.generateStore(true); + activate: function() { + var me = this; + + if (!me.activated && me.canActivate && me.rendered && !me.isDisabled() && me.isVisible()) { + me.el.addCls(me.activeCls); + me.focus(); + me.activated = true; + me.fireEvent('activate', me); } - Ext.form.TimeField.superclass.initComponent.call(this); - }, - - - setMinValue: function(value, initial){ - this.setLimit(value, true, initial); - return this; }, - - setMaxValue: function(value, initial){ - this.setLimit(value, false, initial); - return this; + blur: function() { + this.$focused = false; + this.callParent(arguments); }, - - generateStore: function(initial){ - var min = this.minValue || new Date(this.initDate).clearTime(), - max = this.maxValue || new Date(this.initDate).clearTime().add('mi', (24 * 60) - 1), - times = []; - - while(min <= max){ - times.push(min.dateFormat(this.format)); - min = min.add('mi', this.increment); + deactivate: function() { + var me = this; + + if (me.activated) { + me.el.removeCls(me.activeCls); + me.blur(); + me.hideMenu(); + me.activated = false; + me.fireEvent('deactivate', me); } - this.bindStore(times, initial); }, - - setLimit: function(value, isMin, initial){ - var d; - if(Ext.isString(value)){ - d = this.parseDate(value); - }else if(Ext.isDate(value)){ - d = value; - } - if(d){ - var val = new Date(this.initDate).clearTime(); - val.setHours(d.getHours(), d.getMinutes(), d.getSeconds(), d.getMilliseconds()); - this[isMin ? 'minValue' : 'maxValue'] = val; - if(!initial){ - this.generateStore(); - } + deferExpandMenu: function() { + var me = this; + + if (!me.menu.rendered || !me.menu.isVisible()) { + me.parentMenu.activeChild = me.menu; + me.menu.parentItem = me; + me.menu.parentMenu = me.menu.ownerCt = me.parentMenu; + me.menu.showBy(me, me.menuAlign); } }, - - getValue : function(){ - var v = Ext.form.TimeField.superclass.getValue.call(this); - return this.formatDate(this.parseDate(v)) || ''; + deferHideMenu: function() { + if (this.menu.isVisible()) { + this.menu.hide(); + } }, - - setValue : function(value){ - return Ext.form.TimeField.superclass.setValue.call(this, this.formatDate(this.parseDate(value))); + deferHideParentMenus: function() { + Ext.menu.Manager.hideAll(); }, - - - validateValue : Ext.form.DateField.prototype.validateValue, - - formatDate : Ext.form.DateField.prototype.formatDate, - - parseDate: function(value) { - if (!value || Ext.isDate(value)) { - return value; - } - - var id = this.initDate + ' ', - idf = this.initDateFormat + ' ', - v = Date.parseDate(id + value, idf + this.format), - af = this.altFormats; - - if (!v && af) { - if (!this.altFormatsArray) { - this.altFormatsArray = af.split("|"); - } - for (var i = 0, afa = this.altFormatsArray, len = afa.length; i < len && !v; i++) { - v = Date.parseDate(id + value, idf + afa[i]); - } - } - - return v; - } -}); -Ext.reg('timefield', Ext.form.TimeField); -Ext.form.SliderField = Ext.extend(Ext.form.Field, { - - useTips : true, - - - tipText : null, - - - actionMode: 'wrap', - - - initComponent : function() { - var cfg = Ext.copyTo({ - id: this.id + '-slider' - }, this.initialConfig, ['vertical', 'minValue', 'maxValue', 'decimalPrecision', 'keyIncrement', 'increment', 'clickToChange', 'animate']); - + expandMenu: function(delay) { + var me = this; - if (this.useTips) { - var plug = this.tipText ? {getText: this.tipText} : {}; - cfg.plugins = [new Ext.slider.Tip(plug)]; + if (me.menu) { + clearTimeout(me.hideMenuTimer); + if (delay === 0) { + me.deferExpandMenu(); + } else { + me.expandMenuTimer = Ext.defer(me.deferExpandMenu, Ext.isNumber(delay) ? delay : me.menuExpandDelay, me); + } } - this.slider = new Ext.Slider(cfg); - Ext.form.SliderField.superclass.initComponent.call(this); - }, - - - onRender : function(ct, position){ - this.autoCreate = { - id: this.id, - name: this.name, - type: 'hidden', - tag: 'input' - }; - Ext.form.SliderField.superclass.onRender.call(this, ct, position); - this.wrap = this.el.wrap({cls: 'x-form-field-wrap'}); - this.resizeEl = this.positionEl = this.wrap; - this.slider.render(this.wrap); - }, - - - onResize : function(w, h, aw, ah){ - Ext.form.SliderField.superclass.onResize.call(this, w, h, aw, ah); - this.slider.setSize(w, h); - }, - - - initEvents : function(){ - Ext.form.SliderField.superclass.initEvents.call(this); - this.slider.on('change', this.onChange, this); - }, - - - onChange : function(slider, v){ - this.setValue(v, undefined, true); - }, - - - onEnable : function(){ - Ext.form.SliderField.superclass.onEnable.call(this); - this.slider.enable(); }, - - onDisable : function(){ - Ext.form.SliderField.superclass.onDisable.call(this); - this.slider.disable(); + focus: function() { + this.$focused = true; + this.callParent(arguments); }, - - beforeDestroy : function(){ - Ext.destroy(this.slider); - Ext.form.SliderField.superclass.beforeDestroy.call(this); + getRefItems: function(deep){ + var menu = this.menu, + items; + + if (menu) { + items = menu.getRefItems(deep); + items.unshift(menu); + } + return items || []; }, - - alignErrorIcon : function(){ - this.errorIcon.alignTo(this.slider.el, 'tl-tr', [2, 0]); + hideMenu: function(delay) { + var me = this; + + if (me.menu) { + clearTimeout(me.expandMenuTimer); + me.hideMenuTimer = Ext.defer(me.deferHideMenu, Ext.isNumber(delay) ? delay : me.menuHideDelay, me); + } }, - - setMinValue : function(v){ - this.slider.setMinValue(v); - return this; + initComponent: function() { + var me = this, + prefix = Ext.baseCSSPrefix, + cls = [prefix + 'menu-item']; + + me.addEvents( + + 'activate', + + + 'click', + + + 'deactivate' + ); + + if (me.plain) { + cls.push(prefix + 'menu-item-plain'); + } + + if (me.cls) { + cls.push(me.cls); + } + + me.cls = cls.join(' '); + + if (me.menu) { + me.menu = Ext.menu.Manager.get(me.menu); + } + + me.callParent(arguments); }, - - setMaxValue : function(v){ - this.slider.setMaxValue(v); - return this; + onClick: function(e) { + var me = this; + + if (!me.href) { + e.stopEvent(); + } + + if (me.disabled) { + return; + } + + if (me.hideOnClick) { + me.deferHideParentMenusTimer = Ext.defer(me.deferHideParentMenus, me.clickHideDelay, me); + } + + Ext.callback(me.handler, me.scope || me, [me, e]); + me.fireEvent('click', me, e); + + if (!me.hideOnClick) { + me.focus(); + } }, - - setValue : function(v, animate, silent){ + onDestroy: function() { + var me = this; + clearTimeout(me.expandMenuTimer); + clearTimeout(me.hideMenuTimer); + clearTimeout(me.deferHideParentMenusTimer); - if(!silent){ - this.slider.setValue(v, animate); + if (me.menu) { + delete me.menu.parentItem; + delete me.menu.parentMenu; + delete me.menu.ownerCt; + if (me.destroyMenu !== false) { + me.menu.destroy(); + } } - return Ext.form.SliderField.superclass.setValue.call(this, this.slider.getValue()); + me.callParent(arguments); }, - - getValue : function(){ - return this.slider.getValue(); - } -}); - -Ext.reg('sliderfield', Ext.form.SliderField); -Ext.form.Label = Ext.extend(Ext.BoxComponent, { + onRender: function(ct, pos) { + var me = this, + prefix = '.' + Ext.baseCSSPrefix; + + Ext.applyIf(me.renderData, { + href: me.href || '#', + hrefTarget: me.hrefTarget, + icon: me.icon || Ext.BLANK_IMAGE_URL, + iconCls: me.iconCls, + menu: Ext.isDefined(me.menu), + plain: me.plain, + text: me.text + }); + + Ext.applyIf(me.renderSelectors, { + itemEl: prefix + 'menu-item-link', + iconEl: prefix + 'menu-item-icon', + textEl: prefix + 'menu-item-text', + arrowEl: prefix + 'menu-item-arrow' + }); + + me.callParent(arguments); + }, + setHandler: function(fn, scope) { + this.handler = fn || null; + this.scope = scope; + }, - - onRender : function(ct, position){ - if(!this.el){ - this.el = document.createElement('label'); - this.el.id = this.getId(); - this.el.innerHTML = this.text ? Ext.util.Format.htmlEncode(this.text) : (this.html || ''); - if(this.forId){ - this.el.setAttribute('for', this.forId); + setIconCls: function(iconCls) { + var me = this; + + if (me.iconEl) { + if (me.iconCls) { + me.iconEl.removeCls(me.iconCls); + } + + if (iconCls) { + me.iconEl.addCls(iconCls); } } - Ext.form.Label.superclass.onRender.call(this, ct, position); + + me.iconCls = iconCls; }, - - setText : function(t, encode){ - var e = encode === false; - this[!e ? 'text' : 'html'] = t; - delete this[e ? 'text' : 'html']; - if(this.rendered){ - this.el.dom.innerHTML = encode !== false ? Ext.util.Format.htmlEncode(t) : t; + + setText: function(text) { + var me = this, + el = me.textEl || me.el, + newWidth; + + if (text && el) { + el.update(text); + + if (me.textEl) { + + newWidth = me.textEl.getWidth() + me.iconEl.getWidth() + 25 + (me.arrowEl ? me.arrowEl.getWidth() : 0); + if (newWidth > me.itemEl.getWidth()) { + me.parentMenu.setWidth(newWidth); + } + } + } else if (el) { + el.update(''); } - return this; + + me.text = text; } }); -Ext.reg('label', Ext.form.Label); -Ext.form.Action = function(form, options){ - this.form = form; - this.options = options || {}; -}; - - -Ext.form.Action.CLIENT_INVALID = 'client'; - -Ext.form.Action.SERVER_INVALID = 'server'; - -Ext.form.Action.CONNECT_FAILURE = 'connect'; -Ext.form.Action.LOAD_FAILURE = 'load'; -Ext.form.Action.prototype = { - - - - - - - - - - - - - - - type : 'default', - - - +Ext.define('Ext.menu.CheckItem', { + extend: 'Ext.menu.Item', + alias: 'widget.menucheckitem', - run : function(options){ - - }, + checkedCls: Ext.baseCSSPrefix + 'menu-item-checked', + + uncheckedCls: Ext.baseCSSPrefix + 'menu-item-unchecked', + + groupCls: Ext.baseCSSPrefix + 'menu-group-icon', - success : function(response){ + hideOnClick: false, + afterRender: function() { + var me = this; + this.callParent(); + me.checked = !me.checked; + me.setChecked(!me.checked, true); }, - - handleResponse : function(response){ + initComponent: function() { + var me = this; + me.addEvents( + + 'beforecheckchange', - }, + + 'checkchange' + ); - - failure : function(response){ - this.response = response; - this.failureType = Ext.form.Action.CONNECT_FAILURE; - this.form.afterAction(this, false); - }, + me.callParent(arguments); - - - - processResponse : function(response){ - this.response = response; - if(!response.responseText && !response.responseXML){ - return true; - } - this.result = this.handleResponse(response); - return this.result; - }, + Ext.menu.Manager.registerCheckable(me); - - getUrl : function(appendParams){ - var url = this.options.url || this.form.url || this.form.el.dom.action; - if(appendParams){ - var p = this.getParams(); - if(p){ - url = Ext.urlAppend(url, p); + if (me.group) { + if (!me.iconCls) { + me.iconCls = me.groupCls; + } + if (me.initialConfig.hideOnClick !== false) { + me.hideOnClick = true; } } - return url; }, - getMethod : function(){ - return (this.options.method || this.form.method || this.form.el.dom.method || 'POST').toUpperCase(); - }, + disableCheckChange: function() { + var me = this; - - getParams : function(){ - var bp = this.form.baseParams; - var p = this.options.params; - if(p){ - if(typeof p == "object"){ - p = Ext.urlEncode(Ext.applyIf(p, bp)); - }else if(typeof p == 'string' && bp){ - p += '&' + Ext.urlEncode(bp); - } - }else if(bp){ - p = Ext.urlEncode(bp); - } - return p; + me.iconEl.addCls(me.disabledCls); + me.checkChangeDisabled = true; }, - createCallback : function(opts){ - var opts = opts || {}; - return { - success: this.success, - failure: this.failure, - scope: this, - timeout: (opts.timeout*1000) || (this.form.timeout*1000), - upload: this.form.fileUpload ? this.success : undefined - }; - } -}; - - -Ext.form.Action.Submit = function(form, options){ - Ext.form.Action.Submit.superclass.constructor.call(this, form, options); -}; + enableCheckChange: function() { + var me = this; -Ext.extend(Ext.form.Action.Submit, Ext.form.Action, { - - - type : 'submit', + me.iconEl.removeCls(me.disabledCls); + me.checkChangeDisabled = false; + }, - - run : function(){ - var o = this.options, - method = this.getMethod(), - isGet = method == 'GET'; - if(o.clientValidation === false || this.form.isValid()){ - if (o.submitEmptyText === false) { - var fields = this.form.items, - emptyFields = [], - setupEmptyFields = function(f){ - if (f.el.getValue() == f.emptyText) { - emptyFields.push(f); - f.el.dom.value = ""; - } - if(f.isComposite && f.rendered){ - f.items.each(setupEmptyFields); - } - }; - - fields.each(setupEmptyFields); - } - Ext.Ajax.request(Ext.apply(this.createCallback(o), { - form:this.form.el.dom, - url:this.getUrl(isGet), - method: method, - headers: o.headers, - params:!isGet ? this.getParams() : null, - isUpload: this.form.fileUpload - })); - if (o.submitEmptyText === false) { - Ext.each(emptyFields, function(f) { - if (f.applyEmptyText) { - f.applyEmptyText(); - } - }); - } - }else if (o.clientValidation !== false){ - this.failureType = Ext.form.Action.CLIENT_INVALID; - this.form.afterAction(this, false); + onClick: function(e) { + var me = this; + if(!me.disabled && !me.checkChangeDisabled && !(me.checked && me.group)) { + me.setChecked(!me.checked); } + this.callParent([e]); }, - - success : function(response){ - var result = this.processResponse(response); - if(result === true || result.success){ - this.form.afterAction(this, true); - return; - } - if(result.errors){ - this.form.markInvalid(result.errors); - } - this.failureType = Ext.form.Action.SERVER_INVALID; - this.form.afterAction(this, false); + onDestroy: function() { + Ext.menu.Manager.unregisterCheckable(this); + this.callParent(arguments); }, - handleResponse : function(response){ - if(this.form.errorReader){ - var rs = this.form.errorReader.read(response); - var errors = []; - if(rs.records){ - for(var i = 0, len = rs.records.length; i < len; i++) { - var r = rs.records[i]; - errors[i] = r.data; - } + setChecked: function(checked, suppressEvents) { + var me = this; + if (me.checked !== checked && (suppressEvents || me.fireEvent('beforecheckchange', me, checked) !== false)) { + if (me.el) { + me.el[checked ? 'addCls' : 'removeCls'](me.checkedCls)[!checked ? 'addCls' : 'removeCls'](me.uncheckedCls); } - if(errors.length < 1){ - errors = null; + me.checked = checked; + Ext.menu.Manager.onCheckChange(me, checked); + if (!suppressEvents) { + Ext.callback(me.checkHandler, me.scope, [me, checked]); + me.fireEvent('checkchange', me, checked); } - return { - success : rs.success, - errors : errors - }; } - return Ext.decode(response.responseText); } }); +Ext.define('Ext.menu.KeyNav', { + extend: 'Ext.util.KeyNav', -Ext.form.Action.Load = function(form, options){ - Ext.form.Action.Load.superclass.constructor.call(this, form, options); - this.reader = this.form.reader; -}; - -Ext.extend(Ext.form.Action.Load, Ext.form.Action, { + requires: ['Ext.FocusManager'], - type : 'load', + constructor: function(menu) { + var me = this; - - run : function(){ - Ext.Ajax.request(Ext.apply( - this.createCallback(this.options), { - method:this.getMethod(), - url:this.getUrl(false), - headers: this.options.headers, - params:this.getParams() - })); + me.menu = menu; + me.callParent([menu.el, { + down: me.down, + enter: me.enter, + esc: me.escape, + left: me.left, + right: me.right, + space: me.enter, + tab: me.tab, + up: me.up + }]); }, - - success : function(response){ - var result = this.processResponse(response); - if(result === true || !result.success || !result.data){ - this.failureType = Ext.form.Action.LOAD_FAILURE; - this.form.afterAction(this, false); - return; - } - this.form.clearInvalid(); - this.form.setValues(result.data); - this.form.afterAction(this, true); - }, + down: function(e) { + var me = this, + fi = me.menu.focusedItem; - - handleResponse : function(response){ - if(this.form.reader){ - var rs = this.form.reader.read(response); - var data = rs.records && rs.records[0] ? rs.records[0].data : null; - return { - success : rs.success, - data : data - }; + if (fi && e.getKey() == Ext.EventObject.DOWN && me.isWhitelisted(fi)) { + return true; } - return Ext.decode(response.responseText); - } -}); - - + me.focusNextItem(1); + }, + enter: function(e) { + var menu = this.menu; -Ext.form.Action.DirectLoad = Ext.extend(Ext.form.Action.Load, { - constructor: function(form, opts) { - Ext.form.Action.DirectLoad.superclass.constructor.call(this, form, opts); + if (menu.activeItem) { + menu.onClick(e); + } }, - type : 'directload', - run : function(){ - var args = this.getParams(); - args.push(this.success, this); - this.form.api.load.apply(window, args); + escape: function(e) { + Ext.menu.Manager.hideAll(); }, - getParams : function() { - var buf = [], o = {}; - var bp = this.form.baseParams; - var p = this.options.params; - Ext.apply(o, p, bp); - var paramOrder = this.form.paramOrder; - if(paramOrder){ - for(var i = 0, len = paramOrder.length; i < len; i++){ - buf.push(o[paramOrder[i]]); + focusNextItem: function(step) { + var menu = this.menu, + items = menu.items, + focusedItem = menu.focusedItem, + startIdx = focusedItem ? items.indexOf(focusedItem) : -1, + idx = startIdx + step; + + while (idx != startIdx) { + if (idx < 0) { + idx = items.length - 1; + } else if (idx >= items.length) { + idx = 0; + } + + var item = items.getAt(idx); + if (menu.canActivateItem(item)) { + menu.setActiveItem(item); + break; } - }else if(this.form.paramsAsHash){ - buf.push(o); + idx += step; } - return buf; }, - - - - processResponse : function(result) { - this.result = result; - return result; + + isWhitelisted: function(item) { + return Ext.FocusManager.isWhitelisted(item); }, - success : function(response, trans){ - if(trans.type == Ext.Direct.exceptions.SERVER){ - response = {}; - } - Ext.form.Action.DirectLoad.superclass.success.call(this, response); - } -}); + left: function(e) { + var menu = this.menu, + fi = menu.focusedItem, + ai = menu.activeItem; + if (fi && this.isWhitelisted(fi)) { + return true; + } -Ext.form.Action.DirectSubmit = Ext.extend(Ext.form.Action.Submit, { - constructor : function(form, opts) { - Ext.form.Action.DirectSubmit.superclass.constructor.call(this, form, opts); - }, - type : 'directsubmit', - - run : function(){ - var o = this.options; - if(o.clientValidation === false || this.form.isValid()){ - - - this.success.params = this.getParams(); - this.form.api.submit(this.form.el.dom, this.success, this); - }else if (o.clientValidation !== false){ - this.failureType = Ext.form.Action.CLIENT_INVALID; - this.form.afterAction(this, false); + menu.hide(); + if (menu.parentMenu) { + menu.parentMenu.focus(); } }, - getParams : function() { - var o = {}; - var bp = this.form.baseParams; - var p = this.options.params; - Ext.apply(o, p, bp); - return o; - }, - - - - processResponse : function(result) { - this.result = result; - return result; - }, + right: function(e) { + var menu = this.menu, + fi = menu.focusedItem, + ai = menu.activeItem, + am; - success : function(response, trans){ - if(trans.type == Ext.Direct.exceptions.SERVER){ - response = {}; + if (fi && this.isWhitelisted(fi)) { + return true; } - Ext.form.Action.DirectSubmit.superclass.success.call(this, response); - } -}); - -Ext.form.Action.ACTION_TYPES = { - 'load' : Ext.form.Action.Load, - 'submit' : Ext.form.Action.Submit, - 'directload' : Ext.form.Action.DirectLoad, - 'directsubmit' : Ext.form.Action.DirectSubmit -}; -Ext.form.VTypes = function(){ - - var alpha = /^[a-zA-Z_]+$/, - alphanum = /^[a-zA-Z0-9_]+$/, - email = /^(\w+)([\-+.][\w]+)*@(\w[\-\w]*\.){1,5}([A-Za-z]){2,6}$/, - url = /(((^https?)|(^ftp)):\/\/([\-\w]+\.)+\w{2,3}(\/[%\-\w]+(\.\w{2,})?)*(([\w\-\.\?\\\/+@&#;`~=%!]*)(\.\w{2,})?)*\/?)/i; + if (ai) { + am = menu.activeItem.menu; + if (am) { + ai.expandMenu(0); + Ext.defer(function() { + am.setActiveItem(am.items.getAt(0)); + }, 25); + } + } + }, - - return { - - 'email' : function(v){ - return email.test(v); - }, - - 'emailText' : 'This field should be an e-mail address in the format "user@example.com"', - - 'emailMask' : /[a-z0-9_\.\-@\+]/i, + tab: function(e) { + var me = this; - - 'url' : function(v){ - return url.test(v); - }, - - 'urlText' : 'This field should be a URL in the format "http:/'+'/www.example.com"', + if (e.shiftKey) { + me.up(e); + } else { + me.down(e); + } + }, - - 'alpha' : function(v){ - return alpha.test(v); - }, - - 'alphaText' : 'This field should only contain letters and _', - - 'alphaMask' : /[a-z_]/i, + up: function(e) { + var me = this, + fi = me.menu.focusedItem; - - 'alphanum' : function(v){ - return alphanum.test(v); - }, - - 'alphanumText' : 'This field should only contain letters, numbers and _', - - 'alphanumMask' : /[a-z0-9_]/i - }; -}(); + if (fi && e.getKey() == Ext.EventObject.UP && me.isWhitelisted(fi)) { + return true; + } + me.focusNextItem(-1); + } +}); -Ext.grid.GridPanel = Ext.extend(Ext.Panel, { - - autoExpandColumn : false, - - - autoExpandMax : 1000, - +Ext.define('Ext.menu.Separator', { + extend: 'Ext.menu.Item', + alias: 'widget.menuseparator', - autoExpandMin : 50, - - - columnLines : false, + canActivate: false, + - ddText : '{0} selected row{1}', + + + focusable: false, + - deferRowRender : true, - enableColumnHide : true, + hideOnClick: false, - enableColumnMove : true, - enableDragDrop : false, - enableHdMenu : true, - loadMask : false, - minColumnWidth : 25, + plain: true, + separatorCls: Ext.baseCSSPrefix + 'menu-item-separator', - stripeRows : false, + text: ' ', - trackMouseOver : true, + onRender: function(ct, pos) { + var me = this, + sepCls = me.separatorCls; + + me.cls += ' ' + sepCls; + + Ext.applyIf(me.renderSelectors, { + itemSepEl: '.' + sepCls + }); + + me.callParent(arguments); + } +}); + +Ext.define('Ext.menu.Menu', { + extend: 'Ext.panel.Panel', + alias: 'widget.menu', + requires: [ + 'Ext.layout.container.Fit', + 'Ext.layout.container.VBox', + 'Ext.menu.CheckItem', + 'Ext.menu.Item', + 'Ext.menu.KeyNav', + 'Ext.menu.Manager', + 'Ext.menu.Separator' + ], + + allowOtherMenus: false, + - stateEvents : ['columnmove', 'columnresize', 'sortchange', 'groupchange'], + ariaRole: 'menu', + + - view : null, + defaultAlign: 'tl-bl?', - bubbleEvents: [], + floating: true, + constrain: false, - rendered : false, + hidden: true, + + ignoreParentClicks: false, + + isMenu: true, + - viewReady : false, - initComponent : function() { - Ext.grid.GridPanel.superclass.initComponent.call(this); + showSeparator : true, - if (this.columnLines) { - this.cls = (this.cls || '') + ' x-grid-with-col-lines'; - } - - - this.autoScroll = false; - this.autoWidth = false; + + minWidth: 120, - if(Ext.isArray(this.columns)){ - this.colModel = new Ext.grid.ColumnModel(this.columns); - delete this.columns; - } + - - if(this.ds){ - this.store = this.ds; - delete this.ds; - } - if(this.cm){ - this.colModel = this.cm; - delete this.cm; - } - if(this.sm){ - this.selModel = this.sm; - delete this.sm; - } - this.store = Ext.StoreMgr.lookup(this.store); + initComponent: function() { + var me = this, + prefix = Ext.baseCSSPrefix; - this.addEvents( - + me.addEvents( 'click', - - 'dblclick', - - 'contextmenu', - - 'mousedown', - - 'mouseup', - - 'mouseover', - - 'mouseout', - - 'keypress', - - 'keydown', - - 'cellmousedown', - - 'rowmousedown', - - 'headermousedown', + 'mouseenter', - 'groupmousedown', + 'mouseleave', - 'rowbodymousedown', + 'mouseover' + ); - - 'containermousedown', + Ext.menu.Manager.register(me); - - 'cellclick', - - 'celldblclick', - - 'rowclick', - - 'rowdblclick', - - 'headerclick', - - 'headerdblclick', - - 'groupclick', - - 'groupdblclick', - - 'containerclick', - - 'containerdblclick', + + var cls = [prefix + 'menu']; + if (me.plain) { + cls.push(prefix + 'menu-plain'); + } + me.cls = cls.join(' '); - - 'rowbodyclick', - - 'rowbodydblclick', + + var bodyCls = me.bodyCls ? [me.bodyCls] : []; + bodyCls.unshift(prefix + 'menu-body'); + me.bodyCls = bodyCls.join(' '); + + + + + me.layout = { + type: 'vbox', + align: 'stretchmax', + autoSize: true, + clearInnerCtOnLayout: true, + overflowHandler: 'Scroller' + }; + + + if (me.floating === false && me.initialConfig.hidden !== true) { + me.hidden = false; + } + + me.callParent(arguments); + + me.on('beforeshow', function() { + var hasItems = !!me.items.length; - 'rowcontextmenu', - - 'cellcontextmenu', - - 'headercontextmenu', - - 'groupcontextmenu', - - 'containercontextmenu', - - 'rowbodycontextmenu', - - 'bodyscroll', - - 'columnresize', - - 'columnmove', - - 'sortchange', - - 'groupchange', - 'reconfigure', - 'viewready' - ); + if (hasItems && me.rendered) { + me.el.setStyle('visibility', null); + } + return hasItems; + }); }, - - onRender : function(ct, position){ - Ext.grid.GridPanel.superclass.onRender.apply(this, arguments); + afterRender: function(ct) { + var me = this, + prefix = Ext.baseCSSPrefix, + space = ' '; - var c = this.getGridEl(); + me.callParent(arguments); - this.el.addClass('x-grid-panel'); + + if (me.showSeparator) { + me.iconSepEl = me.layout.getRenderTarget().insertFirst({ + cls: prefix + 'menu-icon-separator', + html: space + }); + } - this.mon(c, { - scope: this, - mousedown: this.onMouseDown, - click: this.onClick, - dblclick: this.onDblClick, - contextmenu: this.onContextMenu + me.focusEl = me.el.createChild({ + cls: prefix + 'menu-focus', + tabIndex: '-1', + html: space }); - this.relayEvents(c, ['mousedown','mouseup','mouseover','mouseout','keypress', 'keydown']); - - var view = this.getView(); - view.init(this); - view.render(); - this.getSelectionModel().init(this); - }, - - - initEvents : function(){ - Ext.grid.GridPanel.superclass.initEvents.call(this); + me.mon(me.el, { + click: me.onClick, + mouseover: me.onMouseOver, + scope: me + }); + me.mouseMonitor = me.el.monitorMouseLeave(100, me.onMouseLeave, me); - if(this.loadMask){ - this.loadMask = new Ext.LoadMask(this.bwrap, - Ext.apply({store:this.store}, this.loadMask)); + if (me.showSeparator && ((!Ext.isStrict && Ext.isIE) || Ext.isIE6)) { + me.iconSepEl.setHeight(me.el.getHeight()); } - }, - initStateEvents : function(){ - Ext.grid.GridPanel.superclass.initStateEvents.call(this); - this.mon(this.colModel, 'hiddenchange', this.saveState, this, {delay: 100}); + me.keyNav = Ext.create('Ext.menu.KeyNav', me); }, - applyState : function(state){ - var cm = this.colModel, - cs = state.columns, - store = this.store, - s, - c, - colIndex; - - if(cs){ - for(var i = 0, len = cs.length; i < len; i++){ - s = cs[i]; - c = cm.getColumnById(s.id); - if(c){ - colIndex = cm.getIndexById(s.id); - cm.setState(colIndex, { - hidden: s.hidden, - width: s.width, - sortable: s.sortable - }); - if(colIndex != i){ - cm.moveColumn(colIndex, i); - } - } - } - } - if(store){ - s = state.sort; - if(s){ - store[store.remoteSort ? 'setDefaultSort' : 'sort'](s.field, s.direction); - } - s = state.group; - if(store.groupBy){ - if(s){ - store.groupBy(s); - }else{ - store.clearGrouping(); - } - } + afterLayout: function() { + var me = this; + me.callParent(arguments); - } - var o = Ext.apply({}, state); - delete o.columns; - delete o.sort; - Ext.grid.GridPanel.superclass.applyState.call(this, o); - }, + + + + + if ((!Ext.iStrict && Ext.isIE) || Ext.isIE6) { + var innerCt = me.layout.getRenderTarget(), + innerCtWidth = 0, + dis = me.dockedItems, + l = dis.length, + i = 0, + di, clone, newWidth; - getState : function(){ - var o = {columns: []}, - store = this.store, - ss, - gs; + innerCtWidth = innerCt.getWidth(); - for(var i = 0, c; (c = this.colModel.config[i]); i++){ - o.columns[i] = { - id: c.id, - width: c.width - }; - if(c.hidden){ - o.columns[i].hidden = true; - } - if(c.sortable){ - o.columns[i].sortable = true; - } - } - if(store){ - ss = store.getSortState(); - if(ss){ - o.sort = ss; - } - if(store.getGroupState){ - gs = store.getGroupState(); - if(gs){ - o.group = gs; + newWidth = innerCtWidth + me.body.getBorderWidth('lr') + me.body.getPadding('lr'); + + + me.body.setWidth(newWidth); + + + for (; i < l, di = dis.getAt(i); i++) { + if (di.dock == 'left' || di.dock == 'right') { + newWidth += di.getWidth(); } } + me.el.setWidth(newWidth); } - return o; }, - afterRender : function(){ - Ext.grid.GridPanel.superclass.afterRender.call(this); - var v = this.view; - this.on('bodyresize', v.layout, v); - v.layout(true); - if(this.deferRowRender){ - if (!this.deferRowRenderTask){ - this.deferRowRenderTask = new Ext.util.DelayedTask(v.afterRender, this.view); - } - this.deferRowRenderTask.delay(10); - }else{ - v.afterRender(); - } - this.viewReady = true; + canActivateItem: function(item) { + return item && !item.isDisabled() && item.isVisible() && (item.canActivate || item.getXTypes().indexOf('menuitem') < 0); }, - reconfigure : function(store, colModel){ - var rendered = this.rendered; - if(rendered){ - if(this.loadMask){ - this.loadMask.destroy(); - this.loadMask = new Ext.LoadMask(this.bwrap, - Ext.apply({}, {store:store}, this.initialConfig.loadMask)); + deactivateActiveItem: function() { + var me = this; + + if (me.activeItem) { + me.activeItem.deactivate(); + if (!me.activeItem.activated) { + delete me.activeItem; } } - if(this.view){ - this.view.initData(store, colModel); - } - this.store = store; - this.colModel = colModel; - if(rendered){ - this.view.refresh(true); + if (me.focusedItem) { + me.focusedItem.blur(); + if (!me.focusedItem.$focused) { + delete me.focusedItem; + } } - this.fireEvent('reconfigure', this, store, colModel); }, - onDestroy : function(){ - if (this.deferRowRenderTask && this.deferRowRenderTask.cancel){ - this.deferRowRenderTask.cancel(); - } - if(this.rendered){ - Ext.destroy(this.view, this.loadMask); - }else if(this.store && this.store.autoDestroy){ - this.store.destroy(); - } - Ext.destroy(this.colModel, this.selModel); - this.store = this.selModel = this.colModel = this.view = this.loadMask = null; - Ext.grid.GridPanel.superclass.onDestroy.call(this); + getFocusEl: function() { + return this.focusEl; }, - processEvent : function(name, e){ - this.view.processEvent(name, e); + hide: function() { + this.deactivateActiveItem(); + this.callParent(arguments); }, - onClick : function(e){ - this.processEvent('click', e); + getItemFromEvent: function(e) { + return this.getChildByElement(e.getTarget()); }, - - onMouseDown : function(e){ - this.processEvent('mousedown', e); - }, + lookupComponent: function(cmp) { + var me = this; - - onContextMenu : function(e, t){ - this.processEvent('contextmenu', e); - }, + if (Ext.isString(cmp)) { + cmp = me.lookupItemFromString(cmp); + } else if (Ext.isObject(cmp)) { + cmp = me.lookupItemFromObject(cmp); + } - - onDblClick : function(e){ - this.processEvent('dblclick', e); + + + cmp.minWidth = cmp.minWidth || me.minWidth; + + return cmp; }, - walkCells : function(row, col, step, fn, scope){ - var cm = this.colModel, - clen = cm.getColumnCount(), - ds = this.store, - rlen = ds.getCount(), - first = true; + lookupItemFromObject: function(cmp) { + var me = this, + prefix = Ext.baseCSSPrefix; - if(step < 0){ - if(col < 0){ - row--; - first = false; - } - while(row >= 0){ - if(!first){ - col = clen-1; - } - first = false; - while(col >= 0){ - if(fn.call(scope || this, row, col, cm) === true){ - return [row, col]; - } - col--; - } - row--; - } - } else { - if(col >= clen){ - row++; - first = false; - } - while(row < rlen){ - if(!first){ - col = 0; - } - first = false; - while(col < clen){ - if(fn.call(scope || this, row, col, cm) === true){ - return [row, col]; - } - col++; - } - row++; + if (!cmp.isComponent) { + if (!cmp.xtype) { + cmp = Ext.create('Ext.menu.' + (Ext.isBoolean(cmp.checked) ? 'Check': '') + 'Item', cmp); + } else { + cmp = Ext.ComponentManager.create(cmp, cmp.xtype); } } - return null; - }, - - - getGridEl : function(){ - return this.body; - }, - - - stopEditing : Ext.emptyFn, - - getSelectionModel : function(){ - if(!this.selModel){ - this.selModel = new Ext.grid.RowSelectionModel( - this.disableSelection ? {selectRow: Ext.emptyFn} : null); + if (cmp.isMenuItem) { + cmp.parentMenu = me; } - return this.selModel; - }, - - getStore : function(){ - return this.store; - }, + if (!cmp.isMenuItem && !cmp.dock) { + var cls = [ + prefix + 'menu-item', + prefix + 'menu-item-cmp' + ], + intercept = Ext.Function.createInterceptor; - - getColumnModel : function(){ - return this.colModel; - }, + + cmp.focus = intercept(cmp.focus, function() { + this.$focused = true; + }, cmp); + cmp.blur = intercept(cmp.blur, function() { + this.$focused = false; + }, cmp); - - getView : function() { - if (!this.view) { - this.view = new Ext.grid.GridView(this.viewConfig); + if (!me.plain && (cmp.indent === true || cmp.iconCls === 'no-icon')) { + cls.push(prefix + 'menu-item-indent'); + } + + if (cmp.rendered) { + cmp.el.addCls(cls); + } else { + cmp.cls = (cmp.cls ? cmp.cls : '') + ' ' + cls.join(' '); + } + cmp.isMenuItem = true; } - - return this.view; + return cmp; }, - - getDragDropText : function(){ - var count = this.selModel.getCount(); - return String.format(this.ddText, count, count == 1 ? '' : 's'); - } - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + lookupItemFromString: function(cmp) { + return (cmp == 'separator' || cmp == '-') ? + Ext.createWidget('menuseparator') + : Ext.createWidget('menuitem', { + canActivate: false, + hideOnClick: false, + plain: true, + text: cmp + }); + }, + onClick: function(e) { + var me = this, + item; - - - - - - - - - - - - - - - - -}); -Ext.reg('grid', Ext.grid.GridPanel); -Ext.grid.PivotGrid = Ext.extend(Ext.grid.GridPanel, { - - - aggregator: 'sum', - - - renderer: undefined, - - - - - - - - - initComponent: function() { - Ext.grid.PivotGrid.superclass.initComponent.apply(this, arguments); - - this.initAxes(); - - - this.enableColumnResize = false; - - this.viewConfig = Ext.apply(this.viewConfig || {}, { - forceFit: true - }); - - - - this.colModel = new Ext.grid.ColumnModel({}); - }, - - - getAggregator: function() { - if (typeof this.aggregator == 'string') { - return Ext.grid.PivotAggregatorMgr.types[this.aggregator]; - } else { - return this.aggregator; + if (me.disabled) { + e.stopEvent(); + return; + } + + if ((e.getTarget() == me.focusEl.dom) || e.within(me.layout.getRenderTarget())) { + item = me.getItemFromEvent(e) || me.activeItem; + + if (item) { + if (item.getXTypes().indexOf('menuitem') >= 0) { + if (!item.menu || !me.ignoreParentClicks) { + item.onClick(e); + } else { + e.stopEvent(); + } + } + } + me.fireEvent('click', me, item, e); } }, - - - setAggregator: function(aggregator) { - this.aggregator = aggregator; - }, - - - setMeasure: function(measure) { - this.measure = measure; - }, - - - setLeftAxis: function(axis, refresh) { - - this.leftAxis = axis; - - if (refresh) { - this.view.refresh(); + + onDestroy: function() { + var me = this; + + Ext.menu.Manager.unregister(me); + if (me.rendered) { + me.el.un(me.mouseMonitor); + me.keyNav.destroy(); + delete me.keyNav; } + me.callParent(arguments); }, - - - setTopAxis: function(axis, refresh) { - - this.topAxis = axis; - - if (refresh) { - this.view.refresh(); + + onMouseLeave: function(e) { + var me = this; + + me.deactivateActiveItem(); + + if (me.disabled) { + return; } + + me.fireEvent('mouseleave', me, e); }, - - - initAxes: function() { - var PivotAxis = Ext.grid.PivotAxis; - - if (!(this.leftAxis instanceof PivotAxis)) { - this.setLeftAxis(new PivotAxis({ - orientation: 'vertical', - dimensions : this.leftAxis || [], - store : this.store - })); - }; - - if (!(this.topAxis instanceof PivotAxis)) { - this.setTopAxis(new PivotAxis({ - orientation: 'horizontal', - dimensions : this.topAxis || [], - store : this.store - })); - }; - }, - - - extractData: function() { - var records = this.store.data.items, - recCount = records.length, - cells = [], - record, i, j, k; - - if (recCount == 0) { - return []; + + onMouseOver: function(e) { + var me = this, + fromEl = e.getRelatedTarget(), + mouseEnter = !me.el.contains(fromEl), + item = me.getItemFromEvent(e); + + if (mouseEnter && me.parentMenu) { + me.parentMenu.setActiveItem(me.parentItem); + me.parentMenu.mouseMonitor.mouseenter(); } - - var leftTuples = this.leftAxis.getTuples(), - leftCount = leftTuples.length, - topTuples = this.topAxis.getTuples(), - topCount = topTuples.length, - aggregator = this.getAggregator(); - - for (i = 0; i < recCount; i++) { - record = records[i]; - - for (j = 0; j < leftCount; j++) { - cells[j] = cells[j] || []; - - if (leftTuples[j].matcher(record) === true) { - for (k = 0; k < topCount; k++) { - cells[j][k] = cells[j][k] || []; - - if (topTuples[k].matcher(record)) { - cells[j][k].push(record); - } + + if (me.disabled) { + return; + } + + if (item) { + me.setActiveItem(item); + if (item.activated && item.expandMenu) { + item.expandMenu(); + } + } + if (mouseEnter) { + me.fireEvent('mouseenter', me, e); + } + me.fireEvent('mouseover', me, item, e); + }, + + setActiveItem: function(item) { + var me = this; + + if (item && (item != me.activeItem && item != me.focusedItem)) { + me.deactivateActiveItem(); + if (me.canActivateItem(item)) { + if (item.activate) { + item.activate(); + if (item.activated) { + me.activeItem = item; + me.focusedItem = item; + me.focus(); } + } else { + item.focus(); + me.focusedItem = item; } } + item.el.scrollIntoView(me.layout.getRenderTarget()); } - - var rowCount = cells.length, - colCount, row; - - for (i = 0; i < rowCount; i++) { - row = cells[i]; - colCount = row.length; + }, + + + showBy: function(cmp, pos, off) { + var me = this; + + if (me.floating && cmp) { + me.layout.autoSize = true; + me.show(); + - for (j = 0; j < colCount; j++) { - cells[i][j] = aggregator(cells[i][j], this.measure); + cmp = cmp.el || cmp; + + + var xy = me.el.getAlignToXY(cmp, pos || me.defaultAlign, off); + if (me.floatParent) { + var r = me.floatParent.getTargetEl().getViewRegion(); + xy[0] -= r.x; + xy[1] -= r.y; } + me.showAt(xy); + me.doConstrain(); } - - return cells; + return me; }, - - - getView: function() { - if (!this.view) { - this.view = new Ext.grid.PivotGridView(this.viewConfig); + + doConstrain : function() { + var me = this, + y = this.el.getY(), + max, full, + returnY = y, normalY, parentEl, scrollTop, viewHeight; + + delete me.height; + me.setSize(); + full = me.getHeight(); + if (me.floating) { + parentEl = Ext.fly(me.el.dom.parentNode); + scrollTop = parentEl.getScroll().top; + viewHeight = parentEl.getViewSize().height; + + + normalY = y - scrollTop; + max = me.maxHeight ? me.maxHeight : viewHeight - normalY; + if (full > viewHeight) { + max = viewHeight; + + returnY = y - normalY; + } else if (max < full) { + returnY = y - (full - max); + max = full; + } + }else{ + max = me.getHeight(); } - return this.view; + if (me.maxHeight){ + max = Math.min(me.maxHeight, max); + } + if (full > max && max > 0){ + me.layout.autoSize = false; + me.setHeight(max); + if (me.showSeparator){ + me.iconSepEl.setHeight(me.layout.getRenderTarget().dom.scrollHeight); + } + } + me.el.setY(returnY); } }); -Ext.reg('pivotgrid', Ext.grid.PivotGrid); + Ext.define('Ext.menu.ColorPicker', { + extend: 'Ext.menu.Menu', + alias: 'widget.colormenu', -Ext.grid.PivotAggregatorMgr = new Ext.AbstractManager(); + requires: [ + 'Ext.picker.Color' + ], -Ext.grid.PivotAggregatorMgr.registerType('sum', function(records, measure) { - var length = records.length, - total = 0, - i; - for (i = 0; i < length; i++) { - total += records[i].get(measure); - } - - return total; -}); + hideOnClick : true, -Ext.grid.PivotAggregatorMgr.registerType('avg', function(records, measure) { - var length = records.length, - total = 0, - i; - - for (i = 0; i < length; i++) { - total += records[i].get(measure); - } - return (total / length) || 'n/a'; -}); + pickerId : null, -Ext.grid.PivotAggregatorMgr.registerType('min', function(records, measure) { - var data = [], - length = records.length, - i; - - for (i = 0; i < length; i++) { - data.push(records[i].get(measure)); - } - return Math.min.apply(this, data) || 'n/a'; -}); -Ext.grid.PivotAggregatorMgr.registerType('max', function(records, measure) { - var data = [], - length = records.length, - i; - - for (i = 0; i < length; i++) { - data.push(records[i].get(measure)); - } - return Math.max.apply(this, data) || 'n/a'; -}); -Ext.grid.PivotAggregatorMgr.registerType('count', function(records, measure) { - return records.length; -}); -Ext.grid.GridView = Ext.extend(Ext.util.Observable, { - + initComponent : function(){ + var me = this; - + Ext.apply(me, { + plain: true, + showSeparator: false, + items: Ext.applyIf({ + cls: Ext.baseCSSPrefix + 'menu-color-item', + id: me.pickerId, + xtype: 'colorpicker' + }, me.initialConfig) + }); - + me.callParent(arguments); - - deferEmptyText : true, + me.picker = me.down('colorpicker'); - - scrollOffset : undefined, + + me.relayEvents(me.picker, ['select']); - - autoFill : false, + if (me.hideOnClick) { + me.on('select', me.hidePickerOnSelect, me); + } + }, - forceFit : false, + hidePickerOnSelect: function() { + Ext.menu.Manager.hideAll(); + } + }); - - sortClasses : ['sort-asc', 'sort-desc'], + Ext.define('Ext.menu.DatePicker', { + extend: 'Ext.menu.Menu', - - sortAscText : 'Sort Ascending', + alias: 'widget.datemenu', - - sortDescText : 'Sort Descending', + requires: [ + 'Ext.picker.Date' + ], - columnsText : 'Columns', + hideOnClick : true, - selectedRowClass : 'x-grid3-row-selected', + pickerId : null, - borderWidth : 2, - tdClass : 'x-grid3-cell', - hdCls : 'x-grid3-hd', - - - - markDirty : true, - cellSelectorDepth : 4, - - - rowSelectorDepth : 10, - rowBodySelectorDepth : 10, - cellSelector : 'td.x-grid3-cell', - - - rowSelector : 'div.x-grid3-row', - - rowBodySelector : 'div.x-grid3-row-body', + initComponent : function(){ + var me = this; - - firstRowCls: 'x-grid3-row-first', - lastRowCls: 'x-grid3-row-last', - rowClsRe: /(?:^|\s+)x-grid3-row-(first|last|alt)(?:\s+|$)/g, - - - headerMenuOpenCls: 'x-grid3-hd-menu-open', - - - rowOverCls: 'x-grid3-row-over', + Ext.apply(me, { + showSeparator: false, + plain: true, + items: Ext.applyIf({ + cls: Ext.baseCSSPrefix + 'menu-date-item', + id: me.pickerId, + xtype: 'datepicker' + }, me.initialConfig) + }); - constructor : function(config) { - Ext.apply(this, config); - - - this.addEvents( - - 'beforerowremoved', - - - 'beforerowsinserted', - - - 'beforerefresh', - - - 'rowremoved', - - - 'rowsinserted', - - - 'rowupdated', - - - 'refresh' - ); + me.callParent(arguments); + + me.picker = me.down('datepicker'); - Ext.grid.GridView.superclass.constructor.call(this); + me.relayEvents(me.picker, ['select']); + + if (me.hideOnClick) { + me.on('select', me.hidePickerOnSelect, me); + } }, + hidePickerOnSelect: function() { + Ext.menu.Manager.hideAll(); + } + }); + +Ext.define('Ext.panel.Tool', { + extend: 'Ext.Component', + requires: ['Ext.tip.QuickTipManager'], + alias: 'widget.tool', + + baseCls: Ext.baseCSSPrefix + 'tool', + disabledCls: Ext.baseCSSPrefix + 'tool-disabled', + toolPressedCls: Ext.baseCSSPrefix + 'tool-pressed', + toolOverCls: Ext.baseCSSPrefix + 'tool-over', + ariaRole: 'button', + renderTpl: [''], - masterTpl: new Ext.Template( - '
    ', - '
    ', - '
    ', - '
    ', - '
    {header}
    ', - '
    ', - '
    ', - '
    ', - '
    ', - '
    {body}
    ', - '', - '
    ', - '
    ', - '
     
    ', - '
     
    ', - '
    ' - ), - - headerTpl: new Ext.Template( - '', - '', - '{cells}', - '', - '
    ' - ), - bodyTpl: new Ext.Template('{rows}'), - cellTpl: new Ext.Template( - '', - '
    {value}
    ', - '' - ), - initTemplates : function() { - var templates = this.templates || {}, - template, name, + stopEvent: true, + + initComponent: function() { + var me = this; + me.addEvents( - headerCellTpl = new Ext.Template( - '', - '
    ', - this.grid.enableHdMenu ? '' : '', - '{value}', - '', - '
    ', - '' - ), - - rowBodyText = [ - '', - '', - '
    {body}
    ', - '', - '' - ].join(""), + 'click' + ); - innerText = [ - '', - '', - '{cells}', - this.enableRowBody ? rowBodyText : '', - '', - '
    ' - ].join(""); + var types = [ + 'close', + 'collapse', + 'down', + 'expand', + 'gear', + 'help', + 'left', + 'maximize', + 'minimize', + 'minus', + 'move', + 'next', + 'pin', + 'plus', + 'prev', + 'print', + 'refresh', + 'resize', + 'restore', + 'right', + 'save', + 'search', + 'toggle', + 'unpin', + 'up' + ]; - Ext.applyIf(templates, { - hcell : headerCellTpl, - cell : this.cellTpl, - body : this.bodyTpl, - header : this.headerTpl, - master : this.masterTpl, - row : new Ext.Template('
    ' + innerText + '
    '), - rowInner: new Ext.Template(innerText) - }); - - for (name in templates) { - template = templates[name]; - - if (template && Ext.isFunction(template.compile) && !template.compiled) { - template.disableFormats = true; - template.compile(); - } + if (me.id && Ext.Array.indexOf(types, me.id) > -1) { + Ext.global.console.warn('When specifying a tool you should use the type option, the id can conflict now that tool is a Component'); } + + me.type = me.type || me.id; - this.templates = templates; - this.colRe = new RegExp('x-grid3-td-([^\\s]+)', ''); + Ext.applyIf(me.renderData, { + baseCls: me.baseCls, + blank: Ext.BLANK_IMAGE_URL, + type: me.type + }); + me.renderSelectors.toolEl = '.' + me.baseCls + '-' + me.type; + me.callParent(); }, - fly : function(el) { - if (!this._flyweight) { - this._flyweight = new Ext.Element.Flyweight(document.body); + afterRender: function() { + var me = this; + me.callParent(arguments); + if (me.qtip) { + if (Ext.isObject(me.qtip)) { + Ext.tip.QuickTipManager.register(Ext.apply({ + target: me.id + }, me.qtip)); + } + else { + me.toolEl.dom.qtip = me.qtip; + } } - this._flyweight.dom = el; - return this._flyweight; - }, - - getEditorParent : function() { - return this.scroller.dom; + me.mon(me.toolEl, { + click: me.onClick, + mousedown: me.onMouseDown, + mouseover: me.onMouseOver, + mouseout: me.onMouseOut, + scope: me + }); }, - initElements : function() { - var Element = Ext.Element, - el = Ext.get(this.grid.getGridEl().dom.firstChild), - mainWrap = new Element(el.child('div.x-grid3-viewport')), - mainHd = new Element(mainWrap.child('div.x-grid3-header')), - scroller = new Element(mainWrap.child('div.x-grid3-scroller')); - - if (this.grid.hideHeaders) { - mainHd.setDisplayed(false); - } + setType: function(type) { + var me = this; - if (this.forceFit) { - scroller.setStyle('overflow-x', 'hidden'); + me.type = type; + if (me.rendered) { + me.toolEl.dom.className = me.baseCls + '-' + type; } - - - - Ext.apply(this, { - el : el, - mainWrap: mainWrap, - scroller: scroller, - mainHd : mainHd, - innerHd : mainHd.child('div.x-grid3-header-inner').dom, - mainBody: new Element(Element.fly(scroller).child('div.x-grid3-body')), - focusEl : new Element(Element.fly(scroller).child('a')), - - resizeMarker: new Element(el.child('div.x-grid3-resize-marker')), - resizeProxy : new Element(el.child('div.x-grid3-resize-proxy')) - }); - - this.focusEl.swallowEvent('click', true); + return me; }, - getRows : function() { - return this.hasRows() ? this.mainBody.dom.childNodes : []; + bindTo: function(component) { + this.owner = component; }, - - - findCell : function(el) { - if (!el) { + onClick: function(e, target) { + var me = this, + owner; + + if (me.disabled) { return false; } - return this.fly(el).findParent(this.cellSelector, this.cellSelectorDepth); - }, + owner = me.owner || me.ownerCt; - - findCellIndex : function(el, requiredCls) { - var cell = this.findCell(el), - hasCls; - if (cell) { - hasCls = this.fly(cell).hasClass(requiredCls); - if (!requiredCls || hasCls) { - return this.getCellIndex(cell); - } - } - return false; - }, + me.el.removeCls(me.toolPressedCls); + me.el.removeCls(me.toolOverCls); - - getCellIndex : function(el) { - if (el) { - var match = el.className.match(this.colRe); - - if (match && match[1]) { - return this.cm.getIndexById(match[1]); - } + if (me.stopEvent !== false) { + e.stopEvent(); } - return false; - }, - - findHeaderCell : function(el) { - var cell = this.findCell(el); - return cell && this.fly(cell).hasClass(this.hdCls) ? cell : null; + Ext.callback(me.handler, me.scope || me, [e, target, owner, me]); + me.fireEvent('click', me, e); + return true; }, - - findHeaderIndex : function(el){ - return this.findCellIndex(el, this.hdCls); + + onDestroy: function(){ + if (Ext.isObject(this.tooltip)) { + Ext.tip.QuickTipManager.unregister(this.id); + } + this.callParent(); }, - findRow : function(el) { - if (!el) { + onMouseDown: function() { + if (this.disabled) { return false; } - return this.fly(el).findParent(this.rowSelector, this.rowSelectorDepth); - }, - - findRowIndex : function(el) { - var row = this.findRow(el); - return row ? row.rowIndex : false; + this.el.addCls(this.toolPressedCls); }, - findRowBody : function(el) { - if (!el) { + onMouseOver: function() { + if (this.disabled) { return false; } - - return this.fly(el).findParent(this.rowBodySelector, this.rowBodySelectorDepth); + this.el.addCls(this.toolOverCls); }, + onMouseOut: function() { + this.el.removeCls(this.toolOverCls); + } +}); +Ext.define('Ext.resizer.Handle', { + extend: 'Ext.Component', + handleCls: '', + baseHandleCls: Ext.baseCSSPrefix + 'resizable-handle', - getRow : function(row) { - return this.getRows()[row]; - }, - - getCell : function(row, col) { - return Ext.fly(this.getRow(row)).query(this.cellSelector)[col]; - }, + region: '', - - getHeaderCell : function(index) { - return this.mainHd.dom.getElementsByTagName('td')[index]; - }, + onRender: function() { + this.addCls( + this.baseHandleCls, + this.baseHandleCls + '-' + this.region, + this.handleCls + ); + this.callParent(arguments); + this.el.unselectable(); + } +}); - - - addRowClass : function(rowId, cls) { - var row = this.getRow(rowId); - if (row) { - this.fly(row).addClass(cls); - } +Ext.define('Ext.resizer.Resizer', { + mixins: { + observable: 'Ext.util.Observable' }, + uses: ['Ext.resizer.ResizeTracker', 'Ext.Component'], - - removeRowClass : function(row, cls) { - var r = this.getRow(row); - if(r){ - this.fly(r).removeClass(cls); - } - }, + alternateClassName: 'Ext.Resizable', - - removeRow : function(row) { - Ext.removeNode(this.getRow(row)); - this.syncFocusEl(row); - }, + handleCls: Ext.baseCSSPrefix + 'resizable-handle', + pinnedCls: Ext.baseCSSPrefix + 'resizable-pinned', + overCls: Ext.baseCSSPrefix + 'resizable-over', + proxyCls: Ext.baseCSSPrefix + 'resizable-proxy', + wrapCls: Ext.baseCSSPrefix + 'resizable-wrap', - removeRows : function(firstRow, lastRow) { - var bd = this.mainBody.dom, - rowIndex; - - for (rowIndex = firstRow; rowIndex <= lastRow; rowIndex++){ - Ext.removeNode(bd.childNodes[firstRow]); - } - - this.syncFocusEl(firstRow); - }, + dynamic: true, - - - getScrollState : function() { - var sb = this.scroller.dom; - - return { - left: sb.scrollLeft, - top : sb.scrollTop - }; - }, + handles: 's e se', - restoreScroll : function(state) { - var sb = this.scroller.dom; - sb.scrollLeft = state.left; - sb.scrollTop = state.top; - }, + height : null, - scrollToTop : function() { - var dom = this.scroller.dom; - - dom.scrollTop = 0; - dom.scrollLeft = 0; - }, + width : null, - syncScroll : function() { - this.syncHeaderScroll(); - var mb = this.scroller.dom; - this.grid.fireEvent('bodyscroll', mb.scrollLeft, mb.scrollTop); - }, + minHeight : 20, - syncHeaderScroll : function() { - var innerHd = this.innerHd, - scrollLeft = this.scroller.dom.scrollLeft; - - innerHd.scrollLeft = scrollLeft; - innerHd.scrollLeft = scrollLeft; - }, + minWidth : 20, + + maxHeight : 10000, + - updateSortIcon : function(col, dir) { - var sortClasses = this.sortClasses, - sortClass = sortClasses[dir == "DESC" ? 1 : 0], - headers = this.mainHd.select('td').removeClass(sortClasses); - - headers.item(col).addClass(sortClass); - }, + maxWidth : 10000, - updateAllColumnWidths : function() { - var totalWidth = this.getTotalWidth(), - colCount = this.cm.getColumnCount(), - rows = this.getRows(), - rowCount = rows.length, - widths = [], - row, rowFirstChild, trow, i, j; - - for (i = 0; i < colCount; i++) { - widths[i] = this.getColumnWidth(i); - this.getHeaderCell(i).style.width = widths[i]; - } - - this.updateHeaderWidth(); - - for (i = 0; i < rowCount; i++) { - row = rows[i]; - row.style.width = totalWidth; - rowFirstChild = row.firstChild; - - if (rowFirstChild) { - rowFirstChild.style.width = totalWidth; - trow = rowFirstChild.rows[0]; - - for (j = 0; j < colCount; j++) { - trow.childNodes[j].style.width = widths[j]; - } - } - } - - this.onAllColumnWidthsUpdated(widths, totalWidth); - }, + pinned: false, - updateColumnWidth : function(column, width) { - var columnWidth = this.getColumnWidth(column), - totalWidth = this.getTotalWidth(), - headerCell = this.getHeaderCell(column), - nodes = this.getRows(), - nodeCount = nodes.length, - row, i, firstChild; - - this.updateHeaderWidth(); - headerCell.style.width = columnWidth; - - for (i = 0; i < nodeCount; i++) { - row = nodes[i]; - firstChild = row.firstChild; - - row.style.width = totalWidth; - if (firstChild) { - firstChild.style.width = totalWidth; - firstChild.rows[0].childNodes[column].style.width = columnWidth; - } - } - - this.onColumnWidthUpdated(column, columnWidth, totalWidth); - }, + preserveRatio: false, + + transparent: false, + - updateColumnHidden : function(col, hidden) { - var totalWidth = this.getTotalWidth(), - display = hidden ? 'none' : '', - headerCell = this.getHeaderCell(col), - nodes = this.getRows(), - nodeCount = nodes.length, - row, rowFirstChild, i; - - this.updateHeaderWidth(); - headerCell.style.display = display; - - for (i = 0; i < nodeCount; i++) { - row = nodes[i]; - row.style.width = totalWidth; - rowFirstChild = row.firstChild; - - if (rowFirstChild) { - rowFirstChild.style.width = totalWidth; - rowFirstChild.rows[0].childNodes[col].style.display = display; - } - } - - this.onColumnHiddenUpdated(col, hidden, totalWidth); - delete this.lastViewWidth; - this.layout(); + + possiblePositions: { + n: 'north', + s: 'south', + e: 'east', + w: 'west', + se: 'southeast', + sw: 'southwest', + nw: 'northwest', + ne: 'northeast' }, - doRender : function(columns, records, store, startRow, colCount, stripe) { - var templates = this.templates, - cellTemplate = templates.cell, - rowTemplate = templates.row, - last = colCount - 1, - tstyle = 'width:' + this.getTotalWidth() + ';', - - rowBuffer = [], - colBuffer = [], - rowParams = {tstyle: tstyle}, - meta = {}, - len = records.length, - alt, - column, - record, i, j, rowIndex; - - for (j = 0; j < len; j++) { - record = records[j]; - colBuffer = []; + - rowIndex = j + startRow; + constructor: function(config) { + var me = this, + target, + tag, + handles = me.handles, + handleCls, + possibles, + len, + i = 0, + pos; + this.addEvents( - for (i = 0; i < colCount; i++) { - column = columns[i]; - - meta.id = column.id; - meta.css = i === 0 ? 'x-grid3-cell-first ' : (i == last ? 'x-grid3-cell-last ' : ''); - meta.attr = meta.cellAttr = ''; - meta.style = column.style; - meta.value = column.renderer.call(column.scope, record.data[column.name], meta, record, rowIndex, i, store); - - if (Ext.isEmpty(meta.value)) { - meta.value = ' '; - } - - if (this.markDirty && record.dirty && typeof record.modified[column.name] != 'undefined') { - meta.css += ' x-grid3-dirty-cell'; - } - - colBuffer[colBuffer.length] = cellTemplate.apply(meta); - } - - alt = []; + 'beforeresize', - if (stripe && ((rowIndex + 1) % 2 === 0)) { - alt[0] = 'x-grid3-row-alt'; - } - - if (record.dirty) { - alt[1] = ' x-grid3-dirty-row'; - } - - rowParams.cols = colCount; - - if (this.getRowClass) { - alt[2] = this.getRowClass(record, rowIndex, rowParams, store); - } - - rowParams.alt = alt.join(' '); - rowParams.cells = colBuffer.join(''); - - rowBuffer[rowBuffer.length] = rowTemplate.apply(rowParams); - } - - return rowBuffer.join(''); - }, + 'resizedrag', + + 'resize' + ); - - processRows : function(startRow, skipStripe) { - if (!this.ds || this.ds.getCount() < 1) { - return; + if (Ext.isString(config) || Ext.isElement(config) || config.dom) { + target = config; + config = arguments[1] || {}; + config.target = target; } + + me.mixins.observable.constructor.call(me, config); - var rows = this.getRows(), - length = rows.length, - row, i; - - skipStripe = skipStripe || !this.grid.stripeRows; - startRow = startRow || 0; - - for (i = 0; i < length; i++) { - row = rows[i]; - if (row) { - row.rowIndex = i; - if (!skipStripe) { - row.className = row.className.replace(this.rowClsRe, ' '); - if ((i + 1) % 2 === 0){ - row.className += ' x-grid3-row-alt'; + + + target = me.target; + if (target) { + if (target.isComponent) { + me.el = target.getEl(); + if (target.minWidth) { + me.minWidth = target.minWidth; + } + if (target.minHeight) { + me.minHeight = target.minHeight; + } + if (target.maxWidth) { + me.maxWidth = target.maxWidth; + } + if (target.maxHeight) { + me.maxHeight = target.maxHeight; + } + if (target.floating) { + if (!this.hasOwnProperty('handles')) { + this.handles = 'n ne e se s sw w nw'; } } + } else { + me.el = me.target = Ext.get(target); } } - - if (startRow === 0) { - Ext.fly(rows[0]).addClass(this.firstRowCls); + else { + me.target = me.el = Ext.get(me.el); } - Ext.fly(rows[length - 1]).addClass(this.lastRowCls); - }, - - - afterRender : function() { - if (!this.ds || !this.cm) { - return; - } - this.mainBody.dom.innerHTML = this.renderBody() || ' '; - this.processRows(0, true); + + + tag = me.el.dom.tagName; + if (tag == 'TEXTAREA' || tag == 'IMG') { + + me.originalTarget = me.target; + me.target = me.el = me.el.wrap({ + cls: me.wrapCls, + id: me.el.id + '-rzwrap' + }); - if (this.deferEmptyText !== true) { - this.applyEmptyText(); + + me.el.setPositioning(me.originalTarget.getPositioning()); + me.originalTarget.clearPositioning(); + var box = me.originalTarget.getBox(); + me.el.setBox(box); } + - this.grid.fireEvent('viewready', this.grid); - }, - - - afterRenderUI: function() { - var grid = this.grid; - this.initElements(); + me.el.position(); + if (me.pinned) { + me.el.addCls(me.pinnedCls); + } - Ext.fly(this.innerHd).on('click', this.handleHdDown, this); - - this.mainHd.on({ - scope : this, - mouseover: this.handleHdOver, - mouseout : this.handleHdOut, - mousemove: this.handleHdMove + me.resizeTracker = Ext.create('Ext.resizer.ResizeTracker', { + disabled: me.disabled, + target: me.target, + constrainTo: me.constrainTo, + overCls: me.overCls, + throttle: me.throttle, + originalTarget: me.originalTarget, + delegate: '.' + me.handleCls, + dynamic: me.dynamic, + preserveRatio: me.preserveRatio, + minHeight: me.minHeight, + maxHeight: me.maxHeight, + minWidth: me.minWidth, + maxWidth: me.maxWidth }); - this.scroller.on('scroll', this.syncScroll, this); - if (grid.enableColumnResize !== false) { - this.splitZone = new Ext.grid.GridView.SplitDragZone(grid, this.mainHd.dom); - } - - if (grid.enableColumnMove) { - this.columnDrag = new Ext.grid.GridView.ColumnDragZone(grid, this.innerHd); - this.columnDrop = new Ext.grid.HeaderDropZone(grid, this.mainHd.dom); - } - - if (grid.enableHdMenu !== false) { - this.hmenu = new Ext.menu.Menu({id: grid.id + '-hctx'}); - this.hmenu.add( - {itemId:'asc', text: this.sortAscText, cls: 'xg-hmenu-sort-asc'}, - {itemId:'desc', text: this.sortDescText, cls: 'xg-hmenu-sort-desc'} - ); - - if (grid.enableColumnHide !== false) { - this.colMenu = new Ext.menu.Menu({id:grid.id + '-hcols-menu'}); - this.colMenu.on({ - scope : this, - beforeshow: this.beforeColMenuShow, - itemclick : this.handleHdMenuClick - }); - this.hmenu.add('-', { - itemId:'columns', - hideOnClick: false, - text: this.columnsText, - menu: this.colMenu, - iconCls: 'x-cols-icon' - }); - } - - this.hmenu.on('itemclick', this.handleHdMenuClick, this); - } - - if (grid.trackMouseOver) { - this.mainBody.on({ - scope : this, - mouseover: this.onRowOver, - mouseout : this.onRowOut - }); - } + me.resizeTracker.on('mousedown', me.onBeforeResize, me); + me.resizeTracker.on('drag', me.onResize, me); + me.resizeTracker.on('dragend', me.onResizeEnd, me); - if (grid.enableDragDrop || grid.enableDrag) { - this.dragZone = new Ext.grid.GridDragZone(grid, { - ddGroup : grid.ddGroup || 'GridDD' - }); + if (me.handles == 'all') { + me.handles = 'n s e w ne nw se sw'; } - this.updateHeaderSortState(); - }, - - - renderUI : function() { - var templates = this.templates; - - return templates.master.apply({ - body : templates.body.apply({rows:' '}), - header: this.renderHeaders(), - ostyle: 'width:' + this.getOffsetWidth() + ';', - bstyle: 'width:' + this.getTotalWidth() + ';' - }); - }, - - - processEvent : function(name, e) { - var target = e.getTarget(), - grid = this.grid, - header = this.findHeaderIndex(target), - row, cell, col, body; - - grid.fireEvent(name, e); - - if (header !== false) { - grid.fireEvent('header' + name, grid, header, e); - } else { - row = this.findRowIndex(target); - - + handles = me.handles = me.handles.split(/ |\s*?[,;]\s*?/); + possibles = me.possiblePositions; + len = handles.length; + handleCls = me.handleCls + ' ' + (this.target.isComponent ? (me.target.baseCls + '-handle ') : '') + me.handleCls + '-'; + for(; i < len; i++){ + + if (handles[i] && possibles[handles[i]]) { + pos = possibles[handles[i]]; + - if (row !== false) { - cell = this.findCellIndex(target); - if (cell !== false) { - col = grid.colModel.getColumnAt(cell); - if (grid.fireEvent('cell' + name, grid, row, cell, e) !== false) { - if (!col || (col.processEvent && (col.processEvent(name, e, grid, row, cell) !== false))) { - grid.fireEvent('row' + name, grid, row, e); - } - } - } else { - if (grid.fireEvent('row' + name, grid, row, e) !== false) { - (body = this.findRowBody(target)) && grid.fireEvent('rowbody' + name, grid, row, e); - } + me[pos] = Ext.create('Ext.Component', { + owner: this, + region: pos, + cls: handleCls + pos, + renderTo: me.el + }); + me[pos].el.unselectable(); + if (me.transparent) { + me[pos].el.setOpacity(0); } - } else { - grid.fireEvent('container' + name, grid, e); } } - }, - - - layout : function(initial) { - if (!this.mainBody) { - return; - } - var grid = this.grid, - gridEl = grid.getGridEl(), - gridSize = gridEl.getSize(true), - gridWidth = gridSize.width, - gridHeight = gridSize.height, - scroller = this.scroller, - scrollStyle, headerHeight, scrollHeight; - if (gridWidth < 20 || gridHeight < 20) { - return; + if (Ext.isNumber(me.width)) { + me.width = Ext.Number.constrain(me.width, me.minWidth, me.maxWidth); } - - if (grid.autoHeight) { - scrollStyle = scroller.dom.style; - scrollStyle.overflow = 'visible'; - - if (Ext.isWebKit) { - scrollStyle.position = 'static'; - } - } else { - this.el.setSize(gridWidth, gridHeight); - - headerHeight = this.mainHd.getHeight(); - scrollHeight = gridHeight - headerHeight; - - scroller.setSize(gridWidth, scrollHeight); - - if (this.innerHd) { - this.innerHd.style.width = (gridWidth) + "px"; - } + if (Ext.isNumber(me.height)) { + me.height = Ext.Number.constrain(me.height, me.minHeight, me.maxHeight); } + - if (this.forceFit || (initial === true && this.autoFill)) { - if (this.lastViewWidth != gridWidth) { - this.fitColumns(false, false); - this.lastViewWidth = gridWidth; + if (me.width != null || me.height != null) { + if (me.originalTarget) { + me.originalTarget.setWidth(me.width); + me.originalTarget.setHeight(me.height); } - } else { - this.autoExpand(); - this.syncHeaderScroll(); + me.resizeTo(me.width, me.height); } - - this.onLayout(gridWidth, scrollHeight); - }, - - - onLayout : function(vw, vh) { - + me.forceHandlesHeight(); }, - onColumnWidthUpdated : function(col, w, tw) { - + disable: function() { + this.resizeTracker.disable(); }, - onAllColumnWidthsUpdated : function(ws, tw) { - + enable: function() { + this.resizeTracker.enable(); }, - onColumnHiddenUpdated : function(col, hidden, tw) { - + + onBeforeResize: function(tracker, e) { + var b = this.target.getBox(); + return this.fireEvent('beforeresize', this, b.width, b.height, e); }, - updateColumnText : function(col, text) { - + + onResize: function(tracker, e) { + var me = this, + b = me.target.getBox(); + me.forceHandlesHeight(); + return me.fireEvent('resizedrag', me, b.width, b.height, e); }, - afterMove : function(colIndex) { - + + onResizeEnd: function(tracker, e) { + var me = this, + b = me.target.getBox(); + me.forceHandlesHeight(); + return me.fireEvent('resize', me, b.width, b.height, e); }, - - init : function(grid) { - this.grid = grid; - - this.initTemplates(); - this.initData(grid.store, grid.colModel); - this.initUI(grid); + resizeTo : function(width, height){ + this.target.setSize(width, height); + this.fireEvent('resize', this, width, height, null); }, - getColumnId : function(index){ - return this.cm.getColumnId(index); + getEl : function() { + return this.el; }, - getOffsetWidth : function() { - return (this.cm.getTotalWidth() + this.getScrollOffset()) + 'px'; + getTarget: function() { + return this.target; }, - - getScrollOffset: function() { - return Ext.num(this.scrollOffset, Ext.getScrollBarWidth()); + destroy: function() { + var h; + for (var i = 0, l = this.handles.length; i < l; i++) { + h = this[this.possiblePositions[this.handles[i]]]; + delete h.owner; + Ext.destroy(h); + } }, - renderHeaders : function() { - var colModel = this.cm, - templates = this.templates, - headerTpl = templates.hcell, - properties = {}, - colCount = colModel.getColumnCount(), - last = colCount - 1, - cells = [], - i, cssCls; - - for (i = 0; i < colCount; i++) { - if (i == 0) { - cssCls = 'x-grid3-cell-first '; - } else { - cssCls = i == last ? 'x-grid3-cell-last ' : ''; + forceHandlesHeight : function() { + var me = this, + handle; + if (Ext.isIE6) { + handle = me.east; + if (handle) { + handle.setHeight(me.el.getHeight()); } - - properties = { - id : colModel.getColumnId(i), - value : colModel.getColumnHeader(i) || '', - style : this.getColumnStyle(i, true), - css : cssCls, - tooltip: this.getColumnTooltip(i) - }; - - if (colModel.config[i].align == 'right') { - properties.istyle = 'padding-right: 16px;'; - } else { - delete properties.istyle; + handle = me.west; + if (handle) { + handle.setHeight(me.el.getHeight()); } - - cells[i] = headerTpl.apply(properties); + me.el.repaint(); } - - return templates.header.apply({ - cells : cells.join(""), - tstyle: String.format("width: {0};", this.getTotalWidth()) - }); - }, + } +}); + + +Ext.define('Ext.resizer.ResizeTracker', { + extend: 'Ext.dd.DragTracker', + dynamic: true, + preserveRatio: false, - getColumnTooltip : function(i) { - var tooltip = this.cm.getColumnTooltip(i); - if (tooltip) { - if (Ext.QuickTips.isEnabled()) { - return 'ext:qtip="' + tooltip + '"'; + constrainTo: null, + + constructor: function(config) { + var me = this; + + if (!config.el) { + if (config.target.isComponent) { + me.el = config.target.getEl(); } else { - return 'title="' + tooltip + '"'; + me.el = config.target; } } - - return ''; - }, - - - beforeUpdate : function() { - this.grid.stopEditing(true); - }, + this.callParent(arguments); - - updateHeaders : function() { - this.innerHd.firstChild.innerHTML = this.renderHeaders(); - this.updateHeaderWidth(false); - }, - - - updateHeaderWidth: function(updateMain) { - var innerHdChild = this.innerHd.firstChild, - totalWidth = this.getTotalWidth(); + if (me.preserveRatio && me.minWidth && me.minHeight) { + var widthRatio = me.minWidth / me.el.getWidth(), + heightRatio = me.minHeight / me.el.getHeight(); + + + + + if (heightRatio > widthRatio) { + me.minWidth = me.el.getWidth() * heightRatio; + } else { + me.minHeight = me.el.getHeight() * widthRatio; + } + } + - innerHdChild.style.width = this.getOffsetWidth(); - innerHdChild.firstChild.style.width = totalWidth; - if (updateMain !== false) { - this.mainBody.dom.style.width = totalWidth; + if (me.throttle) { + var throttledResizeFn = Ext.Function.createThrottled(function() { + Ext.resizer.ResizeTracker.prototype.resize.apply(me, arguments); + }, me.throttle); + + me.resize = function(box, direction, atEnd) { + if (atEnd) { + Ext.resizer.ResizeTracker.prototype.resize.apply(me, arguments); + } else { + throttledResizeFn.apply(null, arguments); + } + }; } }, - - focusRow : function(row) { - this.focusCell(row, 0, false); + onBeforeStart: function(e) { + + this.startBox = this.el.getBox(); }, - focusCell : function(row, col, hscroll) { - this.syncFocusEl(this.ensureVisible(row, col, hscroll)); - - var focusEl = this.focusEl; - - if (Ext.isGecko) { - focusEl.focus(); - } else { - focusEl.focus.defer(1, focusEl); + getDynamicTarget: function() { + var d = this.target; + if (this.dynamic) { + return d; + } else if (!this.proxy) { + this.proxy = d.isComponent ? d.getProxy().addCls(Ext.baseCSSPrefix + 'resizable-proxy') : d.createProxy({tag: 'div', cls: Ext.baseCSSPrefix + 'resizable-proxy', id: d.id + '-rzproxy'}, Ext.getBody()); + this.proxy.removeCls(Ext.baseCSSPrefix + 'proxy-el'); } + this.proxy.show(); + return this.proxy; }, - - resolveCell : function(row, col, hscroll) { - if (!Ext.isNumber(row)) { - row = row.rowIndex; - } + onStart: function(e) { - if (!this.ds) { - return null; - } + this.activeResizeHandle = Ext.getCmp(this.getDragTarget().id); + - if (row < 0 || row >= this.ds.getCount()) { - return null; + if (!this.dynamic) { + this.resize(this.startBox, { + horizontal: 'none', + vertical: 'none' + }); } - col = (col !== undefined ? col : 0); + }, - var rowEl = this.getRow(row), - colModel = this.cm, - colCount = colModel.getColumnCount(), - cellEl; - - if (!(hscroll === false && col === 0)) { - while (col < colCount && colModel.isHidden(col)) { - col++; - } - - cellEl = this.getCell(row, col); + onDrag: function(e) { + + if (this.dynamic || this.proxy) { + this.updateDimensions(e); } - - return {row: rowEl, cell: cellEl}; }, - - getResolvedXY : function(resolved) { - if (!resolved) { - return null; + updateDimensions: function(e, atEnd) { + var me = this, + region = me.activeResizeHandle.region, + offset = me.getOffset(me.constrainTo ? 'dragTarget' : null), + box = me.startBox, + ratio, + widthAdjust = 0, + heightAdjust = 0, + adjustX = 0, + adjustY = 0, + dragRatio, + horizDir = offset[0] < 0 ? 'right' : 'left', + vertDir = offset[1] < 0 ? 'down' : 'up', + oppositeCorner, + axis; + + switch (region) { + case 'south': + heightAdjust = offset[1]; + axis = 2; + break; + case 'north': + heightAdjust = -offset[1]; + adjustY = -heightAdjust; + axis = 2; + break; + case 'east': + widthAdjust = offset[0]; + axis = 1; + break; + case 'west': + widthAdjust = -offset[0]; + adjustX = -widthAdjust; + axis = 1; + break; + case 'northeast': + heightAdjust = -offset[1]; + adjustY = -heightAdjust; + widthAdjust = offset[0]; + oppositeCorner = [box.x, box.y + box.height]; + axis = 3; + break; + case 'southeast': + heightAdjust = offset[1]; + widthAdjust = offset[0]; + oppositeCorner = [box.x, box.y]; + axis = 3; + break; + case 'southwest': + widthAdjust = -offset[0]; + adjustX = -widthAdjust; + heightAdjust = offset[1]; + oppositeCorner = [box.x + box.width, box.y]; + axis = 3; + break; + case 'northwest': + heightAdjust = -offset[1]; + adjustY = -heightAdjust; + widthAdjust = -offset[0]; + adjustX = -widthAdjust; + oppositeCorner = [box.x + box.width, box.y + box.height]; + axis = 3; + break; } + + var newBox = { + width: box.width + widthAdjust, + height: box.height + heightAdjust, + x: box.x + adjustX, + y: box.y + adjustY + }; + - var cell = resolved.cell, - row = resolved.row; - - if (cell) { - return Ext.fly(cell).getXY(); + if (newBox.width < me.minWidth || newBox.width > me.maxWidth) { + newBox.width = Ext.Number.constrain(newBox.width, me.minWidth, me.maxWidth); + newBox.x = me.lastX || newBox.x; } else { - return [this.el.getX(), Ext.fly(row).getY()]; + me.lastX = newBox.x; } - }, - - - syncFocusEl : function(row, col, hscroll) { - var xy = row; - - if (!Ext.isArray(xy)) { - row = Math.min(row, Math.max(0, this.getRows().length-1)); - - if (isNaN(row)) { - return; - } - - xy = this.getResolvedXY(this.resolveCell(row, col, hscroll)); + if (newBox.height < me.minHeight || newBox.height > me.maxHeight) { + newBox.height = Ext.Number.constrain(newBox.height, me.minHeight, me.maxHeight); + newBox.y = me.lastY || newBox.y; + } else { + me.lastY = newBox.y; } - - this.focusEl.setXY(xy || this.scroller.getXY()); - }, - - ensureVisible : function(row, col, hscroll) { - var resolved = this.resolveCell(row, col, hscroll); - if (!resolved || !resolved.row) { - return null; - } + if (me.preserveRatio || e.shiftKey) { + var newHeight, + newWidth; - var rowEl = resolved.row, - cellEl = resolved.cell, - c = this.scroller.dom, - p = rowEl, - ctop = 0, - stop = this.el.dom; + ratio = me.startBox.width / me.startBox.height; - while (p && p != stop) { - ctop += p.offsetTop; - p = p.offsetParent; - } + + newHeight = Math.min(Math.max(me.minHeight, newBox.width / ratio), me.maxHeight); + newWidth = Math.min(Math.max(me.minWidth, newBox.height * ratio), me.maxWidth); - ctop -= this.mainHd.dom.offsetHeight; - stop = parseInt(c.scrollTop, 10); + + if (axis == 1) { + newBox.height = newHeight; + } - var cbot = ctop + rowEl.offsetHeight, - ch = c.clientHeight, - sbot = stop + ch; + + else if (axis == 2) { + newBox.width = newWidth; + } + + else { + + + dragRatio = Math.abs(oppositeCorner[0] - this.lastXY[0]) / Math.abs(oppositeCorner[1] - this.lastXY[1]); - if (ctop < stop) { - c.scrollTop = ctop; - } else if(cbot > sbot) { - c.scrollTop = cbot-ch; - } + + if (dragRatio > ratio) { + newBox.height = newHeight; + } else { + newBox.width = newWidth; + } - if (hscroll !== false) { - var cleft = parseInt(cellEl.offsetLeft, 10), - cright = cleft + cellEl.offsetWidth, - sleft = parseInt(c.scrollLeft, 10), - sright = sleft + c.clientWidth; - if (cleft < sleft) { - c.scrollLeft = cleft; - } else if(cright > sright) { - c.scrollLeft = cright-c.clientWidth; + if (region == 'northeast') { + newBox.y = box.y - (newBox.height - box.height); + } else if (region == 'northwest') { + newBox.y = box.y - (newBox.height - box.height); + newBox.x = box.x - (newBox.width - box.width); + } else if (region == 'southwest') { + newBox.x = box.x - (newBox.width - box.width); + } } } - - return this.getResolvedXY(resolved); + + if (heightAdjust === 0) { + vertDir = 'none'; + } + if (widthAdjust === 0) { + horizDir = 'none'; + } + me.resize(newBox, { + horizontal: horizDir, + vertical: vertDir + }, atEnd); }, - - insertRows : function(dm, firstRow, lastRow, isUpdate) { - var last = dm.getCount() - 1; - if( !isUpdate && firstRow === 0 && lastRow >= last) { - this.fireEvent('beforerowsinserted', this, firstRow, lastRow); - this.refresh(); - this.fireEvent('rowsinserted', this, firstRow, lastRow); - } else { - if (!isUpdate) { - this.fireEvent('beforerowsinserted', this, firstRow, lastRow); - } - var html = this.renderRows(firstRow, lastRow), - before = this.getRow(firstRow); - if (before) { - if(firstRow === 0){ - Ext.fly(this.getRow(0)).removeClass(this.firstRowCls); - } - Ext.DomHelper.insertHtml('beforeBegin', before, html); - } else { - var r = this.getRow(last - 1); - if(r){ - Ext.fly(r).removeClass(this.lastRowCls); - } - Ext.DomHelper.insertHtml('beforeEnd', this.mainBody.dom, html); + getResizeTarget: function(atEnd) { + return atEnd ? this.target : this.getDynamicTarget(); + }, + + resize: function(box, direction, atEnd) { + var target = this.getResizeTarget(atEnd); + if (target.isComponent) { + if (target.floating) { + target.setPagePosition(box.x, box.y); } - if (!isUpdate) { - this.processRows(firstRow); - this.fireEvent('rowsinserted', this, firstRow, lastRow); - } else if (firstRow === 0 || firstRow >= last) { - - Ext.fly(this.getRow(firstRow)).addClass(firstRow === 0 ? this.firstRowCls : this.lastRowCls); + target.setSize(box.width, box.height); + } else { + target.setBox(box); + + if (this.originalTarget) { + this.originalTarget.setBox(box); } } - this.syncFocusEl(firstRow); }, - - deleteRows : function(dm, firstRow, lastRow) { - if (dm.getRowCount() < 1) { - this.refresh(); - } else { - this.fireEvent('beforerowsdeleted', this, firstRow, lastRow); + onEnd: function(e) { + this.updateDimensions(e, true); + if (this.proxy) { + this.proxy.hide(); + } + } +}); - this.removeRows(firstRow, lastRow); - this.processRows(firstRow); - this.fireEvent('rowsdeleted', this, firstRow, lastRow); - } +Ext.define('Ext.resizer.SplitterTracker', { + extend: 'Ext.dd.DragTracker', + requires: ['Ext.util.Region'], + enabled: true, + + getPrevCmp: function() { + var splitter = this.getSplitter(); + return splitter.previousSibling(); }, - - getColumnStyle : function(colIndex, isHeader) { - var colModel = this.cm, - colConfig = colModel.config, - style = isHeader ? '' : colConfig[colIndex].css || '', - align = colConfig[colIndex].align; - - style += String.format("width: {0};", this.getColumnWidth(colIndex)); - - if (colModel.isHidden(colIndex)) { - style += 'display: none; '; - } - - if (align) { - style += String.format("text-align: {0};", align); - } - - return style; + getNextCmp: function() { + var splitter = this.getSplitter(); + return splitter.nextSibling(); }, - getColumnWidth : function(column) { - var columnWidth = this.cm.getColumnWidth(column), - borderWidth = this.borderWidth; + + onBeforeStart: function(e) { + var prevCmp = this.getPrevCmp(), + nextCmp = this.getNextCmp(); + - if (Ext.isNumber(columnWidth)) { - if (Ext.isBorderBox || (Ext.isWebKit && !Ext.isSafari2)) { - return columnWidth + "px"; - } else { - return Math.max(columnWidth - borderWidth, 0) + "px"; - } - } else { - return columnWidth; + if (nextCmp.collapsed || prevCmp.collapsed) { + return false; } + + this.prevBox = prevCmp.getEl().getBox(); + this.nextBox = nextCmp.getEl().getBox(); + this.constrainTo = this.calculateConstrainRegion(); }, - getTotalWidth : function() { - return this.cm.getTotalWidth() + 'px'; + onStart: function(e) { + var splitter = this.getSplitter(); + splitter.addCls(splitter.baseCls + '-active'); }, - fitColumns : function(preventRefresh, onlyExpand, omitColumn) { - var grid = this.grid, - colModel = this.cm, - totalColWidth = colModel.getTotalWidth(false), - gridWidth = this.getGridInnerWidth(), - extraWidth = gridWidth - totalColWidth, - columns = [], - extraCol = 0, - width = 0, - colWidth, fraction, i; - - - if (gridWidth < 20 || extraWidth === 0) { - return false; - } - - var visibleColCount = colModel.getColumnCount(true), - totalColCount = colModel.getColumnCount(false), - adjCount = visibleColCount - (Ext.isNumber(omitColumn) ? 1 : 0); - - if (adjCount === 0) { - adjCount = 1; - omitColumn = undefined; - } - + calculateConstrainRegion: function() { + var splitter = this.getSplitter(), + topPad = 0, + bottomPad = 0, + splitWidth = splitter.getWidth(), + defaultMin = splitter.defaultSplitMin, + orient = splitter.orientation, + prevBox = this.prevBox, + prevCmp = this.getPrevCmp(), + nextBox = this.nextBox, + nextCmp = this.getNextCmp(), + + + + prevConstrainRegion, nextConstrainRegion; + - for (i = 0; i < totalColCount; i++) { - if (!colModel.isFixed(i) && i !== omitColumn) { - colWidth = colModel.getColumnWidth(i); - columns.push(i, colWidth); + if (orient === 'vertical') { + + + + prevConstrainRegion = Ext.create('Ext.util.Region', + prevBox.y, - if (!colModel.isHidden(i)) { - extraCol = i; - width += colWidth; - } - } - } - - fraction = (gridWidth - colModel.getTotalWidth()) / width; - - while (columns.length) { - colWidth = columns.pop(); - i = columns.pop(); + + (prevCmp.maxWidth ? prevBox.x + prevCmp.maxWidth : nextBox.right - (nextCmp.minWidth || defaultMin)) + splitWidth, + prevBox.bottom, + prevBox.x + (prevCmp.minWidth || defaultMin) + ); - colModel.setColumnWidth(i, Math.max(grid.minColumnWidth, Math.floor(colWidth + colWidth * fraction)), true); - } - - - totalColWidth = colModel.getTotalWidth(false); - - if (totalColWidth > gridWidth) { - var adjustCol = (adjCount == visibleColCount) ? extraCol : omitColumn, - newWidth = Math.max(1, colModel.getColumnWidth(adjustCol) - (totalColWidth - gridWidth)); + nextConstrainRegion = Ext.create('Ext.util.Region', + nextBox.y, + nextBox.right - (nextCmp.minWidth || defaultMin), + nextBox.bottom, + + + (nextCmp.maxWidth ? nextBox.right - nextCmp.maxWidth : prevBox.x + (prevBox.minWidth || defaultMin)) - splitWidth + ); + } else { - colModel.setColumnWidth(adjustCol, newWidth, true); - } - - if (preventRefresh !== true) { - this.updateAllColumnWidths(); + prevConstrainRegion = Ext.create('Ext.util.Region', + prevBox.y + (prevCmp.minHeight || defaultMin), + prevBox.right, + + + (prevCmp.maxHeight ? prevBox.y + prevCmp.maxHeight : nextBox.bottom - (nextCmp.minHeight || defaultMin)) + splitWidth, + prevBox.x + ); + + nextConstrainRegion = Ext.create('Ext.util.Region', + + + (nextCmp.maxHeight ? nextBox.bottom - nextCmp.maxHeight : prevBox.y + (prevCmp.minHeight || defaultMin)) - splitWidth, + nextBox.right, + nextBox.bottom - (nextCmp.minHeight || defaultMin), + nextBox.x + ); } + - return true; + return prevConstrainRegion.intersect(nextConstrainRegion); }, - autoExpand : function(preventUpdate) { - var grid = this.grid, - colModel = this.cm, - gridWidth = this.getGridInnerWidth(), - totalColumnWidth = colModel.getTotalWidth(false), - autoExpandColumn = grid.autoExpandColumn; + performResize: function(e) { + var offset = this.getOffset('dragTarget'), + splitter = this.getSplitter(), + orient = splitter.orientation, + prevCmp = this.getPrevCmp(), + nextCmp = this.getNextCmp(), + owner = splitter.ownerCt, + layout = owner.getLayout(); + - if (!this.userResized && autoExpandColumn) { - if (gridWidth != totalColumnWidth) { - - var colIndex = colModel.getIndexById(autoExpandColumn), - currentWidth = colModel.getColumnWidth(colIndex), - desiredWidth = gridWidth - totalColumnWidth + currentWidth, - newWidth = Math.min(Math.max(desiredWidth, grid.autoExpandMin), grid.autoExpandMax); - - if (currentWidth != newWidth) { - colModel.setColumnWidth(colIndex, newWidth, true); - - if (preventUpdate !== true) { - this.updateColumnWidth(colIndex, newWidth); - } + owner.suspendLayout = true; + + if (orient === 'vertical') { + if (prevCmp) { + if (!prevCmp.maintainFlex) { + delete prevCmp.flex; + prevCmp.setSize(this.prevBox.width + offset[0], prevCmp.getHeight()); + } + } + if (nextCmp) { + if (!nextCmp.maintainFlex) { + delete nextCmp.flex; + nextCmp.setSize(this.nextBox.width - offset[0], nextCmp.getHeight()); + } + } + + } else { + if (prevCmp) { + if (!prevCmp.maintainFlex) { + delete prevCmp.flex; + prevCmp.setSize(prevCmp.getWidth(), this.prevBox.height + offset[1]); + } + } + if (nextCmp) { + if (!nextCmp.maintainFlex) { + delete nextCmp.flex; + nextCmp.setSize(prevCmp.getWidth(), this.nextBox.height - offset[1]); } } } + delete owner.suspendLayout; + layout.onLayout(); }, + + + onEnd: function(e) { + var splitter = this.getSplitter(); + splitter.removeCls(splitter.baseCls + '-active'); + this.performResize(); + }, + - getGridInnerWidth: function() { - return this.grid.getGridEl().getWidth(true) - this.getScrollOffset(); + onDrag: function(e) { + var offset = this.getOffset('dragTarget'), + splitter = this.getSplitter(), + splitEl = splitter.getEl(), + orient = splitter.orientation; + + if (orient === "vertical") { + splitEl.setX(this.startRegion.left + offset[0]); + } else { + splitEl.setY(this.startRegion.top + offset[1]); + } }, + getSplitter: function() { + return Ext.getCmp(this.getDragCt().id); + } +}); + +Ext.define('Ext.selection.CellModel', { + extend: 'Ext.selection.Model', + alias: 'selection.cellmodel', + requires: ['Ext.util.KeyNav'], - getColumnData : function() { - var columns = [], - colModel = this.cm, - colCount = colModel.getColumnCount(), - fields = this.ds.fields, - i, name; - - for (i = 0; i < colCount; i++) { - name = colModel.getDataIndex(i); + + enableKeyNav: true, + + + preventWrap: false, + + constructor: function(){ + this.addEvents( - columns[i] = { - name : Ext.isDefined(name) ? name : (fields.get(i) ? fields.get(i).name : undefined), - renderer: colModel.getRenderer(i), - scope : colModel.getRendererScope(i), - id : colModel.getColumnId(i), - style : this.getColumnStyle(i) - }; + 'deselect', + + + 'select' + ); + this.callParent(arguments); + }, + + bindComponent: function(view) { + var me = this; + me.primaryView = view; + me.views = me.views || []; + me.views.push(view); + me.bind(view.getStore(), true); + + view.on({ + cellmousedown: me.onMouseDown, + refresh: me.onViewRefresh, + scope: me + }); + + if (me.enableKeyNav) { + me.initKeyNav(view); } - - return columns; }, - - renderRows : function(startRow, endRow) { - var grid = this.grid, - store = grid.store, - stripe = grid.stripeRows, - colModel = grid.colModel, - colCount = colModel.getColumnCount(), - rowCount = store.getCount(), - records; + initKeyNav: function(view) { + var me = this; - if (rowCount < 1) { - return ''; + if (!view.rendered) { + view.on('render', Ext.Function.bind(me.initKeyNav, me, [view], 0), me, {single: true}); + return; } + + view.el.set({ + tabIndex: -1 + }); + - startRow = startRow || 0; - endRow = Ext.isDefined(endRow) ? endRow : rowCount - 1; - records = store.getRange(startRow, endRow); - return this.doRender(this.getColumnData(), records, store, startRow, colCount, stripe); + me.keyNav = Ext.create('Ext.util.KeyNav', view.el, { + up: me.onKeyUp, + down: me.onKeyDown, + right: me.onKeyRight, + left: me.onKeyLeft, + tab: me.onKeyTab, + scope: me + }); }, - - renderBody : function(){ - var markup = this.renderRows() || ' '; - return this.templates.body.apply({rows: markup}); + getHeaderCt: function() { + return this.primaryView.headerCt; + }, + + onKeyUp: function(e, t) { + this.move('up', e); + }, + + onKeyDown: function(e, t) { + this.move('down', e); }, + onKeyLeft: function(e, t) { + this.move('left', e); + }, - refreshRow: function(record) { - var store = this.ds, - colCount = this.cm.getColumnCount(), - columns = this.getColumnData(), - last = colCount - 1, - cls = ['x-grid3-row'], - rowParams = { - tstyle: String.format("width: {0};", this.getTotalWidth()) - }, - colBuffer = [], - cellTpl = this.templates.cell, - rowIndex, row, column, meta, css, i; - - if (Ext.isNumber(record)) { - rowIndex = record; - record = store.getAt(rowIndex); - } else { - rowIndex = store.indexOf(record); - } - - - if (!record || rowIndex < 0) { - return; - } - - - for (i = 0; i < colCount; i++) { - column = columns[i]; - - if (i == 0) { - css = 'x-grid3-cell-first'; - } else { - css = (i == last) ? 'x-grid3-cell-last ' : ''; - } - - meta = { - id : column.id, - style : column.style, - css : css, - attr : "", - cellAttr: "" - }; - - meta.value = column.renderer.call(column.scope, record.data[column.name], meta, record, rowIndex, i, store); - - if (Ext.isEmpty(meta.value)) { - meta.value = ' '; - } - - if (this.markDirty && record.dirty && typeof record.modified[column.name] != 'undefined') { - meta.css += ' x-grid3-dirty-cell'; - } - - colBuffer[i] = cellTpl.apply(meta); + onKeyRight: function(e, t) { + this.move('right', e); + }, + + move: function(dir, e) { + var me = this, + pos = me.primaryView.walkCells(me.getCurrentPosition(), dir, e, me.preventWrap); + if (pos) { + me.setCurrentPosition(pos); } + return pos; + }, + + + getCurrentPosition: function() { + return this.position; + }, + + + setCurrentPosition: function(pos) { + var me = this; - row = this.getRow(rowIndex); - row.className = ''; - - if (this.grid.stripeRows && ((rowIndex + 1) % 2 === 0)) { - cls.push('x-grid3-row-alt'); + if (me.position) { + me.onCellDeselect(me.position); } - - if (this.getRowClass) { - rowParams.cols = colCount; - cls.push(this.getRowClass(record, rowIndex, rowParams, store)); + if (pos) { + me.onCellSelect(pos); } - - this.fly(row).addClass(cls).setStyle(rowParams.tstyle); - rowParams.cells = colBuffer.join(""); - row.innerHTML = this.templates.rowInner.apply(rowParams); - - this.fireEvent('rowupdated', this, rowIndex, record); + me.position = pos; }, - refresh : function(headersToo) { - this.fireEvent('beforerefresh', this); - this.grid.stopEditing(true); - - var result = this.renderBody(); - this.mainBody.update(result).setWidth(this.getTotalWidth()); - if (headersToo === true) { - this.updateHeaders(); - this.updateHeaderSortState(); - } - this.processRows(0, true); - this.layout(); - this.applyEmptyText(); - this.fireEvent('refresh', this); + onMouseDown: function(view, cell, cellIndex, record, row, rowIndex, e) { + this.setCurrentPosition({ + row: rowIndex, + column: cellIndex + }); }, - applyEmptyText : function() { - if (this.emptyText && !this.hasRows()) { - this.mainBody.update('
    ' + this.emptyText + '
    '); - } + + onCellSelect: function(position) { + var me = this, + store = me.view.getStore(), + record = store.getAt(position.row); + + me.doSelect(record); + me.primaryView.onCellSelect(position); + + me.primaryView.onCellFocus(position); + me.fireEvent('select', me, record, position.row, position.column); }, - updateHeaderSortState : function() { - var state = this.ds.getSortState(); - if (!state) { - return; - } + + onCellDeselect: function(position) { + var me = this, + store = me.view.getStore(), + record = store.getAt(position.row); + + me.doDeselect(record); + me.primaryView.onCellDeselect(position); + me.fireEvent('deselect', me, record, position.row, position.column); + }, + + onKeyTab: function(e, t) { + var me = this, + direction = e.shiftKey ? 'left' : 'right', + editingPlugin = me.view.editingPlugin, + position = me.move(direction, e); - if (!this.sortState || (this.sortState.field != state.field || this.sortState.direction != state.direction)) { - this.grid.fireEvent('sortchange', this.grid, state); + if (editingPlugin && position && me.wasEditing) { + editingPlugin.startEditByPosition(position); } + delete me.wasEditing; + }, - this.sortState = state; + onEditorTab: function(editingPlugin, e) { + var me = this, + direction = e.shiftKey ? 'left' : 'right', + position = me.move(direction, e); - var sortColumn = this.cm.findColumnIndex(state.field); - if (sortColumn != -1) { - var sortDir = state.direction; - this.updateSortIcon(sortColumn, sortDir); + if (position) { + editingPlugin.startEditByPosition(position); + me.wasEditing = true; } }, - - clearHeaderSortState : function() { - if (!this.sortState) { - return; + refresh: function() { + var pos = this.getCurrentPosition(); + if (pos) { + this.onCellSelect(pos); } - this.grid.fireEvent('sortchange', this.grid, null); - this.mainHd.select('td').removeClass(this.sortClasses); - delete this.sortState; }, - - destroy : function() { - var me = this, - grid = me.grid, - gridEl = grid.getGridEl(), - dragZone = me.dragZone, - splitZone = me.splitZone, - columnDrag = me.columnDrag, - columnDrop = me.columnDrop, - scrollToTopTask = me.scrollToTopTask, - columnDragData, - columnDragProxy; - - if (scrollToTopTask && scrollToTopTask.cancel) { - scrollToTopTask.cancel(); + onViewRefresh: function() { + var pos = this.getCurrentPosition(); + if (pos) { + this.onCellDeselect(pos); + this.setCurrentPosition(null); } - - Ext.destroyMembers(me, 'colMenu', 'hmenu'); + }, - me.initData(null, null); - me.purgeListeners(); - - Ext.fly(me.innerHd).un("click", me.handleHdDown, me); + selectByPosition: function(position) { + this.setCurrentPosition(position); + } +}); - if (grid.enableColumnMove) { - columnDragData = columnDrag.dragData; - columnDragProxy = columnDrag.proxy; - Ext.destroy( - columnDrag.el, - columnDragProxy.ghost, - columnDragProxy.el, - columnDrop.el, - columnDrop.proxyTop, - columnDrop.proxyBottom, - columnDragData.ddel, - columnDragData.header - ); +Ext.define('Ext.selection.RowModel', { + extend: 'Ext.selection.Model', + alias: 'selection.rowmodel', + requires: ['Ext.util.KeyNav'], + + + deltaScroll: 5, + + + enableKeyNav: true, + + constructor: function(){ + this.addEvents( - if (columnDragProxy.anim) { - Ext.destroy(columnDragProxy.anim); - } + 'deselect', - delete columnDragProxy.ghost; - delete columnDragData.ddel; - delete columnDragData.header; - columnDrag.destroy(); - delete Ext.dd.DDM.locationCache[columnDrag.id]; - delete columnDrag._domRef; - - delete columnDrop.proxyTop; - delete columnDrop.proxyBottom; - columnDrop.destroy(); - delete Ext.dd.DDM.locationCache["gridHeader" + gridEl.id]; - delete columnDrop._domRef; - delete Ext.dd.DDM.ids[columnDrop.ddGroup]; - } - - if (splitZone) { - splitZone.destroy(); - delete splitZone._domRef; - delete Ext.dd.DDM.ids["gridSplitters" + gridEl.id]; - } + 'select' + ); + this.callParent(arguments); + }, - Ext.fly(me.innerHd).removeAllListeners(); - Ext.removeNode(me.innerHd); - delete me.innerHd; + bindComponent: function(view) { + var me = this; + + me.views = me.views || []; + me.views.push(view); + me.bind(view.getStore(), true); - Ext.destroy( - me.el, - me.mainWrap, - me.mainHd, - me.scroller, - me.mainBody, - me.focusEl, - me.resizeMarker, - me.resizeProxy, - me.activeHdBtn, - me._flyweight, - dragZone, - splitZone - ); + view.on({ + itemmousedown: me.onRowMouseDown, + scope: me + }); - delete grid.container; + if (me.enableKeyNav) { + me.initKeyNav(view); + } + }, - if (dragZone) { - dragZone.destroy(); + initKeyNav: function(view) { + var me = this; + + if (!view.rendered) { + view.on('render', Ext.Function.bind(me.initKeyNav, me, [view], 0), me, {single: true}); + return; } - Ext.dd.DDM.currentTarget = null; - delete Ext.dd.DDM.locationCache[gridEl.id]; + view.el.set({ + tabIndex: -1 + }); - Ext.EventManager.removeResizeListener(me.onWindowResize, me); + + + me.keyNav = new Ext.util.KeyNav(view.el, { + up: me.onKeyUp, + down: me.onKeyDown, + right: me.onKeyRight, + left: me.onKeyLeft, + pageDown: me.onKeyPageDown, + pageUp: me.onKeyPageUp, + home: me.onKeyHome, + end: me.onKeyEnd, + scope: me + }); + view.el.on(Ext.EventManager.getKeyEvent(), me.onKeyPress, me); }, - onDenyColumnHide : function() { + + + getRowsVisible: function() { + var rowsVisible = false, + view = this.views[0], + row = view.getNode(0), + rowHeight, gridViewHeight; + if (row) { + rowHeight = Ext.fly(row).getHeight(); + gridViewHeight = view.el.getHeight(); + rowsVisible = Math.floor(gridViewHeight / rowHeight); + } + + return rowsVisible; }, - render : function() { - if (this.autoFill) { - var ct = this.grid.ownerCt; + onKeyEnd: function(e, t) { + var me = this, + last = me.store.getAt(me.store.getCount() - 1); - if (ct && ct.getLayout()) { - ct.on('afterlayout', function() { - this.fitColumns(true, true); - this.updateHeaders(); - this.updateHeaderSortState(); - }, this, {single: true}); + if (last) { + if (e.shiftKey) { + me.selectRange(last, me.lastFocused || 0); + me.setLastFocused(last); + } else if (e.ctrlKey) { + me.setLastFocused(last); + } else { + me.doSelect(last); } - } else if (this.forceFit) { - this.fitColumns(true, false); - } else if (this.grid.autoExpandColumn) { - this.autoExpand(true); } - - this.grid.getGridEl().dom.innerHTML = this.renderUI(); - - this.afterRenderUI(); }, - - - initData : function(newStore, newColModel) { - var me = this; - - if (me.ds) { - var oldStore = me.ds; - - oldStore.un('add', me.onAdd, me); - oldStore.un('load', me.onLoad, me); - oldStore.un('clear', me.onClear, me); - oldStore.un('remove', me.onRemove, me); - oldStore.un('update', me.onUpdate, me); - oldStore.un('datachanged', me.onDataChange, me); + onKeyHome: function(e, t) { + var me = this, + first = me.store.getAt(0); - if (oldStore !== newStore && oldStore.autoDestroy) { - oldStore.destroy(); + if (first) { + if (e.shiftKey) { + me.selectRange(first, me.lastFocused || 0); + me.setLastFocused(first); + } else if (e.ctrlKey) { + me.setLastFocused(first); + } else { + me.doSelect(first, false); } } - - if (newStore) { - newStore.on({ - scope : me, - load : me.onLoad, - add : me.onAdd, - remove : me.onRemove, - update : me.onUpdate, - clear : me.onClear, - datachanged: me.onDataChange - }); - } - - if (me.cm) { - var oldColModel = me.cm; - - oldColModel.un('configchange', me.onColConfigChange, me); - oldColModel.un('widthchange', me.onColWidthChange, me); - oldColModel.un('headerchange', me.onHeaderChange, me); - oldColModel.un('hiddenchange', me.onHiddenChange, me); - oldColModel.un('columnmoved', me.onColumnMove, me); - } - - if (newColModel) { - delete me.lastViewWidth; - - newColModel.on({ - scope : me, - configchange: me.onColConfigChange, - widthchange : me.onColWidthChange, - headerchange: me.onHeaderChange, - hiddenchange: me.onHiddenChange, - columnmoved : me.onColumnMove - }); - } - - me.ds = newStore; - me.cm = newColModel; }, - onDataChange : function(){ - this.refresh(true); - this.updateHeaderSortState(); - this.syncFocusEl(0); - }, + onKeyPageUp: function(e, t) { + var me = this, + rowsVisible = me.getRowsVisible(), + selIdx, + prevIdx, + prevRecord, + currRec; + + if (rowsVisible) { + selIdx = me.lastFocused ? me.store.indexOf(me.lastFocused) : 0; + prevIdx = selIdx - rowsVisible; + if (prevIdx < 0) { + prevIdx = 0; + } + prevRecord = me.store.getAt(prevIdx); + if (e.shiftKey) { + currRec = me.store.getAt(selIdx); + me.selectRange(prevRecord, currRec, e.ctrlKey, 'up'); + me.setLastFocused(prevRecord); + } else if (e.ctrlKey) { + e.preventDefault(); + me.setLastFocused(prevRecord); + } else { + me.doSelect(prevRecord); + } - - onClear : function() { - this.refresh(); - this.syncFocusEl(0); + } }, - onUpdate : function(store, record) { - this.refreshRow(record); + onKeyPageDown: function(e, t) { + var me = this, + rowsVisible = me.getRowsVisible(), + selIdx, + nextIdx, + nextRecord, + currRec; + + if (rowsVisible) { + selIdx = me.lastFocused ? me.store.indexOf(me.lastFocused) : 0; + nextIdx = selIdx + rowsVisible; + if (nextIdx >= me.store.getCount()) { + nextIdx = me.store.getCount() - 1; + } + nextRecord = me.store.getAt(nextIdx); + if (e.shiftKey) { + currRec = me.store.getAt(selIdx); + me.selectRange(nextRecord, currRec, e.ctrlKey, 'down'); + me.setLastFocused(nextRecord); + } else if (e.ctrlKey) { + + + e.preventDefault(); + me.setLastFocused(nextRecord); + } else { + me.doSelect(nextRecord); + } + } }, - onAdd : function(store, records, index) { - this.insertRows(store, index, index + (records.length-1)); + + onKeyPress: function(e, t) { + if (e.getKey() === e.SPACE) { + e.stopEvent(); + var me = this, + record = me.lastFocused; + + if (record) { + if (me.isSelected(record)) { + me.doDeselect(record, false); + } else { + me.doSelect(record, true); + } + } + } }, - onRemove : function(store, record, index, isUpdate) { - if (isUpdate !== true) { - this.fireEvent('beforerowremoved', this, index, record); + + + onKeyUp: function(e, t) { + var me = this, + view = me.views[0], + idx = me.store.indexOf(me.lastFocused), + record; + + if (idx > 0) { + + + record = me.store.getAt(idx - 1); + if (e.shiftKey && me.lastFocused) { + if (me.isSelected(me.lastFocused) && me.isSelected(record)) { + me.doDeselect(me.lastFocused, true); + me.setLastFocused(record); + } else if (!me.isSelected(me.lastFocused)) { + me.doSelect(me.lastFocused, true); + me.doSelect(record, true); + } else { + me.doSelect(record, true); + } + } else if (e.ctrlKey) { + me.setLastFocused(record); + } else { + me.doSelect(record); + + } } - this.removeRow(index); - if (isUpdate !== true) { - this.processRows(index); - this.applyEmptyText(); - this.fireEvent('rowremoved', this, index, record); - } + + + + + }, - onLoad : function() { - if (Ext.isGecko) { - if (!this.scrollToTopTask) { - this.scrollToTopTask = new Ext.util.DelayedTask(this.scrollToTop, this); + + + onKeyDown: function(e, t) { + var me = this, + view = me.views[0], + idx = me.store.indexOf(me.lastFocused), + record; + + + + if (idx + 1 < me.store.getCount()) { + record = me.store.getAt(idx + 1); + if (me.selected.getCount() === 0) { + me.doSelect(record); + + } else if (e.shiftKey && me.lastFocused) { + if (me.isSelected(me.lastFocused) && me.isSelected(record)) { + me.doDeselect(me.lastFocused, true); + me.setLastFocused(record); + } else if (!me.isSelected(me.lastFocused)) { + me.doSelect(me.lastFocused, true); + me.doSelect(record, true); + } else { + me.doSelect(record, true); + } + } else if (e.ctrlKey) { + me.setLastFocused(record); + } else { + me.doSelect(record); + } - this.scrollToTopTask.delay(1); - } else { - this.scrollToTop(); } }, - - onColWidthChange : function(cm, col, width) { - this.updateColumnWidth(col, width); + scrollByDeltaX: function(delta) { + var view = this.views[0], + section = view.up(), + hScroll = section.horizontalScroller; + + if (hScroll) { + hScroll.scrollByDeltaX(delta); + } }, - - onHeaderChange : function(cm, col, text) { - this.updateHeaders(); + onKeyLeft: function(e, t) { + this.scrollByDeltaX(-this.deltaScroll); }, - - onHiddenChange : function(cm, col, hidden) { - this.updateColumnHidden(col, hidden); + onKeyRight: function(e, t) { + this.scrollByDeltaX(this.deltaScroll); }, - onColumnMove : function(cm, oldIndex, newIndex) { - this.indexMap = null; - this.refresh(true); - this.restoreScroll(this.getScrollState()); - - this.afterMove(newIndex); - this.grid.fireEvent('columnmove', oldIndex, newIndex); - }, - - onColConfigChange : function() { - delete this.lastViewWidth; - this.indexMap = null; - this.refresh(true); + onRowMouseDown: function(view, record, item, index, e) { + view.el.focus(); + this.selectWithEvent(record, e); }, - initUI : function(grid) { - grid.on('headerclick', this.onHeaderClick, this); + onSelectChange: function(record, isSelected, suppressEvent) { + var me = this, + views = me.views, + viewsLn = views.length, + store = me.store, + rowIdx = store.indexOf(record), + i = 0; + + for (; i < viewsLn; i++) { + if (isSelected) { + views[i].onRowSelect(rowIdx, suppressEvent); + if (!suppressEvent) { + me.fireEvent('select', me, record, rowIdx); + } + } else { + views[i].onRowDeselect(rowIdx, suppressEvent); + if (!suppressEvent) { + me.fireEvent('deselect', me, record, rowIdx); + } + } + } }, - initEvents : Ext.emptyFn, - - onHeaderClick : function(g, index) { - if (this.headersDisabled || !this.cm.isSortable(index)) { - return; + onLastFocusChanged: function(oldFocused, newFocused, supressFocus) { + var views = this.views, + viewsLn = views.length, + store = this.store, + rowIdx, + i = 0; + + if (oldFocused) { + rowIdx = store.indexOf(oldFocused); + if (rowIdx != -1) { + for (; i < viewsLn; i++) { + views[i].onRowFocus(rowIdx, false); + } + } } - g.stopEditing(true); - g.store.sort(this.cm.getDataIndex(index)); - }, - - onRowOver : function(e, target) { - var row = this.findRowIndex(target); - - if (row !== false) { - this.addRowClass(row, this.rowOverCls); + if (newFocused) { + rowIdx = store.indexOf(newFocused); + if (rowIdx != -1) { + for (i = 0; i < viewsLn; i++) { + views[i].onRowFocus(rowIdx, true, supressFocus); + } + } } }, - - onRowOut : function(e, target) { - var row = this.findRowIndex(target); - - if (row !== false && !e.within(this.getRow(row), true)) { - this.removeRowClass(row, this.rowOverCls); + onEditorTab: function(editingPlugin, e) { + var me = this, + view = me.views[0], + record = editingPlugin.getActiveRecord(), + header = editingPlugin.getActiveColumn(), + position = view.getPosition(record, header), + direction = e.shiftKey ? 'left' : 'right', + newPosition = view.walkCells(position, direction, e, this.preventWrap); + + if (newPosition) { + editingPlugin.startEditByPosition(newPosition); } }, + + selectByPosition: function(position) { + var record = this.store.getAt(position.row); + this.select(record); + } +}); + +Ext.define('Ext.selection.CheckboxModel', { + extend: 'Ext.selection.RowModel', - onRowSelect : function(row) { - this.addRowClass(row, this.selectedRowClass); - }, + mode: 'MULTI', + + + injectCheckbox: 0, - onRowDeselect : function(row) { - this.removeRowClass(row, this.selectedRowClass); + checkOnly: false, + + + checkerOnCls: Ext.baseCSSPrefix + 'grid-hd-checker-on', + + bindComponent: function() { + this.sortable = false; + this.callParent(arguments); + + var view = this.views[0], + headerCt = view.headerCt; + + if (this.injectCheckbox !== false) { + if (this.injectCheckbox == 'first') { + this.injectCheckbox = 0; + } else if (this.injectCheckbox == 'last') { + this.injectCheckbox = headerCt.getColumnCount(); + } + headerCt.add(this.injectCheckbox, this.getHeaderConfig()); + } + headerCt.on('headerclick', this.onHeaderClick, this); }, - onCellSelect : function(row, col) { - var cell = this.getCell(row, col); - if (cell) { - this.fly(cell).addClass('x-grid3-cell-selected'); + toggleUiHeader: function(isChecked) { + var view = this.views[0], + headerCt = view.headerCt, + checkHd = headerCt.child('gridcolumn[isCheckerHd]'); + + if (checkHd) { + if (isChecked) { + checkHd.el.addCls(this.checkerOnCls); + } else { + checkHd.el.removeCls(this.checkerOnCls); + } } }, - onCellDeselect : function(row, col) { - var cell = this.getCell(row, col); - if (cell) { - this.fly(cell).removeClass('x-grid3-cell-selected'); + onHeaderClick: function(headerCt, header, e) { + if (header.isCheckerHd) { + e.stopEvent(); + var isChecked = header.el.hasCls(Ext.baseCSSPrefix + 'grid-hd-checker-on'); + if (isChecked) { + + this.deselectAll(true); + } else { + + this.selectAll(true); + } } }, - handleWheel : function(e) { - e.stopPropagation(); + getHeaderConfig: function() { + return { + isCheckerHd: true, + text : ' ', + width: 24, + sortable: false, + fixed: true, + hideable: false, + menuDisabled: true, + dataIndex: '', + cls: Ext.baseCSSPrefix + 'column-header-checkbox ', + renderer: Ext.Function.bind(this.renderer, this) + }; + }, + + + renderer: function(value, metaData, record, rowIndex, colIndex, store, view) { + metaData.tdCls = Ext.baseCSSPrefix + 'grid-cell-special'; + return '
     
    '; }, - onColumnSplitterMoved : function(cellIndex, width) { - this.userResized = true; - this.grid.colModel.setColumnWidth(cellIndex, width, true); + onRowMouseDown: function(view, record, item, index, e) { + view.el.focus(); + var me = this, + checker = e.getTarget('.' + Ext.baseCSSPrefix + 'grid-row-checker'); - if (this.forceFit) { - this.fitColumns(true, false, cellIndex); - this.updateAllColumnWidths(); - } else { - this.updateColumnWidth(cellIndex, width); - this.syncHeaderScroll(); + + if (me.checkOnly && !checker) { + return; } - this.grid.fireEvent('columnresize', cellIndex, width); + if (checker) { + var mode = me.getSelectionMode(); + + + if (mode !== 'SINGLE') { + me.setSelectionMode('SIMPLE'); + } + me.selectWithEvent(record, e); + me.setSelectionMode(mode); + } else { + me.selectWithEvent(record, e); + } }, - beforeColMenuShow : function() { - var colModel = this.cm, - colCount = colModel.getColumnCount(), - colMenu = this.colMenu, - i; + onSelectChange: function(record, isSelected) { + this.callParent([record, isSelected]); + + var hdSelectStatus = this.selected.getCount() === this.store.getCount(); + this.toggleUiHeader(hdSelectStatus); + } +}); - colMenu.removeAll(); - for (i = 0; i < colCount; i++) { - if (colModel.config[i].hideable !== false) { - colMenu.add(new Ext.menu.CheckItem({ - text : colModel.getColumnHeader(i), - itemId : 'col-' + colModel.getColumnId(i), - checked : !colModel.isHidden(i), - disabled : colModel.config[i].hideable === false, - hideOnClick: false - })); +Ext.define('Ext.selection.TreeModel', { + extend: 'Ext.selection.RowModel', + alias: 'selection.treemodel', + + + + + pruneRemoved: false, + + onKeyRight: function(e, t) { + var focused = this.getLastFocused(), + view = this.view; + + if (focused) { + + + + if (focused.isExpanded()) { + this.onKeyDown(e, t); + + } else if (!focused.isLeaf()) { + view.expand(focused); } } }, - - handleHdMenuClick : function(item) { - var store = this.ds, - dataIndex = this.cm.getDataIndex(this.hdCtxIndex); + onKeyLeft: function(e, t) { + var focused = this.getLastFocused(), + view = this.view, + viewSm = view.getSelectionModel(), + parentNode, parentRecord; - switch (item.getItemId()) { - case 'asc': - store.sort(dataIndex, 'ASC'); - break; - case 'desc': - store.sort(dataIndex, 'DESC'); - break; - default: - this.handleHdMenuClickDefault(item); + if (focused) { + parentNode = focused.parentNode; + + if (focused.isExpanded()) { + view.collapse(focused); + + + } else if (parentNode && !parentNode.isRoot()) { + + if (e.shiftKey) { + viewSm.selectRange(parentNode, focused, e.ctrlKey, 'up'); + viewSm.setLastFocused(parentNode); + + } else if (e.ctrlKey) { + viewSm.setLastFocused(parentNode); + + } else { + viewSm.select(parentNode); + } + } } - return true; }, - - handleHdMenuClickDefault: function(item) { - var colModel = this.cm, - itemId = item.getItemId(), - index = colModel.getIndexById(itemId.substr(4)); - - if (index != -1) { - if (item.checked && colModel.getColumnsBy(this.isHideableColumn, this).length <= 1) { - this.onDenyColumnHide(); - return; + onKeyPress: function(e, t) { + var selected, checked; + + if (e.getKey() === e.SPACE || e.getKey() === e.ENTER) { + e.stopEvent(); + selected = this.getLastSelected(); + if (selected && selected.isLeaf()) { + checked = selected.get('checked'); + if (Ext.isBoolean(checked)) { + selected.set('checked', !checked); + } } - colModel.setHidden(index, item.checked); + } else { + this.callParent(arguments); } - }, + } +}); + + +Ext.define('Ext.slider.Thumb', { + requires: ['Ext.dd.DragTracker', 'Ext.util.Format'], + + topZIndex: 10000, + + constructor: function(config) { + var me = this; + + + Ext.apply(me, config || {}, { + cls: Ext.baseCSSPrefix + 'slider-thumb', - - handleHdDown : function(e, target) { - if (Ext.fly(target).hasClass('x-grid3-hd-btn')) { - e.stopEvent(); - - var colModel = this.cm, - header = this.findHeaderCell(target), - index = this.getCellIndex(header), - sortable = colModel.isSortable(index), - menu = this.hmenu, - menuItems = menu.items, - menuCls = this.headerMenuOpenCls; - - this.hdCtxIndex = index; - - Ext.fly(header).addClass(menuCls); - menuItems.get('asc').setDisabled(!sortable); - menuItems.get('desc').setDisabled(!sortable); - - menu.on('hide', function() { - Ext.fly(header).removeClass(menuCls); - }, this, {single:true}); - menu.show(target, 'tl-bl?'); + constrain: false + }); + me.callParent([config]); + + if (me.slider.vertical) { + Ext.apply(me, Ext.slider.Thumb.Vertical); } }, - handleHdMove : function(e) { - var header = this.findHeaderCell(this.activeHdRef); + render: function() { + var me = this; - if (header && !this.headersDisabled) { - var handleWidth = this.splitHandleWidth || 5, - activeRegion = this.activeHdRegion, - headerStyle = header.style, - colModel = this.cm, - cursor = '', - pageX = e.getPageX(); - - if (this.grid.enableColumnResize !== false) { - var activeHeaderIndex = this.activeHdIndex, - previousVisible = this.getPreviousVisible(activeHeaderIndex), - currentResizable = colModel.isResizable(activeHeaderIndex), - previousResizable = previousVisible && colModel.isResizable(previousVisible), - inLeftResizer = pageX - activeRegion.left <= handleWidth, - inRightResizer = activeRegion.right - pageX <= (!this.activeHdBtn ? handleWidth : 2); - - if (inLeftResizer && previousResizable) { - cursor = Ext.isAir ? 'move' : Ext.isWebKit ? 'e-resize' : 'col-resize'; - } else if (inRightResizer && currentResizable) { - cursor = Ext.isAir ? 'move' : Ext.isWebKit ? 'w-resize' : 'col-resize'; - } - } - - headerStyle.cursor = cursor; + me.el = me.slider.innerEl.insertFirst({cls: me.cls}); + if (me.disabled) { + me.disable(); } + me.initEvents(); }, - getPreviousVisible: function(index) { - while (index > 0) { - if (!this.cm.isHidden(index - 1)) { - return index; - } - index--; + move: function(v, animate){ + if(!animate){ + this.el.setLeft(v); + }else{ + Ext.create('Ext.fx.Anim', { + target: this.el, + duration: 350, + to: { + left: v + } + }); } - return undefined; }, - handleHdOver : function(e, target) { - var header = this.findHeaderCell(target); + bringToFront: function() { + this.el.setStyle('zIndex', this.topZIndex); + }, + + + sendToBack: function() { + this.el.setStyle('zIndex', ''); + }, + + + enable: function() { + var me = this; - if (header && !this.headersDisabled) { - var fly = this.fly(header); - - this.activeHdRef = target; - this.activeHdIndex = this.getCellIndex(header); - this.activeHdRegion = fly.getRegion(); - - if (!this.isMenuDisabled(this.activeHdIndex, fly)) { - fly.addClass('x-grid3-hd-over'); - this.activeHdBtn = fly.child('.x-grid3-hd-btn'); - - if (this.activeHdBtn) { - this.activeHdBtn.dom.style.height = (header.firstChild.offsetHeight - 1) + 'px'; - } - } + me.disabled = false; + if (me.el) { + me.el.removeCls(me.slider.disabledCls); } }, - handleHdOut : function(e, target) { - var header = this.findHeaderCell(target); + disable: function() { + var me = this; - if (header && (!Ext.isIE || !e.within(header, true))) { - this.activeHdRef = null; - this.fly(header).removeClass('x-grid3-hd-over'); - header.style.cursor = ''; + me.disabled = true; + if (me.el) { + me.el.addCls(me.slider.disabledCls); } }, + - - isMenuDisabled: function(cellIndex, el) { - return this.cm.isMenuDisabled(cellIndex); + initEvents: function() { + var me = this, + el = me.el; + + me.tracker = Ext.create('Ext.dd.DragTracker', { + onBeforeStart: Ext.Function.bind(me.onBeforeDragStart, me), + onStart : Ext.Function.bind(me.onDragStart, me), + onDrag : Ext.Function.bind(me.onDrag, me), + onEnd : Ext.Function.bind(me.onDragEnd, me), + tolerance : 3, + autoStart : 300, + overCls : Ext.baseCSSPrefix + 'slider-thumb-over' + }); + + me.tracker.initEl(el); }, - hasRows : function() { - var fc = this.mainBody.dom.firstChild; - return fc && fc.nodeType == 1 && fc.className != 'x-grid-empty'; + onBeforeDragStart : function(e) { + if (this.disabled) { + return false; + } else { + this.slider.promoteThumb(this); + return true; + } }, + - - isHideableColumn : function(c) { - return !c.hidden; + onDragStart: function(e){ + var me = this; + + me.el.addCls(Ext.baseCSSPrefix + 'slider-thumb-drag'); + me.dragging = true; + me.dragStartValue = me.value; + + me.slider.fireEvent('dragstart', me.slider, e, me); }, - bind : function(d, c) { - this.initData(d, c); - } -}); + onDrag: function(e) { + var me = this, + slider = me.slider, + index = me.index, + newValue = me.getNewValue(), + above, + below; + + if (me.constrain) { + above = slider.thumbs[index + 1]; + below = slider.thumbs[index - 1]; + if (below !== undefined && newValue <= below.value) { + newValue = below.value; + } + + if (above !== undefined && newValue >= above.value) { + newValue = above.value; + } + } + + slider.setValue(index, newValue, false); + slider.fireEvent('drag', slider, e, me); + }, + + getNewValue: function() { + var slider = this.slider, + pos = slider.innerEl.translatePoints(this.tracker.getXY()); + return Ext.util.Format.round(slider.reverseValue(pos.left), slider.decimalPrecision); + }, + + onDragEnd: function(e) { + var me = this, + slider = me.slider, + value = me.value; -Ext.grid.GridView.SplitDragZone = Ext.extend(Ext.dd.DDProxy, { + me.el.removeCls(Ext.baseCSSPrefix + 'slider-thumb-drag'); - constructor: function(grid, hd){ - this.grid = grid; - this.view = grid.getView(); - this.marker = this.view.resizeMarker; - this.proxy = this.view.resizeProxy; - Ext.grid.GridView.SplitDragZone.superclass.constructor.call(this, hd, - 'gridSplitters' + this.grid.getGridEl().id, { - dragElId : Ext.id(this.proxy.dom), resizeFrame:false - }); - this.scroll = false; - this.hw = this.view.splitHandleWidth || 5; - }, - - b4StartDrag : function(x, y){ - this.dragHeadersDisabled = this.view.headersDisabled; - this.view.headersDisabled = true; - var h = this.view.mainWrap.getHeight(); - this.marker.setHeight(h); - this.marker.show(); - this.marker.alignTo(this.view.getHeaderCell(this.cellIndex), 'tl-tl', [-2, 0]); - this.proxy.setHeight(h); - var w = this.cm.getColumnWidth(this.cellIndex), - minw = Math.max(w-this.grid.minColumnWidth, 0); - this.resetConstraints(); - this.setXConstraint(minw, 1000); - this.setYConstraint(0, 0); - this.minX = x - minw; - this.maxX = x + 1000; - this.startPos = x; - Ext.dd.DDProxy.prototype.b4StartDrag.call(this, x, y); + me.dragging = false; + slider.fireEvent('dragend', slider, e); + + if (me.dragStartValue != value) { + slider.fireEvent('changecomplete', slider, value, me); + } }, - allowHeaderDrag : function(e){ - return true; + destroy: function() { + Ext.destroy(this.tracker); }, + statics: { + + Vertical: { + getNewValue: function() { + var slider = this.slider, + innerEl = slider.innerEl, + pos = innerEl.translatePoints(this.tracker.getXY()), + bottom = innerEl.getHeight() - pos.top; - handleMouseDown : function(e){ - var t = this.view.findHeaderCell(e.getTarget()); - if(t && this.allowHeaderDrag(e)){ - var xy = this.view.fly(t).getXY(), - x = xy[0], - exy = e.getXY(), - ex = exy[0], - w = t.offsetWidth, - adjust = false; - - if((ex - x) <= this.hw){ - adjust = -1; - }else if((x+w) - ex <= this.hw){ - adjust = 0; - } - if(adjust !== false){ - this.cm = this.grid.colModel; - var ci = this.view.getCellIndex(t); - if(adjust == -1){ - if (ci + adjust < 0) { - return; - } - while(this.cm.isHidden(ci+adjust)){ - --adjust; - if(ci+adjust < 0){ - return; + return Ext.util.Format.round(slider.reverseValue(bottom), slider.decimalPrecision); + }, + move: function(v, animate) { + if (!animate) { + this.el.setBottom(v); + } else { + Ext.create('Ext.fx.Anim', { + target: this.el, + duration: 350, + to: { + bottom: v } - } - } - this.cellIndex = ci+adjust; - this.split = t.dom; - if(this.cm.isResizable(this.cellIndex) && !this.cm.isFixed(this.cellIndex)){ - Ext.grid.GridView.SplitDragZone.superclass.handleMouseDown.apply(this, arguments); + }); } - }else if(this.view.columnDrag){ - this.view.columnDrag.callHandleMouseDown(e); } } - }, + } +}); - endDrag : function(e){ - this.marker.hide(); - var v = this.view, - endX = Math.max(this.minX, e.getPageX()), - diff = endX - this.startPos, - disabled = this.dragHeadersDisabled; - - v.onColumnSplitterMoved(this.cellIndex, this.cm.getColumnWidth(this.cellIndex)+diff); - setTimeout(function(){ - v.headersDisabled = disabled; - }, 50); + +Ext.define('Ext.slider.Tip', { + extend: 'Ext.tip.Tip', + minWidth: 10, + alias: 'widget.slidertip', + offsets : [0, -10], + + isSliderTip: true, + + init: function(slider) { + var me = this; + + slider.on({ + scope : me, + dragstart: me.onSlide, + drag : me.onSlide, + dragend : me.hide, + destroy : me.destroy + }); + }, + + onSlide : function(slider, e, thumb) { + var me = this; + me.show(); + me.update(me.getText(thumb)); + me.doComponentLayout(); + me.el.alignTo(thumb.el, 'b-t?', me.offsets); }, - autoOffset : function(){ - this.setDelta(0,0); + + getText : function(thumb) { + return String(thumb.value); } }); -Ext.grid.PivotGridView = Ext.extend(Ext.grid.GridView, { - +Ext.define('Ext.slider.Multi', { + extend: 'Ext.form.field.Base', + alias: 'widget.multislider', + alternateClassName: 'Ext.slider.MultiSlider', + + requires: [ + 'Ext.slider.Thumb', + 'Ext.slider.Tip', + 'Ext.Number', + 'Ext.util.Format', + 'Ext.Template', + 'Ext.layout.component.field.Slider' + ], + + fieldSubTpl: [ + '
    ', + '', + '
    ', + { + disableFormats: true, + compiled: true + } + ], + - colHeaderCellCls: 'grid-hd-group-cell', + + - title: '', + vertical: false, + minValue: 0, + maxValue: 100, + decimalPrecision: 0, - getColumnHeaders: function() { - return this.grid.topAxis.buildHeaders();; - }, + keyIncrement: 1, + increment: 0, + - getRowHeaders: function() { - return this.grid.leftAxis.buildHeaders(); - }, + clickRange: [5,15], + + clickToChange : true, - renderRows : function(startRow, endRow) { - var grid = this.grid, - rows = grid.extractData(), - rowCount = rows.length, - templates = this.templates, - renderer = grid.renderer, - hasRenderer = typeof renderer == 'function', - getCellCls = this.getCellCls, - hasGetCellCls = typeof getCellCls == 'function', - cellTemplate = templates.cell, - rowTemplate = templates.row, - rowBuffer = [], - meta = {}, - tstyle = 'width:' + this.getGridInnerWidth() + 'px;', - colBuffer, column, i; - - startRow = startRow || 0; - endRow = Ext.isDefined(endRow) ? endRow : rowCount - 1; - - for (i = 0; i < rowCount; i++) { - row = rows[i]; - colCount = row.length; - colBuffer = []; - - rowIndex = startRow + i; + animate: true, - - for (j = 0; j < colCount; j++) { - cell = row[j]; + + dragging: false, - meta.css = j === 0 ? 'x-grid3-cell-first ' : (j == (colCount - 1) ? 'x-grid3-cell-last ' : ''); - meta.attr = meta.cellAttr = ''; - meta.value = cell; + + constrainThumbs: true, - if (Ext.isEmpty(meta.value)) { - meta.value = ' '; - } - - if (hasRenderer) { - meta.value = renderer(meta.value); - } - - if (hasGetCellCls) { - meta.css += getCellCls(meta.value) + ' '; - } + componentLayout: 'sliderfield', - colBuffer[colBuffer.length] = cellTemplate.apply(meta); - } - - rowBuffer[rowBuffer.length] = rowTemplate.apply({ - tstyle: tstyle, - cols : colCount, - cells : colBuffer.join(""), - alt : '' - }); - } - - return rowBuffer.join(""); - }, - - masterTpl: new Ext.Template( - '
    ', - '
    ', - '
    ', - '
    {title}
    ', - '
    ', - '
    ', - '
    ', - '
    ', - '
    ', - '
    ', - '
    ', - '
    {body}
    ', - '', - '
    ', - '
    ', - '
     
    ', - '
     
    ', - '
    ' - ), + useTips : true, + + tipText : null, + + ariaRole: 'slider', + - initTemplates: function() { - Ext.grid.PivotGridView.superclass.initTemplates.apply(this, arguments); + initValue: function() { + var me = this, + extValue = Ext.value, + + values = extValue(me.values, [extValue(me.value, extValue(me.minValue, 0))]), + i = 0, + len = values.length; + - var templates = this.templates || {}; - if (!templates.gcell) { - templates.gcell = new Ext.XTemplate( - '', - '
    ', - this.grid.enableHdMenu ? '' : '', '{value}', - '
    ', - '' - ); - } + me.originalValue = values; + - this.templates = templates; - this.hrowRe = new RegExp("ux-grid-hd-group-row-(\\d+)", ""); + for (; i < len; i++) { + me.addThumb(values[i]); + } }, + - - initElements: function() { - Ext.grid.PivotGridView.superclass.initElements.apply(this, arguments); - + initComponent : function() { + var me = this, + tipPlug, + hasTip; - this.rowHeadersEl = new Ext.Element(this.scroller.child('div.x-grid3-row-headers')); + me.thumbs = []; + + me.keyIncrement = Math.max(me.increment, me.keyIncrement); + + me.addEvents( + + 'beforechange', + + + 'change', + + + 'changecomplete', + + + 'dragstart', + + + 'drag', + + + 'dragend' + ); + + if (me.vertical) { + Ext.apply(me, Ext.slider.Multi.Vertical); + } + + me.callParent(); + - this.headerTitleEl = new Ext.Element(this.mainHd.child('div.x-grid3-header-title')); + if (me.useTips) { + tipPlug = me.tipText ? {getText: me.tipText} : {}; + me.plugins = me.plugins || []; + Ext.each(me.plugins, function(plug){ + if (plug.isSliderTip) { + hasTip = true; + return false; + } + }); + if (!hasTip) { + me.plugins.push(Ext.create('Ext.slider.Tip', tipPlug)); + } + } }, + - - getGridInnerWidth: function() { - var previousWidth = Ext.grid.PivotGridView.superclass.getGridInnerWidth.apply(this, arguments); + addThumb: function(value) { + var me = this, + thumb = Ext.create('Ext.slider.Thumb', { + value : value, + slider : me, + index : me.thumbs.length, + constrain: me.constrainThumbs + }); + me.thumbs.push(thumb); + - return previousWidth - this.getTotalRowHeaderWidth(); + if (me.rendered) { + thumb.render(); + } + + return thumb; }, + + promoteThumb: function(topThumb) { + var thumbs = this.thumbs, + ln = thumbs.length, + zIndex, thumb, i; + + for (i = 0; i < ln; i++) { + thumb = thumbs[i]; + + if (thumb == topThumb) { + thumb.bringToFront(); + } else { + thumb.sendToBack(); + } + } + }, + - getTotalRowHeaderWidth: function() { - var headers = this.getRowHeaders(), - length = headers.length, - total = 0, - i; + onRender : function() { + var me = this, + i = 0, + thumbs = me.thumbs, + len = thumbs.length, + thumb; + + Ext.applyIf(me.subTplData, { + vertical: me.vertical ? Ext.baseCSSPrefix + 'slider-vert' : Ext.baseCSSPrefix + 'slider-horz', + minValue: me.minValue, + maxValue: me.maxValue, + value: me.value + }); + + Ext.applyIf(me.renderSelectors, { + endEl: '.' + Ext.baseCSSPrefix + 'slider-end', + innerEl: '.' + Ext.baseCSSPrefix + 'slider-inner', + focusEl: '.' + Ext.baseCSSPrefix + 'slider-focus' + }); + + me.callParent(arguments); + - for (i = 0; i< length; i++) { - total += headers[i].width; + for (; i < len; i++) { + thumbs[i].render(); } + - return total; + thumb = me.innerEl.down('.' + Ext.baseCSSPrefix + 'slider-thumb'); + me.halfThumb = (me.vertical ? thumb.getHeight() : thumb.getWidth()) / 2; + }, + - - getTotalColumnHeaderHeight: function() { - return this.getColumnHeaders().length * 21; + onChange : function(slider, v) { + this.setValue(v, undefined, true); }, + - - renderUI : function() { - var templates = this.templates, - innerWidth = this.getGridInnerWidth(); - - return templates.master.apply({ - body : templates.body.apply({rows:' '}), - ostyle: 'width:' + innerWidth + 'px', - bstyle: 'width:' + innerWidth + 'px' + initEvents : function() { + var me = this; + + me.mon(me.el, { + scope : me, + mousedown: me.onMouseDown, + keydown : me.onKeyDown, + change : me.onChange }); + + me.focusEl.swallowEvent("click", true); }, + - - onLayout: function(width, height) { - Ext.grid.PivotGridView.superclass.onLayout.apply(this, arguments); - - var width = this.getGridInnerWidth(); + onMouseDown : function(e) { + var me = this, + thumbClicked = false, + i = 0, + thumbs = me.thumbs, + len = thumbs.length, + local; + + if (me.disabled) { + return; + } + - this.resizeColumnHeaders(width); - this.resizeAllRows(width); + for (; i < len; i++) { + thumbClicked = thumbClicked || e.target == thumbs[i].el.dom; + } + + if (me.clickToChange && !thumbClicked) { + local = me.innerEl.translatePoints(e.getXY()); + me.onClickChange(local); + } + me.focus(); }, + - - refresh : function(headersToo) { - this.fireEvent('beforerefresh', this); - this.grid.stopEditing(true); - - var result = this.renderBody(); - this.mainBody.update(result).setWidth(this.getGridInnerWidth()); - if (headersToo === true) { - this.updateHeaders(); - this.updateHeaderSortState(); + onClickChange : function(local) { + var me = this, + thumb, index; + + if (local.top > me.clickRange[0] && local.top < me.clickRange[1]) { + + thumb = me.getNearest(local, 'left'); + if (!thumb.disabled) { + index = thumb.index; + me.setValue(index, Ext.util.Format.round(me.reverseValue(local.left), me.decimalPrecision), undefined, true); + } } - this.processRows(0, true); - this.layout(); - this.applyEmptyText(); - this.fireEvent('refresh', this); }, + - - renderHeaders: Ext.emptyFn, - - - fitColumns: Ext.emptyFn, - - - resizeColumnHeaders: function(width) { - var topAxis = this.grid.topAxis; - - if (topAxis.rendered) { - topAxis.el.setWidth(width); + getNearest: function(local, prop) { + var me = this, + localValue = prop == 'top' ? me.innerEl.getHeight() - local[prop] : local[prop], + clickValue = me.reverseValue(localValue), + nearestDistance = (me.maxValue - me.minValue) + 5, + index = 0, + nearest = null, + thumbs = me.thumbs, + i = 0, + len = thumbs.length, + thumb, + value, + dist; + + for (; i < len; i++) { + thumb = me.thumbs[i]; + value = thumb.value; + dist = Math.abs(value - clickValue); + + if (Math.abs(dist <= nearestDistance)) { + nearest = thumb; + index = i; + nearestDistance = dist; + } } + return nearest; }, + - - resizeRowHeaders: function() { - var rowHeaderWidth = this.getTotalRowHeaderWidth(), - marginStyle = String.format("margin-left: {0}px;", rowHeaderWidth); + onKeyDown : function(e) { - this.rowHeadersEl.setWidth(rowHeaderWidth); - this.mainBody.applyStyles(marginStyle); - Ext.fly(this.innerHd).applyStyles(marginStyle); + var me = this, + k, + val; - this.headerTitleEl.setWidth(rowHeaderWidth); - this.headerTitleEl.setHeight(this.getTotalColumnHeaderHeight()); - }, - - - resizeAllRows: function(width) { - var rows = this.getRows(), - length = rows.length, - i; + if(me.disabled || me.thumbs.length !== 1) { + e.preventDefault(); + return; + } + k = e.getKey(); - for (i = 0; i < length; i++) { - Ext.fly(rows[i]).setWidth(width); - Ext.fly(rows[i]).child('table').setWidth(width); + switch(k) { + case e.UP: + case e.RIGHT: + e.stopEvent(); + val = e.ctrlKey ? me.maxValue : me.getValue(0) + me.keyIncrement; + me.setValue(0, val, undefined, true); + break; + case e.DOWN: + case e.LEFT: + e.stopEvent(); + val = e.ctrlKey ? me.minValue : me.getValue(0) - me.keyIncrement; + me.setValue(0, val, undefined, true); + break; + default: + e.preventDefault(); } }, + - - updateHeaders: function() { - this.renderGroupRowHeaders(); - this.renderGroupColumnHeaders(); + doSnap : function(value) { + var newValue = value, + inc = this.increment, + m; + + if (!(inc && value)) { + return value; + } + m = value % inc; + if (m !== 0) { + newValue -= m; + if (m * 2 >= inc) { + newValue += inc; + } else if (m * 2 < -inc) { + newValue -= inc; + } + } + return Ext.Number.constrain(newValue, this.minValue, this.maxValue); }, + - - renderGroupRowHeaders: function() { - var leftAxis = this.grid.leftAxis; - - this.resizeRowHeaders(); - leftAxis.rendered = false; - leftAxis.render(this.rowHeadersEl); - - this.setTitle(this.title); + afterRender : function() { + var me = this, + i = 0, + thumbs = me.thumbs, + len = thumbs.length, + thumb, + v; + + me.callParent(arguments); + + for (; i < len; i++) { + thumb = thumbs[i]; + + if (thumb.value !== undefined) { + v = me.normalizeValue(thumb.value); + if (v !== thumb.value) { + + me.setValue(i, v, false); + } else { + thumb.move(me.translateValue(v), false); + } + } + } }, + - - setTitle: function(title) { - this.headerTitleEl.child('span').dom.innerHTML = title; + getRatio : function() { + var w = this.innerEl.getWidth(), + v = this.maxValue - this.minValue; + return v === 0 ? w : (w/v); }, + - - renderGroupColumnHeaders: function() { - var topAxis = this.grid.topAxis; + normalizeValue : function(v) { + var me = this; - topAxis.rendered = false; - topAxis.render(this.innerHd.firstChild); - }, - - - isMenuDisabled: function(cellIndex, el) { - return true; - } -}); -Ext.grid.PivotAxis = Ext.extend(Ext.Component, { - - orientation: 'horizontal', - - - defaultHeaderWidth: 80, - - - paddingWidth: 7, - - - setDimensions: function(dimensions) { - this.dimensions = dimensions; + v = me.doSnap(v); + v = Ext.util.Format.round(v, me.decimalPrecision); + v = Ext.Number.constrain(v, me.minValue, me.maxValue); + return v; }, + - - onRender: function(ct, position) { - var rows = this.orientation == 'horizontal' - ? this.renderHorizontalRows() - : this.renderVerticalRows(); - - this.el = Ext.DomHelper.overwrite(ct.dom, {tag: 'table', cn: rows}, true); + setMinValue : function(val) { + var me = this, + i = 0, + thumbs = me.thumbs, + len = thumbs.length, + t; + + me.minValue = val; + me.inputEl.dom.setAttribute('aria-valuemin', val); + + for (; i < len; ++i) { + t = thumbs[i]; + t.value = t.value < val ? val : t.value; + } + me.syncThumbs(); }, - - - renderHorizontalRows: function() { - var headers = this.buildHeaders(), - rowCount = headers.length, - rows = [], - cells, cols, colCount, i, j; - - for (i = 0; i < rowCount; i++) { - cells = []; - cols = headers[i].items; - colCount = cols.length; - for (j = 0; j < colCount; j++) { - cells.push({ - tag: 'td', - html: cols[j].header, - colspan: cols[j].span - }); - } + + setMaxValue : function(val) { + var me = this, + i = 0, + thumbs = me.thumbs, + len = thumbs.length, + t; + + me.maxValue = val; + me.inputEl.dom.setAttribute('aria-valuemax', val); - rows[i] = { - tag: 'tr', - cn: cells - }; + for (; i < len; ++i) { + t = thumbs[i]; + t.value = t.value > val ? val : t.value; } - - return rows; + me.syncThumbs(); }, + - - renderVerticalRows: function() { - var headers = this.buildHeaders(), - colCount = headers.length, - rowCells = [], - rows = [], - rowCount, col, row, colWidth, i, j; + setValue : function(index, value, animate, changeComplete) { + var me = this, + thumb = me.thumbs[index]; + - for (i = 0; i < colCount; i++) { - col = headers[i]; - colWidth = col.width || 80; - rowCount = col.items.length; - - for (j = 0; j < rowCount; j++) { - row = col.items[j]; + value = me.normalizeValue(value); + + if (value !== thumb.value && me.fireEvent('beforechange', me, value, thumb.value, thumb) !== false) { + thumb.value = value; + if (me.rendered) { - rowCells[row.start] = rowCells[row.start] || []; - rowCells[row.start].push({ - tag : 'td', - html : row.header, - rowspan: row.span, - width : Ext.isBorderBox ? colWidth : colWidth - this.paddingWidth + + me.inputEl.set({ + 'aria-valuenow': value, + 'aria-valuetext': value }); + + thumb.move(me.translateValue(value), Ext.isDefined(animate) ? animate !== false : me.animate); + + me.fireEvent('change', me, value, thumb); + if (changeComplete) { + me.fireEvent('changecomplete', me, value, thumb); + } } } - - rowCount = rowCells.length; - for (i = 0; i < rowCount; i++) { - rows[i] = { - tag: 'tr', - cn : rowCells[i] - }; - } - - return rows; }, + - - getTuples: function() { - var newStore = new Ext.data.Store({}); - - newStore.data = this.store.data.clone(); - newStore.fields = this.store.fields; - - var sorters = [], - dimensions = this.dimensions, - length = dimensions.length, - i; - - for (i = 0; i < length; i++) { - sorters.push({ - field : dimensions[i].dataIndex, - direction: dimensions[i].direction || 'ASC' - }); - } - - newStore.sort(sorters); - - var records = newStore.data.items, - hashes = [], - tuples = [], - recData, hash, info, data, key; - - length = records.length; - - for (i = 0; i < length; i++) { - info = this.getRecordInfo(records[i]); - data = info.data; - hash = ""; - - for (key in data) { - hash += data[key] + '---'; - } - - if (hashes.indexOf(hash) == -1) { - hashes.push(hash); - tuples.push(info); - } - } - - newStore.destroy(); - - return tuples; + translateValue : function(v) { + var ratio = this.getRatio(); + return (v * ratio) - (this.minValue * ratio) - this.halfThumb; }, + - - getRecordInfo: function(record) { - var dimensions = this.dimensions, - length = dimensions.length, - data = {}, - dimension, dataIndex, i; - - - for (i = 0; i < length; i++) { - dimension = dimensions[i]; - dataIndex = dimension.dataIndex; - - data[dataIndex] = record.get(dataIndex); - } - - - - var createMatcherFunction = function(data) { - return function(record) { - for (var dataIndex in data) { - if (record.get(dataIndex) != data[dataIndex]) { - return false; - } - } - - return true; - }; - }; - - return { - data: data, - matcher: createMatcherFunction(data) - }; + reverseValue : function(pos) { + var ratio = this.getRatio(); + return (pos + (this.minValue * ratio)) / ratio; }, + + focus : function() { + this.focusEl.focus(10); + }, + - buildHeaders: function() { - var tuples = this.getTuples(), - rowCount = tuples.length, - dimensions = this.dimensions, - colCount = dimensions.length, - headers = [], - tuple, rows, currentHeader, previousHeader, span, start, isLast, changed, i, j; - - for (i = 0; i < colCount; i++) { - dimension = dimensions[i]; - rows = []; - span = 0; - start = 0; - - for (j = 0; j < rowCount; j++) { - tuple = tuples[j]; - isLast = j == (rowCount - 1); - currentHeader = tuple.data[dimension.dataIndex]; - - - changed = previousHeader != undefined && previousHeader != currentHeader; - if (i > 0 && j > 0) { - changed = changed || tuple.data[dimensions[i-1].dataIndex] != tuples[j-1].data[dimensions[i-1].dataIndex]; - } - - if (changed) { - rows.push({ - header: previousHeader, - span : span, - start : start - }); - - start += span; - span = 0; - } - - if (isLast) { - rows.push({ - header: currentHeader, - span : span + 1, - start : start - }); - - start += span; - span = 0; - } - - previousHeader = currentHeader; - span++; - } - - headers.push({ - items: rows, - width: dimension.width || this.defaultHeaderWidth - }); + onDisable: function() { + var me = this, + i = 0, + thumbs = me.thumbs, + len = thumbs.length, + thumb, + el, + xy; - previousHeader = undefined; - } - - return headers; - } -}); + me.callParent(); + + for (; i < len; i++) { + thumb = thumbs[i]; + el = thumb.el; + + thumb.disable(); + if(Ext.isIE) { + + + xy = el.getXY(); + el.hide(); -Ext.grid.HeaderDragZone = Ext.extend(Ext.dd.DragZone, { - maxDragWidth: 120, - - constructor : function(grid, hd, hd2){ - this.grid = grid; - this.view = grid.getView(); - this.ddGroup = "gridHeader" + this.grid.getGridEl().id; - Ext.grid.HeaderDragZone.superclass.constructor.call(this, hd); - if(hd2){ - this.setHandleElId(Ext.id(hd)); - this.setOuterHandleElId(Ext.id(hd2)); - } - this.scroll = false; - }, - - getDragData : function(e){ - var t = Ext.lib.Event.getTarget(e), - h = this.view.findHeaderCell(t); - if(h){ - return {ddel: h.firstChild, header:h}; - } - return false; - }, + me.innerEl.addCls(me.disabledCls).dom.disabled = true; - onInitDrag : function(e){ - - this.dragHeadersDisabled = this.view.headersDisabled; - this.view.headersDisabled = true; - var clone = this.dragData.ddel.cloneNode(true); - clone.id = Ext.id(); - clone.style.width = Math.min(this.dragData.header.offsetWidth,this.maxDragWidth) + "px"; - this.proxy.update(clone); - return true; - }, + if (!me.thumbHolder) { + me.thumbHolder = me.endEl.createChild({cls: Ext.baseCSSPrefix + 'slider-thumb ' + me.disabledCls}); + } - afterValidDrop : function(){ - this.completeDrop(); + me.thumbHolder.show().setXY(xy); + } + } }, - afterInvalidDrop : function(){ - this.completeDrop(); - }, - completeDrop: function(){ - var v = this.view, - disabled = this.dragHeadersDisabled; - setTimeout(function(){ - v.headersDisabled = disabled; - }, 50); - } -}); + onEnable: function() { + var me = this, + i = 0, + thumbs = me.thumbs, + len = thumbs.length, + thumb, + el; + + this.callParent(); + for (; i < len; i++) { + thumb = thumbs[i]; + el = thumb.el; + thumb.enable(); -Ext.grid.HeaderDropZone = Ext.extend(Ext.dd.DropZone, { - proxyOffsets : [-4, -9], - fly: Ext.Element.fly, - - constructor : function(grid, hd, hd2){ - this.grid = grid; - this.view = grid.getView(); - - this.proxyTop = Ext.DomHelper.append(document.body, { - cls:"col-move-top", html:" " - }, true); - this.proxyBottom = Ext.DomHelper.append(document.body, { - cls:"col-move-bottom", html:" " - }, true); - this.proxyTop.hide = this.proxyBottom.hide = function(){ - this.setLeftTop(-100,-100); - this.setStyle("visibility", "hidden"); - }; - this.ddGroup = "gridHeader" + this.grid.getGridEl().id; - - - Ext.grid.HeaderDropZone.superclass.constructor.call(this, grid.getGridEl().dom); - }, + if (Ext.isIE) { + me.innerEl.removeCls(me.disabledCls).dom.disabled = false; - getTargetFromEvent : function(e){ - var t = Ext.lib.Event.getTarget(e), - cindex = this.view.findCellIndex(t); - if(cindex !== false){ - return this.view.getHeaderCell(cindex); - } - }, + if (me.thumbHolder) { + me.thumbHolder.hide(); + } - nextVisible : function(h){ - var v = this.view, cm = this.grid.colModel; - h = h.nextSibling; - while(h){ - if(!cm.isHidden(v.getCellIndex(h))){ - return h; + el.show(); + me.syncThumbs(); } - h = h.nextSibling; } - return null; }, - prevVisible : function(h){ - var v = this.view, cm = this.grid.colModel; - h = h.prevSibling; - while(h){ - if(!cm.isHidden(v.getCellIndex(h))){ - return h; + + syncThumbs : function() { + if (this.rendered) { + var thumbs = this.thumbs, + length = thumbs.length, + i = 0; + + for (; i < length; i++) { + thumbs[i].move(this.translateValue(thumbs[i].value)); } - h = h.prevSibling; } - return null; }, - positionIndicator : function(h, n, e){ - var x = Ext.lib.Event.getPageX(e), - r = Ext.lib.Dom.getRegion(n.firstChild), - px, - pt, - py = r.top + this.proxyOffsets[1]; - if((r.right - x) <= (r.right-r.left)/2){ - px = r.right+this.view.borderWidth; - pt = "after"; - }else{ - px = r.left; - pt = "before"; - } + + getValue : function(index) { + return Ext.isNumber(index) ? this.thumbs[index].value : this.getValues(); + }, - if(this.grid.colModel.isFixed(this.view.getCellIndex(n))){ - return false; - } + + getValues: function() { + var values = [], + i = 0, + thumbs = this.thumbs, + len = thumbs.length; - px += this.proxyOffsets[0]; - this.proxyTop.setLeftTop(px, py); - this.proxyTop.show(); - if(!this.bottomOffset){ - this.bottomOffset = this.view.mainHd.getHeight(); + for (; i < len; i++) { + values.push(thumbs[i].value); } - this.proxyBottom.setLeftTop(px, py+this.proxyTop.dom.offsetHeight+this.bottomOffset); - this.proxyBottom.show(); - return pt; + + return values; }, - onNodeEnter : function(n, dd, e, data){ - if(data.header != n){ - this.positionIndicator(data.header, n, e); - } + getSubmitValue: function() { + var me = this; + return (me.disabled || !me.submitValue) ? null : me.getValue(); }, - onNodeOver : function(n, dd, e, data){ - var result = false; - if(data.header != n){ - result = this.positionIndicator(data.header, n, e); - } - if(!result){ - this.proxyTop.hide(); - this.proxyBottom.hide(); - } - return result ? this.dropAllowed : this.dropNotAllowed; + reset: function() { + var me = this, + Array = Ext.Array; + Array.forEach(Array.from(me.originalValue), function(val, i) { + me.setValue(i, val); + }); + me.clearInvalid(); + + delete me.wasValid; }, - onNodeOut : function(n, dd, e, data){ - this.proxyTop.hide(); - this.proxyBottom.hide(); + + beforeDestroy : function() { + var me = this; + + Ext.destroyMembers(me.innerEl, me.endEl, me.focusEl); + Ext.each(me.thumbs, function(thumb) { + Ext.destroy(thumb); + }, me); + + me.callParent(); }, - onNodeDrop : function(n, dd, e, data){ - var h = data.header; - if(h != n){ - var cm = this.grid.colModel, - x = Ext.lib.Event.getPageX(e), - r = Ext.lib.Dom.getRegion(n.firstChild), - pt = (r.right - x) <= ((r.right-r.left)/2) ? "after" : "before", - oldIndex = this.view.getCellIndex(h), - newIndex = this.view.getCellIndex(n); - if(pt == "after"){ - newIndex++; - } - if(oldIndex < newIndex){ - newIndex--; - } - cm.moveColumn(oldIndex, newIndex); - return true; + statics: { + + Vertical: { + getRatio : function() { + var h = this.innerEl.getHeight(), + v = this.maxValue - this.minValue; + return h/v; + }, + + onClickChange : function(local) { + var me = this, + thumb, index, bottom; + + if (local.left > me.clickRange[0] && local.left < me.clickRange[1]) { + thumb = me.getNearest(local, 'top'); + if (!thumb.disabled) { + index = thumb.index; + bottom = me.reverseValue(me.innerEl.getHeight() - local.top); + + me.setValue(index, Ext.util.Format.round(me.minValue + bottom, me.decimalPrecision), undefined, true); + } + } + } } - return false; } }); -Ext.grid.GridView.ColumnDragZone = Ext.extend(Ext.grid.HeaderDragZone, { - - constructor : function(grid, hd){ - Ext.grid.GridView.ColumnDragZone.superclass.constructor.call(this, grid, hd, null); - this.proxy.el.addClass('x-grid3-col-dd'); - }, - - handleMouseDown : function(e){ - }, - callHandleMouseDown : function(e){ - Ext.grid.GridView.ColumnDragZone.superclass.handleMouseDown.call(this, e); - } -}); +Ext.define('Ext.slider.Single', { + extend: 'Ext.slider.Multi', + alias: ['widget.slider', 'widget.sliderfield'], + alternateClassName: ['Ext.Slider', 'Ext.form.SliderField', 'Ext.slider.SingleSlider', 'Ext.slider.Slider'], -Ext.grid.SplitDragZone = Ext.extend(Ext.dd.DDProxy, { - fly: Ext.Element.fly, - constructor : function(grid, hd, hd2){ - this.grid = grid; - this.view = grid.getView(); - this.proxy = this.view.resizeProxy; - Ext.grid.SplitDragZone.superclass.constructor.call(this, hd, - "gridSplitters" + this.grid.getGridEl().id, { - dragElId : Ext.id(this.proxy.dom), resizeFrame:false - }); - this.setHandleElId(Ext.id(hd)); - this.setOuterHandleElId(Ext.id(hd2)); - this.scroll = false; - }, - - b4StartDrag : function(x, y){ - this.view.headersDisabled = true; - this.proxy.setHeight(this.view.mainWrap.getHeight()); - var w = this.cm.getColumnWidth(this.cellIndex); - var minw = Math.max(w-this.grid.minColumnWidth, 0); - this.resetConstraints(); - this.setXConstraint(minw, 1000); - this.setYConstraint(0, 0); - this.minX = x - minw; - this.maxX = x + 1000; - this.startPos = x; - Ext.dd.DDProxy.prototype.b4StartDrag.call(this, x, y); + getValue: function() { + + return this.callParent([0]); }, + + setValue: function(value, animate) { + var args = Ext.toArray(arguments), + len = args.length; - handleMouseDown : function(e){ - var ev = Ext.EventObject.setEvent(e); - var t = this.fly(ev.getTarget()); - if(t.hasClass("x-grid-split")){ - this.cellIndex = this.view.getCellIndex(t.dom); - this.split = t.dom; - this.cm = this.grid.colModel; - if(this.cm.isResizable(this.cellIndex) && !this.cm.isFixed(this.cellIndex)){ - Ext.grid.SplitDragZone.superclass.handleMouseDown.apply(this, arguments); - } + + + + if (len == 1 || (len <= 3 && typeof arguments[1] != 'number')) { + args.unshift(0); } - }, - endDrag : function(e){ - this.view.headersDisabled = false; - var endX = Math.max(this.minX, Ext.lib.Event.getPageX(e)); - var diff = endX - this.startPos; - this.view.onColumnSplitterMoved(this.cellIndex, this.cm.getColumnWidth(this.cellIndex)+diff); + return this.callParent(args); }, - autoOffset : function(){ - this.setDelta(0,0); + + getNearest : function(){ + + return this.thumbs[0]; } }); -Ext.grid.GridDragZone = function(grid, config){ - this.view = grid.getView(); - Ext.grid.GridDragZone.superclass.constructor.call(this, this.view.mainBody.dom, config); - this.scroll = false; - this.grid = grid; - this.ddel = document.createElement('div'); - this.ddel.className = 'x-grid-dd-wrap'; -}; -Ext.extend(Ext.grid.GridDragZone, Ext.dd.DragZone, { - ddGroup : "GridDD", +Ext.define('Ext.tab.Tab', { + extend: 'Ext.button.Button', + alias: 'widget.tab', - getDragData : function(e){ - var t = Ext.lib.Event.getTarget(e); - var rowIndex = this.view.findRowIndex(t); - if(rowIndex !== false){ - var sm = this.grid.selModel; - if(!sm.isSelected(rowIndex) || e.hasModifier()){ - sm.handleMouseDown(this.grid, rowIndex, e); - } - return {grid: this.grid, ddel: this.ddel, rowIndex: rowIndex, selections:sm.getSelections()}; - } - return false; - }, + requires: [ + 'Ext.layout.component.Tab', + 'Ext.util.KeyNav' + ], + + componentLayout: 'tab', + + isTab: true, + + baseCls: Ext.baseCSSPrefix + 'tab', - onInitDrag : function(e){ - var data = this.dragData; - this.ddel.innerHTML = this.grid.getDragDropText(); - this.proxy.update(this.ddel); - - }, + activeCls: 'active', + + - afterRepair : function(){ - this.dragging = false; - }, + closableCls: 'closable', - getRepairXY : function(e, data){ - return false; - }, + closable: true, - onEndDrag : function(data, e){ - - }, + + closeText: 'Close Tab', - onValidDrop : function(dd, e, id){ - - this.hideProxy(); - }, + + active: false, - beforeInvalidDrop : function(e, id){ + - } -}); + scale: false, -Ext.grid.ColumnModel = Ext.extend(Ext.util.Observable, { + position: 'top', - defaultWidth: 100, + initComponent: function() { + var me = this; - - defaultSortable: false, + me.addEvents( + + 'activate', + + + 'deactivate', + + + 'beforeclose', + + + 'close' + ); + + me.callParent(arguments); + + if (me.card) { + me.setCard(me.card); + } + }, + onRender: function() { + var me = this; + + me.addClsWithUI(me.position); + + + + + me.syncClosableUI(); + me.callParent(arguments); + + if (me.active) { + me.activate(true); + } + + me.syncClosableElements(); + + me.keyNav = Ext.create('Ext.util.KeyNav', me.el, { + enter: me.onEnterKey, + del: me.onDeleteKey, + scope: me + }); + }, + + enable : function(silent) { + var me = this; - constructor : function(config) { + me.callParent(arguments); - if (config.columns) { - Ext.apply(this, config); - this.setConfig(config.columns, true); - } else { - this.setConfig(config, true); - } - - this.addEvents( - - "widthchange", - - - "headerchange", - - - "hiddenchange", - - - "columnmoved", - - - "configchange" - ); - - Ext.grid.ColumnModel.superclass.constructor.call(this); + me.removeClsWithUI(me.position + '-disabled'); + + return me; }, - getColumnId : function(index) { - return this.config[index].id; + disable : function(silent) { + var me = this; + + me.callParent(arguments); + + me.addClsWithUI(me.position + '-disabled'); + + return me; }, + + + onDestroy: function() { + var me = this; + + if (me.closeEl) { + me.closeEl.un('click', Ext.EventManager.preventDefault); + me.closeEl = null; + } + + Ext.destroy(me.keyNav); + delete me.keyNav; - getColumnAt : function(index) { - return this.config[index]; + me.callParent(arguments); }, - setConfig : function(config, initial) { - var i, c, len; + setClosable: function(closable) { + var me = this; + - if (!initial) { - delete this.totalWidth; + closable = (!arguments.length || !!closable); + + if (me.closable != closable) { + me.closable = closable; + - for (i = 0, len = this.config.length; i < len; i++) { - c = this.config[i]; + if (me.card) { + me.card.closable = closable; + } + + me.syncClosableUI(); + + if (me.rendered) { + me.syncClosableElements(); + - if (c.setEditor) { - - c.setEditor(null); + me.doComponentLayout(); + if (me.ownerCt) { + me.ownerCt.doLayout(); } } } + }, - - this.defaults = Ext.apply({ - width: this.defaultWidth, - sortable: this.defaultSortable - }, this.defaults); - - this.config = config; - this.lookup = {}; + + syncClosableElements: function () { + var me = this; - for (i = 0, len = config.length; i < len; i++) { - c = Ext.applyIf(config[i], this.defaults); - - - if (Ext.isEmpty(c.id)) { - c.id = i; + if (me.closable) { + if (!me.closeEl) { + me.closeEl = me.el.createChild({ + tag: 'a', + cls: me.baseCls + '-close-btn', + href: '#', + html: me.closeText, + title: me.closeText + }).on('click', Ext.EventManager.preventDefault); } - - if (!c.isColumn) { - var Cls = Ext.grid.Column.types[c.xtype || 'gridcolumn']; - c = new Cls(c); - config[i] = c; + } else { + var closeEl = me.closeEl; + if (closeEl) { + closeEl.un('click', Ext.EventManager.preventDefault); + closeEl.remove(); + me.closeEl = null; } - - this.lookup[c.id] = c; } - - if (!initial) { - this.fireEvent('configchange', this); + }, + + + syncClosableUI: function () { + var me = this, classes = [me.closableCls, me.closableCls + '-' + me.position]; + + if (me.closable) { + me.addClsWithUI(classes); + } else { + me.removeClsWithUI(classes); } }, - getColumnById : function(id) { - return this.lookup[id]; + setCard: function(card) { + var me = this; + + me.card = card; + me.setText(me.title || card.title); + me.setIconCls(me.iconCls || card.iconCls); }, - getIndexById : function(id) { - for (var i = 0, len = this.config.length; i < len; i++) { - if (this.config[i].id == id) { - return i; + onCloseClick: function() { + var me = this; + + if (me.fireEvent('beforeclose', me) !== false) { + if (me.tabBar) { + me.tabBar.closeTab(me); } + + me.fireEvent('close', me); } - return -1; }, - - moveColumn : function(oldIndex, newIndex) { - var config = this.config, - c = config[oldIndex]; - - config.splice(oldIndex, 1); - config.splice(newIndex, 0, c); - this.dataMap = null; - this.fireEvent("columnmoved", this, oldIndex, newIndex); + + onEnterKey: function(e) { + var me = this; + + if (me.tabBar) { + me.tabBar.onClick(e, me.el); + } }, - - getColumnCount : function(visibleOnly) { - var length = this.config.length, - c = 0, - i; + + onDeleteKey: function(e) { + var me = this; - if (visibleOnly === true) { - for (i = 0; i < length; i++) { - if (!this.isHidden(i)) { - c++; - } - } - - return c; + if (me.closable) { + me.onCloseClick(); } + }, + + + activate : function(supressEvent) { + var me = this; - return length; + me.active = true; + me.addClsWithUI([me.activeCls, me.position + '-' + me.activeCls]); + + if (supressEvent !== true) { + me.fireEvent('activate', me); + } }, - getColumnsBy : function(fn, scope) { - var config = this.config, - length = config.length, - result = [], - i, c; - - for (i = 0; i < length; i++){ - c = config[i]; - - if (fn.call(scope || this, c, i) === true) { - result[result.length] = c; - } - } + deactivate : function(supressEvent) { + var me = this; - return result; - }, + me.active = false; + me.removeClsWithUI([me.activeCls, me.position + '-' + me.activeCls]); + + if (supressEvent !== true) { + me.fireEvent('deactivate', me); + } + } +}); + + +Ext.define('Ext.tab.Bar', { + extend: 'Ext.panel.Header', + alias: 'widget.tabbar', + baseCls: Ext.baseCSSPrefix + 'tab-bar', + + requires: [ + 'Ext.tab.Tab', + 'Ext.FocusManager' + ], - isSortable : function(col) { - return !!this.config[col].sortable; - }, + defaultType: 'tab', - isMenuDisabled : function(col) { - return !!this.config[col].menuDisabled; - }, + plain: false, - getRenderer : function(col) { - return this.config[col].renderer || Ext.grid.ColumnModel.defaultRenderer; - }, + renderTpl: [ + '
    {baseCls}-body-{ui} {parent.baseCls}-body-{parent.ui}-{.}" style="{bodyStyle}">
    ', + '
    {baseCls}-strip-{ui} {parent.baseCls}-strip-{parent.ui}-{.}">
    ' + ], - getRendererScope : function(col) { - return this.config[col].scope; - }, + + minTabWidth: 30, - setRenderer : function(col, fn) { - this.config[col].renderer = fn; - }, + maxTabWidth: undefined, - getColumnWidth : function(col) { - var width = this.config[col].width; - if(typeof width != 'number'){ - width = this.defaultWidth; + initComponent: function() { + var me = this, + keys; + + if (me.plain) { + me.setUI(me.ui + '-plain'); } - return width; - }, + + me.addClsWithUI(me.dock); + + me.addEvents( + + 'change' + ); + + Ext.applyIf(this.renderSelectors, { + body : '.' + this.baseCls + '-body', + strip: '.' + this.baseCls + '-strip' + }); + me.callParent(arguments); - - setColumnWidth : function(col, width, suppressEvent) { - this.config[col].width = width; - this.totalWidth = null; - if (!suppressEvent) { - this.fireEvent("widthchange", this, col, width); - } + me.layout.align = (me.orientation == 'vertical') ? 'left' : 'top'; + me.layout.overflowHandler = Ext.create('Ext.layout.container.boxOverflow.Scroller', me.layout); + me.items.removeAt(me.items.getCount() - 1); + me.items.removeAt(me.items.getCount() - 1); + + + keys = me.orientation == 'vertical' ? ['up', 'down'] : ['left', 'right']; + Ext.FocusManager.subscribe(me, { + keys: keys + }); }, - getTotalWidth : function(includeHidden) { - if (!this.totalWidth) { - this.totalWidth = 0; - for (var i = 0, len = this.config.length; i < len; i++) { - if (includeHidden || !this.isHidden(i)) { - this.totalWidth += this.getColumnWidth(i); - } - } + onAdd: function(tab) { + var me = this, + tabPanel = me.tabPanel, + hasOwner = !!tabPanel; + + me.callParent(arguments); + tab.position = me.dock; + if (hasOwner) { + tab.minWidth = tabPanel.minTabWidth; + } + else { + tab.minWidth = me.minTabWidth + (tab.iconCls ? 25 : 0); } - return this.totalWidth; + tab.maxWidth = me.maxTabWidth || (hasOwner ? tabPanel.maxTabWidth : undefined); }, - getColumnHeader : function(col) { - return this.config[col].header; - }, + afterRender: function() { + var me = this; - - setColumnHeader : function(col, header) { - this.config[col].header = header; - this.fireEvent("headerchange", this, col, header); + me.mon(me.el, { + scope: me, + click: me.onClick, + delegate: '.' + Ext.baseCSSPrefix + 'tab' + }); + me.callParent(arguments); + }, - - getColumnTooltip : function(col) { - return this.config[col].tooltip; - }, - - setColumnTooltip : function(col, tooltip) { - this.config[col].tooltip = tooltip; + afterComponentLayout : function() { + var me = this; + + me.callParent(arguments); + me.strip.setWidth(me.el.getWidth()); }, - getDataIndex : function(col) { - return this.config[col].dataIndex; - }, + onClick: function(e, target) { + + var tab = Ext.getCmp(target.id), + tabPanel = this.tabPanel; - - setDataIndex : function(col, dataIndex) { - this.config[col].dataIndex = dataIndex; - }, + target = e.getTarget(); - - findColumnIndex : function(dataIndex) { - var c = this.config; - for(var i = 0, len = c.length; i < len; i++){ - if(c[i].dataIndex == dataIndex){ - return i; + if (tab && tab.isDisabled && !tab.isDisabled()) { + if (tab.closable && target === tab.closeEl.dom) { + tab.onCloseClick(); + } else { + this.setActiveTab(tab); + if (tabPanel) { + tabPanel.setActiveTab(tab.card); + } + tab.focus(); } } - return -1; }, - isCellEditable : function(colIndex, rowIndex) { - var c = this.config[colIndex], - ed = c.editable; + closeTab: function(tab) { + var card = tab.card, + tabPanel = this.tabPanel, + nextTab; + + if (tab.active && this.items.getCount() > 1) { + nextTab = tab.next('tab') || this.items.items[0]; + this.setActiveTab(nextTab); + if (tabPanel) { + tabPanel.setActiveTab(nextTab.card); + } + } + this.remove(tab); + if (tabPanel && card) { + tabPanel.remove(card); + } - return !!(ed || (!Ext.isDefined(ed) && c.editor)); + if (nextTab) { + nextTab.focus(); + } }, - getCellEditor : function(colIndex, rowIndex) { - return this.config[colIndex].getCellEditor(rowIndex); - }, + setActiveTab: function(tab) { + if (tab.disabled) { + return; + } + var me = this; + if (me.activeTab) { + me.activeTab.deactivate(); + } + tab.activate(); + + if (me.rendered) { + me.layout.layout(); + tab.el.scrollIntoView(me.layout.getRenderTarget()); + } + me.activeTab = tab; + me.fireEvent('change', me, tab, tab.card); + } +}); + +Ext.define('Ext.tab.Panel', { + extend: 'Ext.panel.Panel', + alias: 'widget.tabpanel', + alternateClassName: ['Ext.TabPanel'], + + requires: ['Ext.layout.container.Card', 'Ext.tab.Bar'], - setEditable : function(col, editable) { - this.config[col].editable = editable; - }, + tabPosition : 'top', + + - isHidden : function(colIndex) { - return !!this.config[colIndex].hidden; - }, - isFixed : function(colIndex) { - return !!this.config[colIndex].fixed; - }, + removePanelHeader: true, - isResizable : function(colIndex) { - return colIndex >= 0 && this.config[colIndex].resizable !== false && this.config[colIndex].fixed !== true; - }, + plain: false, + + itemCls: 'x-tabpanel-child', + - setHidden : function(colIndex, hidden) { - var c = this.config[colIndex]; - if(c.hidden !== hidden){ - c.hidden = hidden; - this.totalWidth = null; - this.fireEvent("hiddenchange", this, colIndex, hidden); - } - }, - setEditor : function(col, editor) { - this.config[col].setEditor(editor); - }, + deferredRender : true, - destroy : function() { - var length = this.config.length, - i = 0; + initComponent: function() { + var me = this, + dockedItems = me.dockedItems || [], + activeTab = me.activeTab || 0; + + me.layout = Ext.create('Ext.layout.container.Card', Ext.apply({ + owner: me, + deferredRender: me.deferredRender, + itemCls: me.itemCls + }, me.layout)); + + + me.tabBar = Ext.create('Ext.tab.Bar', Ext.apply({}, me.tabBar, { + dock: me.tabPosition, + plain: me.plain, + border: me.border, + cardLayout: me.layout, + tabPanel: me + })); - for (; i < length; i++){ - this.config[i].destroy(); + if (dockedItems && !Ext.isArray(dockedItems)) { + dockedItems = [dockedItems]; } - delete this.config; - delete this.lookup; - this.purgeListeners(); - }, - - setState : function(col, state) { - state = Ext.applyIf(state, this.defaults); - Ext.apply(this.config[col], state); - } -}); + dockedItems.push(me.tabBar); + me.dockedItems = dockedItems; + me.addEvents( + + 'beforetabchange', -Ext.grid.ColumnModel.defaultRenderer = function(value) { - if (typeof value == "string" && value.length < 1) { - return " "; - } - return value; -}; -Ext.grid.AbstractSelectionModel = Ext.extend(Ext.util.Observable, { - + + 'tabchange' + ); + me.callParent(arguments); - constructor : function(){ - this.locked = false; - Ext.grid.AbstractSelectionModel.superclass.constructor.call(this); + + me.setActiveTab(activeTab); + + me.on('afterlayout', me.afterInitialLayout, me, {single: true}); }, - init : function(grid){ - this.grid = grid; - if(this.lockOnInit){ - delete this.lockOnInit; - this.locked = false; - this.lock(); + afterInitialLayout: function() { + var me = this, + card = me.getComponent(me.activeTab); + + if (card) { + me.layout.setActiveItem(card); } - this.initEvents(); }, - lock : function(){ - if(!this.locked){ - this.locked = true; + setActiveTab: function(card) { + var me = this, + previous; + + card = me.getComponent(card); + if (card) { + previous = me.getActiveTab(); - var g = this.grid; - if(g){ - g.getView().on({ - scope: this, - beforerefresh: this.sortUnLock, - refresh: this.sortLock - }); - }else{ - this.lockOnInit = true; + if (previous && previous !== card && me.fireEvent('beforetabchange', me, card, previous) === false) { + return false; + } + + me.tabBar.setActiveTab(card.tab); + me.activeTab = card; + if (me.rendered) { + me.layout.setActiveItem(card); + } + + if (previous && previous !== card) { + me.fireEvent('tabchange', me, card, previous); } } }, - sortLock : function() { - this.locked = true; + getActiveTab: function() { + return this.activeTab; }, - sortUnLock : function() { - this.locked = false; + getTabBar: function() { + return this.tabBar; }, - unlock : function(){ - if(this.locked){ - this.locked = false; - var g = this.grid, - gv; - - - if(g){ - gv = g.getView(); - gv.un('beforerefresh', this.sortUnLock, this); - gv.un('refresh', this.sortLock, this); - }else{ - delete this.lockOnInit; + onAdd: function(item, index) { + var me = this; + + item.tab = me.tabBar.insert(index, { + xtype: 'tab', + card: item, + disabled: item.disabled, + closable: item.closable, + hidden: item.hidden, + tabBar: me.tabBar + }); + + item.on({ + scope : me, + enable: me.onItemEnable, + disable: me.onItemDisable, + beforeshow: me.onItemBeforeShow, + iconchange: me.onItemIconChange, + titlechange: me.onItemTitleChange + }); + + if (item.isPanel) { + if (me.removePanelHeader) { + item.preventHeader = true; + if (item.rendered) { + item.updateHeader(); + } + } + if (item.isPanel && me.border) { + item.setBorder(false); } } - }, + + if (this.rendered && me.items.getCount() === 1) { + me.setActiveTab(0); + } + }, - isLocked : function(){ - return this.locked; + + onItemEnable: function(item){ + item.tab.enable(); }, - destroy: function(){ - this.unlock(); - this.purgeListeners(); - } -}); -Ext.grid.RowSelectionModel = Ext.extend(Ext.grid.AbstractSelectionModel, { + + onItemDisable: function(item){ + item.tab.disable(); + }, - singleSelect : false, - constructor : function(config){ - Ext.apply(this, config); - this.selections = new Ext.util.MixedCollection(false, function(o){ - return o.id; - }); - - this.last = false; - this.lastActive = false; - - this.addEvents( - - 'selectionchange', - - 'beforerowselect', - - 'rowselect', - - 'rowdeselect' - ); - Ext.grid.RowSelectionModel.superclass.constructor.call(this); + onItemBeforeShow: function(item) { + if (item !== this.activeTab) { + this.setActiveTab(item); + return false; + } }, - - initEvents : function(){ - - if(!this.grid.enableDragDrop && !this.grid.enableDrag){ - this.grid.on('rowmousedown', this.handleMouseDown, this); - } - - this.rowNav = new Ext.KeyNav(this.grid.getGridEl(), { - up: this.onKeyPress, - down: this.onKeyPress, - scope: this - }); - - this.grid.getView().on({ - scope: this, - refresh: this.onRefresh, - rowupdated: this.onRowUpdated, - rowremoved: this.onRemove - }); + onItemIconChange: function(item, newIconCls) { + item.tab.setIconCls(newIconCls); + this.getTabBar().doLayout(); }, - onKeyPress : function(e, name){ - var up = name == 'up', - method = up ? 'selectPrevious' : 'selectNext', - add = up ? -1 : 1, - last; - if(!e.shiftKey || this.singleSelect){ - this[method](false); - }else if(this.last !== false && this.lastActive !== false){ - last = this.last; - this.selectRange(this.last, this.lastActive + add); - this.grid.getView().focusRow(this.lastActive); - if(last !== false){ - this.last = last; - } - }else{ - this.selectFirstRow(); - } + + onItemTitleChange: function(item, newTitle) { + item.tab.setText(newTitle); + this.getTabBar().doLayout(); }, + - onRefresh : function(){ - var ds = this.grid.store, - s = this.getSelections(), - i = 0, - len = s.length, - index, r; + doRemove: function(item, autoDestroy) { + var me = this, + items = me.items, - this.silent = true; - this.clearSelections(true); - for(; i < len; i++){ - r = s[i]; - if((index = ds.indexOfId(r.id)) != -1){ - this.selectRow(index, true); - } - } - if(s.length != this.selections.getCount()){ - this.fireEvent('selectionchange', this); + hasItemsLeft = items.getCount() > 1; + + if (me.destroying || !hasItemsLeft) { + me.activeTab = null; + } else if (item === me.activeTab) { + me.setActiveTab(item.next() || items.getAt(0)); } - this.silent = false; + me.callParent(arguments); + + + delete item.tab.card; + delete item.tab; }, - onRemove : function(v, index, r){ - if(this.selections.remove(r) !== false){ - this.fireEvent('selectionchange', this); + onRemove: function(item, autoDestroy) { + var me = this; + + item.un({ + scope : me, + enable: me.onItemEnable, + disable: me.onItemDisable, + beforeshow: me.onItemBeforeShow + }); + if (!me.destroying && item.tab.ownerCt == me.tabBar) { + me.tabBar.remove(item.tab); } + } +}); + + +Ext.define('Ext.toolbar.Spacer', { + extend: 'Ext.Component', + alias: 'widget.tbspacer', + alternateClassName: 'Ext.Toolbar.Spacer', + baseCls: Ext.baseCSSPrefix + 'toolbar-spacer', + focusable: false +}); + +Ext.define('Ext.tree.Column', { + extend: 'Ext.grid.column.Column', + alias: 'widget.treecolumn', + + initComponent: function() { + var origRenderer = this.renderer || this.defaultRenderer, + origScope = this.scope || window; + + this.renderer = function(value, metaData, record, rowIdx, colIdx, store, view) { + var buf = [], + format = Ext.String.format, + depth = record.getDepth(), + treePrefix = Ext.baseCSSPrefix + 'tree-', + elbowPrefix = treePrefix + 'elbow-', + expanderCls = treePrefix + 'expander', + imgText = '', + checkboxText= '', + formattedValue = origRenderer.apply(origScope, arguments), + href = record.get('href'), + target = record.get('hrefTarget'); + + while (record) { + if (!record.isRoot() || (record.isRoot() && view.rootVisible)) { + if (record.getDepth() === depth) { + buf.unshift(format(imgText, + treePrefix + 'icon ' + + treePrefix + 'icon' + (record.get('icon') ? '-inline ' : (record.isLeaf() ? '-leaf ' : '-parent ')) + + (record.get('iconCls') || ''), + record.get('icon') || Ext.BLANK_IMAGE_URL + )); + if (record.get('checked') !== null) { + buf.unshift(format( + checkboxText, + (treePrefix + 'checkbox') + (record.get('checked') ? ' ' + treePrefix + 'checkbox-checked' : ''), + record.get('checked') ? 'aria-checked="true"' : '' + )); + if (record.get('checked')) { + metaData.tdCls += (' ' + Ext.baseCSSPrefix + 'tree-checked'); + } + } + if (record.isLast()) { + if (record.isLeaf() || (record.isLoaded() && !record.hasChildNodes())) { + buf.unshift(format(imgText, (elbowPrefix + 'end'), Ext.BLANK_IMAGE_URL)); + } else { + buf.unshift(format(imgText, (elbowPrefix + 'end-plus ' + expanderCls), Ext.BLANK_IMAGE_URL)); + } + + } else { + if (record.isLeaf() || (record.isLoaded() && !record.hasChildNodes())) { + buf.unshift(format(imgText, (treePrefix + 'elbow'), Ext.BLANK_IMAGE_URL)); + } else { + buf.unshift(format(imgText, (elbowPrefix + 'plus ' + expanderCls), Ext.BLANK_IMAGE_URL)); + } + } + } else { + if (record.isLast() || record.getDepth() === 0) { + buf.unshift(format(imgText, (elbowPrefix + 'empty'), Ext.BLANK_IMAGE_URL)); + } else if (record.getDepth() !== 0) { + buf.unshift(format(imgText, (elbowPrefix + 'line'), Ext.BLANK_IMAGE_URL)); + } + } + } + record = record.parentNode; + } + if (href) { + formattedValue = format('{2}', href, target, formattedValue); + } + return buf.join("") + formattedValue; + }; + this.callParent(arguments); }, + defaultRenderer: function(value) { + return value; + } +}); + +Ext.define('Ext.tree.View', { + extend: 'Ext.view.Table', + alias: 'widget.treeview', + + loadingCls: Ext.baseCSSPrefix + 'grid-tree-loading', + expandedCls: Ext.baseCSSPrefix + 'grid-tree-node-expanded', + + expanderSelector: '.' + Ext.baseCSSPrefix + 'tree-expander', + checkboxSelector: '.' + Ext.baseCSSPrefix + 'tree-checkbox', + expanderIconOverCls: Ext.baseCSSPrefix + 'tree-expander-over', + + blockRefresh: true, + + + rootVisible: true, + - onRowUpdated : function(v, index, r){ - if(this.isSelected(r)){ - v.onRowSelect(index); - } - }, + expandDuration: 250, + collapseDuration: 250, - selectRecords : function(records, keepExisting){ - if(!keepExisting){ - this.clearSelections(); + toggleOnDblClick: true, + + initComponent: function() { + var me = this; + + if (me.initialConfig.animate === undefined) { + me.animate = Ext.enableFx; } - var ds = this.grid.store, - i = 0, - len = records.length; - for(; i < len; i++){ - this.selectRow(ds.indexOf(records[i]), true); + + me.store = Ext.create('Ext.data.NodeStore', { + recursive: true, + rootVisible: me.rootVisible, + listeners: { + beforeexpand: me.onBeforeExpand, + expand: me.onExpand, + beforecollapse: me.onBeforeCollapse, + collapse: me.onCollapse, + scope: me + } + }); + + if (me.node) { + me.setRootNode(me.node); } + me.animQueue = {}; + me.callParent(arguments); }, - - getCount : function(){ - return this.selections.length; + onClear: function(){ + this.store.removeAll(); }, - - selectFirstRow : function(){ - this.selectRow(0); + setRootNode: function(node) { + var me = this; + me.store.setNode(node); + me.node = node; + if (!me.rootVisible) { + node.expand(); + } }, - - selectLastRow : function(keepExisting){ - this.selectRow(this.grid.store.getCount() - 1, keepExisting); - }, + onRender: function() { + var me = this, + opts = {delegate: me.expanderSelector}, + el; - - selectNext : function(keepExisting){ - if(this.hasNext()){ - this.selectRow(this.last+1, keepExisting); - this.grid.getView().focusRow(this.last); - return true; - } - return false; + me.callParent(arguments); + + el = me.el; + el.on({ + scope: me, + delegate: me.expanderSelector, + mouseover: me.onExpanderMouseOver, + mouseout: me.onExpanderMouseOut + }); + el.on({ + scope: me, + delegate: me.checkboxSelector, + click: me.onCheckboxChange + }); }, - - selectPrevious : function(keepExisting){ - if(this.hasPrevious()){ - this.selectRow(this.last-1, keepExisting); - this.grid.getView().focusRow(this.last); - return true; + onCheckboxChange: function(e, t) { + var item = e.getTarget(this.getItemSelector(), this.getTargetEl()), + record, value; + + if (item) { + record = this.getRecord(item); + value = !record.get('checked'); + record.set('checked', value); + this.fireEvent('checkchange', record, value); } - return false; }, - - hasNext : function(){ - return this.last !== false && (this.last+1) < this.grid.store.getCount(); + getChecked: function() { + var checked = []; + this.node.cascadeBy(function(rec){ + if (rec.get('checked')) { + checked.push(rec); + } + }); + return checked; }, - - hasPrevious : function(){ - return !!this.last; + isItemChecked: function(rec){ + return rec.get('checked'); }, + createAnimWrap: function(record, index) { + var thHtml = '', + headerCt = this.panel.headerCt, + headers = headerCt.getGridColumns(), + i = 0, len = headers.length, item, + node = this.getNode(record), + tmpEl, nodeEl; + + for (; i < len; i++) { + item = headers[i]; + thHtml += ''; + } + + nodeEl = Ext.get(node); + tmpEl = nodeEl.insertSibling({ + tag: 'tr', + html: [ + '', + '
    ', + '', + thHtml, + '
    ', + '
    ', + '' + ].join('') + }, 'after'); - - getSelections : function(){ - return [].concat(this.selections.items); + return { + record: record, + node: node, + el: tmpEl, + expanding: false, + collapsing: false, + animating: false, + animateEl: tmpEl.down('div'), + targetEl: tmpEl.down('tbody') + }; }, - - getSelected : function(){ - return this.selections.itemAt(0); - }, + getAnimWrap: function(parent) { + if (!this.animate) { + return null; + } - - each : function(fn, scope){ - var s = this.getSelections(), - i = 0, - len = s.length; - - for(; i < len; i++){ - if(fn.call(scope || this, s[i], i) === false){ - return false; + + while (parent) { + if (parent.animWrap) { + return parent.animWrap; } + parent = parent.parentNode; } - return true; + return null; }, - - clearSelections : function(fast){ - if(this.isLocked()){ - return; - } - if(fast !== true){ - var ds = this.grid.store, - s = this.selections; - s.each(function(r){ - this.deselectRow(ds.indexOfId(r.id)); - }, this); - s.clear(); - }else{ - this.selections.clear(); - } - this.last = false; - }, + doAdd: function(nodes, records, index) { + + + var me = this, + record = records[0], + parent = record.parentNode, + a = me.all.elements, + relativeIndex = 0, + animWrap = me.getAnimWrap(parent), + targetEl, children, len; + if (!animWrap || !animWrap.expanding) { + me.resetScrollers(); + return me.callParent(arguments); + } - - selectAll : function(){ - if(this.isLocked()){ - return; + + parent = animWrap.record; + + + targetEl = animWrap.targetEl; + children = targetEl.dom.childNodes; + + + len = children.length - 1; + + + relativeIndex = index - me.indexOf(parent) - 1; + + + + if (!len || relativeIndex >= len) { + targetEl.appendChild(nodes); + } + + + else { + + Ext.fly(children[relativeIndex + 1]).insertSibling(nodes, 'before', true); + } + + + if (index < a.length) { + a.splice.apply(a, [index, 0].concat(nodes)); + } + else { + a.push.apply(a, nodes); } - this.selections.clear(); - for(var i = 0, len = this.grid.store.getCount(); i < len; i++){ - this.selectRow(i, true); + + + + if (animWrap.isAnimating) { + me.onExpand(parent); } }, - - hasSelection : function(){ - return this.selections.length > 0; - }, + doRemove: function(record, index) { + + + var me = this, + parent = record.parentNode, + all = me.all, + animWrap = me.getAnimWrap(record), + node = all.item(index).dom; - - isSelected : function(index){ - var r = Ext.isNumber(index) ? this.grid.store.getAt(index) : index; - return (r && this.selections.key(r.id) ? true : false); - }, + if (!animWrap || !animWrap.collapsing) { + me.resetScrollers(); + return me.callParent(arguments); + } - - isIdSelected : function(id){ - return (this.selections.key(id) ? true : false); + animWrap.targetEl.appendChild(node); + all.removeElement(index); }, - - handleMouseDown : function(g, rowIndex, e){ - if(e.button !== 0 || this.isLocked()){ + onBeforeExpand: function(parent, records, index) { + var me = this, + animWrap; + + if (!me.animate) { return; } - var view = this.grid.getView(); - if(e.shiftKey && !this.singleSelect && this.last !== false){ - var last = this.last; - this.selectRange(last, rowIndex, e.ctrlKey); - this.last = last; - view.focusRow(rowIndex); - }else{ - var isSelected = this.isSelected(rowIndex); - if(e.ctrlKey && isSelected){ - this.deselectRow(rowIndex); - }else if(!isSelected || this.getCount() > 1){ - this.selectRow(rowIndex, e.ctrlKey || e.shiftKey); - view.focusRow(rowIndex); + + if (me.getNode(parent)) { + animWrap = me.getAnimWrap(parent); + if (!animWrap) { + animWrap = parent.animWrap = me.createAnimWrap(parent); + animWrap.animateEl.setHeight(0); } + else if (animWrap.collapsing) { + + + animWrap.targetEl.select(me.itemSelector).remove(); + } + animWrap.expanding = true; + animWrap.collapsing = false; } }, - - selectRows : function(rows, keepExisting){ - if(!keepExisting){ - this.clearSelections(); - } - for(var i = 0, len = rows.length; i < len; i++){ - this.selectRow(rows[i], true); + onExpand: function(parent) { + var me = this, + queue = me.animQueue, + id = parent.getId(), + animWrap, + animateEl, + targetEl, + queueItem; + + if (me.singleExpand) { + me.ensureSingleExpand(parent); } - }, + + animWrap = me.getAnimWrap(parent); - - selectRange : function(startRow, endRow, keepExisting){ - var i; - if(this.isLocked()){ + if (!animWrap) { + me.resetScrollers(); return; } - if(!keepExisting){ - this.clearSelections(); - } - if(startRow <= endRow){ - for(i = startRow; i <= endRow; i++){ - this.selectRow(i, true); - } - }else{ - for(i = startRow; i >= endRow; i--){ - this.selectRow(i, true); + + animateEl = animWrap.animateEl; + targetEl = animWrap.targetEl; + + animateEl.stopAnimation(); + + queue[id] = true; + animateEl.slideIn('t', { + duration: me.expandDuration, + listeners: { + scope: me, + lastframe: function() { + + animWrap.el.insertSibling(targetEl.query(me.itemSelector), 'before'); + animWrap.el.remove(); + me.resetScrollers(); + delete animWrap.record.animWrap; + delete queue[id]; + } } - } + }); + + animWrap.isAnimating = true; }, - - deselectRange : function(startRow, endRow, preventViewNotify){ - if(this.isLocked()){ - return; - } - for(var i = startRow; i <= endRow; i++){ - this.deselectRow(i, preventViewNotify); - } + resetScrollers: function(){ + var panel = this.panel; + + panel.determineScrollbars(); + panel.invalidateScroller(); }, - - selectRow : function(index, keepExisting, preventViewNotify){ - if(this.isLocked() || (index < 0 || index >= this.grid.store.getCount()) || (keepExisting && this.isSelected(index))){ + onBeforeCollapse: function(parent, records, index) { + var me = this, + animWrap; + + if (!me.animate) { return; } - var r = this.grid.store.getAt(index); - if(r && this.fireEvent('beforerowselect', this, index, keepExisting, r) !== false){ - if(!keepExisting || this.singleSelect){ - this.clearSelections(); - } - this.selections.add(r); - this.last = this.lastActive = index; - if(!preventViewNotify){ - this.grid.getView().onRowSelect(index); + + if (me.getNode(parent)) { + animWrap = me.getAnimWrap(parent); + if (!animWrap) { + animWrap = parent.animWrap = me.createAnimWrap(parent, index); } - if(!this.silent){ - this.fireEvent('rowselect', this, index, r); - this.fireEvent('selectionchange', this); + else if (animWrap.expanding) { + + + animWrap.targetEl.select(this.itemSelector).remove(); } + animWrap.expanding = false; + animWrap.collapsing = true; } }, - - deselectRow : function(index, preventViewNotify){ - if(this.isLocked()){ + onCollapse: function(parent) { + var me = this, + queue = me.animQueue, + id = parent.getId(), + animWrap = me.getAnimWrap(parent), + animateEl, targetEl; + + if (!animWrap) { + me.resetScrollers(); return; } - if(this.last == index){ - this.last = false; - } - if(this.lastActive == index){ - this.lastActive = false; - } - var r = this.grid.store.getAt(index); - if(r){ - this.selections.remove(r); - if(!preventViewNotify){ - this.grid.getView().onRowDeselect(index); + + animateEl = animWrap.animateEl; + targetEl = animWrap.targetEl; + + queue[id] = true; + + + animateEl.stopAnimation(); + animateEl.slideOut('t', { + duration: me.collapseDuration, + listeners: { + scope: me, + lastframe: function() { + animWrap.el.remove(); + delete animWrap.record.animWrap; + me.resetScrollers(); + delete queue[id]; + } } - this.fireEvent('rowdeselect', this, index, r); - this.fireEvent('selectionchange', this); - } + }); + animWrap.isAnimating = true; }, - - acceptsNav : function(row, col, cm){ - return !cm.isHidden(col) && cm.isCellEditable(col, row); + + isAnimating: function(node) { + return !!this.animQueue[node.getId()]; }, - - onEditorKey : function(field, e){ - var k = e.getKey(), - newCell, - g = this.grid, - last = g.lastEdit, - ed = g.activeEditor, - shift = e.shiftKey, - ae, last, r, c; + collectData: function(records) { + var data = this.callParent(arguments), + rows = data.rows, + len = rows.length, + i = 0, + row, record; - if(k == e.TAB){ - e.stopEvent(); - ed.completeEdit(); - if(shift){ - newCell = g.walkCells(ed.row, ed.col-1, -1, this.acceptsNav, this); - }else{ - newCell = g.walkCells(ed.row, ed.col+1, 1, this.acceptsNav, this); - } - }else if(k == e.ENTER){ - if(this.moveEditorOnEnter !== false){ - if(shift){ - newCell = g.walkCells(last.row - 1, last.col, -1, this.acceptsNav, this); - }else{ - newCell = g.walkCells(last.row + 1, last.col, 1, this.acceptsNav, this); + for (; i < len; i++) { + row = rows[i]; + record = records[i]; + if (record.get('qtip')) { + row.rowAttr = 'data-qtip="' + record.get('qtip') + '"'; + if (record.get('qtitle')) { + row.rowAttr += ' ' + 'data-qtitle="' + record.get('qtitle') + '"'; } } - } - if(newCell){ - r = newCell[0]; - c = newCell[1]; - - this.onEditorSelect(r, last.row); - - if(g.isEditor && g.editing){ - ae = g.activeEditor; - if(ae && ae.field.triggerBlur){ - - ae.field.triggerBlur(); - } + if (record.isExpanded()) { + row.rowCls = (row.rowCls || '') + ' ' + this.expandedCls; + } + if (record.isLoading()) { + row.rowCls = (row.rowCls || '') + ' ' + this.loadingCls; } - g.startEditing(r, c); - } - }, - - onEditorSelect: function(row, lastRow){ - if(lastRow != row){ - this.selectRow(row); } + + return data; }, - destroy : function(){ - Ext.destroy(this.rowNav); - this.rowNav = null; - Ext.grid.RowSelectionModel.superclass.destroy.call(this); - } -}); - -Ext.grid.Column = Ext.extend(Ext.util.Observable, { - - - - - - - - - - - - - - - - - + expand: function(record, deep, callback, scope) { + return record.expand(deep, callback, scope); + }, + collapse: function(record, deep, callback, scope) { + return record.collapse(deep, callback, scope); + }, - + toggle: function(record) { + this[record.isExpanded() ? 'collapse' : 'expand'](record); + }, - isColumn : true, - - constructor : function(config){ - Ext.apply(this, config); - - if(Ext.isString(this.renderer)){ - this.renderer = Ext.util.Format[this.renderer]; - }else if(Ext.isObject(this.renderer)){ - this.scope = this.renderer.scope; - this.renderer = this.renderer.fn; + onItemDblClick: function(record, item, index) { + this.callParent(arguments); + if (this.toggleOnDblClick) { + this.toggle(record); } - if(!this.scope){ - this.scope = this; - } - - var ed = this.editor; - delete this.editor; - this.setEditor(ed); - this.addEvents( - - 'click', - - 'contextmenu', - - 'dblclick', - - 'mousedown' - ); - Ext.grid.Column.superclass.constructor.call(this); }, - - processEvent : function(name, e, grid, rowIndex, colIndex){ - return this.fireEvent(name, this, grid, rowIndex, e); + onBeforeItemMouseDown: function(record, item, index, e) { + if (e.getTarget(this.expanderSelector, item)) { + return false; + } + return this.callParent(arguments); }, - - destroy: function() { - if(this.setEditor){ - this.setEditor(null); + onItemClick: function(record, item, index, e) { + if (e.getTarget(this.expanderSelector, item)) { + this.toggle(record); + return false; } - this.purgeListeners(); + return this.callParent(arguments); }, - - renderer : function(value){ - return value; + onExpanderMouseOver: function(e, t) { + e.getTarget(this.cellSelector, 10, true).addCls(this.expanderIconOverCls); }, - - getEditor: function(rowIndex){ - return this.editable !== false ? this.editor : null; + onExpanderMouseOut: function(e, t) { + e.getTarget(this.cellSelector, 10, true).removeCls(this.expanderIconOverCls); }, - - setEditor : function(editor){ - var ed = this.editor; - if(ed){ - if(ed.gridEditor){ - ed.gridEditor.destroy(); - delete ed.gridEditor; - }else{ - ed.destroy(); - } - } - this.editor = null; - if(editor){ - - if(!editor.isXType){ - editor = Ext.create(editor, 'textfield'); - } - this.editor = editor; - } - }, - - getCellEditor: function(rowIndex){ - var ed = this.getEditor(rowIndex); - if(ed){ - if(!ed.startEdit){ - if(!ed.gridEditor){ - ed.gridEditor = new Ext.grid.GridEditor(ed); + getTreeStore: function() { + return this.panel.store; + }, + + ensureSingleExpand: function(node) { + var parent = node.parentNode; + if (parent) { + parent.eachChild(function(child) { + if (child !== node && child.isExpanded()) { + child.collapse(); } - ed = ed.gridEditor; - } + }); } - return ed; } }); - -Ext.grid.BooleanColumn = Ext.extend(Ext.grid.Column, { - - trueText: 'true', +Ext.define('Ext.tree.Panel', { + extend: 'Ext.panel.Table', + alias: 'widget.treepanel', + alternateClassName: ['Ext.tree.TreePanel', 'Ext.TreePanel'], + requires: ['Ext.tree.View', 'Ext.selection.TreeModel', 'Ext.tree.Column'], + viewType: 'treeview', + selType: 'treemodel', - falseText: 'false', - - undefinedText: ' ', - - constructor: function(cfg){ - Ext.grid.BooleanColumn.superclass.constructor.call(this, cfg); - var t = this.trueText, f = this.falseText, u = this.undefinedText; - this.renderer = function(v){ - if(v === undefined){ - return u; - } - if(!v || v === 'false'){ - return f; - } - return t; - }; - } -}); - - -Ext.grid.NumberColumn = Ext.extend(Ext.grid.Column, { + treeCls: Ext.baseCSSPrefix + 'tree-panel', - format : '0,000.00', - constructor: function(cfg){ - Ext.grid.NumberColumn.superclass.constructor.call(this, cfg); - this.renderer = Ext.util.Format.numberRenderer(this.format); - } -}); - - -Ext.grid.DateColumn = Ext.extend(Ext.grid.Column, { - format : 'm/d/Y', - constructor: function(cfg){ - Ext.grid.DateColumn.superclass.constructor.call(this, cfg); - this.renderer = Ext.util.Format.dateRenderer(this.format); - } -}); - - -Ext.grid.TemplateColumn = Ext.extend(Ext.grid.Column, { + lines: true, - constructor: function(cfg){ - Ext.grid.TemplateColumn.superclass.constructor.call(this, cfg); - var tpl = (!Ext.isPrimitive(this.tpl) && this.tpl.compile) ? this.tpl : new Ext.XTemplate(this.tpl); - this.renderer = function(value, p, r){ - return tpl.apply(r.data); - }; - this.tpl = tpl; - } -}); - - -Ext.grid.ActionColumn = Ext.extend(Ext.grid.Column, { + useArrows: false, + singleExpand: false, + ddConfig: { + enableDrag: true, + enableDrop: true + }, + + rootVisible: true, - header: ' ', + + displayField: 'text', - actionIdRe: /x-action-col-(\d+)/, + root: null, - altText: '', - - constructor: function(cfg) { - var me = this, - items = cfg.items || (me.items = [me]), - l = items.length, - i, - item; - - Ext.grid.ActionColumn.superclass.constructor.call(me, cfg); - - - - me.renderer = function(v, meta) { - - v = Ext.isFunction(cfg.renderer) ? cfg.renderer.apply(this, arguments)||'' : ''; - - meta.css += ' x-action-col-cell'; - for (i = 0; i < l; i++) { - item = items[i]; - v += '' + me.altText + ''; - } - return v; - }; - }, - - destroy: function() { - delete this.items; - delete this.renderer; - return Ext.grid.ActionColumn.superclass.destroy.apply(this, arguments); - }, - - processEvent : function(name, e, grid, rowIndex, colIndex){ - var m = e.getTarget().className.match(this.actionIdRe), - item, fn; - if (m && (item = this.items[parseInt(m[1], 10)])) { - if (name == 'click') { - (fn = item.handler || this.handler) && fn.call(item.scope||this.scope||this, grid, rowIndex, colIndex, item, e); - } else if ((name == 'mousedown') && (item.stopSelection !== false)) { - return false; - } - } - return Ext.grid.ActionColumn.superclass.processEvent.apply(this, arguments); - } -}); - - -Ext.grid.Column.types = { - gridcolumn : Ext.grid.Column, - booleancolumn: Ext.grid.BooleanColumn, - numbercolumn: Ext.grid.NumberColumn, - datecolumn: Ext.grid.DateColumn, - templatecolumn: Ext.grid.TemplateColumn, - actioncolumn: Ext.grid.ActionColumn -}; -Ext.grid.RowNumberer = Ext.extend(Object, { - header: "", + normalCfgCopy: ['displayField', 'root', 'singleExpand', 'useArrows', 'lines', 'rootVisible', 'scroll'], + lockedCfgCopy: ['displayField', 'root', 'singleExpand', 'useArrows', 'lines', 'rootVisible'], + - width: 23, - sortable: false, + - constructor : function(config){ - Ext.apply(this, config); - if(this.rowspan){ - this.renderer = this.renderer.createDelegate(this); + constructor: function(config) { + config = config || {}; + if (config.animate === undefined) { + config.animate = Ext.enableFx; } + this.enableAnimations = config.animate; + delete config.animate; + + this.callParent([config]); }, - - fixed:true, - hideable: false, - menuDisabled:true, - dataIndex: '', - id: 'numberer', - rowspan: undefined, + initComponent: function() { + var me = this, + cls = [me.treeCls]; - - renderer : function(v, p, record, rowIndex){ - if(this.rowspan){ - p.cellAttr = 'rowspan="'+this.rowspan+'"'; + if (me.useArrows) { + cls.push(Ext.baseCSSPrefix + 'tree-arrows'); + me.lines = false; + } + + if (me.lines) { + cls.push(Ext.baseCSSPrefix + 'tree-lines'); + } else if (!me.useArrows) { + cls.push(Ext.baseCSSPrefix + 'tree-no-lines'); } - return rowIndex+1; - } -}); -Ext.grid.CheckboxSelectionModel = Ext.extend(Ext.grid.RowSelectionModel, { + if (!me.store || Ext.isObject(me.store) && !me.store.isStore) { + me.store = Ext.create('Ext.data.TreeStore', Ext.apply({}, me.store || {}, { + root: me.root, + fields: me.fields, + model: me.model, + folderSort: me.folderSort + })); + } + else if (me.root) { + me.store = Ext.data.StoreManager.lookup(me.store); + me.store.setRootNode(me.root); + if (me.folderSort !== undefined) { + me.store.folderSort = me.folderSort; + me.store.sort(); + } + } + + + + + + + me.viewConfig = Ext.applyIf(me.viewConfig || {}, { + rootVisible: me.rootVisible, + animate: me.enableAnimations, + singleExpand: me.singleExpand, + node: me.store.getRootNode(), + hideHeaders: me.hideHeaders + }); + + me.mon(me.store, { + scope: me, + rootchange: me.onRootChange, + clear: me.onClear + }); + me.relayEvents(me.store, [ + + 'beforeload', + + + 'load' + ]); + + me.store.on({ + + append: me.createRelayer('itemappend'), + + + remove: me.createRelayer('itemremove'), + + + move: me.createRelayer('itemmove'), + + + insert: me.createRelayer('iteminsert'), + + + beforeappend: me.createRelayer('beforeitemappend'), + + + beforeremove: me.createRelayer('beforeitemremove'), + + + beforemove: me.createRelayer('beforeitemmove'), + + + beforeinsert: me.createRelayer('beforeiteminsert'), + + + expand: me.createRelayer('itemexpand'), + + + collapse: me.createRelayer('itemcollapse'), + + + beforeexpand: me.createRelayer('beforeitemexpand'), + + + beforecollapse: me.createRelayer('beforeitemcollapse') + }); + + + if (!me.columns) { + if (me.initialConfig.hideHeaders === undefined) { + me.hideHeaders = true; + } + me.columns = [{ + xtype : 'treecolumn', + text : 'Name', + flex : 1, + dataIndex: me.displayField + }]; + } + + if (me.cls) { + cls.push(me.cls); + } + me.cls = cls.join(' '); + me.callParent(); + + me.relayEvents(me.getView(), [ + + 'checkchange' + ]); + + + if (!me.getView().rootVisible && !me.getRootNode()) { + me.setRootNode({ + expanded: true + }); + } + }, - header : '
     
    ', + onClear: function(){ + this.view.onClear(); + }, - width : 20, + setRootNode: function() { + return this.store.setRootNode.apply(this.store, arguments); + }, - sortable : false, - + getRootNode: function() { + return this.store.getRootNode(); + }, - menuDisabled : true, - fixed : true, - hideable: false, - dataIndex : '', - id : 'checker', - isColumn: true, - - constructor : function(){ - Ext.grid.CheckboxSelectionModel.superclass.constructor.apply(this, arguments); - if(this.checkOnly){ - this.handleMouseDown = Ext.emptyFn; - } + onRootChange: function(root) { + this.view.setRootNode(root); }, - initEvents : function(){ - Ext.grid.CheckboxSelectionModel.superclass.initEvents.call(this); - this.grid.on('render', function(){ - Ext.fly(this.grid.getView().innerHd).on('mousedown', this.onHdMouseDown, this); - }, this); + getChecked: function() { + return this.getView().getChecked(); }, - - processEvent : function(name, e, grid, rowIndex, colIndex){ - if (name == 'mousedown') { - this.onMouseDown(e, e.getTarget()); - return false; - } else { - return Ext.grid.Column.prototype.processEvent.apply(this, arguments); - } + isItemChecked: function(rec) { + return rec.get('checked'); }, - + - onMouseDown : function(e, t){ - if(e.button === 0 && t.className == 'x-grid3-row-checker'){ - e.stopEvent(); - var row = e.getTarget('.x-grid3-row'); - if(row){ - var index = row.rowIndex; - if(this.isSelected(index)){ - this.deselectRow(index); - }else{ - this.selectRow(index, true); - this.grid.getView().focusRow(index); - } - } + expandAll : function(callback, scope) { + var root = this.getRootNode(); + if (root) { + root.expand(true, callback, scope); } }, - onHdMouseDown : function(e, t) { - if(t.className == 'x-grid3-hd-checker'){ - e.stopEvent(); - var hd = Ext.fly(t.parentNode); - var isChecked = hd.hasClass('x-grid3-hd-checker-on'); - if(isChecked){ - hd.removeClass('x-grid3-hd-checker-on'); - this.clearSelections(); - }else{ - hd.addClass('x-grid3-hd-checker-on'); - this.selectAll(); + collapseAll : function(callback, scope) { + var root = this.getRootNode(); + if (root) { + if (this.getView().rootVisible) { + root.collapse(true, callback, scope); + } + else { + root.collapseChildren(true, callback, scope); } } }, - renderer : function(v, p, record){ - return '
     
    '; + expandPath: function(path, field, separator, callback, scope) { + var me = this, + current = me.getRootNode(), + index = 1, + view = me.getView(), + keys, + expander; + + field = field || me.getRootNode().idProperty; + separator = separator || '/'; + + if (Ext.isEmpty(path)) { + Ext.callback(callback, scope || me, [false, null]); + return; + } + + keys = path.split(separator); + if (current.get(field) != keys[1]) { + + Ext.callback(callback, scope || me, [false, current]); + return; + } + + expander = function(){ + if (++index === keys.length) { + Ext.callback(callback, scope || me, [true, current]); + return; + } + var node = current.findChild(field, keys[index]); + if (!node) { + Ext.callback(callback, scope || me, [false, current]); + return; + } + current = node; + current.expand(false, expander); + }; + current.expand(false, expander); }, - onEditorSelect: function(row, lastRow){ - if(lastRow != row && !this.checkOnly){ - this.selectRow(row); - } + + selectPath: function(path, field, separator, callback, scope) { + var me = this, + keys, + last; + + field = field || me.getRootNode().idProperty; + separator = separator || '/'; + + keys = path.split(separator); + last = keys.pop(); + + me.expandPath(keys.join('/'), field, separator, function(success, node){ + var doSuccess = false; + if (success && node) { + node = node.findChild(field, last); + if (node) { + me.getSelectionModel().select(node); + Ext.callback(callback, scope || me, [true, node]); + doSuccess = true; + } + } else if (node === me.getRootNode()) { + doSuccess = true; + } + Ext.callback(callback, scope || me, [doSuccess, node]); + }, me); } }); -Ext.grid.CellSelectionModel = Ext.extend(Ext.grid.AbstractSelectionModel, { - - constructor : function(config){ - Ext.apply(this, config); - this.selection = null; - - this.addEvents( - - "beforecellselect", - - "cellselect", - - "selectionchange" - ); - - Ext.grid.CellSelectionModel.superclass.constructor.call(this); - }, +Ext.define('Ext.view.DragZone', { + extend: 'Ext.dd.DragZone', + containerScroll: false, - - initEvents : function(){ - this.grid.on('cellmousedown', this.handleMouseDown, this); - this.grid.on(Ext.EventManager.getKeyEvent(), this.handleKeyDown, this); - this.grid.getView().on({ - scope: this, - refresh: this.onViewChange, - rowupdated: this.onRowUpdated, - beforerowremoved: this.clearSelections, - beforerowsinserted: this.clearSelections - }); - if(this.grid.isEditor){ - this.grid.on('beforeedit', this.beforeEdit, this); - } - }, + constructor: function(config) { + var me = this; - - beforeEdit : function(e){ - this.select(e.row, e.column, false, true, e.record); - }, + Ext.apply(me, config); - - onRowUpdated : function(v, index, r){ - if(this.selection && this.selection.record == r){ - v.onCellSelect(index, this.selection.cell[1]); + + + + + + if (!me.ddGroup) { + me.ddGroup = 'view-dd-zone-' + me.view.id; } - }, - - onViewChange : function(){ - this.clearSelections(true); + + + + + + + + me.callParent([me.view.el.dom.parentNode]); + + me.ddel = Ext.get(document.createElement('div')); + me.ddel.addCls(Ext.baseCSSPrefix + 'grid-dd-wrap'); }, - - getSelectedCell : function(){ - return this.selection ? this.selection.cell : null; + init: function(id, sGroup, config) { + this.initTarget(id, sGroup, config); + this.view.mon(this.view, { + itemmousedown: this.onItemMouseDown, + scope: this + }); }, - - clearSelections : function(preventNotify){ - var s = this.selection; - if(s){ - if(preventNotify !== true){ - this.grid.view.onCellDeselect(s.cell[0], s.cell[1]); - } - this.selection = null; - this.fireEvent("selectionchange", this, null); + onItemMouseDown: function(view, record, item, index, e) { + if (!this.isPreventDrag(e, record, item, index)) { + this.handleMouseDown(e); } }, - hasSelection : function(){ - return this.selection ? true : false; + isPreventDrag: function(e) { + return false; }, - - handleMouseDown : function(g, row, cell, e){ - if(e.button !== 0 || this.isLocked()){ - return; - } - this.select(row, cell); - }, + getDragData: function(e) { + var view = this.view, + item = e.getTarget(view.getItemSelector()), + record, selectionModel, records; - - select : function(rowIndex, colIndex, preventViewNotify, preventFocus, r){ - if(this.fireEvent("beforecellselect", this, rowIndex, colIndex) !== false){ - this.clearSelections(); - r = r || this.grid.store.getAt(rowIndex); - this.selection = { - record : r, - cell : [rowIndex, colIndex] + if (item) { + record = view.getRecord(item); + selectionModel = view.getSelectionModel(); + records = selectionModel.getSelection(); + return { + copy: this.view.copy || (this.view.allowCopy && e.ctrlKey), + event: new Ext.EventObjectImpl(e), + view: view, + ddel: this.ddel, + item: item, + records: records, + fromPosition: Ext.fly(item).getXY() }; - if(!preventViewNotify){ - var v = this.grid.getView(); - v.onCellSelect(rowIndex, colIndex); - if(preventFocus !== true){ - v.focusCell(rowIndex, colIndex); - } - } - this.fireEvent("cellselect", this, rowIndex, colIndex); - this.fireEvent("selectionchange", this, this.selection); } }, - - isSelectable : function(rowIndex, colIndex, cm){ - return !cm.isHidden(colIndex); - }, - - - onEditorKey: function(field, e){ - if(e.getKey() == e.TAB){ - this.handleKeyDown(e); - } - }, + onInitDrag: function(x, y) { + var me = this, + data = me.dragData, + view = data.view, + selectionModel = view.getSelectionModel(), + record = view.getRecord(data.item), + e = data.event; - - handleKeyDown : function(e){ - if(!e.isNavKeyPress()){ - return; - } - var k = e.getKey(), - g = this.grid, - s = this.selection, - sm = this, - walk = function(row, col, step){ - return g.walkCells( - row, - col, - step, - g.isEditor && g.editing ? sm.acceptsNav : sm.isSelectable, - sm - ); - }, - cell, newCell, r, c, ae; - - switch(k){ - case e.ESC: - case e.PAGE_UP: - case e.PAGE_DOWN: - - break; - default: - - e.stopEvent(); - break; - } - - if(!s){ - cell = walk(0, 0, 1); - if(cell){ - this.select(cell[0], cell[1]); - } - return; - } - - cell = s.cell; - r = cell[0]; - c = cell[1]; - switch(k){ - case e.TAB: - if(e.shiftKey){ - newCell = walk(r, c - 1, -1); - }else{ - newCell = walk(r, c + 1, 1); - } - break; - case e.DOWN: - newCell = walk(r + 1, c, 1); - break; - case e.UP: - newCell = walk(r - 1, c, -1); - break; - case e.RIGHT: - newCell = walk(r, c + 1, 1); - break; - case e.LEFT: - newCell = walk(r, c - 1, -1); - break; - case e.ENTER: - if (g.isEditor && !g.editing) { - g.startEditing(r, c); - return; - } - break; + if (!selectionModel.isSelected(record) || e.hasModifier()) { + selectionModel.selectWithEvent(record, e); } + data.records = selectionModel.getSelection(); - if(newCell){ - - r = newCell[0]; - c = newCell[1]; - - this.select(r, c); + me.ddel.update(me.getDragText()); + me.proxy.update(me.ddel.dom); + me.onStartDrag(x, y); + return true; + }, - if(g.isEditor && g.editing){ - ae = g.activeEditor; - if(ae && ae.field.triggerBlur){ - - ae.field.triggerBlur(); - } - g.startEditing(r, c); - } - } + getDragText: function() { + var count = this.dragData.records.length; + return Ext.String.format(this.dragText, count, count == 1 ? '' : 's'); }, - acceptsNav : function(row, col, cm){ - return !cm.isHidden(col) && cm.isCellEditable(col, row); + getRepairXY : function(e, data){ + return data ? data.fromPosition : false; + } +}); +Ext.define('Ext.tree.ViewDragZone', { + extend: 'Ext.view.DragZone', + + isPreventDrag: function(e, record) { + return (record.get('allowDrag') === false) || !!e.getTarget(this.view.expanderSelector); + }, + + afterRepair: function() { + var me = this, + view = me.view, + selectedRowCls = view.selectedItemCls, + records = me.dragData.records, + fly = Ext.fly; + + if (Ext.enableFx && me.repairHighlight) { + + Ext.Array.forEach(records, function(record) { + + + var item = view.getNode(record); + + + + fly(item.firstChild).highlight(me.repairHighlightColor, { + listeners: { + beforeanimate: function() { + if (view.isSelected(item)) { + fly(item).removeCls(selectedRowCls); + } + }, + afteranimate: function() { + if (view.isSelected(item)) { + fly(item).addCls(selectedRowCls); + } + } + } + }); + }); + } + me.dragging = false; } }); -Ext.grid.EditorGridPanel = Ext.extend(Ext.grid.GridPanel, { - - clicksToEdit: 2, - - forceValidation: false, +Ext.define('Ext.tree.ViewDropZone', { + extend: 'Ext.view.DropZone', - isEditor : true, + allowParentInserts: false, + - detectEdit: false, + allowContainerDrops: false, - autoEncode : false, + appendOnly: false, - - trackMouseOver: false, + expandDelay : 500, - - initComponent : function(){ - Ext.grid.EditorGridPanel.superclass.initComponent.call(this); + indicatorCls: 'x-tree-ddindicator', - if(!this.selModel){ - - this.selModel = new Ext.grid.CellSelectionModel(); + + expandNode : function(node) { + var view = this.view; + if (!node.isLeaf() && !node.isExpanded()) { + view.expand(node); + this.expandProcId = false; } + }, - this.activeEditor = null; - - this.addEvents( - - "beforeedit", - - "afteredit", - - "validateedit" - ); + + queueExpand : function(node) { + this.expandProcId = Ext.Function.defer(this.expandNode, this.expandDelay, this, [node]); }, - initEvents : function(){ - Ext.grid.EditorGridPanel.superclass.initEvents.call(this); + cancelExpand : function() { + if (this.expandProcId) { + clearTimeout(this.expandProcId); + this.expandProcId = false; + } + }, - this.getGridEl().on('mousewheel', this.stopEditing.createDelegate(this, [true]), this); - this.on('columnresize', this.stopEditing, this, [true]); + getPosition: function(e, node) { + var view = this.view, + record = view.getRecord(node), + y = e.getPageY(), + noAppend = record.isLeaf(), + noBelow = false, + region = Ext.fly(node).getRegion(), + fragment; - if(this.clicksToEdit == 1){ - this.on("cellclick", this.onCellDblClick, this); - }else { - var view = this.getView(); - if(this.clicksToEdit == 'auto' && view.mainBody){ - view.mainBody.on('mousedown', this.onAutoEditClick, this); - } - this.on('celldblclick', this.onCellDblClick, this); + + if (record.isRoot()) { + return 'append'; } - }, - onResize : function(){ - Ext.grid.EditorGridPanel.superclass.onResize.apply(this, arguments); - var ae = this.activeEditor; - if(this.editing && ae){ - ae.realign(true); + + if (this.appendOnly) { + return noAppend ? false : 'append'; } - }, - - onCellDblClick : function(g, row, col){ - this.startEditing(row, col); - }, + if (!this.allowParentInsert) { + noBelow = record.hasChildNodes() && record.isExpanded(); + } - - onAutoEditClick : function(e, t){ - if(e.button !== 0){ - return; + fragment = (region.bottom - region.top) / (noAppend ? 2 : 3); + if (y >= region.top && y < (region.top + fragment)) { + return 'before'; } - var row = this.view.findRowIndex(t), - col = this.view.findCellIndex(t); - if(row !== false && col !== false){ - this.stopEditing(); - if(this.selModel.getSelectedCell){ - var sc = this.selModel.getSelectedCell(); - if(sc && sc[0] === row && sc[1] === col){ - this.startEditing(row, col); - } - }else{ - if(this.selModel.isSelected(row)){ - this.startEditing(row, col); - } - } + else if (!noBelow && (noAppend || (y >= (region.bottom - fragment) && y <= region.bottom))) { + return 'after'; + } + else { + return 'append'; } }, - - onEditComplete : function(ed, value, startValue){ - this.editing = false; - this.lastActiveEditor = this.activeEditor; - this.activeEditor = null; - - var r = ed.record, - field = this.colModel.getDataIndex(ed.col); - value = this.postEditValue(value, startValue, r, field); - if(this.forceValidation === true || String(value) !== String(startValue)){ - var e = { - grid: this, - record: r, - field: field, - originalValue: startValue, - value: value, - row: ed.row, - column: ed.col, - cancel:false - }; - if(this.fireEvent("validateedit", e) !== false && !e.cancel && String(value) !== String(startValue)){ - r.set(field, e.value); - delete e.cancel; - this.fireEvent("afteredit", e); - } - } - this.view.focusCell(ed.row, ed.col); - }, - - - startEditing : function(row, col){ - this.stopEditing(); - if(this.colModel.isCellEditable(col, row)){ - this.view.ensureVisible(row, col, true); - var r = this.store.getAt(row), - field = this.colModel.getDataIndex(col), - e = { - grid: this, - record: r, - field: field, - value: r.data[field], - row: row, - column: col, - cancel:false - }; - if(this.fireEvent("beforeedit", e) !== false && !e.cancel){ - this.editing = true; - var ed = this.colModel.getCellEditor(col, row); - if(!ed){ - return; - } - if(!ed.rendered){ - ed.parentEl = this.view.getEditorParent(ed); - ed.on({ - scope: this, - render: { - fn: function(c){ - c.field.focus(false, true); - }, - single: true, - scope: this - }, - specialkey: function(field, e){ - this.getSelectionModel().onEditorKey(field, e); - }, - complete: this.onEditComplete, - canceledit: this.stopEditing.createDelegate(this, [true]) - }); - } - Ext.apply(ed, { - row : row, - col : col, - record : r - }); - this.lastEdit = { - row: row, - col: col - }; - this.activeEditor = ed; - - - ed.selectSameEditor = (this.activeEditor == this.lastActiveEditor); - var v = this.preEditValue(r, field); - ed.startEdit(this.view.getCell(row, col).firstChild, Ext.isDefined(v) ? v : ''); - - - (function(){ - delete ed.selectSameEditor; - }).defer(50); - } + isValidDropPoint : function(node, position, dragZone, e, data) { + if (!node || !data.item) { + return false; } - }, - - preEditValue : function(r, field){ - var value = r.data[field]; - return this.autoEncode && Ext.isString(value) ? Ext.util.Format.htmlDecode(value) : value; - }, + var view = this.view, + targetNode = view.getRecord(node), + draggedRecords = data.records, + dataLength = draggedRecords.length, + ln = draggedRecords.length, + i, record; - - postEditValue : function(value, originalValue, r, field){ - return this.autoEncode && Ext.isString(value) ? Ext.util.Format.htmlEncode(value) : value; - }, + + if (!(targetNode && position && dataLength)) { + return false; + } - - stopEditing : function(cancel){ - if(this.editing){ - - var ae = this.lastActiveEditor = this.activeEditor; - if(ae){ - ae[cancel === true ? 'cancelEdit' : 'completeEdit'](); - this.view.focusCell(ae.row, ae.col); + + for (i = 0; i < ln; i++) { + record = draggedRecords[i]; + if (record.isNode && record.contains(targetNode)) { + return false; } - this.activeEditor = null; } - this.editing = false; - } -}); -Ext.reg('editorgrid', Ext.grid.EditorGridPanel); - -Ext.grid.GridEditor = function(field, config){ - Ext.grid.GridEditor.superclass.constructor.call(this, field, config); - field.monitorTab = false; -}; - -Ext.extend(Ext.grid.GridEditor, Ext.Editor, { - alignment: "tl-tl", - autoSize: "width", - hideEl : false, - cls: "x-small-editor x-grid-editor", - shim:false, - shadow:false -}); -Ext.grid.PropertyRecord = Ext.data.Record.create([ - {name:'name',type:'string'}, 'value' -]); - - -Ext.grid.PropertyStore = Ext.extend(Ext.util.Observable, { - - constructor : function(grid, source){ - this.grid = grid; - this.store = new Ext.data.Store({ - recordType : Ext.grid.PropertyRecord - }); - this.store.on('update', this.onUpdate, this); - if(source){ - this.setSource(source); + + + if (position === 'append' && targetNode.get('allowDrop') == false) { + return false; } - Ext.grid.PropertyStore.superclass.constructor.call(this); - }, - - - setSource : function(o){ - this.source = o; - this.store.removeAll(); - var data = []; - for(var k in o){ - if(this.isEditableValue(o[k])){ - data.push(new Ext.grid.PropertyRecord({name: k, value: o[k]}, k)); - } + else if (position != 'append' && targetNode.parentNode.get('allowDrop') == false) { + return false; } - this.store.loadRecords({records: data}, {}, true); - }, - - onUpdate : function(ds, record, type){ - if(type == Ext.data.Record.EDIT){ - var v = record.data.value; - var oldValue = record.modified.value; - if(this.grid.fireEvent('beforepropertychange', this.source, record.id, v, oldValue) !== false){ - this.source[record.id] = v; - record.commit(); - this.grid.fireEvent('propertychange', this.source, record.id, v, oldValue); - }else{ - record.reject(); - } + + if (Ext.Array.contains(draggedRecords, targetNode)) { + return false; } - }, - - getProperty : function(row){ - return this.store.getAt(row); + + + return true; }, - - isEditableValue: function(val){ - return Ext.isPrimitive(val) || Ext.isDate(val); - }, + onNodeOver : function(node, dragZone, e, data) { + var position = this.getPosition(e, node), + returnCls = this.dropNotAllowed, + view = this.view, + targetNode = view.getRecord(node), + indicator = this.getIndicator(), + indicatorX = 0, + indicatorY = 0; - - setValue : function(prop, value, create){ - var r = this.getRec(prop); - if(r){ - r.set('value', value); - this.source[prop] = value; - }else if(create){ + + this.cancelExpand(); + if (position == 'append' && !this.expandProcId && !Ext.Array.contains(data.records, targetNode) && !targetNode.isLeaf() && !targetNode.isExpanded()) { + this.queueExpand(targetNode); + } - this.source[prop] = value; - r = new Ext.grid.PropertyRecord({name: prop, value: value}, prop); - this.store.add(r); + if (this.isValidDropPoint(node, position, dragZone, e, data)) { + this.valid = true; + this.currentPosition = position; + this.overRecord = targetNode; + indicator.setWidth(Ext.fly(node).getWidth()); + indicatorY = Ext.fly(node).getY() - Ext.fly(view.el).getY() - 1; + + if (position == 'before') { + returnCls = targetNode.isFirst() ? Ext.baseCSSPrefix + 'tree-drop-ok-above' : Ext.baseCSSPrefix + 'tree-drop-ok-between'; + indicator.showAt(0, indicatorY); + indicator.toFront(); + } + else if (position == 'after') { + returnCls = targetNode.isLast() ? Ext.baseCSSPrefix + 'tree-drop-ok-below' : Ext.baseCSSPrefix + 'tree-drop-ok-between'; + indicatorY += Ext.fly(node).getHeight(); + indicator.showAt(0, indicatorY); + indicator.toFront(); + } + else { + returnCls = Ext.baseCSSPrefix + 'tree-drop-ok-append'; + + indicator.hide(); + } } - }, - - - remove : function(prop){ - var r = this.getRec(prop); - if(r){ - this.store.remove(r); - delete this.source[prop]; + else { + this.valid = false; } - }, - - - getRec : function(prop){ - return this.store.getById(prop); - }, - - - getSource : function(){ - return this.source; - } -}); - -Ext.grid.PropertyColumnModel = Ext.extend(Ext.grid.ColumnModel, { - - nameText : 'Name', - valueText : 'Value', - dateFormat : 'm/j/Y', - trueText: 'true', - falseText: 'false', - - constructor : function(grid, store){ - var g = Ext.grid, - f = Ext.form; - - this.grid = grid; - g.PropertyColumnModel.superclass.constructor.call(this, [ - {header: this.nameText, width:50, sortable: true, dataIndex:'name', id: 'name', menuDisabled:true}, - {header: this.valueText, width:50, resizable:false, dataIndex: 'value', id: 'value', menuDisabled:true} - ]); - this.store = store; - - var bfield = new f.Field({ - autoCreate: {tag: 'select', children: [ - {tag: 'option', value: 'true', html: this.trueText}, - {tag: 'option', value: 'false', html: this.falseText} - ]}, - getValue : function(){ - return this.el.dom.value == 'true'; - } - }); - this.editors = { - 'date' : new g.GridEditor(new f.DateField({selectOnFocus:true})), - 'string' : new g.GridEditor(new f.TextField({selectOnFocus:true})), - 'number' : new g.GridEditor(new f.NumberField({selectOnFocus:true, style:'text-align:left;'})), - 'boolean' : new g.GridEditor(bfield, { - autoSize: 'both' - }) - }; - this.renderCellDelegate = this.renderCell.createDelegate(this); - this.renderPropDelegate = this.renderProp.createDelegate(this); - }, - - - renderDate : function(dateVal){ - return dateVal.dateFormat(this.dateFormat); - }, - - - renderBool : function(bVal){ - return this[bVal ? 'trueText' : 'falseText']; + this.currentCls = returnCls; + return returnCls; }, - - isCellEditable : function(colIndex, rowIndex){ - return colIndex == 1; + onContainerOver : function(dd, e, data) { + return e.getTarget('.' + this.indicatorCls) ? this.currentCls : this.dropNotAllowed; }, - - getRenderer : function(col){ - return col == 1 ? - this.renderCellDelegate : this.renderPropDelegate; + notifyOut: function() { + this.callParent(arguments); + this.cancelExpand(); }, - - renderProp : function(v){ - return this.getPropertyName(v); - }, + handleNodeDrop : function(data, targetNode, position) { + var me = this, + view = me.view, + parentNode = targetNode.parentNode, + store = view.getStore(), + recordDomNodes = [], + records, i, len, + insertionMethod, argList, + needTargetExpand, + transferData, + processDrop; - - renderCell : function(val, meta, rec){ - var renderer = this.grid.customRenderers[rec.get('name')]; - if(renderer){ - return renderer.apply(this, arguments); - } - var rv = val; - if(Ext.isDate(val)){ - rv = this.renderDate(val); - }else if(typeof val == 'boolean'){ - rv = this.renderBool(val); + + if (data.copy) { + records = data.records; + data.records = []; + for (i = 0, len = records.length; i < len; i++) { + data.records.push(Ext.apply({}, records[i].data)); + } } - return Ext.util.Format.htmlEncode(rv); - }, - - getPropertyName : function(name){ - var pn = this.grid.propertyNames; - return pn && pn[name] ? pn[name] : name; - }, + + me.cancelExpand(); - - getCellEditor : function(colIndex, rowIndex){ - var p = this.store.getProperty(rowIndex), - n = p.data.name, - val = p.data.value; - if(this.grid.customEditors[n]){ - return this.grid.customEditors[n]; + + + + + if (position == 'before') { + insertionMethod = parentNode.insertBefore; + argList = [null, targetNode]; + targetNode = parentNode; } - if(Ext.isDate(val)){ - return this.editors.date; - }else if(typeof val == 'number'){ - return this.editors.number; - }else if(typeof val == 'boolean'){ - return this.editors['boolean']; - }else{ - return this.editors.string; + else if (position == 'after') { + if (targetNode.nextSibling) { + insertionMethod = parentNode.insertBefore; + argList = [null, targetNode.nextSibling]; + } + else { + insertionMethod = parentNode.appendChild; + argList = [null]; + } + targetNode = parentNode; + } + else { + if (!targetNode.isExpanded()) { + needTargetExpand = true; + } + insertionMethod = targetNode.appendChild; + argList = [null]; } - }, - - destroy : function(){ - Ext.grid.PropertyColumnModel.superclass.destroy.call(this); - this.destroyEditors(this.editors); - this.destroyEditors(this.grid.customEditors); - }, - - destroyEditors: function(editors){ - for(var ed in editors){ - Ext.destroy(editors[ed]); + + transferData = function() { + var node; + for (i = 0, len = data.records.length; i < len; i++) { + argList[0] = data.records[i]; + node = insertionMethod.apply(targetNode, argList); + + if (Ext.enableFx && me.dropHighlight) { + recordDomNodes.push(view.getNode(node)); + } + } + + + + if (Ext.enableFx && me.dropHighlight) { + + + Ext.Array.forEach(recordDomNodes, function(n) { + Ext.fly(n.firstChild ? n.firstChild : n).highlight(me.dropHighlightColor); + }); + } + }; + + + if (needTargetExpand) { + targetNode.expand(false, transferData); + } + + else { + transferData(); } } }); +Ext.define('Ext.tree.plugin.TreeViewDragDrop', { + extend: 'Ext.AbstractPlugin', + alias: 'plugin.treeviewdragdrop', -Ext.grid.PropertyGrid = Ext.extend(Ext.grid.EditorGridPanel, { - - - - - + uses: [ + 'Ext.tree.ViewDragZone', + 'Ext.tree.ViewDropZone' + ], - enableColumnMove:false, - stripeRows:false, - trackMouseOver: false, - clicksToEdit:1, - enableHdMenu : false, - viewConfig : { - forceFit:true - }, - initComponent : function(){ - this.customRenderers = this.customRenderers || {}; - this.customEditors = this.customEditors || {}; - this.lastEditRow = null; - var store = new Ext.grid.PropertyStore(this); - this.propStore = store; - var cm = new Ext.grid.PropertyColumnModel(this, store); - store.store.sort('name', 'ASC'); - this.addEvents( - - 'beforepropertychange', - - 'propertychange' - ); - this.cm = cm; - this.ds = store.store; - Ext.grid.PropertyGrid.superclass.initComponent.call(this); - this.mon(this.selModel, 'beforecellselect', function(sm, rowIndex, colIndex){ - if(colIndex === 0){ - this.startEditing.defer(200, this, [rowIndex, 1]); - return false; - } - }, this); - }, + dragText : '{0} selected node{1}', - onRender : function(){ - Ext.grid.PropertyGrid.superclass.onRender.apply(this, arguments); - - this.getGridEl().addClass('x-props-grid'); - }, + allowParentInserts: false, - afterRender: function(){ - Ext.grid.PropertyGrid.superclass.afterRender.apply(this, arguments); - if(this.source){ - this.setSource(this.source); - } - }, + allowContainerDrops: false, - setSource : function(source){ - this.propStore.setSource(source); - }, + appendOnly: false, - getSource : function(){ - return this.propStore.getSource(); - }, - - - setProperty : function(prop, value, create){ - this.propStore.setValue(prop, value, create); - }, - - - removeProperty : function(prop){ - this.propStore.remove(prop); - } + ddGroup : "TreeDD", - - - -}); -Ext.reg("propertygrid", Ext.grid.PropertyGrid); - -Ext.grid.GroupingView = Ext.extend(Ext.grid.GridView, { - groupByText : 'Group By This Field', - - showGroupsText : 'Show in Groups', - - hideGroupedColumn : false, + - showGroupName : true, + expandDelay : 1000, + - startCollapsed : false, + enableDrop: true, + - enableGrouping : true, + enableDrag: true, - enableGroupingMenu : true, - enableNoGroups : true, + nodeHighlightColor: 'c3daf9', - emptyGroupText : '(None)', - ignoreAdd : false, + nodeHighlightOnDrop: Ext.enableFx, - groupTextTpl : '{text}', - - groupMode: 'value', + nodeHighlightOnRepair: Ext.enableFx, - - - - cancelEditOnToggle: true, + init : function(view) { + view.on('render', this.onViewRender, this, {single: true}); + }, - initTemplates : function(){ - Ext.grid.GroupingView.superclass.initTemplates.call(this); - this.state = {}; + destroy: function() { + Ext.destroy(this.dragZone, this.dropZone); + }, - var sm = this.grid.getSelectionModel(); - sm.on(sm.selectRow ? 'beforerowselect' : 'beforecellselect', - this.onBeforeRowSelect, this); + onViewRender : function(view) { + var me = this; - if(!this.startGroup){ - this.startGroup = new Ext.XTemplate( - '
    ', - '
    ', this.groupTextTpl ,'
    ', - '
    ' - ); + if (me.enableDrag) { + me.dragZone = Ext.create('Ext.tree.ViewDragZone', { + view: view, + ddGroup: me.dragGroup || me.ddGroup, + dragText: me.dragText, + repairHighlightColor: me.nodeHighlightColor, + repairHighlight: me.nodeHighlightOnRepair + }); } - this.startGroup.compile(); - if (!this.endGroup) { - this.endGroup = '
    '; + if (me.enableDrop) { + me.dropZone = Ext.create('Ext.tree.ViewDropZone', { + view: view, + ddGroup: me.dropGroup || me.ddGroup, + allowContainerDrops: me.allowContainerDrops, + appendOnly: me.appendOnly, + allowParentInserts: me.allowParentInserts, + expandDelay: me.expandDelay, + dropHighlightColor: me.nodeHighlightColor, + dropHighlight: me.nodeHighlightOnDrop + }); } - }, + } +}); +Ext.define('Ext.util.Cookies', { + singleton: true, - findGroup : function(el){ - return Ext.fly(el).up('.x-grid-group', this.mainBody.dom); - }, - - getGroups : function(){ - return this.hasRows() ? this.mainBody.dom.childNodes : []; + set : function(name, value){ + var argv = arguments, + argc = arguments.length, + expires = (argc > 2) ? argv[2] : null, + path = (argc > 3) ? argv[3] : '/', + domain = (argc > 4) ? argv[4] : null, + secure = (argc > 5) ? argv[5] : false; + + document.cookie = name + "=" + escape(value) + ((expires === null) ? "" : ("; expires=" + expires.toGMTString())) + ((path === null) ? "" : ("; path=" + path)) + ((domain === null) ? "" : ("; domain=" + domain)) + ((secure === true) ? "; secure" : ""); }, - onAdd : function(ds, records, index) { - if (this.canGroup() && !this.ignoreAdd) { - var ss = this.getScrollState(); - this.fireEvent('beforerowsinserted', ds, index, index + (records.length-1)); - this.refresh(); - this.restoreScroll(ss); - this.fireEvent('rowsinserted', ds, index, index + (records.length-1)); - } else if (!this.canGroup()) { - Ext.grid.GroupingView.superclass.onAdd.apply(this, arguments); + get : function(name){ + var arg = name + "=", + alen = arg.length, + clen = document.cookie.length, + i = 0, + j = 0; + + while(i < clen){ + j = i + alen; + if(document.cookie.substring(i, j) == arg){ + return this.getCookieVal(j); + } + i = document.cookie.indexOf(" ", i) + 1; + if(i === 0){ + break; + } } + return null; }, - onRemove : function(ds, record, index, isUpdate){ - Ext.grid.GroupingView.superclass.onRemove.apply(this, arguments); - var g = document.getElementById(record._groupId); - if(g && g.childNodes[1].childNodes.length < 1){ - Ext.removeNode(g); + clear : function(name, path){ + if(this.get(name)){ + path = path || '/'; + document.cookie = name + '=' + '; expires=Thu, 01-Jan-70 00:00:01 GMT; path=' + path; } - this.applyEmptyText(); }, - - refreshRow : function(record){ - if(this.ds.getCount()==1){ - this.refresh(); - }else{ - this.isUpdating = true; - Ext.grid.GroupingView.superclass.refreshRow.apply(this, arguments); - this.isUpdating = false; - } - }, - - beforeMenuShow : function(){ - var item, items = this.hmenu.items, disabled = this.cm.config[this.hdCtxIndex].groupable === false; - if((item = items.get('groupBy'))){ - item.setDisabled(disabled); - } - if((item = items.get('showGroups'))){ - item.setDisabled(disabled); - item.setChecked(this.canGroup(), true); + getCookieVal : function(offset){ + var endstr = document.cookie.indexOf(";", offset); + if(endstr == -1){ + endstr = document.cookie.length; } - }, + return unescape(document.cookie.substring(offset, endstr)); + } +}); - - renderUI : function(){ - var markup = Ext.grid.GroupingView.superclass.renderUI.call(this); - if(this.enableGroupingMenu && this.hmenu){ - this.hmenu.add('-',{ - itemId:'groupBy', - text: this.groupByText, - handler: this.onGroupByClick, - scope: this, - iconCls:'x-group-by-icon' - }); - if(this.enableNoGroups){ - this.hmenu.add({ - itemId:'showGroups', - text: this.showGroupsText, - checked: true, - checkHandler: this.onShowGroupsClick, - scope: this - }); +Ext.define('Ext.util.CSS', function() { + var rules = null; + var doc = document; + + var camelRe = /(-[a-z])/gi; + var camelFn = function(m, a){ return a.charAt(1).toUpperCase(); }; + + return { + + singleton: true, + + constructor: function() { + this.rules = {}; + this.initialized = false; + }, + + + createStyleSheet : function(cssText, id) { + var ss, + head = doc.getElementsByTagName("head")[0], + styleEl = doc.createElement("style"); + + styleEl.setAttribute("type", "text/css"); + if (id) { + styleEl.setAttribute("id", id); } - this.hmenu.on('beforeshow', this.beforeMenuShow, this); - } - return markup; - }, - processEvent: function(name, e){ - Ext.grid.GroupingView.superclass.processEvent.call(this, name, e); - var hd = e.getTarget('.x-grid-group-hd', this.mainBody); - if(hd){ - - var field = this.getGroupField(), - prefix = this.getPrefix(field), - groupValue = hd.id.substring(prefix.length), - emptyRe = new RegExp('gp-' + Ext.escapeRe(field) + '--hd'); + if (Ext.isIE) { + head.appendChild(styleEl); + ss = styleEl.styleSheet; + ss.cssText = cssText; + } else { + try{ + styleEl.appendChild(doc.createTextNode(cssText)); + } catch(e) { + styleEl.cssText = cssText; + } + head.appendChild(styleEl); + ss = styleEl.styleSheet ? styleEl.styleSheet : (styleEl.sheet || doc.styleSheets[doc.styleSheets.length-1]); + } + this.cacheStyleSheet(ss); + return ss; + }, - - groupValue = groupValue.substr(0, groupValue.length - 3); - - - if(groupValue || emptyRe.test(hd.id)){ - this.grid.fireEvent('group' + name, this.grid, field, groupValue, e); + + removeStyleSheet : function(id) { + var existing = document.getElementById(id); + if (existing) { + existing.parentNode.removeChild(existing); + } + }, + + + swapStyleSheet : function(id, url) { + var doc = document; + this.removeStyleSheet(id); + var ss = doc.createElement("link"); + ss.setAttribute("rel", "stylesheet"); + ss.setAttribute("type", "text/css"); + ss.setAttribute("id", id); + ss.setAttribute("href", url); + doc.getElementsByTagName("head")[0].appendChild(ss); + }, + + + refreshCache : function() { + return this.getRules(true); + }, + + + cacheStyleSheet : function(ss) { + if(!rules){ + rules = {}; + } + try { + var ssRules = ss.cssRules || ss.rules, + selectorText, + i = ssRules.length - 1, + j, + selectors; + + for (; i >= 0; --i) { + selectorText = ssRules[i].selectorText; + if (selectorText) { + + + selectorText = selectorText.split(','); + selectors = selectorText.length; + for (j = 0; j < selectors; j++) { + rules[Ext.String.trim(selectorText[j]).toLowerCase()] = ssRules[i]; + } + } + } + } catch(e) {} + }, + + + getRules : function(refreshCache) { + if (rules === null || refreshCache) { + rules = {}; + var ds = doc.styleSheets, + i = 0, + len = ds.length; + + for (; i < len; i++) { + try { + if (!ds[i].disabled) { + this.cacheStyleSheet(ds[i]); + } + } catch(e) {} + } } - if(name == 'mousedown' && e.button == 0){ - this.toggleGroup(hd.parentNode); + return rules; + }, + + + getRule: function(selector, refreshCache) { + var rs = this.getRules(refreshCache); + if (!Ext.isArray(selector)) { + return rs[selector.toLowerCase()]; + } + for (var i = 0; i < selector.length; i++) { + if (rs[selector[i]]) { + return rs[selector[i].toLowerCase()]; + } + } + return null; + }, + + + updateRule : function(selector, property, value){ + if (!Ext.isArray(selector)) { + var rule = this.getRule(selector); + if (rule) { + rule.style[property.replace(camelRe, camelFn)] = value; + return true; + } + } else { + for (var i = 0; i < selector.length; i++) { + if (this.updateRule(selector[i], property, value)) { + return true; + } + } } + return false; } + }; +}()); +Ext.define('Ext.util.History', { + singleton: true, + alternateClassName: 'Ext.History', + mixins: { + observable: 'Ext.util.Observable' }, - - onGroupByClick : function(){ - var grid = this.grid; - this.enableGrouping = true; - grid.store.groupBy(this.cm.getDataIndex(this.hdCtxIndex)); - grid.fireEvent('groupchange', grid, grid.store.getGroupState()); - this.beforeMenuShow(); - this.refresh(); + constructor: function() { + var me = this; + me.oldIEMode = Ext.isIE6 || Ext.isIE7 || !Ext.isStrict && Ext.isIE8; + me.iframe = null; + me.hiddenField = null; + me.ready = false; + me.currentToken = null; }, - - onShowGroupsClick : function(mi, checked){ - this.enableGrouping = checked; - if(checked){ - this.onGroupByClick(); - }else{ - this.grid.store.clearGrouping(); - this.grid.fireEvent('groupchange', this, null); - } + getHash: function() { + var href = window.location.href, + i = href.indexOf("#"); + + return i >= 0 ? href.substr(i + 1) : null; }, - - toggleRowIndex : function(rowIndex, expanded){ - if(!this.canGroup()){ - return; - } - var row = this.getRow(rowIndex); - if(row){ - this.toggleGroup(this.findGroup(row), expanded); - } + doSave: function() { + this.hiddenField.value = this.currentToken; }, - - toggleGroup : function(group, expanded){ - var gel = Ext.get(group); - expanded = Ext.isDefined(expanded) ? expanded : gel.hasClass('x-grid-group-collapsed'); - if(this.state[gel.id] !== expanded){ - if (this.cancelEditOnToggle !== false) { - this.grid.stopEditing(true); - } - this.state[gel.id] = expanded; - gel[expanded ? 'removeClass' : 'addClass']('x-grid-group-collapsed'); - } + + handleStateChange: function(token) { + this.currentToken = token; + this.fireEvent('change', token); }, - - toggleAllGroups : function(expanded){ - var groups = this.getGroups(); - for(var i = 0, len = groups.length; i < len; i++){ - this.toggleGroup(groups[i], expanded); + updateIFrame: function(token) { + var html = '
    ' + + Ext.util.Format.htmlEncode(token) + + '
    '; + + try { + var doc = this.iframe.contentWindow.document; + doc.open(); + doc.write(html); + doc.close(); + return true; + } catch (e) { + return false; } }, - - expandAllGroups : function(){ - this.toggleAllGroups(true); + checkIFrame: function () { + var me = this, + contentWindow = me.iframe.contentWindow; + + if (!contentWindow || !contentWindow.document) { + Ext.Function.defer(this.checkIFrame, 10, this); + return; + } + + var doc = contentWindow.document, + elem = doc.getElementById("state"), + oldToken = elem ? elem.innerText : null, + oldHash = me.getHash(); + + Ext.TaskManager.start({ + run: function () { + var doc = contentWindow.document, + elem = doc.getElementById("state"), + newToken = elem ? elem.innerText : null, + newHash = me.getHash(); + + if (newToken !== oldToken) { + oldToken = newToken; + me.handleStateChange(newToken); + window.top.location.hash = newToken; + oldHash = newToken; + me.doSave(); + } else if (newHash !== oldHash) { + oldHash = newHash; + me.updateIFrame(newHash); + } + }, + interval: 50, + scope: me + }); + me.ready = true; + me.fireEvent('ready', me); }, - - collapseAllGroups : function(){ - this.toggleAllGroups(false); - }, + startUp: function () { + var me = this; + + me.currentToken = me.hiddenField.value || this.getHash(); - - getGroup : function(v, r, groupRenderer, rowIndex, colIndex, ds){ - var column = this.cm.config[colIndex], - g = groupRenderer ? groupRenderer.call(column.scope, v, {}, r, rowIndex, colIndex, ds) : String(v); - if(g === '' || g === ' '){ - g = column.emptyGroupText || this.emptyGroupText; + if (me.oldIEMode) { + me.checkIFrame(); + } else { + var hash = me.getHash(); + Ext.TaskManager.start({ + run: function () { + var newHash = me.getHash(); + if (newHash !== hash) { + hash = newHash; + me.handleStateChange(hash); + me.doSave(); + } + }, + interval: 50, + scope: me + }); + me.ready = true; + me.fireEvent('ready', me); } - return g; + }, - getGroupField : function(){ - return this.grid.store.getGroupState(); - }, + fieldId: Ext.baseCSSPrefix + 'history-field', + + iframeId: Ext.baseCSSPrefix + 'history-frame', - afterRender : function(){ - if(!this.ds || !this.cm){ + init: function (onReady, scope) { + var me = this; + + if (me.ready) { + Ext.callback(onReady, scope, [me]); return; } - Ext.grid.GroupingView.superclass.afterRender.call(this); - if(this.grid.deferRowRender){ - this.updateGroupWidths(); - } - }, - - afterRenderUI: function () { - Ext.grid.GroupingView.superclass.afterRenderUI.call(this); - - if (this.enableGroupingMenu && this.hmenu) { - this.hmenu.add('-',{ - itemId:'groupBy', - text: this.groupByText, - handler: this.onGroupByClick, - scope: this, - iconCls:'x-group-by-icon' + + if (!Ext.isReady) { + Ext.onReady(function() { + me.init(onReady, scope); }); + return; + } + + me.hiddenField = Ext.getDom(me.fieldId); + + if (me.oldIEMode) { + me.iframe = Ext.getDom(me.iframeId); + } + + me.addEvents( - if (this.enableNoGroups) { - this.hmenu.add({ - itemId:'showGroups', - text: this.showGroupsText, - checked: true, - checkHandler: this.onShowGroupsClick, - scope: this - }); - } + 'ready', - this.hmenu.on('beforeshow', this.beforeMenuShow, this); + 'change' + ); + + if (onReady) { + me.on('ready', onReady, scope, {single: true}); } + me.startUp(); }, - renderRows : function(){ - var groupField = this.getGroupField(); - var eg = !!groupField; + add: function (token, preventDup) { + var me = this; - if(this.hideGroupedColumn) { - var colIndex = this.cm.findColumnIndex(groupField), - hasLastGroupField = Ext.isDefined(this.lastGroupField); - if(!eg && hasLastGroupField){ - this.mainBody.update(''); - this.cm.setHidden(this.cm.findColumnIndex(this.lastGroupField), false); - delete this.lastGroupField; - }else if (eg && !hasLastGroupField){ - this.lastGroupField = groupField; - this.cm.setHidden(colIndex, true); - }else if (eg && hasLastGroupField && groupField !== this.lastGroupField) { - this.mainBody.update(''); - var oldIndex = this.cm.findColumnIndex(this.lastGroupField); - this.cm.setHidden(oldIndex, false); - this.lastGroupField = groupField; - this.cm.setHidden(colIndex, true); + if (preventDup !== false) { + if (me.getToken() === token) { + return true; } } - return Ext.grid.GroupingView.superclass.renderRows.apply( - this, arguments); + + if (me.oldIEMode) { + return me.updateIFrame(token); + } else { + window.top.location.hash = token; + return true; + } }, - doRender : function(cs, rs, ds, startRow, colCount, stripe){ - if(rs.length < 1){ - return ''; - } - - if(!this.canGroup() || this.isUpdating){ - return Ext.grid.GroupingView.superclass.doRender.apply(this, arguments); - } - - var groupField = this.getGroupField(), - colIndex = this.cm.findColumnIndex(groupField), - g, - gstyle = 'width:' + this.getTotalWidth() + ';', - cfg = this.cm.config[colIndex], - groupRenderer = cfg.groupRenderer || cfg.renderer, - prefix = this.showGroupName ? (cfg.groupName || cfg.header)+': ' : '', - groups = [], - curGroup, i, len, gid; - - for(i = 0, len = rs.length; i < len; i++){ - var rowIndex = startRow + i, - r = rs[i], - gvalue = r.data[groupField]; - - g = this.getGroup(gvalue, r, groupRenderer, rowIndex, colIndex, ds); - if(!curGroup || curGroup.group != g){ - gid = this.constructId(gvalue, groupField, colIndex); - - - this.state[gid] = !(Ext.isDefined(this.state[gid]) ? !this.state[gid] : this.startCollapsed); - curGroup = { - group: g, - gvalue: gvalue, - text: prefix + g, - groupId: gid, - startRow: rowIndex, - rs: [r], - cls: this.state[gid] ? '' : 'x-grid-group-collapsed', - style: gstyle - }; - groups.push(curGroup); - }else{ - curGroup.rs.push(r); - } - r._groupId = gid; - } - - var buf = []; - for(i = 0, len = groups.length; i < len; i++){ - g = groups[i]; - this.doGroupStart(buf, g, cs, ds, colCount); - buf[buf.length] = Ext.grid.GroupingView.superclass.doRender.call( - this, cs, g.rs, ds, g.startRow, colCount, stripe); - - this.doGroupEnd(buf, g, cs, ds, colCount); - } - return buf.join(''); + back: function() { + window.history.go(-1); }, - getGroupId : function(value){ - var field = this.getGroupField(); - return this.constructId(value, field, this.cm.findColumnIndex(field)); + forward: function(){ + window.history.go(1); }, - constructId : function(value, field, idx){ - var cfg = this.cm.config[idx], - groupRenderer = cfg.groupRenderer || cfg.renderer, - val = (this.groupMode == 'value') ? value : this.getGroup(value, {data:{}}, groupRenderer, 0, idx, this.ds); + getToken: function() { + return this.ready ? this.currentToken : this.getHash(); + } +}); - return this.getPrefix(field) + Ext.util.Format.htmlEncode(val); - }, +Ext.define('Ext.view.TableChunker', { + singleton: true, + requires: ['Ext.XTemplate'], + metaTableTpl: [ + '{[this.openTableWrap()]}', + '', + '', + '', + '', + '', + '', + '', + '{[this.openRows()]}', + '{row}', + '', + '{[this.embedFeature(values, parent, xindex, xcount)]}', + '', + '{[this.closeRows()]}', + '', + '
    ', + '{[this.closeTableWrap()]}' + ], - - canGroup : function(){ - return this.enableGrouping && !!this.getGroupField(); + constructor: function() { + Ext.XTemplate.prototype.recurse = function(values, reference) { + return this.apply(reference ? values[reference] : values); + }; }, - - getPrefix: function(field){ - return this.grid.getGridEl().id + '-gp-' + field + '-'; + embedFeature: function(values, parent, x, xcount) { + var tpl = ''; + if (!values.disabled) { + tpl = values.getFeatureTpl(values, parent, x, xcount); + } + return tpl; }, - - doGroupStart : function(buf, g, cs, ds, colCount){ - buf[buf.length] = this.startGroup.apply(g); + embedFullWidth: function() { + return 'style="width: {fullWidth}px;"'; }, - - doGroupEnd : function(buf, g, cs, ds, colCount){ - buf[buf.length] = this.endGroup; + openRows: function() { + return ''; }, - - getRows : function(){ - if(!this.canGroup()){ - return Ext.grid.GroupingView.superclass.getRows.call(this); - } - var r = [], - gs = this.getGroups(), - g, - i = 0, - len = gs.length, - j, - jlen; - for(; i < len; ++i){ - g = gs[i].childNodes[1]; - if(g){ - g = g.childNodes; - for(j = 0, jlen = g.length; j < jlen; ++j){ - r[r.length] = g[j]; - } - } - } - return r; + closeRows: function() { + return ''; }, + metaRowTpl: [ + '', + '', + '
    {{id}}
    ', + '
    ', + '' + ], - updateGroupWidths : function(){ - if(!this.canGroup() || !this.hasRows()){ - return; - } - var tw = Math.max(this.cm.getTotalWidth(), this.el.dom.offsetWidth-this.getScrollOffset()) +'px'; - var gs = this.getGroups(); - for(var i = 0, len = gs.length; i < len; i++){ - gs[i].firstChild.style.width = tw; + firstOrLastCls: function(xindex, xcount) { + var cssCls = ''; + if (xindex === 1) { + cssCls = Ext.baseCSSPrefix + 'grid-cell-first'; + } else if (xindex === xcount) { + cssCls = Ext.baseCSSPrefix + 'grid-cell-last'; } + return cssCls; }, - - onColumnWidthUpdated : function(col, w, tw){ - Ext.grid.GroupingView.superclass.onColumnWidthUpdated.call(this, col, w, tw); - this.updateGroupWidths(); + embedRowCls: function() { + return '{rowCls}'; }, - - onAllColumnWidthsUpdated : function(ws, tw){ - Ext.grid.GroupingView.superclass.onAllColumnWidthsUpdated.call(this, ws, tw); - this.updateGroupWidths(); + embedRowAttr: function() { + return '{rowAttr}'; }, - - onColumnHiddenUpdated : function(col, hidden, tw){ - Ext.grid.GroupingView.superclass.onColumnHiddenUpdated.call(this, col, hidden, tw); - this.updateGroupWidths(); + openTableWrap: function() { + return ''; }, - - onLayout : function(){ - this.updateGroupWidths(); + closeTableWrap: function() { + return ''; }, - - onBeforeRowSelect : function(sm, rowIndex){ - this.toggleRowIndex(rowIndex, true); + getTableTpl: function(cfg, textOnly) { + var tpl, + tableTplMemberFns = { + openRows: this.openRows, + closeRows: this.closeRows, + embedFeature: this.embedFeature, + embedFullWidth: this.embedFullWidth, + openTableWrap: this.openTableWrap, + closeTableWrap: this.closeTableWrap + }, + tplMemberFns = {}, + features = cfg.features || [], + ln = features.length, + i = 0, + memberFns = { + embedRowCls: this.embedRowCls, + embedRowAttr: this.embedRowAttr, + firstOrLastCls: this.firstOrLastCls + }, + + metaRowTpl = Array.prototype.slice.call(this.metaRowTpl, 0), + metaTableTpl; + + for (; i < ln; i++) { + if (!features[i].disabled) { + features[i].mutateMetaRowTpl(metaRowTpl); + Ext.apply(memberFns, features[i].getMetaRowTplFragments()); + Ext.apply(tplMemberFns, features[i].getFragmentTpl()); + Ext.apply(tableTplMemberFns, features[i].getTableFragments()); + } + } + + metaRowTpl = Ext.create('Ext.XTemplate', metaRowTpl.join(''), memberFns); + cfg.row = metaRowTpl.applyTemplate(cfg); + + metaTableTpl = Ext.create('Ext.XTemplate', this.metaTableTpl.join(''), tableTplMemberFns); + + tpl = metaTableTpl.applyTemplate(cfg); + + + if (!textOnly) { + tpl = Ext.create('Ext.XTemplate', tpl, tplMemberFns); + } + return tpl; + } }); -Ext.grid.GroupingView.GROUP_ID = 1000; + + +